FreeCalypso > hg > fc-tourmaline
comparison src/ui/atb/ATBPb.c @ 3:67bfe9f274f6
src/ui: import of src/ui3 from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:33:10 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:3a14ee9a9843 | 3:67bfe9f274f6 |
---|---|
1 /******************************************************************************* | |
2 | |
3 CONDAT (UK) | |
4 | |
5 ******************************************************************************** | |
6 | |
7 This software product is the property of Condat (UK) Ltd and may not be | |
8 disclosed to any third party without the express permission of the owner. | |
9 | |
10 ******************************************************************************** | |
11 | |
12 $Project name: | |
13 $Project code: | |
14 $Module: | |
15 $File: ATBPb.c | |
16 $Revision: | |
17 | |
18 $Author: Condat(UK) | |
19 $Date: | |
20 | |
21 ******************************************************************************** | |
22 | |
23 Description: | |
24 | |
25 | |
26 ******************************************************************************** | |
27 | |
28 $History: ATBPb.c | |
29 | |
30 Jan 18, 2004 REF: CRR MMI-SPR-25332 xnkulkar | |
31 Description: Moving entries from Sim Card to phone memory fails. | |
32 Solution: When entries are moved, corresponding updations are done in cache as well. | |
33 | |
34 | |
35 $End | |
36 | |
37 *******************************************************************************/ | |
38 | |
39 #if defined (NEW_FRAME) | |
40 | |
41 #include "typedefs.h" | |
42 #include "vsi.h" | |
43 #include "pei.h" | |
44 #include "custom.h" | |
45 #include "gsm.h" | |
46 | |
47 #else | |
48 | |
49 #include "STDDEFS.H" | |
50 #include "custom.h" | |
51 #include "gsm.h" | |
52 #include "vsi.h" | |
53 | |
54 #endif | |
55 | |
56 #include <stdio.h> | |
57 #include <string.h> | |
58 | |
59 #include "mfw_mfw.h" | |
60 #include "mfw_sys.h" | |
61 | |
62 #include "cus_aci.h" | |
63 #include "prim.h" | |
64 #include "pcm.h" | |
65 | |
66 #include "ATBPb.h" | |
67 #include "ATBPb_i.h" | |
68 | |
69 /* Global data for phonebook */ | |
70 | |
71 static T_PB_DATA *phonebook[PB_PHONEBOOKS_MAX] = {0}; | |
72 | |
73 | |
74 /******************************************************************************* | |
75 | |
76 $Function: ATB_pb_GetPhonebook | |
77 | |
78 $Description: Checks to see which file system is selected | |
79 | |
80 $Returns: PB_OK Action completed OK. | |
81 PB_FILEWRITEFAIL File write encountered an error | |
82 | |
83 $Arguments: phonebook_id The phonebook identifier | |
84 current_type Place to store type of phonebook selected. | |
85 | |
86 *******************************************************************************/ | |
87 | |
88 PB_RET ATB_pb_GetPhonebook(SHORT phonebook_id, T_PB_TYPE *current_type) | |
89 { | |
90 PB_RET result; | |
91 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
92 | |
93 tracefunction("ATB_pb_GetPhonebook"); | |
94 | |
95 if (data) | |
96 { | |
97 *current_type = data->current_type; | |
98 return PB_OK; | |
99 } | |
100 | |
101 result = FS_pb_GetPhonebook(phonebook_id, current_type); | |
102 | |
103 return result; | |
104 } | |
105 | |
106 | |
107 /******************************************************************************* | |
108 | |
109 $Function: ATB_pb_SetPhonebook | |
110 | |
111 $Description: Select file system | |
112 | |
113 $Returns: PB_OK Action completed OK. | |
114 PB_FILEREADFAIL File read encountered an error | |
115 | |
116 $Arguments: phonebook_id The phonebook identifier | |
117 current_type Type of phonebook selected. | |
118 | |
119 *******************************************************************************/ | |
120 | |
121 PB_RET ATB_pb_SetPhonebook(SHORT phonebook_id, T_PB_TYPE current_type) | |
122 { | |
123 PB_RET result; | |
124 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
125 | |
126 tracefunction("ATB_pb_SetPhonebook"); | |
127 | |
128 if (data) | |
129 data->current_type = current_type; | |
130 | |
131 result = FS_pb_SetPhonebook(phonebook_id, current_type); | |
132 | |
133 return result; | |
134 } | |
135 | |
136 | |
137 /******************************************************************************* | |
138 | |
139 $Function: ATB_pb_Initialise | |
140 | |
141 $Description: Initialise an instance of phonebook. Dynamically allocates a record | |
142 cache in RAM. Creates the necessary file(s) if they do not already exist. | |
143 Sorts the phonebook by name and by number, creating the appropriate | |
144 index tables. | |
145 IMPORTANT: if the file reading is non-blocking - i.e. if a request to read | |
146 a file does not return with an answer straight away, but the system | |
147 awaits a callback - then "cache_max" must equal "records_max". This | |
148 ensures that all records are stored in RAM and can be retrieved without | |
149 waiting for a response. If the file reading is blocking, then cache_max | |
150 can be smaller than records_max. | |
151 | |
152 The memory allocated by this operation will not be freed until | |
153 ATB_pb_Exit() is called. | |
154 | |
155 $Returns: PB_OK Action completed OK. | |
156 PB_EXCT Action currently executing, callback awaited. | |
157 GI_pb_OK will be called if successful, | |
158 GI_pb_Error otherwise. | |
159 PB_BUSY Failed, phonebook is busy. | |
160 PB_FILEREADFAIL File read encountered an error | |
161 PB_FILEWRITEFAIL File write encountered an error | |
162 PB_BOOKALREADYEXISTS Tried to initialise a phonebook that already | |
163 exists | |
164 | |
165 $Arguments: phonebook_id The phonebook identifier | |
166 type Type of phonebook. | |
167 records_max Indicates the maximum number of entries the | |
168 phonebook can hold. | |
169 cache_max Indicates the maximum number of records that the | |
170 PB will store concurrently in RAM. | |
171 alpha_max Maximum size of unicode alpha tag in characters | |
172 number_max Maximum size of phone number in digits | |
173 ext_max Maximum size of extended data in bytes | |
174 | |
175 *******************************************************************************/ | |
176 | |
177 PB_RET ATB_pb_Initialise(SHORT phonebook_id, T_PB_TYPE type, SHORT records_max, SHORT cache_max, | |
178 SHORT alpha_max, SHORT number_max, SHORT ext_max) | |
179 { | |
180 T_PB_DATA *data; | |
181 | |
182 tracefunction("ATB_pb_Initialise()"); | |
183 | |
184 /* Check to see if this phonebook has already been allocated */ | |
185 | |
186 if (ATB_hnd_GetPbData(phonebook_id)!=NULL) | |
187 { | |
188 trace("* ERROR * - Phonebook already exists"); | |
189 GI_pb_Error(phonebook_id, PB_INITIALISE, PB_BOOKALREADYEXISTS); | |
190 return PB_BOOKALREADYEXISTS; | |
191 } | |
192 | |
193 /* Allocate memory for phonebook data */ | |
194 | |
195 data = (T_PB_DATA *)GI_pb_MemAlloc(sizeof(T_PB_DATA)); | |
196 ATB_hnd_SetPbData(phonebook_id, data); | |
197 | |
198 data->records_max = records_max; | |
199 data->records_used = 0; | |
200 data->search_results = 0; | |
201 | |
202 data->alpha_max = alpha_max; | |
203 data->number_max = number_max; | |
204 data->ext_max = ext_max; | |
205 | |
206 /* Allocate memory for index tables */ | |
207 | |
208 data->name_table = (SHORT *)GI_pb_MemAlloc(records_max*sizeof(SHORT)); | |
209 memset(data->name_table, 0, records_max*sizeof(SHORT)); | |
210 data->number_table = (SHORT *)GI_pb_MemAlloc(records_max*sizeof(SHORT)); | |
211 memset(data->number_table, 0, records_max*sizeof(SHORT)); | |
212 data->search_table = (SHORT *)GI_pb_MemAlloc(records_max*sizeof(SHORT)); | |
213 memset(data->search_table, 0, records_max*sizeof(SHORT)); | |
214 data->in_memory = (SHORT *)GI_pb_MemAlloc(records_max*sizeof(SHORT)); | |
215 memset(data->in_memory, PB_EMPTY_RECORD, records_max*sizeof(SHORT)); | |
216 | |
217 /* Allocate memory for cache */ | |
218 | |
219 data->cache_max = cache_max; | |
220 data->cache_size = 0; | |
221 data->cache = (T_PB_RECORD **)GI_pb_MemAlloc(records_max*sizeof(T_PB_RECORD *)); | |
222 memset(data->cache, 0, records_max*sizeof(T_PB_RECORD *)); | |
223 | |
224 /* Set up command */ | |
225 | |
226 data->command_id = PB_INITIALISE; | |
227 data->status = PB_STATUS_INIT; | |
228 data->param.Initialise.type = type; | |
229 data->param.Initialise.records_max = records_max; | |
230 | |
231 return ATB_status_Initialise(phonebook_id); | |
232 } | |
233 | |
234 /* Status function for Initialise */ | |
235 | |
236 PB_RET ATB_status_Initialise(SHORT phonebook_id) | |
237 { | |
238 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
239 T_PB_INITIALISE *Initialise; | |
240 SHORT blocking; | |
241 PB_RET result=PB_ERROR; | |
242 | |
243 /* Ensure that phonebook exists */ | |
244 if (!data) | |
245 { | |
246 trace("**ERROR** Phonebook does not exist"); | |
247 return PB_BOOKDOESNOTEXIST; | |
248 } | |
249 | |
250 Initialise = &data->param.Initialise; | |
251 blocking = TRUE; | |
252 while (blocking) | |
253 { | |
254 switch(data->status) | |
255 { | |
256 case PB_STATUS_INIT: | |
257 trace("ATB_status_Initialise: INIT"); | |
258 result = FS_pb_Initialise(phonebook_id, Initialise->type, Initialise->records_max, | |
259 data->alpha_max, data->number_max, data->ext_max); | |
260 | |
261 /* Select next state */ | |
262 | |
263 data->status = PB_STATUS_EXEC; | |
264 Initialise->phys_index = 0; | |
265 Initialise->first_record = TRUE; | |
266 Initialise->record = ATB_pb_AllocRec(phonebook_id); | |
267 | |
268 /* Allow exit from function */ | |
269 | |
270 if (result!=PB_OK) | |
271 blocking = FALSE; | |
272 break; | |
273 | |
274 case PB_STATUS_EXEC: | |
275 trace("ATB_status_Initialise: EXEC"); | |
276 | |
277 /* Try to read in index tables from file system. If we can't find them, the | |
278 * records will be read in and sorted. */ | |
279 | |
280 if (Initialise->first_record) | |
281 { | |
282 result = FS_pb_ReadTables(phonebook_id, &data->records_used, data->name_table, data->number_table); | |
283 if (result==PB_OK) | |
284 { | |
285 /* Escape to PB_STATUS_COMPLETE */ | |
286 result = PB_OK; | |
287 data->status = PB_STATUS_COMPLETE; | |
288 break; | |
289 } | |
290 } | |
291 /* If we've already read a record, and it's an existing record, add it to the | |
292 * index tables and to the cache */ | |
293 | |
294 else | |
295 { | |
296 if (Initialise->record->alpha.data[0]!=(USHORT)0xFFFF) | |
297 { | |
298 ATB_mem_UpdateCache(phonebook_id, Initialise->phys_index, Initialise->record); | |
299 ATB_index_AddRec(phonebook_id, INDEX_NAME, Initialise->phys_index, Initialise->record, NULL); | |
300 ATB_index_AddRec(phonebook_id, INDEX_NUMBER, Initialise->phys_index, Initialise->record, NULL); | |
301 data->records_used++; | |
302 } | |
303 | |
304 Initialise->phys_index++; | |
305 } | |
306 | |
307 /* Start processing after first record is read */ | |
308 | |
309 Initialise->first_record = FALSE; | |
310 | |
311 /* If we haven't just read the last record, read the next one */ | |
312 | |
313 if (Initialise->phys_index<data->records_max) | |
314 { | |
315 result = FS_pb_ReadRec(phonebook_id, Initialise->phys_index, Initialise->record); | |
316 } | |
317 else | |
318 { | |
319 /* Set next state as finished */ | |
320 result = PB_OK; | |
321 data->status = PB_STATUS_COMPLETE; | |
322 } | |
323 | |
324 | |
325 /* Allow exit from function */ | |
326 | |
327 if (result!=PB_OK) | |
328 blocking = FALSE; | |
329 break; | |
330 | |
331 case PB_STATUS_COMPLETE: | |
332 trace("ATB_status_Initialise: COMPLETE"); | |
333 blocking = FALSE; | |
334 | |
335 /* Close file */ | |
336 | |
337 FS_pb_Finished(phonebook_id); | |
338 FS_pb_WriteTables(phonebook_id, data->records_used, data->name_table, data->number_table); | |
339 | |
340 /* Free the allocated record */ | |
341 | |
342 ATB_pb_FreeRec(phonebook_id, Initialise->record); | |
343 | |
344 /* Notify the GI of success */ | |
345 GI_pb_OK(phonebook_id, data->command_id, NULL); | |
346 result = PB_OK; | |
347 data->status = PB_STATUS_NONE; | |
348 break; | |
349 } | |
350 } | |
351 | |
352 return result; | |
353 } | |
354 | |
355 | |
356 /******************************************************************************* | |
357 | |
358 $Function: ATB_pb_Exit | |
359 | |
360 $Description: Frees memory associated with phonebook. To be called when the | |
361 phonebook is no longer required, or at shutdown. | |
362 | |
363 $Returns: PB_OK Action completed OK. | |
364 | |
365 $Arguments: phonebook_id The phonebook identifier | |
366 | |
367 *******************************************************************************/ | |
368 | |
369 PB_RET ATB_pb_Exit(SHORT phonebook_id) | |
370 { | |
371 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
372 SHORT phys_index; | |
373 | |
374 trace("ATB_pb_Exit"); | |
375 | |
376 /* Ensure that phonebook exists */ | |
377 if (!data) | |
378 { | |
379 trace("**ERROR** Phonebook does not exist"); | |
380 return PB_BOOKDOESNOTEXIST; | |
381 } | |
382 | |
383 for (phys_index = 0; phys_index<data->records_max; phys_index++) | |
384 { | |
385 if (data->cache[phys_index]!=NULL) | |
386 ATB_pb_FreeRec(phonebook_id, data->cache[phys_index]); | |
387 } | |
388 | |
389 GI_pb_MemFree((UBYTE *)data->cache, data->records_max*sizeof(T_PB_RECORD *)); | |
390 GI_pb_MemFree((UBYTE *)data->in_memory, data->records_max*sizeof(SHORT)); | |
391 GI_pb_MemFree((UBYTE *)data->search_table, data->records_max*sizeof(SHORT)); | |
392 GI_pb_MemFree((UBYTE *)data->number_table, data->records_max*sizeof(SHORT)); | |
393 GI_pb_MemFree((UBYTE *)data->name_table, data->records_max*sizeof(SHORT)); | |
394 | |
395 GI_pb_MemFree((UBYTE *)data, sizeof(T_PB_DATA)); | |
396 | |
397 ATB_hnd_SetPbData(phonebook_id, NULL); | |
398 return PB_OK; | |
399 } | |
400 | |
401 | |
402 /******************************************************************************* | |
403 | |
404 $Function: ATB_pb_Status | |
405 | |
406 $Description: Returns PB_OK if the phonebook is ready for a new command, | |
407 or PB_BUSY if the phonebook is busy. | |
408 | |
409 $Returns: PB_OK All tasks completed, phonebook ready. | |
410 PB_BUSY Commands currently executing. | |
411 | |
412 $Arguments: phonebook_id The phonebook identifier | |
413 | |
414 *******************************************************************************/ | |
415 | |
416 PB_RET ATB_pb_Status(SHORT phonebook_id) | |
417 { | |
418 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
419 PB_RET result; | |
420 | |
421 /* Ensure that phonebook exists */ | |
422 if (!data) | |
423 { | |
424 trace("**ERROR** Phonebook does not exist"); | |
425 return PB_BOOKDOESNOTEXIST; | |
426 } | |
427 | |
428 // Jan 18, 2004 REF: CRR MMI-SPR-25332 xnkulkar | |
429 // Description: Moving entries from Sim Card to phone memory fails. | |
430 // Solution: result should be set as PB_OK when PB_STATUS_COMPLETE is true also. | |
431 if ((data->status==PB_STATUS_NONE) ||(data->status==PB_STATUS_COMPLETE)) | |
432 result = PB_OK; | |
433 else | |
434 result = PB_BUSY; | |
435 | |
436 return result; | |
437 } | |
438 | |
439 | |
440 /******************************************************************************* | |
441 | |
442 $Function: ATB_pb_Info | |
443 | |
444 $Description: Returns information about the phonebook, which will be returned | |
445 in the data structure pointed to by phonebook_info. The caller must | |
446 allocate the T_PB_INFO structure. | |
447 | |
448 $Returns: PB_OK Action completed OK. | |
449 | |
450 $Arguments: phonebook_id The phonebook identifier | |
451 phonebook_info Pointer to data structure to contain phonebook | |
452 information (allocated by caller). | |
453 | |
454 *******************************************************************************/ | |
455 | |
456 PB_RET ATB_pb_Info(SHORT phonebook_id, T_PB_INFO *phonebook_info) | |
457 { | |
458 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
459 | |
460 /* Ensure that phonebook exists */ | |
461 if (!data) | |
462 { | |
463 trace("**ERROR** Phonebook does not exist"); | |
464 return PB_BOOKDOESNOTEXIST; | |
465 } | |
466 | |
467 phonebook_info->records_used = data->records_used; | |
468 phonebook_info->records_max = data->records_max; | |
469 phonebook_info->records_free = data->records_max - data->records_used; | |
470 phonebook_info->search_results = data->search_results; | |
471 | |
472 return PB_OK; | |
473 } | |
474 | |
475 | |
476 /******************************************************************************* | |
477 | |
478 $Function: ATB_pb_ReadRec | |
479 | |
480 $Description: Reads a record from the logical position index. The record information | |
481 will be returned in the data structure pointed to by record. The | |
482 T_PB_RECORD structure must be allocated by the user. | |
483 | |
484 This function calls the ATB_mem_ReadRec function, with an additional | |
485 check to make sure no other commands are currently executing. | |
486 | |
487 $Returns: PB_OK Action completed OK. | |
488 PB_BUSY Failed, phonebook is busy. | |
489 PB_FILEREADFAIL File read encountered an error | |
490 PB_RECDOESNOTEXIST Tried to access a record that does not exist | |
491 | |
492 $Arguments: phonebook_id The phonebook identifier | |
493 index_type The index list from which the record is to be read | |
494 log_index Logical index in the index list of the record to read | |
495 record Structure in which to store record data | |
496 | |
497 *******************************************************************************/ | |
498 | |
499 PB_RET ATB_pb_ReadRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index, T_PB_RECORD *record) | |
500 { | |
501 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
502 PB_RET result; | |
503 | |
504 tracefunction("ATB_pb_ReadRec"); | |
505 | |
506 /* Ensure that phonebook exists */ | |
507 if (!data) | |
508 { | |
509 trace("**ERROR** Phonebook does not exist"); | |
510 return PB_BOOKDOESNOTEXIST; | |
511 } | |
512 | |
513 /* Make sure phonebook is not busy */ | |
514 | |
515 if (ATB_pb_Status(phonebook_id)==PB_BUSY) | |
516 { | |
517 trace("* ERROR * - Phonebook is busy"); | |
518 result = PB_BUSY; | |
519 } | |
520 else | |
521 { | |
522 /* Read the record from cache or from file */ | |
523 | |
524 result = ATB_mem_ReadRec(phonebook_id, index_type, log_index, record); | |
525 } | |
526 | |
527 /* Send success/failure info to the GI */ | |
528 | |
529 if (result==PB_OK) | |
530 GI_pb_OK(phonebook_id, PB_READREC, NULL); | |
531 else if (result!=PB_EXCT) | |
532 GI_pb_Error(phonebook_id, PB_READREC, result); | |
533 | |
534 /* Close any open file */ | |
535 | |
536 FS_pb_Finished(phonebook_id); | |
537 | |
538 return result; | |
539 } | |
540 | |
541 | |
542 /******************************************************************************* | |
543 | |
544 $Function: ATB_pb_WriteRec | |
545 | |
546 $Description: Writes a record to the logical position index. If the index is | |
547 PB_NEW_RECORD, a new record is added, otherwise the previous | |
548 record at that position is overwritten. The name and number index lists | |
549 will be updated with the new entry in the appropriate place in each. | |
550 GI_pb_OK will be called to confirm that the write completed successfully, | |
551 otherwise GI_pb_Error will be called with an error code. | |
552 Since the order of the records may change due to sorting, GI_pb_OK | |
553 will receive a pointer to an integer new_log_index, which will store the | |
554 new position of the record in the chosen index list. This is allocated | |
555 by and will be destroyed by the phonebook, so must be copied by the | |
556 GI before function return. | |
557 | |
558 $Returns: PB_OK Action completed OK. | |
559 PB_EXCT Action currently executing, callback awaited. | |
560 GI_pb_OK will be called if successful, | |
561 GI_pb_Error otherwise. | |
562 GI_pb_OK will receive a pointer to the following: | |
563 SHORT new_log_index - The new position of the | |
564 record in the chosen index list | |
565 PB_BUSY Failed, phonebook is busy. | |
566 PB_FILEWRITEFAIL File write encountered an error | |
567 PB_RECDOESNOTEXIST (Overwriting only) Tried to access a record that | |
568 does not exist | |
569 | |
570 $Arguments: phonebook_id The phonebook identifier | |
571 index_type The index list of the record to write | |
572 log_index Logical index in the index list of the record to write | |
573 record Pointer to record data to write to phonebook | |
574 (allocated by caller) | |
575 | |
576 *******************************************************************************/ | |
577 /*a0393213 warnings removal-second parameter type changed from T_PB_TYPE to T_PB_INDEX*/ | |
578 PB_RET ATB_pb_WriteRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index, T_PB_RECORD *record) | |
579 { | |
580 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
581 SHORT phys_index; | |
582 | |
583 tracefunction("ATB_pb_WriteRec"); | |
584 | |
585 /* Ensure that phonebook exists */ | |
586 if (!data) | |
587 { | |
588 trace("**ERROR** Phonebook does not exist"); | |
589 return PB_BOOKDOESNOTEXIST; | |
590 } | |
591 | |
592 /* Make sure phonebook is not busy */ | |
593 | |
594 if (ATB_pb_Status(phonebook_id)==PB_BUSY) | |
595 { | |
596 trace("* ERROR * - Phonebook is busy"); | |
597 GI_pb_Error(phonebook_id, PB_WRITEREC, PB_BUSY); | |
598 return PB_BUSY; | |
599 } | |
600 | |
601 /* Are we adding a new record, or overwriting an old one? */ | |
602 | |
603 if (log_index==PB_NEW_RECORD) | |
604 { | |
605 /* Is phonebook full? */ | |
606 | |
607 if (data->records_used==data->records_max) | |
608 { | |
609 GI_pb_Error(phonebook_id, PB_WRITEREC, PB_BOOKFULL); | |
610 return PB_BOOKFULL; | |
611 } | |
612 | |
613 /* Find an empty physical record */ | |
614 for (phys_index=0; phys_index<data->records_max; phys_index++) | |
615 { | |
616 if (data->in_memory[phys_index]==PB_EMPTY_RECORD) | |
617 break; | |
618 } | |
619 } | |
620 else | |
621 { | |
622 /* Check that record exists */ | |
623 | |
624 if (log_index<0 | |
625 || (log_index>=data->records_used && (index_type==INDEX_NAME || index_type==INDEX_NUMBER)) | |
626 || (index_type==INDEX_SEARCH && log_index>data->search_results) | |
627 || (index_type==INDEX_PHYSICAL && log_index>data->records_max)) | |
628 { | |
629 GI_pb_Error(phonebook_id, PB_WRITEREC, PB_RECDOESNOTEXIST); | |
630 return PB_RECDOESNOTEXIST; | |
631 } | |
632 | |
633 phys_index = ATB_index_GetPhysIndex(phonebook_id, index_type, log_index); | |
634 } | |
635 | |
636 /* Set up command */ | |
637 | |
638 data->command_id = PB_WRITEREC; | |
639 data->status = PB_STATUS_INIT; | |
640 | |
641 data->param.WriteRec.log_index = log_index; | |
642 data->param.WriteRec.index_type = index_type; | |
643 data->param.WriteRec.phys_index = phys_index; | |
644 data->param.WriteRec.record = record; | |
645 | |
646 return ATB_status_WriteRec(phonebook_id); | |
647 } | |
648 | |
649 /* Status function for WriteRec */ | |
650 | |
651 PB_RET ATB_status_WriteRec(SHORT phonebook_id) | |
652 { | |
653 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
654 T_PB_WRITEREC *WriteRec = &data->param.WriteRec; | |
655 SHORT blocking; | |
656 PB_RET result=PB_ERROR; | |
657 SHORT name_log_index; | |
658 SHORT number_log_index; | |
659 SHORT *log_index_return; | |
660 | |
661 blocking = TRUE; | |
662 while (blocking) | |
663 { | |
664 switch(data->status) | |
665 { | |
666 case PB_STATUS_INIT: | |
667 result = FS_pb_WriteRec(phonebook_id, WriteRec->phys_index, WriteRec->record); | |
668 | |
669 /* Select next state */ | |
670 | |
671 data->status = PB_STATUS_COMPLETE; | |
672 | |
673 /* Allow exit from function */ | |
674 | |
675 if (result!=PB_OK) | |
676 blocking = FALSE; | |
677 break; | |
678 | |
679 case PB_STATUS_COMPLETE: | |
680 | |
681 if (WriteRec->log_index!=PB_NEW_RECORD) | |
682 { | |
683 name_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NAME, WriteRec->phys_index); | |
684 ATB_index_RemoveRec(phonebook_id, INDEX_NAME, name_log_index); | |
685 number_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NUMBER, WriteRec->phys_index); | |
686 ATB_index_RemoveRec(phonebook_id, INDEX_NUMBER, number_log_index); | |
687 data->records_used--; | |
688 } | |
689 | |
690 /* Indicate that record is new, then add to the cache */ | |
691 | |
692 data->in_memory[WriteRec->phys_index] = 0; | |
693 ATB_mem_UpdateCache(phonebook_id, WriteRec->phys_index, WriteRec->record); | |
694 | |
695 /* Add the record to the index lists */ | |
696 | |
697 ATB_index_AddRec(phonebook_id, INDEX_NAME, WriteRec->phys_index, WriteRec->record, &name_log_index); | |
698 ATB_index_AddRec(phonebook_id, INDEX_NUMBER, WriteRec->phys_index, WriteRec->record, &number_log_index); | |
699 data->records_used++; | |
700 | |
701 blocking = FALSE; | |
702 | |
703 /* Close any open file */ | |
704 | |
705 FS_pb_Finished(phonebook_id); | |
706 FS_pb_WriteTables(phonebook_id, data->records_used, data->name_table, data->number_table); | |
707 | |
708 /* Notify the GI of success */ | |
709 log_index_return = NULL; | |
710 if (WriteRec->index_type==INDEX_NAME) | |
711 log_index_return = &name_log_index; | |
712 if (WriteRec->index_type==INDEX_NUMBER) | |
713 log_index_return = &number_log_index; | |
714 | |
715 GI_pb_OK(phonebook_id, data->command_id, log_index_return); | |
716 result = PB_OK; | |
717 data->status = PB_STATUS_NONE; | |
718 break; | |
719 } | |
720 } | |
721 | |
722 /* Report any errors to the GI */ | |
723 | |
724 if (result!=PB_OK && result!=PB_EXCT) | |
725 { | |
726 GI_pb_Error(phonebook_id, PB_WRITEREC, result); | |
727 } | |
728 | |
729 return result; | |
730 } | |
731 | |
732 | |
733 /******************************************************************************* | |
734 | |
735 $Function: ATB_pb_DeleteRec | |
736 | |
737 $Description: Deletes a record at a logical position index. | |
738 GI_pb_OK will be called to confirm that the delete completed successfully, | |
739 otherwise GI_pb_Error will be called with an error code. | |
740 | |
741 $Returns: PB_OK Action completed OK. | |
742 PB_EXCT Action currently executing, callback awaited. | |
743 GI_pb_OK will be called if successful, | |
744 GI_pb_Error otherwise. | |
745 PB_BUSY Failed, phonebook is busy. | |
746 PB_FILEWRITEFAIL File write encountered an error | |
747 PB_RECDOESNOTEXIST Tried to access a record that does not exist | |
748 | |
749 $Arguments: phonebook_id The phonebook identifier | |
750 index_type The index list of the record to delete | |
751 log_index Logical index in the index list of the record to delete | |
752 | |
753 *******************************************************************************/ | |
754 | |
755 PB_RET ATB_pb_DeleteRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index) | |
756 { | |
757 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
758 | |
759 tracefunction("ATB_pb_DeleteRec"); | |
760 | |
761 /* Ensure that phonebook exists */ | |
762 if (!data) | |
763 { | |
764 trace("**ERROR** Phonebook does not exist"); | |
765 return PB_BOOKDOESNOTEXIST; | |
766 } | |
767 | |
768 /* Make sure phonebook is not busy */ | |
769 | |
770 if (ATB_pb_Status(phonebook_id)==PB_BUSY) | |
771 { | |
772 trace("* ERROR * - Phonebook is busy"); | |
773 GI_pb_Error(phonebook_id, PB_DELETEREC, PB_BUSY); | |
774 return PB_BUSY; | |
775 } | |
776 | |
777 /* Check that record exists */ | |
778 | |
779 if (log_index<0 | |
780 || (log_index>=data->records_used && (index_type==INDEX_NAME || index_type==INDEX_NUMBER)) | |
781 || (index_type==INDEX_SEARCH && log_index>data->search_results) | |
782 || (index_type==INDEX_PHYSICAL && log_index>data->records_max)) | |
783 { | |
784 GI_pb_Error(phonebook_id, PB_DELETEREC, PB_RECDOESNOTEXIST); | |
785 return PB_RECDOESNOTEXIST; | |
786 } | |
787 | |
788 /* Set up the command */ | |
789 | |
790 data->command_id = PB_DELETEREC; | |
791 data->status = PB_STATUS_INIT; | |
792 | |
793 data->param.DeleteRec.log_index = log_index; | |
794 data->param.DeleteRec.index_type = index_type; | |
795 data->param.DeleteRec.phys_index = ATB_index_GetPhysIndex(phonebook_id, index_type, log_index); | |
796 | |
797 return ATB_status_DeleteRec(phonebook_id); | |
798 } | |
799 | |
800 /* Status function for DeleteRec */ | |
801 | |
802 PB_RET ATB_status_DeleteRec(SHORT phonebook_id) | |
803 { | |
804 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
805 T_PB_DELETEREC *DeleteRec = &data->param.DeleteRec; | |
806 SHORT blocking; | |
807 PB_RET result=PB_ERROR; | |
808 SHORT name_log_index; | |
809 SHORT number_log_index; | |
810 | |
811 blocking = TRUE; | |
812 while (blocking) | |
813 { | |
814 switch(data->status) | |
815 { | |
816 case PB_STATUS_INIT: | |
817 result = FS_pb_DeleteRec(phonebook_id, DeleteRec->phys_index); | |
818 | |
819 /* Select next state */ | |
820 | |
821 data->status = PB_STATUS_COMPLETE; | |
822 | |
823 /* Allow exit from function */ | |
824 | |
825 if (result!=PB_OK) | |
826 blocking = FALSE; | |
827 break; | |
828 | |
829 case PB_STATUS_COMPLETE: | |
830 name_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NAME, DeleteRec->phys_index); | |
831 ATB_index_RemoveRec(phonebook_id, INDEX_NAME, name_log_index); | |
832 number_log_index = ATB_index_GetLogIndex(phonebook_id, INDEX_NUMBER, DeleteRec->phys_index); | |
833 ATB_index_RemoveRec(phonebook_id, INDEX_NUMBER, number_log_index); | |
834 data->records_used--; | |
835 data->in_memory[DeleteRec->phys_index] = -1; | |
836 | |
837 // Jan 18, 2004 REF: CRR MMI-SPR-25332 xnkulkar | |
838 // Description: Moving entries from Sim Card to phone memory fails. | |
839 // Solution: When entries are moved, corresponding updations are done in cache as well. | |
840 if(data->cache[DeleteRec->phys_index]!=NULL) | |
841 { | |
842 ATB_pb_FreeRec(phonebook_id, data->cache[DeleteRec->phys_index]); | |
843 data->cache[DeleteRec->phys_index]=NULL; | |
844 data->cache_size--; | |
845 } | |
846 | |
847 /* Close any open file */ | |
848 | |
849 FS_pb_Finished(phonebook_id); | |
850 FS_pb_WriteTables(phonebook_id, data->records_used, data->name_table, data->number_table); | |
851 | |
852 blocking = FALSE; | |
853 | |
854 /* Notify the GI of success */ | |
855 | |
856 GI_pb_OK(phonebook_id, data->command_id, NULL); | |
857 result = PB_OK; | |
858 data->status = PB_STATUS_NONE; | |
859 break; | |
860 } | |
861 } | |
862 | |
863 /* Report any errors to the GI */ | |
864 | |
865 if (result!=PB_OK && result!=PB_EXCT) | |
866 { | |
867 GI_pb_Error(phonebook_id, PB_DELETEREC, result); | |
868 } | |
869 | |
870 return result; | |
871 } | |
872 | |
873 | |
874 /******************************************************************************* | |
875 | |
876 $Function: ATB_pb_Find | |
877 | |
878 $Description: Find the nearest match to the supplied record. Only the index_type | |
879 specified will be considered: if the index_type is INDEX_NAME, then the | |
880 name only will be matched; if INDEX_NUMBER, then just the number. | |
881 The new_log_index parameter should be a pointer to a user allocated | |
882 integer. This will return the logical index of the closest match in the | |
883 index list specified. This index either corresponds to a perfect match, | |
884 or to the record that would appear just after the provided record in the | |
885 list. For example, if the list consisted of record 0, Alice and record 1, | |
886 Carol, then a search for Bob would return 1. A search for a record | |
887 that would occur before the first record always returns 0. A search for | |
888 a record that would occur after the last record returns the index of the | |
889 last record +1. | |
890 The "match" parameter should be a pointer to a user allocated variable | |
891 of type T_PB_MATCH. This returns information about how closely the | |
892 found entry matches the record. In the example above, a search for | |
893 Bob would return 1 and MATCH_NONE; a search for Ca would return 1 | |
894 and MATCH_START, and a search for Carol would return 1 and | |
895 MATCH_EXACT. Rarely, match may be MATCH_FRAGMENT: this can be | |
896 considered equivalent to MATCH_NONE in this context. | |
897 | |
898 $Returns: PB_OK Action completed OK. | |
899 PB_BUSY Failed, phonebook is busy. | |
900 PB_FILEREADFAIL File read encountered an error | |
901 PB_RECDOESNOTEXIST Tried to access a record that does not exist | |
902 (should never happen) | |
903 | |
904 $Arguments: phonebook_id The phonebook identifier | |
905 index_type The index_type of the provided record that is to be | |
906 searched for, and the index list that the resulting | |
907 new_log_index pertains to | |
908 record The record whose index_type is to be matched | |
909 new_log_index Returns with the logical index of the closest matching | |
910 record | |
911 match Specifies how good the resulting match was | |
912 (MATCH_NONE, MATCH_START, MATCH_FRAGMENT | |
913 or MATCH_EXACT). | |
914 | |
915 *******************************************************************************/ | |
916 | |
917 | |
918 PB_RET ATB_pb_Find (SHORT phonebook_id, T_PB_INDEX index_type, T_PB_RECORD *record, SHORT *new_log_index, T_PB_MATCH *match) | |
919 { | |
920 PB_RET result; | |
921 | |
922 tracefunction("ATB_pb_Find"); | |
923 | |
924 result = ATB_index_Find(phonebook_id, index_type, record, new_log_index, match); | |
925 | |
926 /* Close any open file */ | |
927 | |
928 FS_pb_Finished(phonebook_id); | |
929 | |
930 /* Send success/failure info to the GI */ | |
931 | |
932 if (result==PB_OK) | |
933 GI_pb_OK(phonebook_id, PB_FIND, NULL); | |
934 else if (result!=PB_EXCT) | |
935 GI_pb_Error(phonebook_id, PB_FIND, result); | |
936 | |
937 return result; | |
938 } | |
939 | |
940 | |
941 /******************************************************************************* | |
942 | |
943 $Function: ATB_pb_ReadRecList | |
944 | |
945 $Description: Fetches record information of sequential records in an index list, starting | |
946 at logical record start_log_index and fetching recs_count records in total. | |
947 The information will be stored in the caller allocated array of records | |
948 provided. | |
949 | |
950 $Returns: PB_OK Action completed OK. | |
951 PB_BUSY Failed, phonebook is busy. | |
952 PB_FILEREADFAIL File read encountered an error | |
953 PB_RECDOESNOTEXIST Tried to access a record that does not exist | |
954 | |
955 $Arguments: phonebook_id The phonebook identifier | |
956 index_type The index list to use | |
957 start_log_index Logical index in the index list of the first record to | |
958 read | |
959 recs_count Total number of sequential records to read. | |
960 record Array of entries in which to store the fetched records. | |
961 The array must be recs_count in size. (Caller allocated). | |
962 | |
963 *******************************************************************************/ | |
964 | |
965 PB_RET ATB_pb_ReadRecList(SHORT phonebook_id, T_PB_INDEX index_type, SHORT start_log_index, SHORT num_recs, T_PB_LIST *list) | |
966 { | |
967 PB_RET result; | |
968 SHORT log_index; | |
969 | |
970 tracefunction("ATB_pb_ReadRecList"); | |
971 | |
972 list->records_used = 0; | |
973 | |
974 /* Make sure phonebook is not busy */ | |
975 | |
976 if (ATB_pb_Status(phonebook_id)==PB_BUSY) | |
977 { | |
978 trace("* ERROR * - Phonebook is busy"); | |
979 /* Report any errors to the GI */ | |
980 GI_pb_Error(phonebook_id, PB_READRECLIST, PB_BUSY); | |
981 return PB_BUSY; | |
982 } | |
983 | |
984 /* Read in list of records */ | |
985 | |
986 for (log_index = start_log_index; log_index<start_log_index+num_recs && log_index<list->records_max; log_index++) | |
987 { | |
988 result = ATB_mem_ReadRec(phonebook_id, index_type, log_index, &list->record[log_index-start_log_index]); | |
989 if (result!=PB_OK) | |
990 break; | |
991 list->records_used++; | |
992 } | |
993 | |
994 /* Close any open file */ | |
995 | |
996 FS_pb_Finished(phonebook_id); | |
997 | |
998 /* Send success/failure info to the GI */ | |
999 | |
1000 if (result==PB_OK) | |
1001 GI_pb_OK(phonebook_id, PB_READRECLIST, NULL); | |
1002 else if (result!=PB_EXCT) | |
1003 GI_pb_Error(phonebook_id, PB_READRECLIST, result); | |
1004 | |
1005 return result; | |
1006 } | |
1007 | |
1008 | |
1009 /******************************************************************************* | |
1010 | |
1011 $Function: ATB_pb_Search | |
1012 | |
1013 $Description: Searches every record in the index list for a fragment. The index list | |
1014 must be either INDEX_NAME or INDEX_NUMBER. If it is INDEX_NAME, | |
1015 then a name fragment will be searched for; if it is INDEX_NUMBER, | |
1016 a number fragment will be searched for. | |
1017 | |
1018 The results are stored in an index list. They may be accessed by | |
1019 using the normal read and write functions, using the index type | |
1020 INDEX_SEARCH. The size of the search list is returned in the variable | |
1021 recs_count. | |
1022 | |
1023 $Returns: PB_OK Action completed OK. | |
1024 PB_BUSY Failed, phonebook is busy. | |
1025 PB_FILEREADFAIL File read encountered an error | |
1026 PB_RECDOESNOTEXIST Tried to access a record that does not exist | |
1027 (should never happen) | |
1028 | |
1029 $Arguments: phonebook_id The phonebook identifier | |
1030 index_type The index list to use | |
1031 record Record containing the fragment to search for | |
1032 recs_count Pointer to an int (user allocated) in which will be returned | |
1033 the number of search results. | |
1034 | |
1035 | |
1036 *******************************************************************************/ | |
1037 | |
1038 PB_RET ATB_pb_Search(SHORT phonebook_id, T_PB_INDEX index_type, T_PB_RECORD *record, SHORT *recs_count) | |
1039 { | |
1040 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1041 PB_RET result; | |
1042 SHORT count = 0; | |
1043 SHORT log_index; | |
1044 T_PB_MATCH match; | |
1045 T_PB_RECORD *cur_record; | |
1046 | |
1047 /* Ensure that phonebook exists */ | |
1048 if (!data) | |
1049 { | |
1050 trace("**ERROR** Phonebook does not exist"); | |
1051 return PB_BOOKDOESNOTEXIST; | |
1052 } | |
1053 | |
1054 /* Allocate record for temporary use */ | |
1055 | |
1056 cur_record = ATB_pb_AllocRec(phonebook_id); | |
1057 | |
1058 /* Make sure phonebook is not busy */ | |
1059 | |
1060 if (ATB_pb_Status(phonebook_id)==PB_BUSY) | |
1061 { | |
1062 trace("* ERROR * - Phonebook is busy"); | |
1063 GI_pb_Error(phonebook_id, PB_SEARCH, PB_BUSY); | |
1064 return PB_BUSY; | |
1065 } | |
1066 | |
1067 /* Make sure we're searching a valid index type */ | |
1068 | |
1069 if (index_type==INDEX_PHYSICAL || index_type==INDEX_SEARCH) | |
1070 { | |
1071 GI_pb_Error(phonebook_id, PB_SEARCH, PB_INDEXINVALID); | |
1072 return PB_INDEXINVALID; | |
1073 } | |
1074 | |
1075 for (log_index=0; log_index<data->records_used; log_index++) | |
1076 { | |
1077 result = ATB_mem_ReadRec(phonebook_id, index_type, log_index, cur_record); | |
1078 if (result!=PB_OK) | |
1079 break; | |
1080 | |
1081 match = ATB_index_Match(record, cur_record, index_type); | |
1082 | |
1083 if (match==MATCH_EXACT || match==MATCH_START || match==MATCH_FRAGMENT) | |
1084 { | |
1085 data->search_table[count] = ATB_index_GetPhysIndex(phonebook_id, index_type, log_index); | |
1086 count++; | |
1087 } | |
1088 } | |
1089 | |
1090 data->search_results = count; | |
1091 *recs_count = count; | |
1092 | |
1093 /* Free allocated record */ | |
1094 | |
1095 ATB_pb_FreeRec(phonebook_id, cur_record); | |
1096 | |
1097 /* Close any open file */ | |
1098 | |
1099 FS_pb_Finished(phonebook_id); | |
1100 | |
1101 /* Send success/failure info to the GI */ | |
1102 | |
1103 if (result==PB_OK) | |
1104 GI_pb_OK(phonebook_id, PB_SEARCH, NULL); | |
1105 else if (result!=PB_EXCT) | |
1106 GI_pb_Error(phonebook_id, PB_SEARCH, result); | |
1107 | |
1108 return result; | |
1109 } | |
1110 | |
1111 | |
1112 /******************************************************************************* | |
1113 | |
1114 $Function: ATB_pb_ConvIndex | |
1115 | |
1116 $Description: Returns the index in table dest_index_type corresponding to the index | |
1117 in table src_index_type. | |
1118 | |
1119 $Returns: PB_OK Action completed OK. | |
1120 | |
1121 $Arguments: phonebook_id The phonebook identifier. | |
1122 index_type The index table of the original index. | |
1123 log_index The original logical index. | |
1124 new_index_type The index table required. | |
1125 new_log_index Pointer to where the new logical index will be stored | |
1126 | |
1127 *******************************************************************************/ | |
1128 | |
1129 PB_RET ATB_pb_ConvIndex(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index, | |
1130 T_PB_INDEX new_index_type, SHORT *new_log_index) | |
1131 { | |
1132 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1133 SHORT phys_index; | |
1134 | |
1135 /* Ensure that phonebook exists */ | |
1136 if (!data) | |
1137 { | |
1138 trace("**ERROR** Phonebook does not exist"); | |
1139 return PB_BOOKDOESNOTEXIST; | |
1140 } | |
1141 | |
1142 if (index_type==new_index_type) | |
1143 { | |
1144 *new_log_index = log_index; | |
1145 } | |
1146 else | |
1147 { | |
1148 phys_index = ATB_index_GetPhysIndex(phonebook_id, index_type, log_index); | |
1149 *new_log_index = ATB_index_GetLogIndex(phonebook_id, new_index_type, phys_index); | |
1150 } | |
1151 | |
1152 return PB_OK; | |
1153 } | |
1154 | |
1155 | |
1156 /******************************************************************************* | |
1157 | |
1158 $Function: ATB_pb_CharToBCD | |
1159 | |
1160 $Description: Converts an ascii string of digits into BCD form, with 4 bits representing | |
1161 each digit. | |
1162 | |
1163 $Returns: None | |
1164 | |
1165 $Arguments: src - source string (ascii) | |
1166 dest - destination string for BCD digits | |
1167 | |
1168 *******************************************************************************/ | |
1169 | |
1170 void ATB_pb_CharToBCD(UBYTE *dest, char *src, int max_len) | |
1171 { | |
1172 UBYTE srcIndex = 0; | |
1173 UBYTE destIndex = 0; | |
1174 BOOL leftbits = TRUE; /* Left or right nibble */ | |
1175 UBYTE digit = 0; | |
1176 //add "*" "#" in number by Peng Hou on 19/06/2006 begin | |
1177 while (digit!=0xF && srcIndex<max_len) | |
1178 { | |
1179 if (src[srcIndex]==NULL) | |
1180 digit = 0xF; /* 0xF terminates BCD */ | |
1181 else | |
1182 { | |
1183 switch ( src[srcIndex] ) | |
1184 { | |
1185 case '0': | |
1186 case '1': | |
1187 case '2': | |
1188 case '3': | |
1189 case '4': | |
1190 case '5': | |
1191 case '6': | |
1192 case '7': | |
1193 case '8': | |
1194 case '9': | |
1195 digit = src[srcIndex]-'0'; | |
1196 break; | |
1197 | |
1198 case '*': | |
1199 digit = 0x0a; | |
1200 break; | |
1201 | |
1202 case '#': | |
1203 digit = 0x0b; | |
1204 break; | |
1205 | |
1206 case 'p': | |
1207 case 'P': | |
1208 digit = 0x0c; | |
1209 break; | |
1210 | |
1211 case 'w': | |
1212 case 'W': | |
1213 digit = 0x0d; | |
1214 break; | |
1215 | |
1216 case 'E': | |
1217 digit = 0x0e; | |
1218 break; | |
1219 | |
1220 default: | |
1221 continue; | |
1222 } | |
1223 } | |
1224 //add "*" "#" in number by Peng Hou on 19/06/2006 end | |
1225 | |
1226 // digit = src[srcIndex]-'0'; /* The digit, 0 to 9. */ | |
1227 | |
1228 | |
1229 if (leftbits) | |
1230 { | |
1231 dest[destIndex] = digit; | |
1232 leftbits = FALSE; | |
1233 } | |
1234 else | |
1235 { | |
1236 dest[destIndex] |= digit<<4; /* *16 shifts right 4 bits */ | |
1237 leftbits = TRUE; | |
1238 destIndex++; | |
1239 } | |
1240 srcIndex++; | |
1241 } | |
1242 | |
1243 return; | |
1244 } | |
1245 | |
1246 | |
1247 /******************************************************************************* | |
1248 | |
1249 $Function: ATB_pb_BCDToChar | |
1250 | |
1251 $Description: Converts a BCD string to ascii digits | |
1252 | |
1253 $Returns: None | |
1254 | |
1255 $Arguments: src - source string (BCD) | |
1256 dest - destination string for ascii digits | |
1257 | |
1258 *******************************************************************************/ | |
1259 | |
1260 void ATB_pb_BCDToChar(char *dest, UBYTE *src, int max_len) | |
1261 { | |
1262 SHORT numIndex = 0; | |
1263 UBYTE digit = 0xF; //dummy | |
1264 //add "*" "#" in number by Peng Hou on 19/06/2006 begin | |
1265 while (digit!=NULL && numIndex<max_len) | |
1266 { | |
1267 /*HELLO!*/ | |
1268 digit = ATB_num_Digit(src, numIndex); | |
1269 | |
1270 if (digit==0xF) | |
1271 digit = NULL; | |
1272 else | |
1273 { | |
1274 switch ( digit ) | |
1275 { | |
1276 case 0: | |
1277 case 1: | |
1278 case 2: | |
1279 case 3: | |
1280 case 4: | |
1281 case 5: | |
1282 case 6: | |
1283 case 7: | |
1284 case 8: | |
1285 case 9: | |
1286 { | |
1287 digit+='0'; | |
1288 dest[numIndex] = digit; | |
1289 } | |
1290 break; | |
1291 | |
1292 case 0x0a: | |
1293 dest[numIndex]='*'; | |
1294 break; | |
1295 case 0x0b: | |
1296 dest[numIndex]='#'; | |
1297 break; | |
1298 case 0x0c: | |
1299 dest[numIndex]='P'; | |
1300 break; | |
1301 case 0x0d: | |
1302 dest[numIndex]='W'; | |
1303 break; | |
1304 case 0x0e: | |
1305 dest[numIndex] ='E'; | |
1306 break; | |
1307 default: | |
1308 dest[numIndex] ='\0'; | |
1309 } | |
1310 | |
1311 } | |
1312 | |
1313 // digit+='0'; | |
1314 //add "*" "#" in number by Peng Hou on 19/06/2006 end | |
1315 numIndex++; | |
1316 } | |
1317 | |
1318 return; | |
1319 } | |
1320 | |
1321 | |
1322 /******************************************************************************* | |
1323 | |
1324 $Function: ATB_pb_AllocRec | |
1325 | |
1326 $Description: Allocates memory for a record | |
1327 | |
1328 $Returns: | |
1329 | |
1330 $Arguments: phonebook_id The phonebook identifier | |
1331 | |
1332 *******************************************************************************/ | |
1333 | |
1334 T_PB_RECORD *ATB_pb_AllocRec(SHORT phonebook_id) | |
1335 { | |
1336 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1337 T_PB_RECORD *record; | |
1338 | |
1339 record = (T_PB_RECORD *)GI_pb_MemAlloc(sizeof(T_PB_RECORD)); | |
1340 | |
1341 record->alpha.data = (USHORT *)GI_pb_MemAlloc(data->alpha_max*sizeof(USHORT)); | |
1342 record->number = (UBYTE *)GI_pb_MemAlloc(data->number_max/2); | |
1343 if (data->ext_max>0) | |
1344 { | |
1345 record->ext_data = (UBYTE *)GI_pb_MemAlloc(data->ext_max); | |
1346 } | |
1347 else | |
1348 { | |
1349 record->ext_data = NULL; | |
1350 } | |
1351 record->ton_npi = 0; | |
1352 | |
1353 return record; | |
1354 } | |
1355 | |
1356 | |
1357 /******************************************************************************* | |
1358 | |
1359 $Function: ATB_pb_FreeRec | |
1360 | |
1361 $Description: Frees memory allocated for a record | |
1362 | |
1363 $Returns: | |
1364 | |
1365 $Arguments: phonebook_id The phonebook identifier | |
1366 record The record to destroy | |
1367 | |
1368 *******************************************************************************/ | |
1369 | |
1370 void ATB_pb_FreeRec(SHORT phonebook_id, T_PB_RECORD *record) | |
1371 { | |
1372 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1373 | |
1374 if (data->ext_max>0 && record->ext_data!=NULL) | |
1375 { | |
1376 GI_pb_MemFree((UBYTE *)record->ext_data, data->ext_max); | |
1377 } | |
1378 GI_pb_MemFree((UBYTE *)record->number, data->number_max/2); | |
1379 GI_pb_MemFree((UBYTE *)record->alpha.data, data->alpha_max*sizeof(USHORT)); | |
1380 | |
1381 GI_pb_MemFree((UBYTE *)record, sizeof(T_PB_RECORD)); | |
1382 | |
1383 return; | |
1384 } | |
1385 | |
1386 | |
1387 /******************************************************************************* | |
1388 | |
1389 $Function: ATB_pb_AllocRecList | |
1390 | |
1391 $Description: Allocates memory for a list of records | |
1392 | |
1393 $Returns: | |
1394 | |
1395 $Arguments: phonebook_id The phonebook identifier | |
1396 num_recs The number of records to allocate | |
1397 | |
1398 *******************************************************************************/ | |
1399 | |
1400 T_PB_LIST *ATB_pb_AllocRecList(SHORT phonebook_id, SHORT num_recs) | |
1401 { | |
1402 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1403 T_PB_LIST *list; | |
1404 SHORT rec_index; | |
1405 | |
1406 list = (T_PB_LIST *)GI_pb_MemAlloc(sizeof(T_PB_LIST)); | |
1407 list->records_max = num_recs; | |
1408 list->records_used = 0; | |
1409 list->record = (T_PB_RECORD *)GI_pb_MemAlloc(sizeof(T_PB_RECORD)*num_recs); | |
1410 | |
1411 for (rec_index=0; rec_index<num_recs; rec_index++) | |
1412 { | |
1413 list->record[rec_index].alpha.data = (USHORT *)GI_pb_MemAlloc(data->alpha_max*sizeof(USHORT)); | |
1414 list->record[rec_index].number = (UBYTE *)GI_pb_MemAlloc(data->number_max/2); | |
1415 if (data->ext_max>0) | |
1416 { | |
1417 list->record[rec_index].ext_data = (UBYTE *)GI_pb_MemAlloc(data->ext_max); | |
1418 } | |
1419 else | |
1420 { | |
1421 list->record[rec_index].ext_data = NULL; | |
1422 } | |
1423 } | |
1424 | |
1425 return list; | |
1426 } | |
1427 | |
1428 | |
1429 /******************************************************************************* | |
1430 | |
1431 $Function: ATB_pb_FreeRecList | |
1432 | |
1433 $Description: Frees memory allocated for a list of records | |
1434 | |
1435 $Returns: | |
1436 | |
1437 $Arguments: phonebook_id The phonebook identifier | |
1438 record The records to destroy | |
1439 num_recs Number of records in the list | |
1440 | |
1441 *******************************************************************************/ | |
1442 | |
1443 void ATB_pb_FreeRecList(SHORT phonebook_id, T_PB_LIST *list) | |
1444 { | |
1445 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1446 SHORT rec_index; | |
1447 | |
1448 for (rec_index=0; rec_index<list->records_max; rec_index++) | |
1449 { | |
1450 if (data->ext_max>0 && list->record[rec_index].ext_data!=NULL) | |
1451 { | |
1452 GI_pb_MemFree((UBYTE *)list->record[rec_index].ext_data, data->ext_max); | |
1453 } | |
1454 GI_pb_MemFree((UBYTE *)list->record[rec_index].number, data->number_max/2); | |
1455 GI_pb_MemFree((UBYTE *)list->record[rec_index].alpha.data, data->alpha_max*sizeof(USHORT)); | |
1456 } | |
1457 | |
1458 GI_pb_MemFree((UBYTE *)list->record, sizeof(T_PB_RECORD)*list->records_max); | |
1459 GI_pb_MemFree((UBYTE *)list, sizeof(T_PB_LIST)); | |
1460 | |
1461 return; | |
1462 } | |
1463 | |
1464 | |
1465 /******************************************************************************* | |
1466 | |
1467 $Function: ATB_mem_CopyRec | |
1468 | |
1469 $Description: Copies a record from one location to another. The destination should | |
1470 have memory allocated for its strings. | |
1471 | |
1472 $Returns: | |
1473 | |
1474 $Arguments: dest_record The destination record | |
1475 src_record The source record | |
1476 | |
1477 *******************************************************************************/ | |
1478 | |
1479 void ATB_pb_CopyRec(SHORT phonebook_id, T_PB_RECORD *dest_record, T_PB_RECORD *src_record) | |
1480 { | |
1481 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1482 | |
1483 dest_record->alpha.length = src_record->alpha.length; | |
1484 dest_record->alpha.dcs = src_record->alpha.dcs; | |
1485 memcpy((UBYTE *)dest_record->alpha.data, (UBYTE *)src_record->alpha.data, data->alpha_max*sizeof(USHORT)); | |
1486 memcpy(dest_record->number, src_record->number, data->number_max/2); | |
1487 if (data->ext_max>0) | |
1488 { | |
1489 memcpy(dest_record->ext_data, src_record->ext_data, data->ext_max); | |
1490 } | |
1491 dest_record->ton_npi = src_record->ton_npi; | |
1492 | |
1493 return; | |
1494 } | |
1495 | |
1496 | |
1497 /******************************************************************************* | |
1498 | |
1499 $Function: ATB_pb_OK | |
1500 | |
1501 $Description: This function is called if the requested FS command executed successfully. | |
1502 | |
1503 $Returns: None. | |
1504 | |
1505 $Arguments: phonebook_id The phonebook identifier | |
1506 | |
1507 *******************************************************************************/ | |
1508 | |
1509 | |
1510 PB_RET ATB_pb_OK(SHORT phonebook_id) | |
1511 { | |
1512 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1513 PB_RET result=PB_ERROR; | |
1514 | |
1515 switch(data->command_id) | |
1516 { | |
1517 case PB_INITIALISE: | |
1518 result = ATB_status_Initialise(phonebook_id); | |
1519 break; | |
1520 case PB_WRITEREC: | |
1521 result = ATB_status_WriteRec(phonebook_id); | |
1522 break; | |
1523 case PB_DELETEREC: | |
1524 result = ATB_status_DeleteRec(phonebook_id); | |
1525 break; | |
1526 } | |
1527 | |
1528 return result; | |
1529 } | |
1530 | |
1531 | |
1532 /******************************************************************************* | |
1533 | |
1534 $Function: ATB_pb_Error | |
1535 | |
1536 $Description: This function is called if an error was returned while executing the | |
1537 requested command. | |
1538 | |
1539 $Returns: None. | |
1540 | |
1541 $Arguments: phonebook_id The phonebook identifier | |
1542 error_id Identifies the error that occurred. | |
1543 | |
1544 *******************************************************************************/ | |
1545 | |
1546 void ATB_pb_Error(SHORT phonebook_id, SHORT error_id) | |
1547 { | |
1548 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1549 | |
1550 /* Forward the error report to the GI */ | |
1551 | |
1552 GI_pb_Error(phonebook_id, data->command_id, error_id); | |
1553 data->status = PB_STATUS_NONE; | |
1554 | |
1555 return; | |
1556 } | |
1557 | |
1558 /******************************************************************************* | |
1559 | |
1560 $Function: ATB_index_GetTable | |
1561 | |
1562 $Description: Returns a pointer to the index table specified by the index_type | |
1563 | |
1564 $Returns: None. | |
1565 | |
1566 $Arguments: phonebook_id The phonebook identifier | |
1567 index_type The index table required. | |
1568 | |
1569 *******************************************************************************/ | |
1570 | |
1571 SHORT * ATB_index_GetTable(SHORT phonebook_id, T_PB_INDEX index_type) | |
1572 { | |
1573 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1574 SHORT *table = NULL; | |
1575 | |
1576 switch(index_type) | |
1577 { | |
1578 case INDEX_NAME: | |
1579 table = data->name_table; | |
1580 break; | |
1581 case INDEX_NUMBER: | |
1582 table = data->number_table; | |
1583 break; | |
1584 case INDEX_SEARCH: | |
1585 table = data->search_table; | |
1586 break; | |
1587 default: | |
1588 table = GI_pb_GetTable(index_type); | |
1589 break; | |
1590 } | |
1591 | |
1592 return table; | |
1593 } | |
1594 | |
1595 | |
1596 /******************************************************************************* | |
1597 | |
1598 $Function: ATB_index_Find | |
1599 | |
1600 $Description: Find the nearest match to the supplied record. See ATB_pb_Find for | |
1601 more information. | |
1602 | |
1603 $Returns: PB_OK Action completed OK. | |
1604 PB_BUSY Failed, phonebook is busy. | |
1605 PB_FILEREADFAIL File read encountered an error | |
1606 PB_RECDOESNOTEXIST Tried to access a record that does not exist | |
1607 (should never happen) | |
1608 | |
1609 $Arguments: phonebook_id The phonebook identifier | |
1610 index_type The index_type of the provided record that is to be | |
1611 searched for, and the index list that the resulting | |
1612 new_log_index pertains to | |
1613 record The record whose index_type is to be matched | |
1614 new_log_index Returns with the logical index of the closest matching | |
1615 record | |
1616 match Specifies how good the resulting match was | |
1617 (MATCH_NONE, MATCH_START, MATCH_FRAGMENT | |
1618 or MATCH_EXACT). | |
1619 | |
1620 *******************************************************************************/ | |
1621 | |
1622 PB_RET ATB_index_Find (SHORT phonebook_id, T_PB_INDEX index_type, T_PB_RECORD *record, SHORT *new_log_index, T_PB_MATCH *match) | |
1623 { | |
1624 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1625 PB_RET result = PB_OK; | |
1626 /*SHORT *table;*/ /*a0393213 warning removal-variable set but not used*/ | |
1627 SHORT lower; | |
1628 SHORT upper; | |
1629 SHORT middle; | |
1630 T_PB_RECORD *comp_record; | |
1631 T_PB_COMPARE compare; | |
1632 UBYTE searching; | |
1633 | |
1634 /* Ensure that phonebook exists */ | |
1635 if (!data) | |
1636 { | |
1637 trace("**ERROR** Phonebook does not exist"); | |
1638 return PB_BOOKDOESNOTEXIST; | |
1639 } | |
1640 | |
1641 /* Allocate record for comparison */ | |
1642 | |
1643 comp_record = ATB_pb_AllocRec(phonebook_id); | |
1644 | |
1645 /* Make sure we're searching a valid index type */ | |
1646 | |
1647 if (index_type==INDEX_PHYSICAL || index_type==INDEX_SEARCH) | |
1648 { | |
1649 GI_pb_Error(phonebook_id, PB_FIND, PB_INDEXINVALID); | |
1650 return PB_INDEXINVALID; | |
1651 } | |
1652 | |
1653 /*table = ATB_index_GetTable(phonebook_id, index_type);*//*a0393213 warning removal-variable set but not used*/ | |
1654 | |
1655 /* The initial upper and lower bounds are the bounds of the array */ | |
1656 lower = 0; | |
1657 upper = data->records_used-1; | |
1658 | |
1659 searching = TRUE; | |
1660 | |
1661 /* If the list is empty, insert at 0 */ | |
1662 | |
1663 if (data->records_used==0) | |
1664 { | |
1665 middle = 0; | |
1666 searching = FALSE; | |
1667 } | |
1668 | |
1669 while (searching) | |
1670 { | |
1671 /* Compare our record with the middle element of the partition */ | |
1672 | |
1673 middle = (lower+upper)/2; | |
1674 | |
1675 result = ATB_mem_ReadRec(phonebook_id, index_type, middle, comp_record); | |
1676 | |
1677 if (result!=PB_OK) | |
1678 break; | |
1679 | |
1680 compare = ATB_index_Compare(record, comp_record, index_type); | |
1681 | |
1682 switch(compare) | |
1683 { | |
1684 case COMPARE_IDENTICAL: | |
1685 /* We've found a match; stop searching */ | |
1686 searching = FALSE; | |
1687 break; | |
1688 | |
1689 case COMPARE_FIRSTBEFORE: | |
1690 if (middle==lower) | |
1691 { | |
1692 /* The partition is a single element, so stop here. */ | |
1693 searching = FALSE; | |
1694 } | |
1695 else | |
1696 { | |
1697 /* Our record comes before the middle element; | |
1698 * redefine the partiton */ | |
1699 upper = middle - 1; | |
1700 } | |
1701 break; | |
1702 | |
1703 case COMPARE_FIRSTAFTER: | |
1704 if (middle==upper) | |
1705 { | |
1706 /* The partition is a single element, so stop here. The record | |
1707 * we need is the record after this one. */ | |
1708 middle++; | |
1709 searching = FALSE; | |
1710 } | |
1711 else | |
1712 { | |
1713 /* Our record comes after the middle element; | |
1714 * redefine the partiton */ | |
1715 lower = middle+1; | |
1716 } | |
1717 break; | |
1718 } | |
1719 } | |
1720 | |
1721 /* Store our results */ | |
1722 | |
1723 if (new_log_index) | |
1724 *new_log_index = middle; | |
1725 | |
1726 if (match) | |
1727 { | |
1728 ATB_mem_ReadRec(phonebook_id, index_type, middle, comp_record); | |
1729 *match = ATB_index_Match(record, comp_record, index_type); | |
1730 } | |
1731 | |
1732 /* Free allocated record */ | |
1733 | |
1734 ATB_pb_FreeRec(phonebook_id, comp_record); | |
1735 | |
1736 /* Send success/failure info to the GI */ | |
1737 | |
1738 if (result==PB_OK) | |
1739 GI_pb_OK(phonebook_id, PB_FIND, NULL); | |
1740 else if (result!=PB_EXCT) | |
1741 GI_pb_Error(phonebook_id, PB_FIND, result); | |
1742 | |
1743 return result; | |
1744 } | |
1745 | |
1746 | |
1747 /******************************************************************************* | |
1748 | |
1749 $Function: ATB_index_GetPhysIndex | |
1750 | |
1751 $Description: Returns the physical index corresponding to the given logical index, in | |
1752 the index table specified by the index_type. | |
1753 | |
1754 $Returns: None. | |
1755 | |
1756 $Arguments: phonebook_id The phonebook identifier. | |
1757 index_type The index table required. | |
1758 log_index The logical index. | |
1759 | |
1760 *******************************************************************************/ | |
1761 | |
1762 SHORT ATB_index_GetPhysIndex(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index) | |
1763 { | |
1764 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1765 SHORT phys_index=-1; | |
1766 SHORT *table; | |
1767 | |
1768 switch(index_type) | |
1769 { | |
1770 case INDEX_PHYSICAL: | |
1771 phys_index = log_index; | |
1772 break; | |
1773 case INDEX_NAME: | |
1774 case INDEX_NUMBER: | |
1775 case INDEX_SEARCH: | |
1776 table = ATB_index_GetTable(phonebook_id, index_type); | |
1777 phys_index = table[log_index]; | |
1778 break; | |
1779 default: | |
1780 TRACE_ERROR("ATB_index_GetPhysIndex():Unknown index"); | |
1781 break; | |
1782 } | |
1783 | |
1784 return phys_index; | |
1785 } | |
1786 | |
1787 | |
1788 /******************************************************************************* | |
1789 | |
1790 $Function: ATB_index_GetLogIndex | |
1791 | |
1792 $Description: Provided with the physical index, finds the logical index of the record | |
1793 in the index table specified. | |
1794 | |
1795 $Returns: None. | |
1796 | |
1797 $Arguments: phonebook_id The phonebook identifier | |
1798 index_type The index table required. | |
1799 phys_index The logical index of the record to find | |
1800 | |
1801 *******************************************************************************/ | |
1802 | |
1803 SHORT ATB_index_GetLogIndex(SHORT phonebook_id, T_PB_INDEX index_type, SHORT phys_index) | |
1804 { | |
1805 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1806 SHORT *table = ATB_index_GetTable(phonebook_id, index_type); | |
1807 SHORT log_index; | |
1808 | |
1809 if (index_type==INDEX_PHYSICAL) | |
1810 { | |
1811 log_index = phys_index; | |
1812 } | |
1813 else | |
1814 { | |
1815 for (log_index=0; log_index<data->records_used; log_index++) | |
1816 { | |
1817 if (table[log_index]==phys_index) | |
1818 break; | |
1819 } | |
1820 } | |
1821 | |
1822 return log_index; | |
1823 } | |
1824 | |
1825 | |
1826 /******************************************************************************* | |
1827 | |
1828 $Function: ATB_index_AddRec | |
1829 | |
1830 $Description: Adds a record to an index list, sorting automatically as required. | |
1831 | |
1832 $Returns: None. | |
1833 | |
1834 $Arguments: phonebook_id The phonebook identifier | |
1835 index_type The index table required. | |
1836 phys_index The physical index of the record to add. | |
1837 record The record to add. | |
1838 new_log_index New logical index of record. | |
1839 | |
1840 *******************************************************************************/ | |
1841 | |
1842 void ATB_index_AddRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT phys_index, T_PB_RECORD *record, SHORT *new_log_index) | |
1843 { | |
1844 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1845 SHORT *table = ATB_index_GetTable(phonebook_id, index_type); | |
1846 SHORT log_index; | |
1847 SHORT found_log_index; | |
1848 | |
1849 ATB_index_Find(phonebook_id, index_type, record, &found_log_index, NULL); | |
1850 | |
1851 /* Shift end of index table down */ | |
1852 | |
1853 for (log_index=data->records_used; log_index>found_log_index; log_index--) | |
1854 { | |
1855 table[log_index] = table[log_index-1]; | |
1856 } | |
1857 | |
1858 table[found_log_index] = phys_index; | |
1859 | |
1860 if (new_log_index) | |
1861 *new_log_index = found_log_index; | |
1862 | |
1863 return; | |
1864 } | |
1865 | |
1866 /******************************************************************************* | |
1867 | |
1868 $Function: ATB_index_RemoveRec | |
1869 | |
1870 $Description: Removes a record reference from an index list, sorting the index list | |
1871 appropriately. | |
1872 | |
1873 $Returns: None. | |
1874 | |
1875 $Arguments: phonebook_id The phonebook identifier | |
1876 index_type The index table required. | |
1877 log_index The logical index of the record to remove | |
1878 | |
1879 *******************************************************************************/ | |
1880 | |
1881 void ATB_index_RemoveRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index) | |
1882 { | |
1883 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
1884 SHORT *table = ATB_index_GetTable(phonebook_id, index_type); | |
1885 SHORT table_index; | |
1886 | |
1887 for (table_index = log_index+1; table_index<data->records_used; table_index++) | |
1888 { | |
1889 table[table_index-1] = table[table_index]; | |
1890 } | |
1891 | |
1892 return; | |
1893 } | |
1894 | |
1895 | |
1896 /******************************************************************************* | |
1897 | |
1898 $Function: ATB_index_Match | |
1899 | |
1900 $Description: This function attempts a match between two records based on the | |
1901 index_type specified in index_type. It returns a value indicating | |
1902 whether there is no match (MATCH_NONE), a partial match | |
1903 (MAX_START), or an exact match (MATCH_EXACT). | |
1904 The function GI_pb_Match is called first, to check whether there is | |
1905 any user-specific matching required. If not, then ATB_alpha_Match | |
1906 is called for an alpha tag, or ATB_num_Match for a phone number. | |
1907 For any other index_type, MATCH_NONE is returned as default. | |
1908 | |
1909 $Returns: MATCH_EXACT, MATCH_START or MATCH_NONE | |
1910 | |
1911 $Arguments: record1 The first record to be compared | |
1912 record2 The second record to be compared | |
1913 index_type Indicator of the index_type which is to be matched | |
1914 | |
1915 *******************************************************************************/ | |
1916 | |
1917 T_PB_MATCH ATB_index_Match(T_PB_RECORD *record1, T_PB_RECORD *record2, T_PB_INDEX index_type) | |
1918 { | |
1919 T_PB_MATCH match; | |
1920 | |
1921 match = GI_pb_Match(record1, record2, index_type); | |
1922 | |
1923 if (match==MATCH_DEFAULT) | |
1924 { | |
1925 switch(index_type) | |
1926 { | |
1927 case INDEX_NAME: | |
1928 match = ATB_alpha_Match(&record1->alpha, &record2->alpha); | |
1929 break; | |
1930 case INDEX_NUMBER: | |
1931 match = ATB_num_Match(record1->number, record2->number); | |
1932 break; | |
1933 } | |
1934 } | |
1935 | |
1936 return match; | |
1937 } | |
1938 | |
1939 | |
1940 | |
1941 /******************************************************************************* | |
1942 | |
1943 $Function: ATB_index_Compare | |
1944 | |
1945 $Description: This function compares two records based on the index_type specified in | |
1946 index_type. It returns a value indicating whether the first record should | |
1947 come before or after the second. | |
1948 The function GI_pb_Compare is called first, to check whether there is | |
1949 any user-specific sorting required. If not, then ATB_alpha_Compare is | |
1950 called for an alpha tag, or ATB_num_Compare for a phone number. | |
1951 For any other index_type, COMPARE_FIRSTBEFORE is returned as default. | |
1952 | |
1953 $Returns: COMPARE_IDENTICAL The two records are identical | |
1954 COMPARE_FIRSTBEFORE The first record should come before the second record | |
1955 COMPARE_FIRSTAFTER The first record should come after the second record | |
1956 | |
1957 $Arguments: record1 The first record to be compared | |
1958 record2 The second record to be compared | |
1959 index_type Indicator of the index_type which is to be compared | |
1960 | |
1961 *******************************************************************************/ | |
1962 | |
1963 T_PB_COMPARE ATB_index_Compare(T_PB_RECORD *record1, T_PB_RECORD *record2, T_PB_INDEX index_type) | |
1964 { | |
1965 T_PB_COMPARE compare; | |
1966 | |
1967 compare = GI_pb_Compare(record1, record2, index_type); | |
1968 | |
1969 if (compare==COMPARE_DEFAULT) | |
1970 { | |
1971 switch(index_type) | |
1972 { | |
1973 case INDEX_NAME: | |
1974 compare = ATB_alpha_Compare(&record1->alpha, &record2->alpha); | |
1975 break; | |
1976 case INDEX_NUMBER: | |
1977 compare = ATB_num_Compare(record1->number, record2->number); | |
1978 break; | |
1979 } | |
1980 } | |
1981 | |
1982 return compare; | |
1983 } | |
1984 | |
1985 | |
1986 /******************************************************************************* | |
1987 | |
1988 $Function: ATB_alpha_Compare | |
1989 | |
1990 $Description: This function compares two alpha strings on the basis of an ascending | |
1991 alphanumeric latin list, and specifies which record would come first. | |
1992 | |
1993 | |
1994 $Returns: COMPARE_FIRSTBEFORE The first record should come before the second record | |
1995 COMPARE_FIRSTAFTER The first record should come after the second record | |
1996 | |
1997 $Arguments: alpha1 The first alpha tag | |
1998 alpha2 The second alpha tag | |
1999 | |
2000 *******************************************************************************/ | |
2001 | |
2002 T_PB_COMPARE ATB_alpha_Compare(T_PB_ALPHA *alpha1, T_PB_ALPHA *alpha2) | |
2003 { | |
2004 T_PB_COMPARE compare; | |
2005 SHORT charIndex; | |
2006 USHORT length1 = alpha1->length; | |
2007 USHORT length2 = alpha2->length; | |
2008 USHORT char1; | |
2009 USHORT char2; | |
2010 | |
2011 compare = COMPARE_IDENTICAL; /* Default */ | |
2012 | |
2013 /* Special case, length of first string is 0 */ | |
2014 | |
2015 if (length1==0) | |
2016 compare = COMPARE_FIRSTBEFORE; | |
2017 | |
2018 for (charIndex = 0; charIndex < length1; charIndex++) | |
2019 { | |
2020 if (charIndex==length2) /* E.g. "Johnson" and "John" */ | |
2021 { | |
2022 compare = COMPARE_FIRSTAFTER; | |
2023 break; | |
2024 } | |
2025 | |
2026 char1 = alpha1->data[charIndex]; | |
2027 if (char1>=(SHORT)'A' && char1<=(SHORT)'Z') | |
2028 char1 += (SHORT)('a'-'A'); | |
2029 char2 = alpha2->data[charIndex]; | |
2030 if (char2>=(SHORT)'A' && char2<=(SHORT)'Z') | |
2031 char2 += (SHORT)('a'-'A'); | |
2032 | |
2033 if (char1 < char2) | |
2034 { | |
2035 compare = COMPARE_FIRSTBEFORE; | |
2036 break; | |
2037 } | |
2038 if (char1 > char2) | |
2039 { | |
2040 compare = COMPARE_FIRSTAFTER; | |
2041 break; | |
2042 } | |
2043 if (charIndex==length1-1 && length2>length1) /*E.g. "John" and "Johnson" */ | |
2044 { | |
2045 compare = COMPARE_FIRSTBEFORE; | |
2046 break; | |
2047 } | |
2048 } | |
2049 | |
2050 return compare; | |
2051 } | |
2052 | |
2053 | |
2054 /******************************************************************************* | |
2055 | |
2056 $Function: ATB_alpha_Match | |
2057 | |
2058 $Description: This function matches two alpha strings on the basis of a latin string | |
2059 matched from the start, and specifies how they match. | |
2060 | |
2061 $Returns: MATCH_NONE The strings do not match | |
2062 MATCH_START The first string matches the start of the second string | |
2063 MATCH_EXACT The two strings match exactly | |
2064 | |
2065 $Arguments: alpha1 The first alpha tag | |
2066 alpha2 The second alpha tag | |
2067 | |
2068 *******************************************************************************/ | |
2069 | |
2070 T_PB_MATCH ATB_alpha_Match(T_PB_ALPHA *alpha1, T_PB_ALPHA *alpha2) | |
2071 { | |
2072 T_PB_MATCH match; | |
2073 SHORT charIndex; | |
2074 USHORT length1 = alpha1->length; | |
2075 USHORT length2 = alpha2->length; | |
2076 SHORT offset; | |
2077 UBYTE searching; | |
2078 UBYTE some_match; | |
2079 USHORT char1, char2; | |
2080 | |
2081 match = MATCH_EXACT; /* Default */ | |
2082 searching = TRUE; | |
2083 some_match = FALSE; | |
2084 offset = 0; | |
2085 | |
2086 do | |
2087 { | |
2088 for (charIndex = 0; charIndex < length1; charIndex++) | |
2089 { | |
2090 | |
2091 if (charIndex==(length2-offset)) /* E.g. "Johnson" and "John" */ | |
2092 { | |
2093 searching = FALSE; | |
2094 break; /* No match, will exit do/while */ | |
2095 } | |
2096 | |
2097 char1 = alpha1->data[charIndex]; | |
2098 if (char1>=(SHORT)'A' && char1<=(SHORT)'Z') | |
2099 char1 += (SHORT)('a'-'A'); | |
2100 char2 = alpha2->data[charIndex+offset]; | |
2101 if (char2>=(SHORT)'A' && char2<=(SHORT)'Z') | |
2102 char2 += (SHORT)('a'-'A'); | |
2103 | |
2104 if (char1 != char2) | |
2105 { | |
2106 some_match = FALSE; /* Any fragment so far identified does not fit */ | |
2107 break; /* No match, keep looking */ | |
2108 } | |
2109 | |
2110 some_match = TRUE; | |
2111 | |
2112 if (charIndex==length1-1 && length2>length1) /*E.g. "John" and "Johnson" */ | |
2113 { | |
2114 if (offset==0) | |
2115 match = MATCH_START; | |
2116 else | |
2117 match = MATCH_FRAGMENT; | |
2118 break; | |
2119 } | |
2120 } | |
2121 | |
2122 if (some_match==TRUE) | |
2123 { | |
2124 searching = FALSE; | |
2125 } | |
2126 else | |
2127 { | |
2128 offset++; | |
2129 | |
2130 /* If the fragment won't fit, don't keep looking */ | |
2131 if ((offset+length1)>length2) | |
2132 { | |
2133 match=MATCH_NONE; | |
2134 searching = FALSE; | |
2135 } | |
2136 } | |
2137 }while (searching); | |
2138 | |
2139 return match; | |
2140 } | |
2141 | |
2142 | |
2143 /******************************************************************************* | |
2144 | |
2145 $Function: ATB_num_Digit | |
2146 | |
2147 $Description: Extracts the four-bit digit from a BCD number | |
2148 | |
2149 $Returns: The four bit digit | |
2150 | |
2151 $Arguments: num The BCD number | |
2152 numIndex The position in the BCD number to look | |
2153 | |
2154 *******************************************************************************/ | |
2155 | |
2156 UBYTE ATB_num_Digit(UBYTE *num, SHORT numIndex) | |
2157 { | |
2158 UBYTE digit; | |
2159 UBYTE shift = (numIndex&0x1)*0x4; | |
2160 | |
2161 digit = num[numIndex>>1]; /* Each BCD digit takes up half a byte */ | |
2162 digit &= (0xF<<shift); /* Isolate the digit */ | |
2163 digit >>= shift; /* Shift it so it has a value 0x0 - 0xF */ | |
2164 | |
2165 return digit; | |
2166 } | |
2167 | |
2168 | |
2169 /******************************************************************************* | |
2170 | |
2171 $Function: ATB_num_Length | |
2172 | |
2173 $Description: Returns the length of a BCD number in digits | |
2174 | |
2175 $Returns: Length of BCD number | |
2176 | |
2177 $Arguments: num The BCD number | |
2178 | |
2179 *******************************************************************************/ | |
2180 | |
2181 SHORT ATB_num_Length(UBYTE *num) | |
2182 { | |
2183 SHORT length; | |
2184 | |
2185 for (length = 0; ATB_num_Digit(num, length)!=0xF; length++) | |
2186 { | |
2187 } | |
2188 | |
2189 return length; | |
2190 } | |
2191 | |
2192 | |
2193 /******************************************************************************* | |
2194 | |
2195 $Function: ATB_num_Compare | |
2196 | |
2197 $Description: This function compares two phone numbers by the standard comparison | |
2198 method (ascending numeric, from the end of the number) and specifies | |
2199 which record would come first if sorted in this method. | |
2200 | |
2201 $Returns: COMPARE_FIRSTBEFORE The first record should come before the second record | |
2202 COMPARE_FIRSTAFTER The first record should come after the second record | |
2203 | |
2204 $Arguments: num1 The first number | |
2205 num2 The second number | |
2206 | |
2207 *******************************************************************************/ | |
2208 | |
2209 T_PB_COMPARE ATB_num_Compare(UBYTE *num1, UBYTE *num2) | |
2210 { | |
2211 T_PB_COMPARE compare; | |
2212 SHORT charIndex; | |
2213 SHORT length1 = ATB_num_Length(num1); | |
2214 SHORT length2 = ATB_num_Length(num2); | |
2215 UBYTE digit1; | |
2216 UBYTE digit2; | |
2217 | |
2218 compare = COMPARE_IDENTICAL; /* Default */ | |
2219 | |
2220 for (charIndex = 0; charIndex < length1; charIndex++) | |
2221 { | |
2222 if (charIndex==length2) /* E.g. "123456" and "1234" */ | |
2223 { | |
2224 compare = COMPARE_FIRSTAFTER; | |
2225 break; | |
2226 } | |
2227 | |
2228 digit1 = ATB_num_Digit(num1, (SHORT)(length1-charIndex-1)); | |
2229 digit2 = ATB_num_Digit(num2, (SHORT)(length2-charIndex-1)); | |
2230 | |
2231 if (digit1 < digit2) | |
2232 { | |
2233 compare = COMPARE_FIRSTBEFORE; | |
2234 break; | |
2235 } | |
2236 if (digit1 > digit2) | |
2237 { | |
2238 compare = COMPARE_FIRSTAFTER; | |
2239 break; | |
2240 } | |
2241 if (charIndex==length1-1 && length2>length1) /*E.g. "1234" and "123456" */ | |
2242 { | |
2243 compare = COMPARE_FIRSTBEFORE; | |
2244 break; | |
2245 } | |
2246 } | |
2247 | |
2248 return compare; | |
2249 } | |
2250 | |
2251 /******************************************************************************* | |
2252 | |
2253 $Function: ATB_num_Match | |
2254 | |
2255 $Description: This function matches phone numbers, from the end backwards, and | |
2256 specifies how they match. | |
2257 | |
2258 $Returns: MATCH_NONE The numbers do not match | |
2259 MATCH_START The first number matches the end of the second number | |
2260 MATCH_EXACT The two numbers match exactly | |
2261 | |
2262 $Arguments: num1 The first number | |
2263 num2 The second number | |
2264 | |
2265 *******************************************************************************/ | |
2266 | |
2267 T_PB_MATCH ATB_num_Match(UBYTE *num1, UBYTE *num2) | |
2268 { | |
2269 T_PB_MATCH match; | |
2270 SHORT charIndex; | |
2271 SHORT length1 = ATB_num_Length(num1); | |
2272 SHORT length2 = ATB_num_Length(num2); | |
2273 SHORT offset; | |
2274 UBYTE searching; | |
2275 UBYTE some_match; | |
2276 UBYTE digit1; | |
2277 UBYTE digit2; | |
2278 | |
2279 match = MATCH_EXACT; /* Default */ | |
2280 searching = TRUE; | |
2281 some_match = FALSE; | |
2282 offset = 0; | |
2283 | |
2284 do | |
2285 { | |
2286 for (charIndex = 0; charIndex < length1; charIndex++) | |
2287 { | |
2288 if (charIndex==(length2-offset)) /* E.g. "12345" and "123" */ | |
2289 { | |
2290 searching = FALSE; | |
2291 break; /* No match, will exit do/while */ | |
2292 } | |
2293 | |
2294 digit1 = ATB_num_Digit(num1, (SHORT)(length1-charIndex-1)); | |
2295 digit2 = ATB_num_Digit(num2, (SHORT)(length2-charIndex-1)); | |
2296 | |
2297 if (digit1 != digit2) | |
2298 { | |
2299 some_match = FALSE; /* Any fragment so far identified does not fit */ | |
2300 break; /* No match, keep looking */ | |
2301 } | |
2302 | |
2303 some_match = TRUE; | |
2304 | |
2305 if (charIndex==length1-1 && length2>length1) /*E.g. "123" and "12345" */ | |
2306 { | |
2307 if (offset==0) | |
2308 match = MATCH_START; | |
2309 else | |
2310 match = MATCH_FRAGMENT; | |
2311 break; | |
2312 } | |
2313 } | |
2314 | |
2315 if (some_match==TRUE) | |
2316 { | |
2317 searching = FALSE; | |
2318 } | |
2319 else | |
2320 { | |
2321 offset++; | |
2322 | |
2323 /* If the fragment won't fit, don't keep looking */ | |
2324 if ((offset+length1)>length2) | |
2325 { | |
2326 match=MATCH_NONE; | |
2327 searching = FALSE; | |
2328 } | |
2329 } | |
2330 } while (searching); | |
2331 | |
2332 return match; | |
2333 } | |
2334 | |
2335 | |
2336 /******************************************************************************* | |
2337 | |
2338 $Function: ATB_mem_UpdateCache | |
2339 | |
2340 $Description: Updates the cache with the record provided. If the cache is full, the | |
2341 least used record is overwritten. | |
2342 | |
2343 $Returns: None. | |
2344 | |
2345 $Arguments: phonebook_id The phonebook identifier | |
2346 index_type The index table required. | |
2347 phys_index The physical index of the record to add. | |
2348 record The record to add. | |
2349 | |
2350 *******************************************************************************/ | |
2351 | |
2352 void ATB_mem_UpdateCache(SHORT phonebook_id, SHORT phys_index, T_PB_RECORD *record) | |
2353 { | |
2354 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
2355 SHORT cacheIndex; | |
2356 SHORT leastUsed; | |
2357 SHORT leastIndex; | |
2358 | |
2359 /* First check if record is already in RAM */ | |
2360 | |
2361 if (data->cache[phys_index] != NULL) | |
2362 { | |
2363 /* Copy the record in case it has changed */ | |
2364 | |
2365 ATB_pb_CopyRec(phonebook_id, data->cache[phys_index], record); | |
2366 | |
2367 if (data->in_memory[phys_index]<0x7FFF)/*a0393213 lint WR:Constant out of range Soln:0xffff changed to 0x7fff*/ | |
2368 data->in_memory[phys_index]++; | |
2369 return; | |
2370 } | |
2371 | |
2372 /* If the cache is full, find the least accessed record */ | |
2373 | |
2374 if (data->cache_size==data->cache_max) | |
2375 { | |
2376 leastIndex = 0; | |
2377 leastUsed = 255; | |
2378 | |
2379 for (cacheIndex=0; cacheIndex<data->records_max; cacheIndex++) | |
2380 { | |
2381 if (data->cache[cacheIndex]!=NULL && data->in_memory[cacheIndex] < leastUsed) | |
2382 { | |
2383 leastUsed = data->in_memory[cacheIndex]; | |
2384 leastIndex = cacheIndex; | |
2385 } | |
2386 } | |
2387 | |
2388 /* Give the new record the memory allocated for the least used record */ | |
2389 | |
2390 data->cache[phys_index] = data->cache[leastIndex]; | |
2391 data->cache[leastIndex] = NULL; | |
2392 data->in_memory[leastIndex] = 0; | |
2393 } | |
2394 | |
2395 /* If the cache is not full, allocate memory for record */ | |
2396 | |
2397 else | |
2398 { | |
2399 data->cache[phys_index] = ATB_pb_AllocRec(phonebook_id); | |
2400 data->cache_size++; | |
2401 } | |
2402 | |
2403 /* Copy the record into cache */ | |
2404 | |
2405 ATB_pb_CopyRec(phonebook_id, data->cache[phys_index], record); | |
2406 data->in_memory[phys_index] = 1; | |
2407 | |
2408 return; | |
2409 } | |
2410 | |
2411 /******************************************************************************* | |
2412 | |
2413 $Function: ATB_mem_ReadRec | |
2414 | |
2415 $Description: Reads a record from the logical position index. Information is read from | |
2416 cache if it is present in memory, otherwise it will be read from file. | |
2417 | |
2418 The record information will be returned in the data structure pointed to | |
2419 by record. The T_PB_RECORD structure must be allocated by the caller. | |
2420 | |
2421 $Returns: PB_OK Action completed OK. | |
2422 PB_FILEREADFAIL File read encountered an error | |
2423 PB_RECDOESNOTEXIST Tried to access a record that does not exist | |
2424 | |
2425 $Arguments: phonebook_id The phonebook identifier | |
2426 index_type The index list from which the record is to be read | |
2427 log_index Logical index in the index list of the record to read | |
2428 record Structure in which to store record data | |
2429 | |
2430 *******************************************************************************/ | |
2431 | |
2432 PB_RET ATB_mem_ReadRec(SHORT phonebook_id, T_PB_INDEX index_type, SHORT log_index, T_PB_RECORD *record) | |
2433 { | |
2434 T_PB_DATA *data = ATB_hnd_GetPbData(phonebook_id); | |
2435 SHORT phys_index; | |
2436 PB_RET result; | |
2437 | |
2438 /* Check that record exists */ | |
2439 | |
2440 if (log_index<0 | |
2441 || (log_index>=data->records_used && (index_type==INDEX_NAME || index_type==INDEX_NUMBER)) | |
2442 || (index_type==INDEX_SEARCH && log_index>data->search_results) | |
2443 || (index_type==INDEX_PHYSICAL && log_index>data->records_max)) | |
2444 { | |
2445 trace("*** Error - record does not exist ***"); | |
2446 return PB_RECDOESNOTEXIST; | |
2447 } | |
2448 | |
2449 /* Get the corresponding physical record index */ | |
2450 | |
2451 phys_index = ATB_index_GetPhysIndex(phonebook_id, index_type, log_index); | |
2452 | |
2453 /* If the record is in the cache, simply copy it. Otherwise, call FS to read the record. */ | |
2454 | |
2455 if (data->in_memory[phys_index]>0) | |
2456 { | |
2457 ATB_pb_CopyRec(phonebook_id, record, data->cache[phys_index]); | |
2458 result = PB_OK; | |
2459 } | |
2460 else | |
2461 { | |
2462 /* NB - assumes blocking read operation. If the read operation is blocking, | |
2463 * the cache must be large enough to store all the phonebook entries. */ | |
2464 result = FS_pb_ReadRec(phonebook_id, phys_index, record); | |
2465 ATB_mem_UpdateCache(phonebook_id, phys_index, record); | |
2466 } | |
2467 | |
2468 return result; | |
2469 } | |
2470 | |
2471 | |
2472 /******************************************************************************* | |
2473 | |
2474 $Function: ATB_hnd_GetPbData | |
2475 | |
2476 $Description: Returns phonebook data handle | |
2477 | |
2478 $Returns: The phonebook data handle | |
2479 | |
2480 $Arguments: phonebook_id The phonebook identifier | |
2481 | |
2482 *******************************************************************************/ | |
2483 | |
2484 T_PB_DATA* ATB_hnd_GetPbData(SHORT phonebook_id) | |
2485 { | |
2486 return phonebook[phonebook_id]; | |
2487 } | |
2488 | |
2489 | |
2490 /******************************************************************************* | |
2491 | |
2492 $Function: ATB_hnd_SetPbData | |
2493 | |
2494 $Description: Sets phonebook data handle | |
2495 | |
2496 $Returns: None | |
2497 | |
2498 $Arguments: phonebook_id The phonebook identifier | |
2499 data The phonebook data | |
2500 | |
2501 *******************************************************************************/ | |
2502 | |
2503 void ATB_hnd_SetPbData(SHORT phonebook_id, T_PB_DATA *data) | |
2504 { | |
2505 phonebook[phonebook_id] = data; | |
2506 | |
2507 return; | |
2508 } | |
2509 |