FreeCalypso > hg > fc-magnetite
comparison src/g23m-aci/aci/conc_sms.c @ 162:53929b40109c
src/g23m-aci: initial import from TCS3.2/LoCosto
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2016 02:02:43 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
161:4557e2a9c18e | 162:53929b40109c |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : $Workfile:: | |
4 | Modul : CONC_SMS | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : SMS Concatenation Handler | |
18 +----------------------------------------------------------------------------- | |
19 */ | |
20 | |
21 #ifndef CONC_SMS_C | |
22 #define CONC_SMS_C | |
23 #endif | |
24 | |
25 /*==== INCLUDES ===================================================*/ | |
26 | |
27 #include "aci_all.h" | |
28 | |
29 #include "aci_cmh.h" | |
30 #include "ati_cmd.h" | |
31 #include "aci_cmd.h" | |
32 | |
33 #include "aci_fd.h" | |
34 #include "aci_mem.h" | |
35 | |
36 #include "psa.h" | |
37 #include "psa_sms.h" | |
38 | |
39 #include "cmh.h" | |
40 #include "cmh_sms.h" | |
41 | |
42 #include "psa_cc.h" | |
43 | |
44 #include "typedefs.h" | |
45 #include "aci_lst.h" | |
46 | |
47 #include "psa_util.h" | |
48 #include "conc_sms.h" | |
49 | |
50 #ifdef _CONC_TESTING_ | |
51 #include "aci_io.h" | |
52 #include "aci_mfw.h" | |
53 #endif | |
54 | |
55 /*==== VARIABLES ==================================================*/ | |
56 | |
57 GLOBAL T_SM_ASSEMBLY assembly_list[MAX_BUF_ELEMS]; | |
58 GLOBAL T_SEG_BUF segBuf_list [MAX_BUF_ELEMS]; | |
59 GLOBAL T_CONC_BUF concBuf_list [MAX_CONC_BUF_ELEMS]; | |
60 LOCAL USHORT RefNum_Del = 0xFF; | |
61 LOCAL BOOL dFLAG = FALSE; | |
62 LOCAL CHAR Addres[MAX_SMS_ADDR_DIG]; | |
63 | |
64 | |
65 | |
66 /*==== FUNCTIONS ==================================================*/ | |
67 | |
68 LOCAL void concSMS_printConcatList (); | |
69 LOCAL USHORT concSMS_findMaxRefNum(void); // Marcus: Issue 872: 03/10/2002 | |
70 | |
71 | |
72 | |
73 /* | |
74 +--------------------------------------------------------------------+ | |
75 | PROJECT : MODULE : CONC_SMS | | |
76 | STATE : code ROUTINE : concSMS_findSeqNumSB | | |
77 +--------------------------------------------------------------------+ | |
78 | |
79 PURPOSE : find 'seq_num' in segment buffer | |
80 */ | |
81 LOCAL BOOL concSMS_findSeqNumSB ( UBYTE critrerium, | |
82 void *elem ) | |
83 { | |
84 T_SEG_BUF_ELEM *compared = (T_SEG_BUF_ELEM *)elem; | |
85 | |
86 if ( compared->seq_num == critrerium ) | |
87 return TRUE; | |
88 else | |
89 return FALSE; | |
90 } | |
91 | |
92 | |
93 | |
94 /* | |
95 +--------------------------------------------------------------------+ | |
96 | PROJECT : MODULE : CONC_SMS | | |
97 | STATE : code ROUTINE : concSMS_findSeqNumElemCB | | |
98 +--------------------------------------------------------------------+ | |
99 | |
100 PURPOSE : find 'seq_num' in concatenation buffer | |
101 */ | |
102 LOCAL BOOL concSMS_findSeqNumElemCB ( UBYTE critrerium, | |
103 void *elem ) | |
104 { | |
105 T_CONC_BUF_ELEM *compared = (T_CONC_BUF_ELEM *)elem; | |
106 | |
107 if ( compared->seq_num == critrerium ) | |
108 return TRUE; | |
109 else | |
110 return FALSE; | |
111 } | |
112 | |
113 | |
114 | |
115 /* | |
116 +--------------------------------------------------------------------+ | |
117 | PROJECT : MODULE : CONC_SMS | | |
118 | STATE : code ROUTINE : concSMS_findRecNumElemCB | | |
119 +--------------------------------------------------------------------+ | |
120 | |
121 PURPOSE : find 'rec_num' in concatenation buffer | |
122 */ | |
123 LOCAL BOOL concSMS_findRecNumElemCB ( UBYTE critrerium, | |
124 void *elem ) | |
125 { | |
126 T_CONC_BUF_ELEM *compared = (T_CONC_BUF_ELEM *)elem; | |
127 | |
128 if ( compared->rec_num == critrerium ) | |
129 return TRUE; | |
130 else | |
131 return FALSE; | |
132 } | |
133 | |
134 /* | |
135 +--------------------------------------------------------------------+ | |
136 | PROJECT : MODULE : CONC_SMS | | |
137 | STATE : code ROUTINE : concSMS_getAsBuffer | | |
138 +--------------------------------------------------------------------+ | |
139 | |
140 PURPOSE : This functions searchs the assembly buffer for ref_num | |
141 and address. | |
142 */ | |
143 LOCAL T_SM_ASSEMBLY* concSMS_getAsBuffer( USHORT ref_num, CHAR *address ) | |
144 { | |
145 UBYTE i; | |
146 | |
147 TRACE_FUNCTION ("concSMS_getAsBuffer()"); | |
148 | |
149 /* search for the element */ | |
150 for (i=0; i<MAX_BUF_ELEMS; i++) | |
151 { | |
152 if ( (assembly_list[i].ref_num EQ ref_num) AND | |
153 (assembly_list[i].in_use) ) | |
154 { | |
155 if ((address NEQ NULL) /* AND (address[0] NEQ '\0') */) | |
156 { | |
157 if (!strcmp(assembly_list[i].address, address)) | |
158 { | |
159 return &assembly_list[i]; | |
160 } | |
161 } | |
162 else | |
163 { | |
164 return &assembly_list[i]; | |
165 } | |
166 } | |
167 } | |
168 | |
169 return NULL; | |
170 } | |
171 | |
172 | |
173 /* | |
174 +--------------------------------------------------------------------+ | |
175 | PROJECT : MODULE : CONC_SMS | | |
176 | STATE : code ROUTINE : concSMS_addToAsBuffer | | |
177 +--------------------------------------------------------------------+ | |
178 | |
179 PURPOSE : This function adds data to the assembly buffer. It returns | |
180 NULL if buffer is full. | |
181 | |
182 */ | |
183 LOCAL T_SM_ASSEMBLY* concSMS_addToAsBuffer ( USHORT ref_num, | |
184 CHAR *address, | |
185 UBYTE max_num, | |
186 T_SM_DATA_EXT *data ) | |
187 { | |
188 UBYTE i; | |
189 T_SM_ASSEMBLY *assembly_elem = NULL; | |
190 | |
191 TRACE_FUNCTION ("concSMS_addToAsBuffer()"); | |
192 | |
193 | |
194 /* search for the element */ | |
195 assembly_elem = concSMS_getAsBuffer( ref_num, address ); | |
196 | |
197 #ifdef _CONC_TESTING_ | |
198 TRACE_EVENT_P1("addToAsBuffer:[0].in_use: %d", assembly_list[0].in_use); | |
199 TRACE_EVENT_P1("addToAsBuffer:[1].in_use: %d", assembly_list[1].in_use); | |
200 #endif | |
201 | |
202 /* element not found */ | |
203 if (assembly_elem EQ NULL) | |
204 { | |
205 /* search for an unused list entry */ | |
206 for (i=0; i<MAX_BUF_ELEMS; i++) | |
207 { | |
208 if (assembly_list[i].in_use EQ FALSE) | |
209 { | |
210 assembly_elem = &assembly_list[i]; | |
211 break; | |
212 } | |
213 } | |
214 | |
215 /* buffer is full */ | |
216 if (assembly_elem EQ NULL) | |
217 return NULL; | |
218 | |
219 | |
220 /* create new assembly buffer for this ref_num*/ | |
221 assembly_elem->in_use = TRUE; | |
222 assembly_elem->ref_num = ref_num; | |
223 | |
224 if ( (address NEQ NULL) AND (address[0] NEQ '\0') ) | |
225 strcpy(assembly_elem->address, address); | |
226 else | |
227 assembly_elem->address[0] = '\0'; | |
228 | |
229 assembly_elem->next_exp_num = 1; | |
230 assembly_elem->segs_left = max_num; | |
231 assembly_elem->seg_count = 0; | |
232 } /* if (assembly_elem EQ NULL) */ | |
233 | |
234 if (assembly_elem->seg_count EQ 0) | |
235 { | |
236 /* alloc memory for data to assemble */ | |
237 | |
238 UBYTE segs; | |
239 | |
240 segs = MINIMUM(assembly_elem->segs_left, CONC_MAX_SEGS); | |
241 ACI_MALLOC(assembly_elem->data.data, (USHORT)(MAX_SM_LEN*segs)); | |
242 assembly_elem->segs_left -= segs; | |
243 assembly_elem->data.len = 0; | |
244 } | |
245 | |
246 memcpy(assembly_elem->data.data+assembly_elem->data.len, | |
247 data->data, data->len); | |
248 | |
249 assembly_elem->data.len += data->len; | |
250 assembly_elem->data.data[assembly_elem->data.len] = '\0'; | |
251 assembly_elem->next_exp_num++; | |
252 assembly_elem->seg_count++; | |
253 | |
254 #ifdef _CONC_TESTING_ | |
255 if (assembly_elem->data.len < TTRACE_LEN) | |
256 { | |
257 TRACE_EVENT_P1("addToAsBuffer:data.data: %s", assembly_elem->data.data); | |
258 } | |
259 TRACE_EVENT_P1("addToAsBuffer:data.len: %d", assembly_elem->data.len); | |
260 TRACE_EVENT_P1("addToAsBuffer:next_exp_num: %d", assembly_elem->next_exp_num); | |
261 TRACE_EVENT_P1("addToAsBuffer:seg_count: %d", assembly_elem->seg_count); | |
262 #endif | |
263 | |
264 return assembly_elem; | |
265 } | |
266 | |
267 | |
268 /* | |
269 +---------------------------------------------------------------------+ | |
270 | PROJECT : MODULE : CONC_SMS | | |
271 | STATE : code ROUTINE : concSMS_removeFromAsBuffer | | |
272 +---------------------------------------------------------------------+ | |
273 | |
274 PURPOSE : This functions gets data from the assembly buffer and | |
275 sets it to 'unused'. The assembly is completed. | |
276 | |
277 */ | |
278 LOCAL UBYTE concSMS_removeFromAsBuffer(T_SM_DATA_EXT *data_conc, | |
279 USHORT ref_num, | |
280 CHAR *address) | |
281 { | |
282 T_SM_ASSEMBLY *assembly_buf; | |
283 | |
284 TRACE_FUNCTION ("concSMS_removeFromAsBuffer()"); | |
285 | |
286 | |
287 /* search for the element */ | |
288 assembly_buf = concSMS_getAsBuffer( ref_num, address ); | |
289 | |
290 if (assembly_buf EQ NULL) | |
291 return FALSE; | |
292 | |
293 assembly_buf->in_use = FALSE; | |
294 | |
295 data_conc->data = assembly_buf->data.data; | |
296 data_conc->len = assembly_buf->data.len; | |
297 | |
298 return TRUE; | |
299 } | |
300 | |
301 | |
302 /* | |
303 +---------------------------------------------------------------------+ | |
304 | PROJECT : MODULE : CONC_SMS | | |
305 | STATE : code ROUTINE : concSMS_getFromAsBuffer | | |
306 +---------------------------------------------------------------------+ | |
307 | |
308 PURPOSE : This functions gets data from the assembly buffer and | |
309 resets the seg_count. The assembly buffer is still in use | |
310 and the assembly is not completed. | |
311 | |
312 */ | |
313 LOCAL UBYTE concSMS_getFromAsBuffer(T_SM_DATA_EXT *data_conc, | |
314 USHORT ref_num, | |
315 CHAR *address) | |
316 { | |
317 T_SM_ASSEMBLY *assembly_buf; | |
318 | |
319 TRACE_FUNCTION ("concSMS_getFromAsBuffer()"); | |
320 | |
321 | |
322 /* search for the element */ | |
323 assembly_buf = concSMS_getAsBuffer( ref_num, address ); | |
324 | |
325 /* assemlby buffer not found */ | |
326 if (assembly_buf EQ NULL) | |
327 return FALSE; | |
328 | |
329 assembly_buf->seg_count = 0; | |
330 | |
331 data_conc->data = assembly_buf->data.data; | |
332 data_conc->len = assembly_buf->data.len; | |
333 | |
334 return TRUE; | |
335 } | |
336 | |
337 | |
338 /* | |
339 +--------------------------------------------------------------------+ | |
340 | PROJECT : MODULE : CONC_SMS | | |
341 | STATE : code ROUTINE : concSMS_getSegBuffer | | |
342 +--------------------------------------------------------------------+ | |
343 | |
344 PURPOSE : This functions searchs the segment buffer for ref_num | |
345 and address. | |
346 */ | |
347 LOCAL T_SEG_BUF* concSMS_getSegBuffer( USHORT ref_num, CHAR *address ) | |
348 { | |
349 UBYTE i; | |
350 | |
351 TRACE_FUNCTION ("concSMS_getSegBuffer()"); | |
352 | |
353 | |
354 /* search for the element */ | |
355 for (i=0; i<MAX_BUF_ELEMS; i++) | |
356 { | |
357 if ((segBuf_list[i].ref_num EQ ref_num) AND | |
358 (segBuf_list[i].in_use)) | |
359 { | |
360 | |
361 if ((address NEQ NULL) /* AND (address[0] NEQ '\0') */) | |
362 { | |
363 if (!strcmp(segBuf_list[i].address, address)) | |
364 return &segBuf_list[i]; | |
365 } | |
366 else | |
367 { | |
368 return &segBuf_list[i]; | |
369 } | |
370 } | |
371 } | |
372 | |
373 return NULL; | |
374 } | |
375 | |
376 | |
377 /* | |
378 +--------------------------------------------------------------------+ | |
379 | PROJECT : MODULE : CONC_SMS | | |
380 | STATE : code ROUTINE : concSMS_addToSegBuffer | | |
381 +--------------------------------------------------------------------+ | |
382 | |
383 PURPOSE : This functions adds one segment to the buffer and returns | |
384 FALSE if no segment buffer is available or the current | |
385 seg buffer is full. | |
386 | |
387 */ | |
388 LOCAL UBYTE concSMS_addToSegBuffer ( USHORT ref_num, | |
389 CHAR *address, | |
390 UBYTE seq_num, | |
391 UBYTE rec_num, | |
392 T_ACI_SMS_STAT status, | |
393 T_SM_DATA_EXT *data ) | |
394 { | |
395 T_SEG_BUF *segBuf = NULL; | |
396 T_SEG_BUF_ELEM *segBufElem; | |
397 USHORT count; | |
398 UBYTE i; | |
399 | |
400 TRACE_FUNCTION ("concSMS_addToSegBuffer()"); | |
401 | |
402 | |
403 /* search for the segment buffer */ | |
404 segBuf = concSMS_getSegBuffer( ref_num, address ); | |
405 | |
406 /* element not found */ | |
407 if (segBuf EQ NULL) | |
408 { | |
409 /* search for an unused list entry */ | |
410 for (i=0; i<MAX_BUF_ELEMS; i++) | |
411 { | |
412 if (segBuf_list[i].in_use EQ FALSE) | |
413 { | |
414 segBuf = &segBuf_list[i]; | |
415 break; | |
416 } | |
417 } | |
418 | |
419 /* no segment buffer available */ | |
420 if ( segBuf EQ NULL) | |
421 return FALSE; | |
422 | |
423 /* initialise new buffer */ | |
424 segBuf->in_use = TRUE; | |
425 segBuf->ref_num = ref_num; | |
426 if ( (address) AND (address[0] NEQ '\0') ) | |
427 strcpy(segBuf->address, address); | |
428 else | |
429 segBuf->address[0] = '\0'; | |
430 segBuf->list = new_list(); | |
431 } | |
432 | |
433 count = get_list_count(segBuf->list); | |
434 if ( count >= CONC_MAX_SEGS ) | |
435 { | |
436 /* clean segment buffer before it overflows */ | |
437 while (1) | |
438 { | |
439 segBufElem = remove_first_element(segBuf->list); | |
440 if (segBufElem EQ NULL) | |
441 break; | |
442 ACI_MFREE(segBufElem->data.data); | |
443 ACI_MFREE(segBufElem); | |
444 } | |
445 segBuf->in_use = FALSE; | |
446 return FALSE; | |
447 } | |
448 | |
449 /* create new segment buffer element */ | |
450 ACI_MALLOC(segBufElem, sizeof(T_SEG_BUF_ELEM)); | |
451 memset(segBufElem, 0, sizeof(T_SEG_BUF_ELEM)); | |
452 | |
453 /* fill new buffer element */ | |
454 segBufElem->seq_num = seq_num; | |
455 segBufElem->rec_num = rec_num; | |
456 segBufElem->status = status; | |
457 | |
458 /* alloc memory and copy user data to segment buffer */ | |
459 ACI_MALLOC(segBufElem->data.data, data->len); | |
460 segBufElem->data.len = data->len; | |
461 memcpy(segBufElem->data.data, data->data, data->len); | |
462 | |
463 /* insert element (segment) into the segment buffer */ | |
464 insert_list(segBuf->list, segBufElem); | |
465 | |
466 return TRUE; | |
467 } | |
468 | |
469 | |
470 /* | |
471 +--------------------------------------------------------------------+ | |
472 | PROJECT : MODULE : CONC_SMS | | |
473 | STATE : code ROUTINE : concSMS_removeFromSegBuffer| | |
474 +--------------------------------------------------------------------+ | |
475 | |
476 PURPOSE : This function finds and removes the segment with | |
477 'seq_num' from the segment buffer. | |
478 | |
479 */ | |
480 LOCAL T_SEG_BUF_ELEM* concSMS_removeFromSegBuffer ( USHORT ref_num, | |
481 CHAR* address, | |
482 UBYTE seq_num ) | |
483 { | |
484 T_SEG_BUF *segBuf = NULL; | |
485 T_SEG_BUF_ELEM *segBufElem; | |
486 | |
487 USHORT count; | |
488 | |
489 TRACE_FUNCTION ("concSMS_removeFromSegBuffer()"); | |
490 | |
491 | |
492 /* search for the segment buffer */ | |
493 segBuf = concSMS_getSegBuffer( ref_num, address ); | |
494 | |
495 | |
496 /* segment buffer not found */ | |
497 if (segBuf EQ NULL) | |
498 return NULL; | |
499 | |
500 segBufElem = remove_element(segBuf->list, seq_num, concSMS_findSeqNumSB); | |
501 | |
502 if (segBufElem EQ NULL) | |
503 { | |
504 return NULL; /* didn't find the segment buffer element for this seq_num */ | |
505 } | |
506 | |
507 count = get_list_count(segBuf->list); | |
508 | |
509 if (count EQ 0) | |
510 { | |
511 ACI_MFREE (segBuf->list); | |
512 segBuf->list = NULL; | |
513 segBuf->in_use = FALSE; | |
514 } | |
515 | |
516 return segBufElem; | |
517 | |
518 } | |
519 | |
520 | |
521 /* | |
522 +--------------------------------------------------------------------+ | |
523 | PROJECT : MODULE : CONC_SMS | | |
524 | STATE : code ROUTINE : concSMS_getConcBuffer | | |
525 +--------------------------------------------------------------------+ | |
526 | |
527 PURPOSE : This functions searchs the concatenations buffer for | |
528 ref_num and address. | |
529 */ | |
530 LOCAL T_CONC_BUF* concSMS_getConcBuffer( USHORT ref_num, CHAR *address ) | |
531 { | |
532 UBYTE i; | |
533 | |
534 TRACE_FUNCTION ("concSMS_getConcBuffer()"); | |
535 | |
536 /* search for the element */ | |
537 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
538 { | |
539 if ((concBuf_list[i].ref_num EQ ref_num) AND | |
540 (concBuf_list[i].in_use)) | |
541 { | |
542 if ((address NEQ NULL) /* AND (address[0] NEQ '\0') */) | |
543 { | |
544 if (!strcmp(concBuf_list[i].address, address)) | |
545 { | |
546 return &concBuf_list[i]; | |
547 } | |
548 } | |
549 else | |
550 { | |
551 return &concBuf_list[i]; | |
552 } | |
553 } | |
554 } | |
555 | |
556 return NULL; | |
557 } | |
558 | |
559 | |
560 /* | |
561 +--------------------------------------------------------------------+ | |
562 | PROJECT : MODULE : CONC_SMS | | |
563 | STATE : code ROUTINE : concSMS_addToConcatList | | |
564 +--------------------------------------------------------------------+ | |
565 | |
566 PURPOSE : | |
567 */ | |
568 LOCAL BOOL concSMS_addToConcatList ( USHORT ref_num, | |
569 CHAR *address, | |
570 UBYTE max_num, | |
571 UBYTE seq_num, | |
572 UBYTE rec_num, | |
573 T_ACI_SMS_STAT status, | |
574 UBYTE mem) | |
575 { | |
576 T_CONC_BUF *concBuf; | |
577 T_CONC_BUF_ELEM *concBufElem; | |
578 UBYTE i; | |
579 | |
580 TRACE_FUNCTION ("concSMS_addToConcatList()"); | |
581 | |
582 | |
583 /* search for concatenation buffer */ | |
584 concBuf = concSMS_getConcBuffer( ref_num, address ); | |
585 | |
586 | |
587 /* element not found */ | |
588 if (concBuf EQ NULL) | |
589 { | |
590 | |
591 /* search for an unused list entry */ | |
592 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
593 { | |
594 if (concBuf_list[i].in_use EQ FALSE) | |
595 { | |
596 concBuf = &concBuf_list[i]; | |
597 break; | |
598 } | |
599 } | |
600 | |
601 /* buffer is full */ | |
602 if ( concBuf EQ NULL) | |
603 return FALSE; | |
604 | |
605 | |
606 concBuf->in_use = TRUE; | |
607 concBuf->ref_num = ref_num; | |
608 | |
609 if ( (address) AND (address[0] NEQ '\0') ) | |
610 strcpy(concBuf->address, address); | |
611 else | |
612 concBuf->address[0] = '\0'; | |
613 | |
614 concBuf->max_num = max_num; | |
615 concBuf->list = new_list(); | |
616 } | |
617 | |
618 | |
619 /* don't add elements with same seq_num to the Concatenation Buffer */ | |
620 concBufElem = find_element(concBuf->list,seq_num,concSMS_findSeqNumElemCB); | |
621 if (concBufElem) | |
622 return FALSE; | |
623 | |
624 | |
625 | |
626 /* create new conc. buffer element */ | |
627 ACI_MALLOC(concBufElem, sizeof(T_CONC_BUF_ELEM)); | |
628 | |
629 /* increase total count of stored CSMS segments by 1*/ | |
630 concShrdPrm.elem_count++; | |
631 | |
632 concBufElem->seq_num = seq_num; | |
633 concBufElem->rec_num = rec_num; | |
634 concBufElem->status = status; | |
635 concBufElem->mem = mem; | |
636 | |
637 /* insert element into the conc. buffer */ | |
638 insert_list(concBuf->list, concBufElem); | |
639 | |
640 concSMS_printConcatList(); | |
641 | |
642 return TRUE; | |
643 } | |
644 | |
645 | |
646 | |
647 /* | |
648 +---------------------------------------------------------------------+ | |
649 | PROJECT : MODULE : CONC_SMS | | |
650 | STATE : code ROUTINE : concSMS_removeFromConcatList| | |
651 +---------------------------------------------------------------------+ | |
652 | |
653 PURPOSE : This function removes and FREES the memory for the element. | |
654 */ | |
655 LOCAL T_ACI_LIST *concSMS_removeFromConcatList ( USHORT ref_num, | |
656 CHAR *address, | |
657 UBYTE rec_num ) | |
658 { | |
659 T_CONC_BUF *concBuf = NULL; | |
660 T_CONC_BUF_ELEM *concBufElem; | |
661 USHORT count; | |
662 | |
663 TRACE_FUNCTION ("concSMS_removeFromConcatList()"); | |
664 | |
665 | |
666 /* search for concatenation buffer */ | |
667 concBuf = concSMS_getConcBuffer( ref_num, address ); | |
668 | |
669 /* concatenation buffer not found */ | |
670 if (concBuf EQ NULL) | |
671 { | |
672 TRACE_EVENT_P1("conc_buf NULL: rec: %d", rec_num); | |
673 return NULL; | |
674 } | |
675 | |
676 concBufElem = remove_element(concBuf->list, rec_num, concSMS_findRecNumElemCB); | |
677 | |
678 if (concBufElem EQ NULL) | |
679 { | |
680 TRACE_EVENT_P1("concBufElem NULL: rec: %d", rec_num); | |
681 return NULL; | |
682 } | |
683 | |
684 /* free memory for this element */ | |
685 ACI_MFREE(concBufElem); | |
686 | |
687 /* decrease total count of stored CSMS segments by 1*/ | |
688 concShrdPrm.elem_count--; | |
689 | |
690 count = get_list_count(concBuf->list); | |
691 | |
692 if (count EQ 0) | |
693 { | |
694 ACI_MFREE (concBuf->list); | |
695 concBuf->list = NULL; | |
696 concBuf->in_use = FALSE; | |
697 return NULL; | |
698 } | |
699 return concBuf->list; | |
700 } | |
701 | |
702 | |
703 /* | |
704 +---------------------------------------------------------------------+ | |
705 | PROJECT : MODULE : CONC_SMS | | |
706 | STATE : code ROUTINE : concSMS_sortConcatList | | |
707 +---------------------------------------------------------------------+ | |
708 | |
709 PURPOSE : This function sorts the concat. buffer acc. to its seq_num. | |
710 */ | |
711 LOCAL void concSMS_sortConcatList ( USHORT ref_num, | |
712 CHAR *address ) | |
713 { | |
714 T_CONC_BUF *concBuf = NULL; | |
715 T_CONC_BUF_ELEM *concBufElem; | |
716 UBYTE seq_num; | |
717 UBYTE rec_num = 0; | |
718 T_ACI_LIST *oldlist, *newlist, *current; | |
719 USHORT count; | |
720 | |
721 TRACE_FUNCTION ("concSMS_sortConcatList()"); | |
722 | |
723 | |
724 /* search for concatenation buffer */ | |
725 concBuf = concSMS_getConcBuffer( ref_num, address ); | |
726 | |
727 /* concatenation buffer not found */ | |
728 if (concBuf EQ NULL) | |
729 return; | |
730 | |
731 newlist = new_list(); | |
732 oldlist = concBuf->list; | |
733 | |
734 count = get_list_count(oldlist); | |
735 | |
736 while (count) | |
737 { | |
738 seq_num = 255; | |
739 current = oldlist; | |
740 while (current) | |
741 { | |
742 concBufElem = (T_CONC_BUF_ELEM*)current->msg; | |
743 if ( concBufElem->seq_num < seq_num ) | |
744 { | |
745 seq_num = concBufElem->seq_num; | |
746 rec_num = concBufElem->rec_num; | |
747 } | |
748 current = current->next; | |
749 } | |
750 | |
751 concBufElem = remove_element(oldlist, rec_num, concSMS_findRecNumElemCB); | |
752 | |
753 insert_list(newlist, concBufElem); | |
754 | |
755 count = get_list_count(oldlist); | |
756 } | |
757 if (concBuf->list) | |
758 { | |
759 ACI_MFREE (concBuf->list); | |
760 concBuf->list = NULL; | |
761 } | |
762 concBuf->list = newlist; | |
763 } | |
764 | |
765 | |
766 /* | |
767 +--------------------------------------------------------------------+ | |
768 | PROJECT : MODULE : CONC_SMS | | |
769 | STATE : code ROUTINE : concSMS_split | | |
770 +--------------------------------------------------------------------+ | |
771 | |
772 PURPOSE : return TRUE if splitting was done, otherwise FALSE | |
773 */ | |
774 LOCAL UBYTE concSMS_split ( T_ACI_SM_DATA* tar_data, | |
775 T_SM_DATA_EXT* src_data, | |
776 UBYTE alphabet, | |
777 T_EXT_CMS_CMD_ID id) | |
778 { | |
779 #ifndef _SIMULATION_ | |
780 T_TIME time_val; /* Used for input to random generator */ | |
781 #endif | |
782 | |
783 TRACE_FUNCTION ("concSMS_split ()"); | |
784 | |
785 if (alphabet EQ 0x00) | |
786 { | |
787 /* 7-bit data coding scheme */ | |
788 if (src_data->len <= concShrdPrm.l_uncomp7bit_data) | |
789 { | |
790 tar_data->len = (UBYTE)src_data->len; | |
791 memcpy ( tar_data->data, src_data->data, tar_data->len ); | |
792 return FALSE; | |
793 } | |
794 else | |
795 { | |
796 tar_data->len = concShrdPrm.l_uncomp7bit_data_conc; | |
797 concShrdPrm.max_sms_len = concShrdPrm.l_uncomp7bit_data_conc; | |
798 } | |
799 } | |
800 else | |
801 { | |
802 /* 8-bit data coding scheme */ | |
803 if (src_data->len <= concShrdPrm.l_uncomp8bit_data) | |
804 { | |
805 tar_data->len = (UBYTE)src_data->len; | |
806 memcpy ( tar_data->data, src_data->data, tar_data->len ); | |
807 return FALSE; | |
808 } | |
809 else | |
810 { | |
811 tar_data->len = concShrdPrm.l_uncomp8bit_data_conc; | |
812 concShrdPrm.max_sms_len = concShrdPrm.l_uncomp8bit_data_conc; | |
813 } | |
814 } | |
815 | |
816 /* copy first segment to 'tar_data' */ | |
817 memcpy ( tar_data->data, src_data->data, tar_data->len ); | |
818 | |
819 concShrdPrm.udh.ref_num = (UBYTE)concSMS_findMaxRefNum(); /* Marcus: Issue 872: 03/10/2002 */ | |
820 concShrdPrm.udh.ref_num++; | |
821 | |
822 concShrdPrm.udh.max_num = (src_data->len+(concShrdPrm.max_sms_len-1)) / concShrdPrm.max_sms_len; | |
823 concShrdPrm.udh.seq_num = 1; | |
824 | |
825 if (id EQ CMGS_CONC) | |
826 { | |
827 #ifndef _SIMULATION_ | |
828 vsi_t_time (VSI_CALLER &time_val); | |
829 srand((USHORT) time_val); /* initialize random generator */ | |
830 | |
831 /* For every conc sms going out, generate a random reference number and | |
832 * send it. Also when power cycled it will generate a new random number. | |
833 */ | |
834 concShrdPrm.udh.ref_num = (UBYTE)rand(); | |
835 #endif | |
836 concShrdPrm.specPrm.concCMGS.data.len = src_data->len; | |
837 concShrdPrm.specPrm.concCMGS.data.data = src_data->data; | |
838 concShrdPrm.specPrm.concCMGS.offset = tar_data->len; | |
839 return TRUE; | |
840 } | |
841 | |
842 if (id EQ CMGW_CONC) | |
843 { | |
844 concShrdPrm.specPrm.concCMGW.data.len = src_data->len; | |
845 concShrdPrm.specPrm.concCMGW.data.data = src_data->data; | |
846 concShrdPrm.specPrm.concCMGW.offset = tar_data->len; | |
847 return TRUE; | |
848 } | |
849 | |
850 return FALSE; | |
851 } | |
852 | |
853 | |
854 /* | |
855 +--------------------------------------------------------------------+ | |
856 | PROJECT : MODULE : CONC_SMS | | |
857 | STATE : code ROUTINE : concSMS_fillUDH | | |
858 +--------------------------------------------------------------------+ | |
859 | |
860 PURPOSE : | |
861 */ | |
862 LOCAL void concSMS_fillUDH ( T_ACI_UDH_DATA* udh, | |
863 UBYTE ref_num, | |
864 UBYTE max_num, | |
865 UBYTE seq_num ) | |
866 { | |
867 /* fill user data header structure for 8-bit ref number */ | |
868 | |
869 udh->len = 0x05; | |
870 | |
871 /* Information Element Identifier */ | |
872 udh->data[0] = SMS_IEI_CONC_8BIT; | |
873 | |
874 /* Information Element Identifier Length */ | |
875 udh->data[1] = 0x03; | |
876 | |
877 /* Information Element Data */ | |
878 udh->data[2] = (UBYTE)(ref_num & 0x00FF); /* since we use only 8-Bit ref number */ | |
879 udh->data[3] = max_num; | |
880 udh->data[4] = seq_num; | |
881 } | |
882 | |
883 | |
884 | |
885 #ifdef TI_PS_FF_CONC_SMS | |
886 /********************** Init Functions *********************************/ | |
887 | |
888 | |
889 /* | |
890 +--------------------------------------------------------------------+ | |
891 | PROJECT : MODULE : CONC_SMS | | |
892 | STATE : code ROUTINE : concSMS_retrieveConcBuf | | |
893 +--------------------------------------------------------------------+ | |
894 | |
895 PURPOSE : This function searches for the concatenation buffer | |
896 which has 'index' in its first element. Returns | |
897 'CONC_ERROR' if index is not the first element or list is | |
898 incomplete. | |
899 | |
900 */ | |
901 LOCAL T_CONC_INIT_RETURN concSMS_retrieveConcBuf ( T_CONC_BUF **concBuf, | |
902 UBYTE index, | |
903 UBYTE mem) | |
904 { | |
905 UBYTE i; | |
906 T_CONC_BUF_ELEM *concBufElem; | |
907 | |
908 TRACE_FUNCTION ("concSMS_retrieveConcBuf ()"); | |
909 | |
910 *concBuf = NULL; | |
911 | |
912 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
913 { | |
914 concSMS_printConcatList(); | |
915 /* find conc. buffer element for this rec number */ | |
916 concBufElem = find_element(concBuf_list[i].list, | |
917 index, | |
918 concSMS_findRecNumElemCB); | |
919 | |
920 /* element was found and check if memory type of the first segment | |
921 * equals to the set memory type (mem1 or mem2) | |
922 */ | |
923 if ((concBufElem NEQ NULL) AND (concBufElem->mem EQ mem)) | |
924 | |
925 { | |
926 break; | |
927 } | |
928 } | |
929 | |
930 if (concBufElem EQ NULL) | |
931 { | |
932 /* no concatenation handler needed */ | |
933 return CONC_NOT_NEEDED; | |
934 } | |
935 | |
936 *concBuf = &concBuf_list[i]; | |
937 | |
938 | |
939 /* check if rec number is the first segment (with seq_num == 1) */ | |
940 if ( ( concBufElem->seq_num EQ 1 ) AND | |
941 ( smsShrdPrm.status EQ CMGD_DEL_INDEX ) ) | |
942 { | |
943 *concBuf = &concBuf_list[i]; | |
944 return CONC_NEEDED; | |
945 | |
946 } | |
947 else if( smsShrdPrm.status > CMGD_DEL_INDEX ) | |
948 { | |
949 /* The below check needs to be changed for deleting all | |
950 the concatmessages in case of DELET FLAG > 0. */ | |
951 | |
952 *concBuf = &concBuf_list[i]; | |
953 return CONC_NEEDED; | |
954 } | |
955 /* rec number is not the first element in conc. buffer | |
956 * allow reading of incomplete segments and tread them like "normal" SMS | |
957 */ | |
958 return CONC_NOT_NEEDED; | |
959 } | |
960 | |
961 | |
962 | |
963 /* | |
964 +--------------------------------------------------------------------+ | |
965 | PROJECT : MODULE : CONC_SMS | | |
966 | STATE : code ROUTINE : concSMS_initSendFromMem | | |
967 +--------------------------------------------------------------------+ | |
968 | |
969 PURPOSE : This function initialises shared parameter for CMSS. | |
970 | |
971 */ | |
972 GLOBAL T_CONC_INIT_RETURN concSMS_initSendFromMem ( T_ACI_CMD_SRC srcId, | |
973 UBYTE *index, | |
974 CHAR *da, | |
975 T_ACI_TOA *toda ) | |
976 { | |
977 T_CONC_BUF *concBuf = NULL; | |
978 T_CONC_BUF_ELEM* elem = NULL; | |
979 T_CONC_INIT_RETURN ret = CONC_ERROR; | |
980 T_CONC_CMSS *prm = &concShrdPrm.specPrm.concCMSS; | |
981 | |
982 | |
983 TRACE_FUNCTION ("concSMS_initSendFromMem ()"); | |
984 | |
985 ret = concSMS_retrieveConcBuf ( &concBuf, *index, smsShrdPrm.mem2); | |
986 | |
987 if (ret EQ CONC_ERROR) | |
988 { | |
989 /* Error: segment is not the first segment of the SM */ | |
990 return CONC_ERROR; | |
991 } | |
992 | |
993 if (ret EQ CONC_NOT_NEEDED) | |
994 { | |
995 /* no conatenation handler needed */ | |
996 return CONC_NOT_NEEDED; | |
997 } | |
998 | |
999 concShrdPrm.sentSegs = 0; | |
1000 concShrdPrm.srcId = srcId; | |
1001 | |
1002 if (da) | |
1003 { | |
1004 memcpy(prm->da, da, strlen(da)); | |
1005 prm->da[strlen(da)] = '\0'; | |
1006 prm->p_da = prm->da; | |
1007 } | |
1008 else | |
1009 { | |
1010 prm->p_da = NULL; | |
1011 } | |
1012 | |
1013 if (toda) | |
1014 { | |
1015 memcpy(&prm->toda, toda, sizeof(T_ACI_TOA)); | |
1016 prm->p_toda = &prm->toda; | |
1017 } | |
1018 else | |
1019 { | |
1020 prm->p_toda = NULL; | |
1021 } | |
1022 | |
1023 /* save the first concatenated buffer element */ | |
1024 prm->currConcBufListElem = concBuf->list; | |
1025 | |
1026 prm->skipStoSent = TRUE; | |
1027 | |
1028 /* skip segments with status SMS_STAT_StoSent */ | |
1029 while (prm->currConcBufListElem) | |
1030 { | |
1031 elem = (T_CONC_BUF_ELEM*)prm->currConcBufListElem->msg; | |
1032 | |
1033 if (elem->status EQ SMS_STAT_StoSent) | |
1034 { | |
1035 prm->currConcBufListElem = prm->currConcBufListElem->next; | |
1036 } | |
1037 else | |
1038 { | |
1039 break; | |
1040 } | |
1041 } | |
1042 | |
1043 /* | |
1044 * All elements were set to SMS_STAT_StoSent. Assume that this message was | |
1045 * sent completly and should be sent for the second time. | |
1046 */ | |
1047 if (prm->currConcBufListElem EQ NULL) | |
1048 { | |
1049 prm->skipStoSent = FALSE; | |
1050 | |
1051 /* save the first concatenated buffer element */ | |
1052 prm->currConcBufListElem = concBuf->list; | |
1053 | |
1054 elem = (T_CONC_BUF_ELEM*)prm->currConcBufListElem->msg; | |
1055 } | |
1056 | |
1057 *index = elem ? elem->rec_num : NULL; | |
1058 | |
1059 if (elem NEQ NULL) | |
1060 { | |
1061 elem->status = SMS_STAT_StoSent; | |
1062 } | |
1063 | |
1064 return CONC_NEEDED; | |
1065 | |
1066 } | |
1067 | |
1068 | |
1069 /* | |
1070 +--------------------------------------------------------------------+ | |
1071 | PROJECT : MODULE : CONC_SMS | | |
1072 | STATE : code ROUTINE : concSMS_initReadFromMem | | |
1073 +--------------------------------------------------------------------+ | |
1074 | |
1075 PURPOSE : This function initialises shared parameter for CMGR. | |
1076 | |
1077 */ | |
1078 GLOBAL T_CONC_INIT_RETURN concSMS_initReadFromMem ( T_ACI_CMD_SRC srcId, | |
1079 UBYTE index, | |
1080 T_ACI_SMS_READ rdMode ) | |
1081 { | |
1082 T_CONC_BUF *concBuf; | |
1083 T_CONC_INIT_RETURN ret; | |
1084 | |
1085 TRACE_FUNCTION ("concSMS_initReadFromMem ()"); | |
1086 | |
1087 ret = concSMS_retrieveConcBuf ( &concBuf, index, smsShrdPrm.mem2); | |
1088 | |
1089 if (ret EQ CONC_ERROR) | |
1090 { | |
1091 /* Error: segment is not the first segment of the SM */ | |
1092 return CONC_ERROR; | |
1093 } | |
1094 | |
1095 if (ret EQ CONC_NOT_NEEDED) | |
1096 { | |
1097 /* no conatenation handler needed */ | |
1098 return CONC_NOT_NEEDED; | |
1099 } | |
1100 | |
1101 concShrdPrm.srcId = srcId; | |
1102 concShrdPrm.specPrm.concCMGR.rdMode = rdMode; | |
1103 | |
1104 /* save the second concatenated buffer element */ | |
1105 concShrdPrm.specPrm.concCMGR.currConcBufListElem = concBuf->list->next; | |
1106 | |
1107 return CONC_NEEDED; | |
1108 | |
1109 } | |
1110 | |
1111 | |
1112 /* | |
1113 +--------------------------------------------------------------------+ | |
1114 | PROJECT : MODULE : CONC_SMS | | |
1115 | STATE : code ROUTINE : concSMS_initDeleteFromMem | | |
1116 +--------------------------------------------------------------------+ | |
1117 | |
1118 PURPOSE : This function initialises shared parameter for CMGD. | |
1119 | |
1120 */ | |
1121 GLOBAL T_CONC_INIT_RETURN concSMS_initDeleteFromMem ( T_ACI_CMD_SRC srcId, | |
1122 UBYTE index ) | |
1123 { | |
1124 T_CONC_BUF *concBuf; | |
1125 T_CONC_INIT_RETURN ret; | |
1126 | |
1127 | |
1128 TRACE_FUNCTION ("concSMS_initDeleteFromMem ()"); | |
1129 | |
1130 | |
1131 ret = concSMS_retrieveConcBuf ( &concBuf, index, smsShrdPrm.mem1); | |
1132 | |
1133 if (ret EQ CONC_ERROR) | |
1134 { | |
1135 /* Error: segment is not the first segment of the SM */ | |
1136 return CONC_ERROR; | |
1137 } | |
1138 | |
1139 if (ret EQ CONC_NOT_NEEDED) | |
1140 { | |
1141 if (concBuf NEQ NULL) | |
1142 { | |
1143 RefNum_Del = concBuf->ref_num; | |
1144 } | |
1145 /*else if (*/ | |
1146 else if (dFLAG EQ TRUE) | |
1147 { | |
1148 TRACE_EVENT("BUFFER FULL"); | |
1149 } | |
1150 else | |
1151 { | |
1152 RefNum_Del = 0xFF; | |
1153 } | |
1154 /* no conatenation handler needed */ | |
1155 return CONC_NOT_NEEDED; | |
1156 } | |
1157 | |
1158 | |
1159 /* save the concatenation list */ | |
1160 concShrdPrm.specPrm.concCMGD.currConcBufListElem = concBuf->list; | |
1161 | |
1162 concShrdPrm.specPrm.concCMGD.ref_num = concBuf->ref_num; | |
1163 | |
1164 concShrdPrm.specPrm.concCMGD.address = concBuf->address; | |
1165 | |
1166 concShrdPrm.srcId = srcId; | |
1167 | |
1168 concShrdPrm.specPrm.concCMGD.error_count = 0; | |
1169 | |
1170 return CONC_NEEDED; | |
1171 } | |
1172 | |
1173 | |
1174 /* | |
1175 +--------------------------------------------------------------------+ | |
1176 | PROJECT : MODULE : CONC_SMS | | |
1177 | STATE : code ROUTINE : concSMS_initSend | | |
1178 +--------------------------------------------------------------------+ | |
1179 | |
1180 PURPOSE : This function initialises shared parameter for CMGS. | |
1181 | |
1182 */ | |
1183 GLOBAL T_CONC_INIT_RETURN concSMS_initSend ( | |
1184 T_ACI_SM_DATA* tar_data, | |
1185 T_ACI_UDH_DATA* udh, | |
1186 T_ACI_CMD_SRC srcId, | |
1187 CHAR* da, | |
1188 T_ACI_TOA* toda, | |
1189 T_SM_DATA_EXT* src_data, | |
1190 CHAR* sca, | |
1191 T_ACI_TOA* tosca, | |
1192 SHORT isReply, | |
1193 UBYTE alphabet ) | |
1194 { | |
1195 UBYTE ret; | |
1196 T_CONC_CMGS *prm = &concShrdPrm.specPrm.concCMGS; | |
1197 | |
1198 TRACE_FUNCTION ("concSMS_initSend ()"); | |
1199 | |
1200 | |
1201 ret = concSMS_split ( tar_data, src_data, alphabet, CMGS_CONC ); | |
1202 | |
1203 if ( ret EQ FALSE ) | |
1204 return CONC_NOT_NEEDED; | |
1205 | |
1206 concShrdPrm.srcId = srcId; | |
1207 | |
1208 if (da) | |
1209 { | |
1210 memcpy(prm->da, da, strlen(da)); | |
1211 prm->da[strlen(da)] = '\0'; | |
1212 prm->p_da = prm->da; | |
1213 } | |
1214 else | |
1215 { | |
1216 prm->p_da = NULL; | |
1217 } | |
1218 if (toda) | |
1219 { | |
1220 memcpy(&prm->toda, toda, sizeof(T_ACI_TOA)); | |
1221 prm->p_toda = &prm->toda; | |
1222 } | |
1223 else | |
1224 { | |
1225 prm->p_toda = NULL; | |
1226 } | |
1227 | |
1228 prm->data.len = src_data->len; | |
1229 prm->data.data = src_data->data; | |
1230 | |
1231 if (sca) | |
1232 { | |
1233 memcpy(prm->sca, sca, strlen(sca)); | |
1234 prm->sca[strlen(sca)] = '\0'; | |
1235 prm->p_sca = prm->sca; | |
1236 } | |
1237 else | |
1238 { | |
1239 prm->p_sca = NULL; | |
1240 } | |
1241 if (tosca) | |
1242 { | |
1243 memcpy(&prm->tosca, tosca, sizeof(T_ACI_TOA)); | |
1244 prm->p_tosca = &prm->tosca; | |
1245 } | |
1246 else | |
1247 { | |
1248 prm->p_tosca = NULL; | |
1249 } | |
1250 | |
1251 prm->isReply = isReply; | |
1252 prm->sent_bytes = 0; | |
1253 | |
1254 concShrdPrm.sentSegs = 0; | |
1255 | |
1256 /* fill user data header structure */ | |
1257 concSMS_fillUDH ( udh, | |
1258 concShrdPrm.udh.ref_num, | |
1259 concShrdPrm.udh.max_num, | |
1260 concShrdPrm.udh.seq_num ); | |
1261 | |
1262 return CONC_NEEDED; | |
1263 } | |
1264 | |
1265 | |
1266 /* | |
1267 +--------------------------------------------------------------------+ | |
1268 | PROJECT : MODULE : CONC_SMS | | |
1269 | STATE : code ROUTINE : concSMS_initStoreInMem | | |
1270 +--------------------------------------------------------------------+ | |
1271 | |
1272 PURPOSE : This function initialises shared parameter for CMGW. | |
1273 | |
1274 */ | |
1275 GLOBAL T_CONC_INIT_RETURN concSMS_initStoreInMem ( T_ACI_SM_DATA* tar_data, | |
1276 T_ACI_UDH_DATA* udh, | |
1277 T_ACI_CMD_SRC srcId, | |
1278 SHORT index, | |
1279 CHAR* address, | |
1280 T_ACI_TOA* toa, | |
1281 T_ACI_SMS_STAT stat, | |
1282 UBYTE msg_ref, | |
1283 T_SM_DATA_EXT* src_data, | |
1284 CHAR* sca, | |
1285 T_ACI_TOA* tosca, | |
1286 SHORT isReply, | |
1287 UBYTE alphabet ) | |
1288 { | |
1289 T_CONC_INIT_RETURN ret; | |
1290 T_CONC_CMGW *prm = &concShrdPrm.specPrm.concCMGW; | |
1291 | |
1292 TRACE_FUNCTION ("concSMS_initStoreInMem ()"); | |
1293 | |
1294 | |
1295 ret = (T_CONC_INIT_RETURN)concSMS_split ( tar_data, src_data, alphabet, CMGW_CONC ); | |
1296 | |
1297 if ( ret EQ FALSE ) | |
1298 { | |
1299 return CONC_NOT_NEEDED; | |
1300 } | |
1301 | |
1302 concShrdPrm.srcId = srcId; | |
1303 | |
1304 if (address) | |
1305 { | |
1306 memcpy(prm->da, address, strlen(address)); | |
1307 prm->da[strlen(address)] = '\0'; | |
1308 prm->p_da = prm->da; | |
1309 } | |
1310 else | |
1311 { | |
1312 prm->p_da = NULL; | |
1313 } | |
1314 if (toa) | |
1315 { | |
1316 memcpy(&prm->toda, toa, sizeof(T_ACI_TOA)); | |
1317 prm->p_toda = &prm->toda; | |
1318 } | |
1319 else | |
1320 { | |
1321 prm->p_toda = NULL; | |
1322 } | |
1323 | |
1324 if ( stat NEQ SMS_STAT_NotPresent) | |
1325 { | |
1326 prm->stat = stat; | |
1327 } | |
1328 else | |
1329 { | |
1330 prm->stat = SMS_STAT_StoUnsent; | |
1331 } | |
1332 | |
1333 prm->msg_ref = msg_ref; | |
1334 prm->data.len = src_data->len; | |
1335 prm->data.data = src_data->data; | |
1336 | |
1337 if (sca) | |
1338 { | |
1339 memcpy(prm->sca, sca, strlen(sca)); | |
1340 prm->sca[strlen(sca)] = '\0'; | |
1341 prm->p_sca = prm->sca; | |
1342 } | |
1343 else | |
1344 { | |
1345 prm->p_sca = NULL; | |
1346 } | |
1347 if (tosca) | |
1348 { | |
1349 memcpy(&prm->tosca, tosca, sizeof(T_ACI_TOA)); | |
1350 prm->p_tosca = &prm->tosca; | |
1351 } | |
1352 else | |
1353 { | |
1354 prm->p_tosca = NULL; | |
1355 } | |
1356 | |
1357 prm->isReply = isReply; | |
1358 | |
1359 /* fill user data header structure */ | |
1360 concSMS_fillUDH ( udh, | |
1361 concShrdPrm.udh.ref_num, | |
1362 concShrdPrm.udh.max_num, | |
1363 concShrdPrm.udh.seq_num ); | |
1364 | |
1365 return CONC_NEEDED; | |
1366 } | |
1367 | |
1368 | |
1369 /* | |
1370 +--------------------------------------------------------------------+ | |
1371 | PROJECT : MODULE : CONC_SMS | | |
1372 | STATE : code ROUTINE : concSMS_initCommand | | |
1373 +--------------------------------------------------------------------+ | |
1374 | |
1375 PURPOSE : This function initialises shared parameter for CMGC. | |
1376 | |
1377 */ | |
1378 GLOBAL T_CONC_INIT_RETURN concSMS_initCommand ( T_ACI_CMD_SRC srcId, | |
1379 SHORT fo, | |
1380 SHORT ct, | |
1381 SHORT pid, | |
1382 SHORT mn, | |
1383 CHAR* da, | |
1384 T_ACI_TOA* toda, | |
1385 T_ACI_CMD_DATA* data ) | |
1386 { | |
1387 T_CONC_CMGC *prm = &concShrdPrm.specPrm.concCMGC; | |
1388 | |
1389 TRACE_FUNCTION ("concSMS_initCommand ()"); | |
1390 | |
1391 | |
1392 if ( ct NEQ COMMAND_TYPE_DELETE) | |
1393 return CONC_NOT_NEEDED; | |
1394 | |
1395 if ((mn < concShrdPrm.first_mr) OR | |
1396 (mn > concShrdPrm.first_mr + concShrdPrm.sentSegs-1)) | |
1397 return CONC_NOT_NEEDED; | |
1398 | |
1399 | |
1400 if ( mn NEQ concShrdPrm.first_mr) | |
1401 { | |
1402 /* Error: segment is not the first segment of the SM */ | |
1403 return CONC_ERROR; | |
1404 } | |
1405 else | |
1406 { | |
1407 concShrdPrm.srcId = srcId; | |
1408 | |
1409 prm->command_count = 0; | |
1410 prm->fo = (UBYTE)fo; | |
1411 prm->ct = (UBYTE)ct; | |
1412 prm->pid = (UBYTE)pid; | |
1413 | |
1414 if (da) | |
1415 { | |
1416 memcpy(prm->da, da, strlen(da)); | |
1417 prm->da[strlen(da)] = '\0'; | |
1418 prm->p_da = prm->da; | |
1419 } | |
1420 else | |
1421 { | |
1422 prm->p_da = NULL; | |
1423 } | |
1424 | |
1425 if (toda) | |
1426 { | |
1427 memcpy(&prm->toda, toda, sizeof(T_ACI_TOA)); | |
1428 prm->p_toda = &prm->toda; | |
1429 } | |
1430 else | |
1431 { | |
1432 prm->p_toda = NULL; | |
1433 } | |
1434 | |
1435 ACI_MALLOC(prm->data.data, MAX_SM_CMD_LEN); | |
1436 memcpy ( prm->data.data, data->data, data->len ); | |
1437 prm->data.len = data->len; | |
1438 | |
1439 } | |
1440 return CONC_NEEDED; | |
1441 } | |
1442 | |
1443 | |
1444 | |
1445 | |
1446 /********************** RAT Callback Fucntions ****************************/ | |
1447 | |
1448 | |
1449 GLOBAL void rConcSMS_PlusCMSS (UBYTE mr, UBYTE numSeg) | |
1450 { | |
1451 UBYTE index; | |
1452 T_CONC_BUF_ELEM* elem; | |
1453 T_CONC_CMSS *prm = &concShrdPrm.specPrm.concCMSS; | |
1454 | |
1455 TRACE_FUNCTION ("rConcSMS_PlusCMSS()"); | |
1456 | |
1457 | |
1458 /* save the first message reference */ | |
1459 if (concShrdPrm.sentSegs EQ 0) | |
1460 { | |
1461 concShrdPrm.first_mr = mr; | |
1462 } | |
1463 | |
1464 /* increment number of successfully sent elements */ | |
1465 concShrdPrm.sentSegs++; | |
1466 | |
1467 /* get next concat. list element */ | |
1468 prm->currConcBufListElem = prm->currConcBufListElem->next; | |
1469 | |
1470 if (prm->skipStoSent) | |
1471 { | |
1472 /* skip segments with status SMS_STAT_StoSent */ | |
1473 while (prm->currConcBufListElem) | |
1474 { | |
1475 elem = (T_CONC_BUF_ELEM*)prm->currConcBufListElem->msg; | |
1476 | |
1477 if (elem->status EQ SMS_STAT_StoSent) | |
1478 { | |
1479 prm->currConcBufListElem = prm->currConcBufListElem->next; | |
1480 } | |
1481 else | |
1482 { | |
1483 break; | |
1484 } | |
1485 } /* while */ | |
1486 } | |
1487 | |
1488 if (prm->currConcBufListElem NEQ NULL) | |
1489 { | |
1490 elem = (T_CONC_BUF_ELEM*)prm->currConcBufListElem->msg; | |
1491 index = elem->rec_num; | |
1492 | |
1493 /* set mem2 (memory to which writing and sending operations are made) | |
1494 temporary to the value stored in conc buffer */ | |
1495 smsShrdPrm.mem2 = elem->mem; | |
1496 | |
1497 sAT_PlusCMSS_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, index, prm->p_da, prm->p_toda, | |
1498 rConcSMS_PlusCMSS, rConcSMS_PlusCMS_CMSS); | |
1499 | |
1500 | |
1501 elem->status = SMS_STAT_StoSent; | |
1502 | |
1503 | |
1504 } | |
1505 else /* if (concShrdPrm.currConcBufListElem NEQ NULL) */ | |
1506 { | |
1507 | |
1508 #ifdef _CONC_TESTING_ | |
1509 char *sa; | |
1510 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1511 sprintf(sa,"+CMSS: %d,%d",concShrdPrm.first_mr, concShrdPrm.sentSegs); | |
1512 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1513 ACI_MFREE(sa); | |
1514 #endif | |
1515 | |
1516 rAT_PlusCMSS(concShrdPrm.first_mr, (UBYTE)(concShrdPrm.sentSegs)); | |
1517 | |
1518 /* restore value for mem2 */ | |
1519 smsShrdPrm.mem2 = concShrdPrm.mem_store; | |
1520 | |
1521 R_AT ( RAT_OK, (T_ACI_CMD_SRC) concShrdPrm.srcId ) ( AT_CMD_CMSS ); | |
1522 UNSET_CONC; | |
1523 } | |
1524 } | |
1525 | |
1526 GLOBAL void rConcSMS_PlusCMGS (UBYTE mr, UBYTE numSeg) | |
1527 { | |
1528 T_ACI_SM_DATA data; | |
1529 T_ACI_UDH_DATA udh; | |
1530 USHORT len_left; | |
1531 T_CONC_CMGS *prm = &concShrdPrm.specPrm.concCMGS; | |
1532 | |
1533 TRACE_FUNCTION ("rConcSMS_PlusCMGS()"); | |
1534 | |
1535 | |
1536 /* save the first message reference */ | |
1537 if (concShrdPrm.udh.seq_num EQ 1) | |
1538 { | |
1539 concShrdPrm.first_mr = mr; | |
1540 } | |
1541 | |
1542 /* increment number of successfully sent elements */ | |
1543 len_left = prm->data.len - prm->offset; | |
1544 | |
1545 concShrdPrm.sentSegs++; | |
1546 | |
1547 if (len_left NEQ 0) | |
1548 { | |
1549 prm->sent_bytes += concShrdPrm.max_sms_len; | |
1550 | |
1551 if ( len_left > concShrdPrm.max_sms_len ) | |
1552 { | |
1553 data.len = concShrdPrm.max_sms_len; | |
1554 } | |
1555 else | |
1556 { | |
1557 data.len = (UBYTE)len_left; | |
1558 } | |
1559 | |
1560 memcpy (data.data, prm->data.data+prm->offset, data.len); | |
1561 prm->offset += data.len; | |
1562 | |
1563 concShrdPrm.udh.seq_num++; | |
1564 | |
1565 | |
1566 /* fill user data header structure */ | |
1567 concSMS_fillUDH ( &udh, | |
1568 concShrdPrm.udh.ref_num, | |
1569 concShrdPrm.udh.max_num, | |
1570 concShrdPrm.udh.seq_num ); | |
1571 | |
1572 sAT_PlusCMGS_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, prm->p_da, prm->p_toda, | |
1573 &data, &udh, prm->p_sca, prm->p_tosca, | |
1574 prm->isReply, rConcSMS_PlusCMGS, rConcSMS_PlusCMS_CMGS); | |
1575 | |
1576 | |
1577 } | |
1578 else | |
1579 { | |
1580 | |
1581 #ifdef _CONC_TESTING_ | |
1582 char *sa; | |
1583 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1584 sprintf(sa,"+CMGS: %d,%d",concShrdPrm.first_mr, concShrdPrm.udh.seq_num); | |
1585 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1586 ACI_MFREE(sa); | |
1587 | |
1588 ACI_MFREE(prm->data.data); | |
1589 | |
1590 #endif | |
1591 | |
1592 rAT_PlusCMGS (concShrdPrm.first_mr, (UBYTE)(concShrdPrm.udh.seq_num)); | |
1593 R_AT ( RAT_OK, (T_ACI_CMD_SRC)concShrdPrm.srcId ) ( AT_CMD_CMGS ); | |
1594 UNSET_CONC; | |
1595 } | |
1596 } | |
1597 | |
1598 | |
1599 | |
1600 GLOBAL void rConcSMS_PlusCMGR ( T_ACI_CMGL_SM* sm, | |
1601 T_ACI_CMGR_CBM* cbm ) | |
1602 { | |
1603 T_CONC_CMGR *prm = &concShrdPrm.specPrm.concCMGR; | |
1604 | |
1605 TRACE_FUNCTION ("rConcSMS_PlusCMGR ()"); | |
1606 | |
1607 if (prm->currConcBufListElem NEQ NULL) | |
1608 { | |
1609 T_CONC_BUF_ELEM *elem; | |
1610 elem = (T_CONC_BUF_ELEM *)prm->currConcBufListElem->msg; | |
1611 | |
1612 /* set mem1 (memory from which messages are read and deleted) | |
1613 * temporary to the value stored in conc buffer */ | |
1614 smsShrdPrm.mem1 = elem->mem; | |
1615 | |
1616 sAT_PlusCMGR_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, elem->rec_num, | |
1617 (T_ACI_SMS_READ)concShrdPrm.specPrm.concCMGR.rdMode, | |
1618 rConcSMS_PlusCMGR); | |
1619 | |
1620 prm->currConcBufListElem = prm->currConcBufListElem->next; | |
1621 | |
1622 #ifdef _CONC_TESTING_ | |
1623 rAT_PlusCMGR_Ext (sm, cbm); | |
1624 #else | |
1625 rAT_PlusCMGR (sm, cbm); | |
1626 #endif | |
1627 | |
1628 } | |
1629 else /* if (concShrdPrm.currConcBufListElem NEQ NULL) */ | |
1630 { | |
1631 #ifdef _CONC_TESTING_ | |
1632 rAT_PlusCMGR_Ext (sm, cbm); | |
1633 #else | |
1634 rAT_PlusCMGR (sm, cbm); | |
1635 #endif | |
1636 | |
1637 /* restore value for mem1 */ | |
1638 smsShrdPrm.mem1 = concShrdPrm.mem_store; | |
1639 | |
1640 | |
1641 R_AT ( RAT_OK, (T_ACI_CMD_SRC) concShrdPrm.srcId ) ( AT_CMD_CMGR ); | |
1642 UNSET_CONC; | |
1643 } | |
1644 } | |
1645 | |
1646 GLOBAL void rConcSMS_PercentCMGMDU (void) | |
1647 { | |
1648 T_CONC_CMGR *prm = &concShrdPrm.specPrm.concCMGR; | |
1649 | |
1650 TRACE_FUNCTION ("rConcSMS_PercentCMGMDU ()"); | |
1651 | |
1652 if (prm->currConcBufListElem NEQ NULL) | |
1653 { | |
1654 T_CONC_BUF_ELEM *elem; | |
1655 elem = (T_CONC_BUF_ELEM *)prm->currConcBufListElem->msg; | |
1656 | |
1657 sAT_PercentCMGMDU_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, elem->rec_num, | |
1658 rConcSMS_PercentCMGMDU); | |
1659 | |
1660 prm->currConcBufListElem = prm->currConcBufListElem->next; | |
1661 | |
1662 } | |
1663 else /* if (concShrdPrm.currConcBufListElem NEQ NULL) */ | |
1664 { | |
1665 if( concShrdPrm.srcId NEQ CMD_SRC_LCL ) | |
1666 R_AT ( RAT_OK, (T_ACI_CMD_SRC) concShrdPrm.srcId ) ( AT_CMD_P_CMGMDU ); | |
1667 UNSET_CONC; | |
1668 } | |
1669 } | |
1670 | |
1671 GLOBAL void rConcSMS_PlusCMGW ( UBYTE index, UBYTE numSeg, UBYTE mem) | |
1672 { | |
1673 T_ACI_SM_DATA data; | |
1674 T_ACI_UDH_DATA udh; | |
1675 USHORT len_left; | |
1676 T_CONC_CMGW *prm = &concShrdPrm.specPrm.concCMGW; | |
1677 | |
1678 static UBYTE first_rec; | |
1679 | |
1680 TRACE_FUNCTION ("rConcSMS_PlusCMGW ()"); | |
1681 | |
1682 | |
1683 /* save the first index */ | |
1684 if (concShrdPrm.udh.seq_num EQ 1) | |
1685 { | |
1686 first_rec = index; | |
1687 } | |
1688 | |
1689 concSMS_addToConcatList((USHORT)concShrdPrm.udh.ref_num, | |
1690 prm->p_da, | |
1691 concShrdPrm.udh.max_num, | |
1692 concShrdPrm.udh.seq_num, | |
1693 index, | |
1694 (T_ACI_SMS_STAT)prm->stat, | |
1695 mem); | |
1696 | |
1697 concSMS_printConcatList(); | |
1698 | |
1699 len_left = prm->data.len - prm->offset; | |
1700 | |
1701 if (len_left NEQ 0) | |
1702 { | |
1703 prm->sent_bytes += concShrdPrm.max_sms_len; | |
1704 | |
1705 if ( len_left > concShrdPrm.max_sms_len ) | |
1706 { | |
1707 data.len = concShrdPrm.max_sms_len; | |
1708 } | |
1709 else | |
1710 { | |
1711 data.len = (UBYTE)len_left; | |
1712 } | |
1713 | |
1714 memcpy (data.data, prm->data.data+prm->offset, data.len); | |
1715 prm->offset += data.len; | |
1716 | |
1717 concShrdPrm.udh.seq_num++; | |
1718 | |
1719 /* fill user data header structure */ | |
1720 concSMS_fillUDH ( &udh, | |
1721 concShrdPrm.udh.ref_num, | |
1722 concShrdPrm.udh.max_num, | |
1723 concShrdPrm.udh.seq_num ); | |
1724 | |
1725 sAT_PlusCMGW_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, CMGW_IDX_FREE_ENTRY, | |
1726 prm->p_da, prm->p_toda, (T_ACI_SMS_STAT)prm->stat, prm->msg_ref, | |
1727 &data, &udh, prm->p_sca, prm->p_tosca, | |
1728 prm->isReply, rConcSMS_PlusCMGW, rConcSMS_PlusCMS_CMGW); | |
1729 | |
1730 } | |
1731 else | |
1732 { | |
1733 | |
1734 #ifdef _CONC_TESTING_ | |
1735 char *sa; | |
1736 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1737 sprintf(sa,"+CMGW: %d,%d",first_rec, concShrdPrm.udh.seq_num); | |
1738 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1739 ACI_MFREE(sa); | |
1740 #endif | |
1741 | |
1742 rAT_PlusCMGW (first_rec, concShrdPrm.udh.seq_num, mem); | |
1743 R_AT ( RAT_OK, (T_ACI_CMD_SRC)concShrdPrm.srcId ) ( AT_CMD_CMGW ); | |
1744 UNSET_CONC; | |
1745 } | |
1746 } | |
1747 | |
1748 | |
1749 | |
1750 | |
1751 | |
1752 | |
1753 GLOBAL void rConcSMS_PlusCMGD ( ) | |
1754 { | |
1755 T_CONC_CMGD *prm = &concShrdPrm.specPrm.concCMGD; | |
1756 T_CONC_BUF_ELEM *elem; | |
1757 T_ACI_LIST *conc_list; | |
1758 | |
1759 TRACE_FUNCTION ("rConcSMS_PlusCMGD ()"); | |
1760 | |
1761 | |
1762 elem = (T_CONC_BUF_ELEM *)prm->currConcBufListElem->msg; | |
1763 | |
1764 /* remove the old element from concatenation list and free its memory */ | |
1765 conc_list = concSMS_removeFromConcatList(prm->ref_num, prm->address, elem->rec_num); | |
1766 | |
1767 concSMS_printConcatList(); | |
1768 | |
1769 if (conc_list NEQ NULL) | |
1770 { | |
1771 TRACE_EVENT("conc_list not null"); | |
1772 elem = (T_CONC_BUF_ELEM *)conc_list->msg; | |
1773 | |
1774 /* save the concatenation list */ | |
1775 prm->currConcBufListElem= conc_list; | |
1776 | |
1777 /* set mem1 (memory from which messages are read and deleted) | |
1778 temporary to the value stored in conc buffer */ | |
1779 smsShrdPrm.mem1 = elem->mem; | |
1780 | |
1781 sAT_PlusCMGD_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, elem->rec_num, smsShrdPrm.status, | |
1782 rConcSMS_PlusCMGD, rConcSMS_PlusCMS_CMGD); | |
1783 | |
1784 } | |
1785 else /* if (concShrdPrm.currConcBufListElem NEQ NULL) */ | |
1786 { | |
1787 if (concShrdPrm.full.Conc_Full EQ TRUE) | |
1788 { | |
1789 concSMS_AddtoconcBuff(); | |
1790 concShrdPrm.full.Conc_Full = FALSE; | |
1791 } | |
1792 | |
1793 /* restore value for mem1 */ | |
1794 smsShrdPrm.mem1 = concShrdPrm.mem_store; | |
1795 | |
1796 TRACE_EVENT("RAT_OK in rConcSMS_PlusCMGD"); | |
1797 R_AT ( RAT_OK, (T_ACI_CMD_SRC) concShrdPrm.srcId ) ( AT_CMD_CMGD ); | |
1798 UNSET_CONC; | |
1799 } | |
1800 } | |
1801 | |
1802 | |
1803 GLOBAL void rConcSMS_PlusCMGC ( UBYTE mr ) | |
1804 { | |
1805 UBYTE mn; | |
1806 T_CONC_CMGC *prm = &concShrdPrm.specPrm.concCMGC; | |
1807 | |
1808 TRACE_FUNCTION ("rConcSMS_PlusCMGC ()"); | |
1809 | |
1810 /* save the first message reference */ | |
1811 if (concShrdPrm.udh.seq_num EQ 1) | |
1812 { | |
1813 concShrdPrm.first_mr = mr; | |
1814 } | |
1815 | |
1816 prm->command_count++; | |
1817 | |
1818 if (prm->command_count < concShrdPrm.sentSegs) | |
1819 { | |
1820 mn = concShrdPrm.first_mr + prm->command_count; | |
1821 | |
1822 sAT_PlusCMGC_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, prm->fo, prm->ct, | |
1823 prm->pid, mn, prm->p_da, prm->p_toda, | |
1824 (T_ACI_CMD_DATA*)&prm->data, rConcSMS_PlusCMGC); | |
1825 } | |
1826 else | |
1827 { | |
1828 | |
1829 #ifdef _CONC_TESTING_ | |
1830 char *sa; | |
1831 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1832 sprintf(sa,"+CMGC: %d",concShrdPrm.first_mr /*, prm->command_count*/); | |
1833 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1834 ACI_MFREE(sa); | |
1835 #endif | |
1836 | |
1837 ACI_MFREE( prm->data.data ); | |
1838 rAT_PlusCMGC (concShrdPrm.first_mr/*, prm->command_count*/); | |
1839 R_AT ( RAT_OK,(T_ACI_CMD_SRC) concShrdPrm.srcId ) ( AT_CMD_CMGC ); | |
1840 UNSET_CONC; | |
1841 } | |
1842 } | |
1843 | |
1844 | |
1845 GLOBAL void rConcSMS_PlusCMS_CMSS (T_ACI_AT_CMD cmdId, T_ACI_CMS_ERR err, | |
1846 T_EXT_CMS_ERROR *ce) | |
1847 { | |
1848 T_EXT_CMS_ERROR conc_error; | |
1849 #ifdef _CONC_TESTING_ | |
1850 char *sa; | |
1851 #endif | |
1852 | |
1853 TRACE_FUNCTION ("rConcSMS_PlusCMS_CMSS ()"); | |
1854 | |
1855 | |
1856 conc_error.id = CMSS_CONC; | |
1857 conc_error.specErr.errConcCMSS.segs = | |
1858 concShrdPrm.udh.max_num - concShrdPrm.sentSegs; | |
1859 | |
1860 #ifdef _CONC_TESTING_ | |
1861 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1862 sprintf(sa,"+CMS ERROR: %d,%d",err, conc_error.specErr.errConcCMSS.segs); | |
1863 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1864 ACI_MFREE(sa); | |
1865 rCI_PlusCMS ( cmdId, err, NULL ); | |
1866 #endif | |
1867 | |
1868 /* restore value for mem2 */ | |
1869 smsShrdPrm.mem2 = concShrdPrm.mem_store; | |
1870 | |
1871 rAT_PlusCMS (cmdId, err, &conc_error); | |
1872 UNSET_CONC; | |
1873 } | |
1874 | |
1875 | |
1876 GLOBAL void rConcSMS_PlusCMS_CMGS (T_ACI_AT_CMD cmdId, T_ACI_CMS_ERR err, | |
1877 T_EXT_CMS_ERROR *ce) | |
1878 { | |
1879 T_EXT_CMS_ERROR conc_error; | |
1880 #ifdef _CONC_TESTING_ | |
1881 char *sa; | |
1882 #endif | |
1883 | |
1884 TRACE_FUNCTION ("rConcSMS_PlusCMS_CMGS ()"); | |
1885 | |
1886 | |
1887 conc_error.id = CMGS_CONC; | |
1888 conc_error.specErr.errConcCMGS.sent_chars = | |
1889 concShrdPrm.specPrm.concCMGS.sent_bytes; | |
1890 conc_error.specErr.errConcCMGS.ref_num = concShrdPrm.udh.ref_num; | |
1891 conc_error.specErr.errConcCMGS.next_seg = concShrdPrm.udh.seq_num; | |
1892 conc_error.specErr.errConcCMGS.max_num = concShrdPrm.udh.max_num; | |
1893 | |
1894 #ifdef _CONC_TESTING_ | |
1895 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1896 sprintf(sa,"+CMS ERROR: %d,%d,%d,%d,%d",err, | |
1897 conc_error.specErr.errConcCMGS.sent_chars, | |
1898 conc_error.specErr.errConcCMGS.ref_num, | |
1899 conc_error.specErr.errConcCMGS.next_seg, | |
1900 conc_error.specErr.errConcCMGS.max_num); | |
1901 | |
1902 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1903 ACI_MFREE(sa); | |
1904 rCI_PlusCMS ( cmdId, err, NULL ); | |
1905 #endif | |
1906 | |
1907 rAT_PlusCMS (cmdId, err, &conc_error); | |
1908 UNSET_CONC; | |
1909 } | |
1910 | |
1911 | |
1912 GLOBAL void rConcSMS_PlusCMS_CMGW (T_ACI_AT_CMD cmdId, T_ACI_CMS_ERR err, | |
1913 T_EXT_CMS_ERROR *ce) | |
1914 { | |
1915 T_EXT_CMS_ERROR conc_error; | |
1916 #ifdef _CONC_TESTING_ | |
1917 char *sa; | |
1918 #endif | |
1919 | |
1920 TRACE_FUNCTION ("rConcSMS_PlusCMS_CMGW ()"); | |
1921 | |
1922 | |
1923 conc_error.id = CMGW_CONC; | |
1924 conc_error.specErr.errConcCMGW.sent_chars = | |
1925 concShrdPrm.specPrm.concCMGW.sent_bytes; | |
1926 conc_error.specErr.errConcCMGW.ref_num = concShrdPrm.udh.ref_num; | |
1927 conc_error.specErr.errConcCMGW.next_seg = concShrdPrm.udh.seq_num; | |
1928 conc_error.specErr.errConcCMGW.max_num = concShrdPrm.udh.max_num; | |
1929 | |
1930 #ifdef _CONC_TESTING_ | |
1931 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1932 sprintf(sa,"+CMS ERROR: %d,%d,%d,%d,%d",err, | |
1933 conc_error.specErr.errConcCMGW.sent_chars, | |
1934 conc_error.specErr.errConcCMGW.ref_num, | |
1935 conc_error.specErr.errConcCMGW.next_seg, | |
1936 conc_error.specErr.errConcCMGW.max_num); | |
1937 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1938 ACI_MFREE(sa); | |
1939 rCI_PlusCMS ( cmdId, err, NULL ); | |
1940 #endif | |
1941 | |
1942 rAT_PlusCMS (cmdId, err, &conc_error); | |
1943 UNSET_CONC; | |
1944 } | |
1945 | |
1946 GLOBAL void rConcSMS_PlusCMS_CMGD (T_ACI_AT_CMD cmdId, T_ACI_CMS_ERR err, | |
1947 T_EXT_CMS_ERROR *ce) | |
1948 { | |
1949 T_CONC_CMGD *prm = &concShrdPrm.specPrm.concCMGD; | |
1950 T_CONC_BUF_ELEM *elem; | |
1951 T_EXT_CMS_ERROR conc_error; | |
1952 | |
1953 TRACE_FUNCTION ("rConcSMS_PlusCMS_CMGD ()"); | |
1954 | |
1955 conc_error.id = EMPTY; | |
1956 | |
1957 prm->error_count++; | |
1958 if (prm->error_count EQ concShrdPrm.udh.max_num) | |
1959 { | |
1960 | |
1961 #ifdef _CONC_TESTING_ | |
1962 char *sa; | |
1963 ACI_MALLOC(sa,KEY + BYTE_LTH); | |
1964 sprintf(sa,"+CMS ERROR: %d",err); | |
1965 io_sendMessage(concShrdPrm.srcId, sa, ATI_NORMAL_OUTPUT); | |
1966 ACI_MFREE(sa); | |
1967 rCI_PlusCMS ( cmdId, err, NULL ); | |
1968 #endif | |
1969 | |
1970 elem = (T_CONC_BUF_ELEM *)prm->currConcBufListElem->msg; | |
1971 /* remove the old element from concatenation list and free its memory */ | |
1972 concSMS_removeFromConcatList(prm->ref_num, prm->address, elem->rec_num); | |
1973 concSMS_printConcatList(); | |
1974 | |
1975 /* restore value for mem1 */ | |
1976 smsShrdPrm.mem1 = concShrdPrm.mem_store; | |
1977 | |
1978 rAT_PlusCMS ( cmdId, err, &conc_error); | |
1979 UNSET_CONC; | |
1980 } | |
1981 else | |
1982 { | |
1983 /* continue with the next segment */ | |
1984 rConcSMS_PlusCMGD(); | |
1985 } | |
1986 } | |
1987 #endif /* TI_PS_FF_CONC_SMS */ | |
1988 | |
1989 | |
1990 | |
1991 | |
1992 /*************** Functions which must be called by MFW ***************/ | |
1993 | |
1994 | |
1995 | |
1996 | |
1997 | |
1998 | |
1999 /* | |
2000 +--------------------------------------------------------------------+ | |
2001 | PROJECT : MODULE : CONC_SMS | | |
2002 | STATE : code ROUTINE : SMS_getSMSType | | |
2003 +--------------------------------------------------------------------+ | |
2004 | |
2005 PURPOSE : This function must be called by the MFW to detect the SMS | |
2006 type from the information element identifier. | |
2007 | |
2008 */ | |
2009 GLOBAL T_SMS_TYPE SMS_getSMSType( T_ACI_UDH_DATA* udh, char *address, UBYTE detMode) | |
2010 { | |
2011 USHORT ref_num = 0; | |
2012 UBYTE seq_num = 0; | |
2013 UBYTE max_num = 0; | |
2014 USHORT count; | |
2015 T_CONC_BUF* concBuf; | |
2016 | |
2017 TRACE_FUNCTION ("SMS_getSMSType()"); | |
2018 TRACE_EVENT_P1("SMS_getSMSType, mode: %d", detMode); | |
2019 | |
2020 | |
2021 if (udh->len EQ 0) | |
2022 { | |
2023 /* SMS does not contain UDH --> normal SMS */ | |
2024 return NORMAL; | |
2025 } | |
2026 | |
2027 /* check if IE is conc SMS */ | |
2028 if ((udh->data[0] EQ SMS_IEI_CONC_8BIT) OR (udh->data[0] EQ SMS_IEI_CONC_16BIT)) | |
2029 { | |
2030 if (udh->data[0] EQ SMS_IEI_CONC_8BIT) | |
2031 { | |
2032 ref_num = udh->data[2]; | |
2033 max_num = udh->data[3]; | |
2034 seq_num = udh->data[4]; | |
2035 } | |
2036 | |
2037 if (udh->data[0] EQ SMS_IEI_CONC_16BIT) | |
2038 { | |
2039 ref_num = (udh->data[2] & 0x00FF) << 8u; | |
2040 ref_num += udh->data[3]; | |
2041 max_num = udh->data[4]; | |
2042 seq_num = udh->data[5]; | |
2043 } | |
2044 | |
2045 switch (detMode) | |
2046 { | |
2047 | |
2048 case MODE1: | |
2049 /* This mode is for rAT_PlusCMT. No Concatenation buffer is needed at all */ | |
2050 break; | |
2051 | |
2052 case MODE2: | |
2053 /* This mode is for rAT_PlusCMTI. This mode requires the allocation of a new | |
2054 * Concatenation buffer (later in concSMS_Collect). Make sure that in case | |
2055 * the conc buffer is full no new CSMS is handled anymore | |
2056 */ | |
2057 concBuf = concSMS_getConcBuffer( ref_num, address ); | |
2058 | |
2059 /* if a new conc buffer is be needed, check if available */ | |
2060 if (concBuf EQ NULL) | |
2061 { | |
2062 if (concSMS_concBufferAvail() EQ FALSE) | |
2063 { | |
2064 return NORMAL_IND_CSMS; | |
2065 } | |
2066 | |
2067 /* Limit the maximum number of CSMS segments to MAX_SEG_TOTAL. Check | |
2068 * only if a new Concatenation buffer is required. | |
2069 */ | |
2070 if (concShrdPrm.elem_count+max_num > MAX_SEG_TOTAL) | |
2071 { | |
2072 return NORMAL_IND_CSMS; | |
2073 } | |
2074 } | |
2075 break; | |
2076 | |
2077 case MODE3: | |
2078 /* This mode is for rAT_PlusCMGL, rAT_PlusCMGR, sms_store_new_msg_info and | |
2079 * sms_store_new_msg_info. Only segments that have been previously stored | |
2080 * in the Concatenation buffer can be handled as CSMS. | |
2081 */ | |
2082 concBuf = concSMS_getConcBuffer( ref_num, address ); | |
2083 if (concBuf EQ NULL) | |
2084 { | |
2085 return NORMAL_IND_CSMS; | |
2086 } | |
2087 | |
2088 /* check if conc buffer is incomplete */ | |
2089 count = get_list_count(concBuf->list); | |
2090 if ((count < concBuf->max_num) AND (count < CONC_MAX_SEGS)) | |
2091 { | |
2092 return NORMAL_IND_CSMS; | |
2093 } | |
2094 break; | |
2095 | |
2096 default: | |
2097 TRACE_ERROR("Wrong detection mode in SMS_getSMSType"); | |
2098 return UNKNOWN; | |
2099 } | |
2100 | |
2101 /* check if sequence number is in range */ | |
2102 if (seq_num <= CONC_MAX_SEGS) | |
2103 { | |
2104 return CONCATE; | |
2105 } | |
2106 else | |
2107 { | |
2108 return NORMAL_IND_CSMS; | |
2109 } | |
2110 } | |
2111 else | |
2112 { | |
2113 /* unknown IE in UDH --> no CSMS */ | |
2114 return UNKNOWN; | |
2115 } | |
2116 } | |
2117 | |
2118 /* | |
2119 +--------------------------------------------------------------------+ | |
2120 | PROJECT : MODULE : CONC_SMS | | |
2121 | STATE : code ROUTINE : concSMS_GetFirstIndex | | |
2122 +--------------------------------------------------------------------+ | |
2123 | |
2124 PURPOSE : This function provides MFW with the first index of a given | |
2125 concatenated SMS (identified by its message reference). | |
2126 | |
2127 returns first index: (0 means no message found...) | |
2128 */ | |
2129 #define FIRST_SEQ_NUM (1) | |
2130 | |
2131 GLOBAL T_CONC_BUF_ELEM *concSMS_GetFirstIndex_ext ( USHORT msg_ref, char *address ) | |
2132 { | |
2133 | |
2134 | |
2135 T_CONC_BUF *concBuf; | |
2136 T_CONC_BUF_ELEM *concBufElem; | |
2137 | |
2138 TRACE_FUNCTION ("concSMS_GetFirstIndex()"); | |
2139 | |
2140 /* search for concatenation buffer */ | |
2141 concBuf = concSMS_getConcBuffer( msg_ref, address ); | |
2142 | |
2143 if( concBuf EQ NULL ) | |
2144 { | |
2145 TRACE_EVENT_P1("ERROR: unknown msg_ref: 0x%04x", msg_ref); | |
2146 return( NULL ); | |
2147 } | |
2148 | |
2149 /* search for the first sequence */ | |
2150 concBufElem = find_element(concBuf->list, FIRST_SEQ_NUM, concSMS_findSeqNumElemCB); | |
2151 | |
2152 if( concBufElem EQ NULL ) | |
2153 { | |
2154 TRACE_EVENT("ERROR: first sequence not found"); | |
2155 return( NULL ); | |
2156 } | |
2157 | |
2158 TRACE_EVENT_P1("first rec_num: %d", concBufElem->rec_num); | |
2159 TRACE_EVENT_P1 ("concSMS_GetFirstIndex_ext(), rec_num=%d", concBufElem->rec_num); | |
2160 | |
2161 /* return index of first segment */ | |
2162 return(concBufElem); | |
2163 | |
2164 } | |
2165 | |
2166 GLOBAL UBYTE concSMS_GetFirstIndex ( USHORT msg_ref, char *address ) | |
2167 { | |
2168 T_CONC_BUF_ELEM *concBufElem = concSMS_GetFirstIndex_ext(msg_ref, address); | |
2169 | |
2170 if( concBufElem EQ NULL ) | |
2171 { | |
2172 TRACE_EVENT("ERROR: first sequence not found"); | |
2173 return(0); | |
2174 } | |
2175 else | |
2176 return(concBufElem->rec_num); | |
2177 | |
2178 } | |
2179 | |
2180 | |
2181 /* | |
2182 +--------------------------------------------------------------------+ | |
2183 | PROJECT : MODULE : CONC_SMS | | |
2184 | STATE : code ROUTINE : concSMS_GetMsgRef | | |
2185 +--------------------------------------------------------------------+ | |
2186 | |
2187 PURPOSE : This function provides MFW with the message reference of a given | |
2188 concatenated SMS (decoded from the header). | |
2189 | |
2190 returns msg ref. | |
2191 */ | |
2192 | |
2193 GLOBAL USHORT concSMS_GetMsgRef ( T_ACI_CMGL_SM *sm ) | |
2194 { | |
2195 USHORT ref_num; | |
2196 | |
2197 TRACE_FUNCTION ("concSMS_GetMsgRef()"); | |
2198 | |
2199 if( sm EQ NULL ) | |
2200 { | |
2201 TRACE_ERROR("sm is NULL"); | |
2202 return 0; | |
2203 } | |
2204 | |
2205 /* 8-bit reference number */ | |
2206 if (sm->udh.data[0] EQ SMS_IEI_CONC_8BIT) | |
2207 { | |
2208 ref_num = sm->udh.data[2]; | |
2209 } | |
2210 | |
2211 /* 16-bit reference number */ | |
2212 else if (sm->udh.data[0] EQ SMS_IEI_CONC_16BIT) | |
2213 { | |
2214 /* MSB */ | |
2215 ref_num = (sm->udh.data[2] & 0x00FF) << 8u; /* 23.040 9.1.2.1 */ | |
2216 | |
2217 /* LSB */ | |
2218 ref_num |= sm->udh.data[3]; | |
2219 } | |
2220 else | |
2221 { | |
2222 TRACE_ERROR("sm->udh.data unknown"); | |
2223 return 0; | |
2224 } | |
2225 | |
2226 TRACE_EVENT_P1("ref_num: 0x%04x", ref_num); | |
2227 | |
2228 return(ref_num); | |
2229 } | |
2230 | |
2231 /* | |
2232 +--------------------------------------------------------------------+ | |
2233 | PROJECT : MODULE : CONC_SMS | | |
2234 | STATE : code ROUTINE : concSMS_Collect | | |
2235 +--------------------------------------------------------------------+ | |
2236 | |
2237 PURPOSE : This function must be called by the MFW. The function | |
2238 reassembles the received SM segments. | |
2239 | |
2240 Set 'isStored' to: | |
2241 TRUE, if rAT_PlusCMTI() was called | |
2242 FALSE, if rAT_PlusCMT() was called | |
2243 FALSE, if rAT_PlusCMGR() was called | |
2244 | |
2245 */ | |
2246 GLOBAL T_CONC_ASSEMBLY_RETURN concSMS_Collect ( T_SM_DATA_EXT *data_conc, | |
2247 T_ACI_CMGL_SM *sm, | |
2248 UBYTE isStored, | |
2249 T_ACI_SMS_STOR mem_aci) | |
2250 { | |
2251 USHORT ref_num = 0; | |
2252 UBYTE max_num = 0; | |
2253 UBYTE seq_num = 0; | |
2254 UBYTE rec_num; | |
2255 T_SM_ASSEMBLY *assembly_elem; | |
2256 T_SEG_BUF_ELEM *segBufElem; | |
2257 T_SM_DATA_EXT data; | |
2258 T_ACI_SMS_STAT status; | |
2259 UBYTE next_exp_num; | |
2260 UBYTE ret; | |
2261 static UBYTE i = 0; | |
2262 UBYTE mem_psa; | |
2263 | |
2264 | |
2265 | |
2266 CHAR *address; | |
2267 | |
2268 TRACE_FUNCTION ("concSMS_Collect()"); | |
2269 | |
2270 /* initialize data_conc->len */ | |
2271 data_conc->len = 0; /* ACI-SPR-16372 */ | |
2272 /* extract parameters from user data header */ | |
2273 | |
2274 /* 8-bit reference number */ | |
2275 if (sm->udh.data[0] EQ SMS_IEI_CONC_8BIT) | |
2276 { | |
2277 ref_num = sm->udh.data[2]; | |
2278 max_num = sm->udh.data[3]; | |
2279 seq_num = sm->udh.data[4]; | |
2280 } | |
2281 | |
2282 /* 16-bit reference number */ | |
2283 else if (sm->udh.data[0] EQ SMS_IEI_CONC_16BIT) | |
2284 { | |
2285 /* MSB */ | |
2286 ref_num = (sm->udh.data[2] & 0x00FF) << 8u; /* 23.040 9.1.2.1 */ | |
2287 | |
2288 /* LSB */ | |
2289 ref_num += sm->udh.data[3]; | |
2290 | |
2291 max_num = sm->udh.data[4]; | |
2292 seq_num = sm->udh.data[5]; | |
2293 } | |
2294 | |
2295 rec_num = sm->msg_ref; | |
2296 status = sm->stat; | |
2297 address = sm->adress; | |
2298 | |
2299 data.data = sm->data.data; | |
2300 data.len = sm->data.len; | |
2301 | |
2302 TRACE_EVENT_P1("rec_num:%d", rec_num); | |
2303 TRACE_EVENT_P1("concSMS_GetFirstIndex():%d", | |
2304 concSMS_GetFirstIndex (ref_num, sm->adress)); | |
2305 TRACE_EVENT_P1("ref_num:0x%04x", ref_num); | |
2306 TRACE_EVENT_P1("concSMS_GetMsgRef():0x%04x", concSMS_GetMsgRef ( sm )); | |
2307 TRACE_EVENT_P1("max_num:%d", max_num); | |
2308 TRACE_EVENT_P1("seq_num:%d", seq_num); | |
2309 | |
2310 /* try to get an existing assembly buffer */ | |
2311 assembly_elem = concSMS_getAsBuffer(ref_num, address); | |
2312 | |
2313 /* if no assembly buffer found, then assume that is a new conc. SM */ | |
2314 if (assembly_elem EQ NULL) | |
2315 { | |
2316 next_exp_num = 1; | |
2317 } | |
2318 else | |
2319 { | |
2320 next_exp_num = assembly_elem->next_exp_num; | |
2321 } | |
2322 | |
2323 | |
2324 /* the received seq_num is not valid */ | |
2325 if ( (seq_num EQ 0) OR (seq_num > max_num) OR (seq_num < next_exp_num) ) | |
2326 { | |
2327 return CONC_ERR_UNKN; | |
2328 } | |
2329 | |
2330 | |
2331 | |
2332 /* | |
2333 * If CMTI, then add every received segment to concatenation buffer. | |
2334 * The segments in the concatenation buffer were also stored in non-volatile | |
2335 * memory. | |
2336 */ | |
2337 if (isStored) | |
2338 { | |
2339 if (cmhSMS_getMemPsa(mem_aci, &mem_psa) EQ FALSE) | |
2340 { | |
2341 return CONC_ERR_UNKN; | |
2342 } | |
2343 | |
2344 ret = concSMS_addToConcatList(ref_num, address, max_num, | |
2345 seq_num, rec_num, status, mem_psa); | |
2346 | |
2347 if (ret EQ FALSE) | |
2348 { | |
2349 dFLAG = TRUE; | |
2350 RefNum_Del = ref_num; | |
2351 concShrdPrm.full.Conc_Full = TRUE; | |
2352 concShrdPrm.full.RefNum = ref_num; | |
2353 memcpy(Addres,address,sizeof(Addres)); | |
2354 concShrdPrm.full.MaxNum = max_num; | |
2355 concShrdPrm.full.SeqNum[i] = seq_num; | |
2356 concShrdPrm.full.RecNum[i] = rec_num; | |
2357 concShrdPrm.full.MemType[i] = mem_psa; | |
2358 i++; | |
2359 concShrdPrm.full.Numsegs = i; | |
2360 /* error: concatenation buffer full */ | |
2361 return CONC_ERR_BUF_FULL; | |
2362 } | |
2363 } | |
2364 i = 0; | |
2365 if ( seq_num > next_exp_num ) | |
2366 { | |
2367 /* | |
2368 * the received segment is not in sequence | |
2369 * -> add it to the segment buffer | |
2370 */ | |
2371 ret = concSMS_addToSegBuffer(ref_num, address, seq_num, | |
2372 rec_num, status, &data); | |
2373 if (ret EQ FALSE) | |
2374 { | |
2375 /* error: segment buffer full */ | |
2376 return CONC_ERR_BUF_FULL; | |
2377 } | |
2378 return CONC_CONTINUED; | |
2379 } | |
2380 else | |
2381 { | |
2382 /* | |
2383 * the received segment is in sequence | |
2384 */ | |
2385 | |
2386 while (1) | |
2387 { | |
2388 | |
2389 /* add segment to assembly buffer */ | |
2390 assembly_elem = concSMS_addToAsBuffer (ref_num, address, max_num, &data); | |
2391 | |
2392 | |
2393 /* free data memory only for data from segment buffer */ | |
2394 if (data.data NEQ sm->data.data) | |
2395 { | |
2396 ACI_MFREE (data.data); | |
2397 } | |
2398 | |
2399 /* error: no assembly buffer available */ | |
2400 if (assembly_elem EQ NULL) | |
2401 { | |
2402 return CONC_ERR_BUF_FULL; | |
2403 } | |
2404 | |
2405 /* assembly of concatenated SM is completed */ | |
2406 if (assembly_elem->next_exp_num EQ max_num+1) | |
2407 { | |
2408 concSMS_removeFromAsBuffer(data_conc, ref_num, address); | |
2409 concSMS_sortConcatList(ref_num, address); | |
2410 return CONC_COMPLETED; | |
2411 } | |
2412 | |
2413 /* maximum reached in assembly buffer , assembly is NOT completed */ | |
2414 if (assembly_elem->seg_count EQ CONC_MAX_SEGS) | |
2415 { | |
2416 concSMS_getFromAsBuffer(data_conc, ref_num, address); | |
2417 concSMS_sortConcatList(ref_num, address); | |
2418 return CONC_COMPLETED; | |
2419 } | |
2420 | |
2421 /* search and remove the next segment from segment buffer */ | |
2422 segBufElem = concSMS_removeFromSegBuffer(ref_num, | |
2423 address, | |
2424 assembly_elem->next_exp_num); | |
2425 if ( segBufElem EQ NULL ) | |
2426 { | |
2427 /* no segment found */ | |
2428 return CONC_CONTINUED; | |
2429 } | |
2430 | |
2431 /* for adding to concatenation list */ | |
2432 rec_num = segBufElem->rec_num; | |
2433 status = (T_ACI_SMS_STAT)segBufElem->status; | |
2434 | |
2435 /* for adding to assembly buffer */ | |
2436 data.data = segBufElem->data.data; | |
2437 data.len = segBufElem->data.len; | |
2438 | |
2439 ACI_MFREE(segBufElem); | |
2440 } /* while */ | |
2441 } /* if ( seq_num EQ next_exp_num ) */ | |
2442 } | |
2443 | |
2444 | |
2445 | |
2446 GLOBAL void concSMS_Init() | |
2447 { | |
2448 concShrdPrm.isConcatenated = FALSE; | |
2449 | |
2450 memset (&concShrdPrm, 0, sizeof(T_CONC_SHRD_PRM) ); | |
2451 | |
2452 memset (&assembly_list, 0, sizeof(T_SM_ASSEMBLY)*MAX_BUF_ELEMS); | |
2453 memset (&segBuf_list, 0, sizeof(T_SEG_BUF) *MAX_BUF_ELEMS); | |
2454 memset (&concBuf_list, 0, sizeof(T_CONC_BUF) *MAX_CONC_BUF_ELEMS); | |
2455 | |
2456 concShrdPrm.l_uncomp8bit_data = L_UNCOMP_8BIT_DATA; | |
2457 concShrdPrm.l_uncomp7bit_data = L_UNCOMP_7BIT_DATA; | |
2458 concShrdPrm.l_uncomp8bit_data_conc = L_UNCOMP_8BIT_DATA_CONC; | |
2459 concShrdPrm.l_uncomp7bit_data_conc = L_UNCOMP_7BIT_DATA_CONC; | |
2460 concShrdPrm.elem_count = 0; | |
2461 #ifdef _CONC_TESTING_ | |
2462 #ifndef _SIMULATION_ | |
2463 concSMS_InitForTesting(); | |
2464 #endif | |
2465 #endif | |
2466 } | |
2467 | |
2468 | |
2469 /* only for test purposes */ | |
2470 GLOBAL void concSMS_InitForTesting() | |
2471 { | |
2472 concShrdPrm.concTesting = TRUE; | |
2473 concShrdPrm.l_uncomp8bit_data = L_UNCOMP_8BIT_DATA_TST; | |
2474 concShrdPrm.l_uncomp7bit_data = L_UNCOMP_7BIT_DATA_TST; | |
2475 concShrdPrm.l_uncomp8bit_data_conc = L_UNCOMP_8BIT_DATA_CONC_TST; | |
2476 concShrdPrm.l_uncomp7bit_data_conc = L_UNCOMP_7BIT_DATA_CONC_TST; | |
2477 } | |
2478 | |
2479 | |
2480 /* | |
2481 +--------------------------------------------------------------------+ | |
2482 | PROJECT : MODULE : CONC_SMS | | |
2483 | STATE : code ROUTINE : concSMS_delAllIncompleteMsg| | |
2484 +--------------------------------------------------------------------+ | |
2485 | |
2486 PURPOSE : This function must be called by the MFW to clean all | |
2487 segment buffers, assembly buffers and remove all | |
2488 incompleted SM from concat. buffer and non-volatile memory. | |
2489 | |
2490 */ | |
2491 GLOBAL void concSMS_delAllIncompleteMsg( ) | |
2492 { | |
2493 T_SEG_BUF *segBuf = NULL; | |
2494 T_SEG_BUF_ELEM *segBufElem; | |
2495 T_CONC_BUF *concBuf = NULL; | |
2496 T_CONC_BUF_ELEM *concBufElem; | |
2497 T_SM_ASSEMBLY *assembly_elem; | |
2498 USHORT count; | |
2499 | |
2500 UBYTE i; | |
2501 | |
2502 TRACE_FUNCTION ("concSMS_delAllIncompleteMsg()"); | |
2503 | |
2504 | |
2505 concShrdPrm.srcId = CMD_SRC_LCL; | |
2506 | |
2507 for (i=0; i<MAX_BUF_ELEMS; i++) | |
2508 { | |
2509 /* delete assembly buffer */ | |
2510 if (assembly_list[i].in_use) | |
2511 { | |
2512 assembly_elem = &assembly_list[i]; | |
2513 assembly_elem->in_use = FALSE; | |
2514 ACI_MFREE(assembly_elem->data.data); | |
2515 } | |
2516 | |
2517 | |
2518 /* delete segment buffer */ | |
2519 if (segBuf_list[i].in_use) | |
2520 { | |
2521 segBuf = &segBuf_list[i]; | |
2522 | |
2523 /* remove element from segment buffer */ | |
2524 segBufElem = remove_first_element(segBuf->list); | |
2525 | |
2526 if (segBufElem NEQ NULL) | |
2527 { | |
2528 /* free memory */ | |
2529 ACI_MFREE(segBufElem->data.data); | |
2530 ACI_MFREE(segBufElem); | |
2531 } | |
2532 else | |
2533 { | |
2534 segBuf->in_use = FALSE; | |
2535 } | |
2536 } | |
2537 } /* for */ | |
2538 | |
2539 | |
2540 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
2541 { | |
2542 /* find concat. buffer in use */ | |
2543 if (concBuf_list[i].in_use) | |
2544 { | |
2545 | |
2546 /* get number of segments in this concat. buffer */ | |
2547 count = get_list_count(concBuf_list[i].list); | |
2548 | |
2549 /* conc buffer is incomplete */ | |
2550 if ((count < concBuf_list[i].max_num) AND (count < CONC_MAX_SEGS)) | |
2551 { | |
2552 if (count EQ 0) | |
2553 { | |
2554 /* last element of one conc buffer was deleted */ | |
2555 concBuf_list[i].in_use = FALSE; | |
2556 R_AT ( RAT_OK,(T_ACI_CMD_SRC) concShrdPrm.srcId ) ( AT_CMD_CMGC ); | |
2557 continue; | |
2558 } | |
2559 concBuf = &concBuf_list[i]; | |
2560 break; | |
2561 } | |
2562 } | |
2563 } | |
2564 | |
2565 if (concBuf) | |
2566 { | |
2567 /* remove element from concat. buffer */ | |
2568 concBufElem = remove_first_element(concBuf->list); | |
2569 | |
2570 if (concBufElem) | |
2571 { | |
2572 | |
2573 /* delete segment from non-volatile memory */ | |
2574 #ifdef TI_PS_FF_CONC_SMS | |
2575 sAT_PlusCMGD_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, concBufElem->rec_num, | |
2576 smsShrdPrm.status, concSMS_delAllIncompleteMsg, rConcSMS_PlusCMS_CMGD); | |
2577 #else | |
2578 sAT_PlusCMGD_Gl(concShrdPrm.srcId, concBufElem->rec_num, smsShrdPrm.status, | |
2579 concSMS_delAllIncompleteMsg, rAT_PlusCMS); | |
2580 #endif /* TI_PS_FF_CONC_SMS */ | |
2581 | |
2582 /* free memory */ | |
2583 ACI_MFREE(concBufElem); | |
2584 /* decrease total count of stored CSMS segments by 1*/ | |
2585 concShrdPrm.elem_count--; | |
2586 } | |
2587 } | |
2588 } | |
2589 | |
2590 | |
2591 | |
2592 /************** Help Functions ******************************/ | |
2593 | |
2594 | |
2595 /* | |
2596 +-------------------------------------------------------------------+ | |
2597 | PROJECT : GSM-PS (6147) MODULE : CONC_SMS | | |
2598 | ROUTINE : concSMS_printConcatList | | |
2599 +-------------------------------------------------------------------+ | |
2600 | |
2601 PURPOSE : | |
2602 */ | |
2603 | |
2604 LOCAL void concSMS_printConcatList () | |
2605 { | |
2606 T_ACI_LIST *current; | |
2607 UBYTE i; | |
2608 T_CONC_BUF *concBuf; | |
2609 T_CONC_BUF_ELEM *elem; | |
2610 | |
2611 | |
2612 TRACE_EVENT("Concatenation List:"); | |
2613 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
2614 { | |
2615 if (concBuf_list[i].in_use EQ TRUE) | |
2616 { | |
2617 concBuf = &concBuf_list[i]; | |
2618 TRACE_EVENT_P2(" ref_num: 0x%04x , max_num: %u", | |
2619 concBuf->ref_num, concBuf->max_num); | |
2620 current = concBuf->list; | |
2621 while (current) | |
2622 { | |
2623 elem = (T_CONC_BUF_ELEM*) current->msg; | |
2624 TRACE_EVENT_P4(" seq_num: %d , rec_num: %d , status: %d, mem= %d", | |
2625 elem->seq_num, elem->rec_num, elem->status, elem->mem); | |
2626 current = current->next; | |
2627 } | |
2628 } | |
2629 } | |
2630 } | |
2631 | |
2632 /* Marcus: Issue 872: 03/10/2002 | |
2633 +-------------------------------------------------------------------+ | |
2634 | PROJECT : GSM-PS (6147) MODULE : CONC_SMS | | |
2635 | ROUTINE : concSMS_findMaxRefNum | | |
2636 +-------------------------------------------------------------------+ | |
2637 | |
2638 PURPOSE : Find the highest value of concBuf_list[i].ref_num | |
2639 */ | |
2640 | |
2641 LOCAL USHORT concSMS_findMaxRefNum(void) | |
2642 { | |
2643 UBYTE i; | |
2644 USHORT ref_num = 0; | |
2645 TRACE_FUNCTION("concSMS_findMaxRefNum()"); | |
2646 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
2647 { | |
2648 if (concBuf_list[i].in_use EQ TRUE) | |
2649 { | |
2650 if ((concBuf_list[i].ref_num & 0x00ff)> ref_num) /* since we use only 8-Bit ref_num */ | |
2651 ref_num = concBuf_list[i].ref_num & 0x00ff; | |
2652 } | |
2653 } | |
2654 return ref_num; | |
2655 } | |
2656 | |
2657 | |
2658 GLOBAL void concSMS_clearIncompleteMsg() | |
2659 { | |
2660 | |
2661 T_SEG_BUF *segBuf = NULL; | |
2662 T_SEG_BUF_ELEM *segBufElem; | |
2663 T_SM_ASSEMBLY *assembly_elem; | |
2664 T_CONC_BUF *concBuf = NULL; | |
2665 T_CONC_BUF_ELEM *concBufElem; | |
2666 UBYTE i; | |
2667 | |
2668 | |
2669 | |
2670 TRACE_FUNCTION ("concSMS_clearIncompleteMsg()"); | |
2671 | |
2672 | |
2673 if (RefNum_Del EQ concShrdPrm.full.RefNum) | |
2674 { | |
2675 concShrdPrm.full.Conc_Full = FALSE; | |
2676 concShrdPrm.full.RefNum = 0xFF; | |
2677 } | |
2678 | |
2679 | |
2680 for (i=0; i<MAX_BUF_ELEMS; i++) | |
2681 { | |
2682 /* delete assembly buffer */ | |
2683 if (assembly_list[i].in_use AND assembly_list[i].ref_num EQ RefNum_Del) | |
2684 { | |
2685 assembly_elem = &assembly_list[i]; | |
2686 assembly_elem->in_use = FALSE; | |
2687 ACI_MFREE(assembly_elem->data.data); | |
2688 break; | |
2689 } | |
2690 | |
2691 | |
2692 /* delete segment buffer */ | |
2693 if (segBuf_list[i].in_use AND segBuf_list[i].ref_num EQ RefNum_Del) | |
2694 { | |
2695 | |
2696 segBuf = &segBuf_list[i]; | |
2697 | |
2698 | |
2699 /*remove element from segment buffer */ | |
2700 segBufElem = remove_first_element(segBuf->list); | |
2701 | |
2702 if (segBufElem NEQ NULL) | |
2703 { | |
2704 segBuf->in_use = FALSE; | |
2705 /* free memory */ | |
2706 ACI_MFREE(segBufElem->data.data); | |
2707 ACI_MFREE(segBufElem); | |
2708 | |
2709 | |
2710 } | |
2711 else | |
2712 { | |
2713 | |
2714 segBuf->in_use = FALSE; | |
2715 | |
2716 } | |
2717 break; | |
2718 } | |
2719 | |
2720 } | |
2721 | |
2722 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
2723 { | |
2724 /* find concat. buffer in use */ | |
2725 if (concBuf_list[i].in_use AND concBuf_list[i].ref_num EQ RefNum_Del) | |
2726 { | |
2727 concBuf_list[i].in_use = FALSE; | |
2728 concBuf = &concBuf_list[i]; | |
2729 break; | |
2730 | |
2731 } | |
2732 } | |
2733 | |
2734 if (concBuf) | |
2735 { | |
2736 /* remove element from concat. buffer */ | |
2737 concBufElem = remove_first_element(concBuf->list); | |
2738 | |
2739 if (concBufElem) | |
2740 { | |
2741 /* free memory */ | |
2742 ACI_MFREE(concBufElem); | |
2743 /* decrease total count of stored CSMS segments by 1*/ | |
2744 concShrdPrm.elem_count--; | |
2745 | |
2746 } | |
2747 } | |
2748 } | |
2749 | |
2750 | |
2751 | |
2752 GLOBAL void concSMS_AddtoconcBuff(void) | |
2753 { | |
2754 UBYTE i; | |
2755 | |
2756 | |
2757 TRACE_FUNCTION("concSMS_AddtoconcBuff()"); | |
2758 | |
2759 for (i=0;i<concShrdPrm.full.Numsegs;i++) | |
2760 { | |
2761 concSMS_addToConcatList(concShrdPrm.full.RefNum,Addres, | |
2762 concShrdPrm.full.MaxNum,concShrdPrm.full.SeqNum[i], | |
2763 concShrdPrm.full.RecNum[i],SMS_STAT_RecRead,concShrdPrm.full.MemType[i]); | |
2764 } | |
2765 } | |
2766 | |
2767 /* | |
2768 +-------------------------------------------------------------------+ | |
2769 | PROJECT : GSM-PS (6147) MODULE : CONC_SMS | | |
2770 | ROUTINE : concSMS_DeleteConcList | | |
2771 +-------------------------------------------------------------------+ | |
2772 | |
2773 PURPOSE : This function is used to delete the concatinated SMS, when | |
2774 the CMGD command contails the delete flag greater than ZERO. | |
2775 | |
2776 */ | |
2777 | |
2778 GLOBAL void concSMS_DeleteConcList ( ) | |
2779 { | |
2780 T_CONC_CMGD *prm = &concShrdPrm.specPrm.concCMGD; | |
2781 T_CONC_BUF_ELEM *elem; | |
2782 T_ACI_LIST *conc_list; | |
2783 | |
2784 TRACE_FUNCTION ("concSMS_DeleteConcList()"); | |
2785 | |
2786 | |
2787 elem = (T_CONC_BUF_ELEM *)prm->currConcBufListElem->msg; | |
2788 | |
2789 /* remove the old element from concatenation list and free its memory */ | |
2790 conc_list = concSMS_removeFromConcatList(prm->ref_num, prm->address, elem->rec_num); | |
2791 | |
2792 concSMS_printConcatList(); | |
2793 | |
2794 if (conc_list NEQ NULL) | |
2795 { | |
2796 TRACE_EVENT("conc_list not null"); | |
2797 elem = (T_CONC_BUF_ELEM *)conc_list->msg; | |
2798 | |
2799 /* save the concatenation list */ | |
2800 prm->currConcBufListElem= conc_list; | |
2801 } | |
2802 else /* if (concShrdPrm.currConcBufListElem NEQ NULL) */ | |
2803 { | |
2804 TRACE_EVENT("Concat List is NULL : concSMS_DeleteConcList"); | |
2805 UNSET_CONC; | |
2806 } | |
2807 } | |
2808 | |
2809 #ifdef TI_PS_FF_CONC_SMS | |
2810 GLOBAL void rConcSMS_PercentCMGR ( T_ACI_CMGL_SM* sm, | |
2811 T_ACI_CMGR_CBM* cbm ) | |
2812 { | |
2813 T_CONC_CMGR *prm = &concShrdPrm.specPrm.concCMGR; | |
2814 | |
2815 TRACE_FUNCTION ("rConcSMS_PercentCMGR ()"); | |
2816 | |
2817 if (prm->currConcBufListElem NEQ NULL) | |
2818 { | |
2819 T_CONC_BUF_ELEM *elem; | |
2820 elem = (T_CONC_BUF_ELEM *)prm->currConcBufListElem->msg; | |
2821 | |
2822 sAT_PercentCMGR_Gl((T_ACI_CMD_SRC)concShrdPrm.srcId, elem->rec_num, | |
2823 (T_ACI_SMS_READ) concShrdPrm.specPrm.concCMGR.rdMode, | |
2824 rConcSMS_PercentCMGR); | |
2825 | |
2826 prm->currConcBufListElem = prm->currConcBufListElem->next; | |
2827 | |
2828 #ifdef _CONC_TESTING_ | |
2829 rAT_PercentCMGR_Ext (sm, cbm); | |
2830 #else | |
2831 rAT_PercentCMGR (sm, cbm); | |
2832 #endif | |
2833 | |
2834 } | |
2835 else /* if (concShrdPrm.currConcBufListElem NEQ NULL) */ | |
2836 { | |
2837 #ifdef _CONC_TESTING_ | |
2838 rAT_PercentCMGR_Ext (sm, cbm); | |
2839 #else | |
2840 rAT_PercentCMGR (sm, cbm); | |
2841 #endif | |
2842 | |
2843 R_AT ( RAT_OK, (T_ACI_CMD_SRC)concShrdPrm.srcId ) ( AT_CMD_P_CMGR ); | |
2844 UNSET_CONC; | |
2845 } | |
2846 } | |
2847 | |
2848 #endif /* TI_PS_FF_CONC_SMS */ | |
2849 /* | |
2850 * This functions checks if the conc can be extended. If the maximum | |
2851 * capacity is reached the CSMS will be handled as normal (single) SMS. | |
2852 */ | |
2853 BOOL concSMS_concBufferAvail() | |
2854 { | |
2855 USHORT count=0; | |
2856 int i; | |
2857 | |
2858 TRACE_FUNCTION("concSMS_concBufferAvail"); | |
2859 | |
2860 /* check if there is a free conc buffer available */ | |
2861 for (i=0; i<MAX_CONC_BUF_ELEMS; i++) | |
2862 { | |
2863 if (concBuf_list[i].in_use EQ TRUE) | |
2864 { | |
2865 count++; | |
2866 } | |
2867 } | |
2868 if (count >= MAX_CONC_BUF_ELEMS) | |
2869 { | |
2870 return FALSE; /* all conc buffer in use, no free available */ | |
2871 } | |
2872 | |
2873 return TRUE; | |
2874 } | |
2875 | |
2876 |