comparison src/g23m-gsm/sms/sms_tlf.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-F&D (8411)
4 | Modul : SMS_TLF
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 : This Modul defines the functions for the transfer layer
18 | capability of the module Short Message Service.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef SMS_TLF_C
23 #define SMS_TLF_C
24
25 #define ENTITY_SMS
26
27 /*==== INCLUDES ===================================================*/
28
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stddef.h>
32 #include "typedefs.h"
33 #include "pcm.h"
34 #include "vsi.h"
35 #include "custom.h"
36 #include "gsm.h"
37 #include "message.h"
38 #include "ccdapi.h"
39 #include "prim.h"
40 #include "cus_sms.h"
41 #include "cnf_sms.h"
42 #include "mon_sms.h"
43 #include "pei.h"
44 #include "tok.h"
45 #include "sms.h"
46 #include "gdi.h"
47 #include "sms_em.h"
48
49 /*==== EXPORT ======================================================*/
50
51 /*==== PRIVAT ======================================================*/
52
53 static const UBYTE ref_nr_23430[] = {
54 0xE, 0x3, 0x8, 0x7, 0x9, 0x5, 0xE, 0x3, 0x7};
55
56 /*==== VARIABLES ===================================================*/
57
58 /* Implements Measure#32: Row 84, 96, 87, 89, 95, 97, 104, 109 & 113 */
59 const char * const ef_sms_id = EF_SMS_ID;
60
61 /*==== FUNCTIONS ===================================================*/
62
63 /* Implements Measure# 14 */
64 /*
65 +---------------------------------------------------------------------------+
66 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
67 | STATE : code ROUTINE : tl_send_sim_update_req |
68 +---------------------------------------------------------------------------+
69
70 PURPOSE : This routine process SIM update request and SMS memo resume request
71
72 */
73
74
75 LOCAL void tl_send_sim_update_req(UBYTE trans_data, USHORT offset)
76 {
77 GET_INSTANCE_DATA;
78 UBYTE sim_acc_ix;
79 TRACE_FUNCTION("tl_send_sim_update_req()");
80 /*
81 * update sim notification flag
82 */
83 if (sms_data->sim_phase >= PHASE_2_SIM)
84 {
85 if (tl_sms_reserve_req_id(&sim_acc_ix))
86 {
87 PALLOC (update_req, SIM_UPDATE_REQ);
88
89 update_req->source = SRC_SMS;
90 update_req->req_id = sim_acc_ix;
91 update_req->v_path_info = FALSE;
92 update_req->datafield =
93 sms_data->sms_sim_access_info[sim_acc_ix].datafield = SIM_SMSS;
94 update_req->length = 1;
95 update_req->trans_data[0] = trans_data;
96 update_req->offset = offset;
97
98 PSENDX (SIM, update_req);
99
100 if(sms_data->inst == INST_MO)
101 tl_set_access_fifo (ACCESS_BY_MMI);
102 else
103 tl_set_access_fifo (ACCESS_BY_NET);
104 }
105 }
106 }
107
108
109 /*
110 +--------------------------------------------------------------------+
111 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
112 | STATE : code ROUTINE : tl_get_octet_len |
113 | ROUTINE : tl_adjust_message_len |
114 +--------------------------------------------------------------------+
115
116 PURPOSE : Derive the number of octets of TP-User-Data and the whole
117 message regarding the Data Coding Scheme.
118 */
119
120 LOCAL BOOL tl_udl_count_septet (UBYTE dcs)
121 {
122 BOOL isSeptet = TRUE;
123
124 switch (dcs & 0xF0)
125 {
126 case 0x00:
127 case 0x10:
128 if ((dcs & 0xC) EQ 0x4 OR /* 8-bit data */
129 (dcs & 0xC) EQ 0x8) /* UCS2 data */
130 isSeptet = FALSE;
131 break;
132 case 0x20: /* compressed data */
133 case 0x30: /* compressed data */
134 case 0xE0: /* UCS2 data */
135 isSeptet = FALSE;
136 break;
137 case 0xF0:
138 if ((dcs & 0x4) NEQ 0) /* 8-bit data */
139 isSeptet = FALSE;
140 break;
141 }
142 return isSeptet;
143 }
144
145 LOCAL USHORT tl_get_octet_len (USHORT tp_udl, UBYTE dcs)
146 {
147 if (tl_udl_count_septet (dcs)) /* convert number of septets */
148 return (USHORT)((tp_udl + 1) * 7 / 8);
149
150 return tp_udl;
151 }
152
153 GLOBAL void tl_adjust_message_len (UBYTE tp_vt_mti, BUF_tpdu *tpdu)
154 {
155 USHORT oct_len, pre_len;
156 UBYTE dcs;
157 UBYTE *tp_data, *tp_msg;
158
159 if (tp_vt_mti EQ SMS_VT_SIM_PDU)
160 {
161 pre_len = tpdu->b_tpdu[0] + 1;
162 tp_msg = &tpdu->b_tpdu[pre_len];
163 switch (*tp_msg & 0x3)
164 {
165 case SMS_SUBMIT:
166 tp_vt_mti = SMS_VT_SUBMIT;
167 break;
168 case SMS_DELIVER:
169 tp_vt_mti = SMS_VT_DELIVER;
170 break;
171 case SMS_STATUS_REPORT:
172 tp_vt_mti = SMS_VT_STATUS;
173 break;
174 default:
175 return;
176 }
177 }
178 else
179 {
180 pre_len = 0;
181 tp_msg = &tpdu->b_tpdu[0];
182 }
183 switch (tp_vt_mti)
184 {
185 case SMS_VT_SUBMIT:
186 oct_len = (tp_msg[2] + 1)/2;
187 tp_data = &tp_msg[5 + oct_len];
188 dcs = *tp_data;
189
190 switch ((tp_msg[0] >> 3) & 0x3) /* TP-VPF */
191 { /* point to TP-UDL */
192 case SMS_VPF_RELATIVE:
193 tp_data += 2;
194 oct_len += 8;
195 break;
196 case SMS_VPF_ENHANCED:
197 case SMS_VPF_ABSOLUTE:
198 tp_data += 8;
199 oct_len += 14;
200 break;
201 default:
202 tp_data++;
203 oct_len += 7;
204 break;
205 }
206 oct_len += tl_get_octet_len (*tp_data, dcs);
207 tpdu->l_tpdu = (oct_len + pre_len) << 3;
208 break;
209 case SMS_VT_DELIVER:
210 oct_len = (tp_msg[1] + 1)/2;
211 tp_data = &tp_msg[4 + oct_len];
212 dcs = *tp_data;
213 tp_data += 8; /* point to TP-UDL */
214 oct_len += (13 + tl_get_octet_len (*tp_data, dcs));
215 tpdu->l_tpdu = (oct_len + pre_len) << 3;
216 break;
217 case SMS_VT_STATUS:
218 oct_len = (tp_msg[2] + 1)/2 + 19;
219 tp_data = &tp_msg[oct_len]; /* tp_data points to PI */
220 if(*tp_data NEQ NOT_PRESENT_8BIT)
221 {
222 dcs = *(tp_data+2);
223 tp_data += 3; /* point to TP-UDL */
224 oct_len += (3 + tl_get_octet_len (*tp_data, dcs));
225 tpdu->l_tpdu = (oct_len + pre_len) << 3;
226 }
227 else
228 {
229 tpdu->l_tpdu = (oct_len + pre_len) << 3;
230 }
231 break;
232 default:
233 break;
234 }
235 }
236
237 /*
238 +--------------------------------------------------------------------+
239 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
240 | STATE : code ROUTINE : tl_establish_connection |
241 +--------------------------------------------------------------------+
242
243 PURPOSE : Initiate the Establishment of a new connection
244
245 */
246 GLOBAL void tl_establish_connection (
247 BOOL incr /* true if reference nr increment needed */)
248 {
249 GET_INSTANCE_DATA;
250 UBYTE ti;
251 TRACE_FUNCTION ("tl_establish_connection()");
252
253 /*
254 * new instance
255 */
256 GET_NEW_SMS_INSTANCE(0);
257 /*
258 * increment TI
259 */
260 ti = csf_get_new_mo_ti();
261 #if defined (GPRS)
262 /*
263 * Set downlink according to prefs,
264 * in case of LL it has to be checked first if up
265 */
266 if ( ( (sms_data->mo_dst_pref EQ GPRS_SMS_GPRS_PREF) ||
267 (sms_data->mo_dst_pref EQ GPRS_SMS_GPRS_ONLY) ) /*&&
268 ( sms_data->llc_flow NEQ SMS_LLC_UNKNOWN )*/ )
269 {
270 SMS_INST.downlink = SMS_DOWNLINK_LL_CHECK;
271 TRACE_EVENT("downlink = SMS_DOWNLINK_LL_CHECK");
272 }
273 else
274 {
275 SMS_INST.downlink = SMS_DOWNLINK_MMSMS;
276 TRACE_EVENT("downlink = SMS_DOWNLINK_MMSMS");
277 }
278 #endif /* GPRS */
279 if (incr)
280 {
281 /*
282 * increment reference
283 */
284 ++SMS_INST.tp_mr;
285 /*
286 * SIM_UPDATE_REQ
287 */
288 tl_build_sim_update_req();
289 }
290 TRACE_EVENT_P2("TI=%u TP_MR=%u", ti, SMS_INST.tp_mr);
291 /*
292 * RL_ESTABLISH_REQ
293 */
294 rl_establish_req(ti);
295 }
296 /*
297 +--------------------------------------------------------------------+
298 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
299 | STATE : code ROUTINE : tl_build_status_rep |
300 +--------------------------------------------------------------------+
301
302 PURPOSE : Processing the function TL_BUILD_STATUS_REP.
303
304 */
305
306 GLOBAL void tl_build_status_rep (T_rp_data_dl *rp_data_dl,
307 T_MNSMS_STATUS_IND *status_ind)
308 {
309 T_SIM_PDU *sim_pdu;
310
311 TRACE_FUNCTION ("tl_build_status_rep()");
312
313 memset (&status_ind->sms_sdu, 0, sizeof(T_sms_sdu));
314
315 if (rp_data_dl NEQ NULL)
316 {
317 MALLOC (sim_pdu, sizeof(T_SIM_PDU));
318
319 sim_pdu->rp_addr = rp_data_dl->rp_addr;
320 sim_pdu->tpdu = rp_data_dl->rp_user_data.tpdu;
321 sim_pdu->tp_mti = SMS_STATUS_REPORT;
322 sim_pdu->v_tpdu = TRUE;
323 sim_pdu->tp_vt_mti = SMS_VT_SIM_PDU;
324
325 ccd_codeMsg (CCDENT_SMS, DOWNLINK,
326 (T_MSGBUF *)&status_ind->sms_sdu,
327 (UBYTE *)sim_pdu, SMS_VT_SIM_PDU);
328
329 MFREE (sim_pdu);
330 }
331 }
332
333 /*
334 +--------------------------------------------------------------------+
335 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
336 | STATE : code ROUTINE : tl_modify_submit |
337 +--------------------------------------------------------------------+
338
339 PURPOSE : The SM taken from storage (rec_data) is modified with
340 certain values from parameter 'sms_sdu' according to
341 parameter 'modify'. The resulting message is returned in
342 parameter 'sim_pdu'.
343 */
344
345 LOCAL void tl_translate_mt_to_mo (T_TP_SUBMIT *submit,
346 T_TP_DELIVER *deliver)
347 {
348 submit->tp_vt_mti = SMS_VT_SUBMIT;
349 submit->tp_udhi = deliver->tp_udhi;
350 submit->tp_mti = SMS_SUBMIT;
351 submit->tp_mr = NOT_PRESENT_8BIT;
352 submit->tp_pid = deliver->tp_pid;
353 submit->tp_dcs = deliver->tp_dcs;
354 if ((submit->v_tp_ud = deliver->v_tp_ud) NEQ 0)
355 {
356 submit->tp_ud = deliver->tp_ud;
357 submit->v_tp_udh_inc = FALSE;
358 }
359 else if (submit->v_tp_udh_inc= deliver->v_tp_udh_inc)
360 submit->tp_udh_inc= deliver->tp_udh_inc;
361 }
362
363 GLOBAL BOOL tl_modify_submit (T_SIM_PDU *sim_pdu,
364 UBYTE modify,
365 T_sms_sdu *sms_sdu,
366 UBYTE *rec_data)
367 {
368 T_TP_SUBMIT *submit;
369 T_sms_sdu *rec_sdu;
370 union {
371 T_TP_SUBMIT *submit;
372 T_TP_DELIVER *deliver;
373 } rec_msg;
374 T_rp_addr rp_addr;
375
376 TRACE_FUNCTION ("tl_modify_submit()");
377
378 if (modify >= SMS_MODIFY_ALL)
379 return TRUE; /* ignore message from storage */
380
381 if ((rec_data[0] & 1) EQ SMS_RECORD_FREE)
382 return FALSE; /* empty or invalid record */
383
384 if (ccd_decodeMsg (CCDENT_SMS, BOTH, (T_MSGBUF *)sms_sdu,
385 (UBYTE *)sim_pdu, SMS_VT_SIM_PDU) EQ ccdError)
386 return FALSE;
387
388 rp_addr = sim_pdu->rp_addr; /* keep SCA */
389
390 MALLOC (submit, sizeof(T_TP_SUBMIT));
391 memset (submit, 0, sizeof(T_TP_SUBMIT));
392
393 if (ccd_decodeMsg (CCDENT_SMS, UPLINK, (T_MSGBUF *)&sim_pdu->tpdu,
394 (UBYTE *)submit, SMS_VT_SUBMIT) EQ ccdError)
395 {
396 MFREE (submit);
397 return FALSE;
398 }
399 MALLOC (rec_sdu, sizeof(T_sms_sdu));
400
401 rec_sdu->o_buf = 0;
402 rec_sdu->l_buf = SIM_PDU_LEN<<3;
403 memcpy (rec_sdu->buf, &rec_data[1], SIM_PDU_LEN);
404 tl_adjust_message_len (SMS_VT_SIM_PDU, (BUF_tpdu *)rec_sdu);
405
406 if (ccd_decodeMsg (CCDENT_SMS, BOTH, (T_MSGBUF *)rec_sdu,
407 (UBYTE *)sim_pdu, SMS_VT_SIM_PDU) EQ ccdError)
408 {
409 MFREE (rec_sdu);
410 return FALSE;
411 }
412 MFREE (rec_sdu);
413
414 switch (modify)
415 {
416 case SMS_MODIFY_SCA:
417 sim_pdu->rp_addr = rp_addr; /* SCA from SUBMIT_REQ */
418 /*FALLTHROUGH*/ /*lint -fallthrough*/
419 case SMS_MODIFY_NON:
420 switch (rec_data[0] & 7)
421 {
422 case SMS_RECORD_REC_UNREAD:
423 case SMS_RECORD_REC_READ:
424 if (sim_pdu->tp_mti NEQ SMS_DELIVER OR !sim_pdu->v_tpdu)
425 {
426 MFREE (submit);
427 return FALSE;
428 }
429 MALLOC (rec_msg.deliver, sizeof(T_TP_DELIVER));
430 memset (rec_msg.deliver, 0, sizeof(T_TP_DELIVER));
431
432 if (ccd_decodeMsg (CCDENT_SMS, DOWNLINK,
433 (T_MSGBUF *)&sim_pdu->tpdu,
434 (UBYTE *)rec_msg.deliver,
435 SMS_VT_DELIVER) EQ ccdError)
436 {
437 MFREE (rec_msg.deliver);
438 return FALSE;
439 }
440 tl_translate_mt_to_mo (submit, rec_msg.deliver);
441 memcpy (&submit->tp_da, &rec_msg.deliver->tp_oa,
442 sizeof(T_tp_da));
443 MFREE (rec_msg.deliver);
444
445 sim_pdu->tpdu.o_tpdu = 0;
446 sim_pdu->tpdu.l_tpdu = TPDU_BIT_LEN;
447 if (ccd_codeMsg (CCDENT_SMS, UPLINK,
448 (T_MSGBUF *)&sim_pdu->tpdu,
449 (UBYTE *)submit, SMS_VT_SUBMIT) NEQ ccdOK)
450 {
451 MFREE (submit);
452 return FALSE;
453 }
454 MFREE (submit);
455 break;
456 /* sim_pdu shall contain a SMS_SUBMIT message */
457 default:
458 MFREE (submit);
459 if (sim_pdu->tp_mti NEQ SMS_SUBMIT OR !sim_pdu->v_tpdu)
460 {
461 return FALSE;
462 }
463 break;
464 }
465 break;
466
467 case SMS_MODIFY_TPOA_SCA:
468 sim_pdu->rp_addr = rp_addr; /* SCA from SUBMIT_REQ */
469 /* no break */
470 case SMS_MODIFY_TPOA:
471 switch (rec_data[0] & 7)
472 {
473 case SMS_RECORD_REC_UNREAD:
474 case SMS_RECORD_REC_READ:
475 if (sim_pdu->tp_mti NEQ SMS_DELIVER OR !sim_pdu->v_tpdu)
476 {
477 MFREE (submit);
478 return FALSE;
479 }
480 MALLOC (rec_msg.deliver, sizeof(T_TP_DELIVER));
481 memset (rec_msg.deliver, 0, sizeof(T_TP_DELIVER));
482
483 if (ccd_decodeMsg (CCDENT_SMS, DOWNLINK,
484 (T_MSGBUF *)&sim_pdu->tpdu,
485 (UBYTE *)rec_msg.deliver,
486 SMS_VT_DELIVER) EQ ccdError)
487 {
488 MFREE (rec_msg.deliver);
489 return FALSE;
490 }
491 tl_translate_mt_to_mo (submit, rec_msg.deliver);
492 MFREE (rec_msg.deliver);
493
494 sim_pdu->tpdu.o_tpdu = 0;
495 sim_pdu->tpdu.l_tpdu = TPDU_BIT_LEN;
496 if (ccd_codeMsg (CCDENT_SMS, UPLINK,
497 (T_MSGBUF *)&sim_pdu->tpdu,
498 (UBYTE *)submit, SMS_VT_SUBMIT) NEQ ccdOK)
499 {
500 MFREE (submit);
501 return FALSE;
502 }
503 MFREE (submit);
504 break;
505 /* sim_pdu shall contain a SMS_SUBMIT message */
506 default:
507 if (sim_pdu->tp_mti NEQ SMS_SUBMIT OR !sim_pdu->v_tpdu)
508 {
509 MFREE (submit);
510 return FALSE;
511 }
512 MALLOC (rec_msg.submit, sizeof(T_TP_SUBMIT));
513 memset (rec_msg.submit, 0, sizeof(T_TP_SUBMIT));
514
515 if (ccd_decodeMsg (CCDENT_SMS, UPLINK,
516 (T_MSGBUF *)&sim_pdu->tpdu,
517 (UBYTE *)rec_msg.submit,
518 SMS_VT_SUBMIT) EQ ccdError)
519 {
520 MFREE (rec_msg.submit);
521 MFREE (submit);
522 return FALSE;
523 }
524 rec_msg.submit->tp_da = submit->tp_da;
525 MFREE (submit);
526
527 sim_pdu->tpdu.o_tpdu = 0;
528 sim_pdu->tpdu.l_tpdu = TPDU_BIT_LEN;
529 if (ccd_codeMsg (CCDENT_SMS, UPLINK,
530 (T_MSGBUF *)&sim_pdu->tpdu,
531 (UBYTE *)rec_msg.submit, SMS_VT_SUBMIT) NEQ ccdOK)
532 {
533 MFREE (rec_msg.submit);
534 return FALSE;
535 }
536 MFREE (rec_msg.submit);
537 break;
538 }
539 break;
540
541 default:
542 MFREE (submit);
543 break;
544 }
545 sim_pdu->tp_mti = SMS_SUBMIT;
546 tl_adjust_message_len (SMS_VT_SUBMIT, &sim_pdu->tpdu);
547 return TRUE;
548 }
549
550 /*
551 +--------------------------------------------------------------------+
552 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
553 | STATE : code ROUTINE : tl_prepare_submit |
554 +--------------------------------------------------------------------+
555
556 PURPOSE : Fills 'cp_data' with required parameters and returns TRUE.
557 If the parameter check fails nothing is changed and
558 FALSE is returned.
559
560 */
561
562 GLOBAL BOOL tl_prepare_submit (
563 T_SIM_PDU *sim_pdu,
564 T_U_CP_DATA *cp_data)
565 {
566 GET_INSTANCE_DATA;
567 TRACE_FUNCTION ("tl_prepare_submit()");
568
569 if (sim_pdu->tp_mti EQ SMS_SUBMIT AND sim_pdu->v_tpdu)
570 {
571 // ++SMS_INST.tp_mr;
572 sim_pdu->tpdu.b_tpdu[1] = SMS_INST.tp_mr;
573
574 SMS_TP_REF_RET(sms_data) = SMS_INST.tp_mr;
575
576 cp_data->cp_user_data_ul.v_rp_error = FALSE;
577 cp_data->cp_user_data_ul.v_rp_ack = FALSE;
578 memset (&cp_data->cp_user_data_ul.rp_data_ul, 0,
579 sizeof (T_rp_data_ul));
580
581 memcpy (&cp_data->cp_user_data_ul.rp_data_ul.rp_addr,
582 &sim_pdu->rp_addr, sizeof (T_rp_addr));
583 cp_data->cp_user_data_ul.rp_data_ul.rp_user_data.tp_mti
584 = sim_pdu->tp_mti;
585 memcpy (&cp_data->cp_user_data_ul.rp_data_ul.rp_user_data.tpdu,
586 &sim_pdu->tpdu, sizeof (BUF_tpdu));
587 cp_data->cp_user_data_ul.rp_data_ul.rp_user_data.v_tpdu
588 = TRUE;
589 cp_data->cp_user_data_ul.v_rp_data_ul = TRUE;
590
591 return TRUE;
592 }
593
594 TRACE_EVENT ("tl_prepare_submit() failed");
595
596 return FALSE;
597 }
598
599 /*
600 +--------------------------------------------------------------------+
601 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
602 | STATE : code ROUTINE : tl_init_complete |
603 +--------------------------------------------------------------------+
604
605 PURPOSE : tasks at initialisation (sim read record loop) completion
606
607 DESCRIPTION: - set init_done flag
608 - send smma message if necessary
609 - send report indication to user if applicable
610
611 */
612 GLOBAL void tl_init_complete (void)
613 {
614 GET_INSTANCE_DATA;
615 BOOL notification_flag;
616 BOOL memory_available;
617 BOOL mem_avail_msg;
618
619 TRACE_FUNCTION ("tl_init_complete()");
620
621 /*
622 * check whether memory available message must be sent
623 */
624 mem_avail_msg = FALSE;
625 notification_flag = !sms_data->mem_cap_avail;
626
627 if ( (notification_flag == TRUE) AND
628 (sms_data->pr_cntrl.delivery_state == SMS_DELIVER_STATUS_RESUME) )
629 {
630 memory_available = (tl_get_free_space (MEM_SM) OR
631 tl_get_free_space (MEM_ME));
632 if (memory_available == TRUE)
633 {
634 /*
635 * initiate the sending of memory available message
636 */
637 mem_avail_msg = TRUE;
638 GET_MO_INSTANCE(sms_data);
639 /*
640 * TL state transition TL_ESTABLISH
641 * EST state transition EST_SMMA
642 */
643 SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH);
644 SET_STATE (STATE_EST, EST_SMMA);
645 /*
646 * 1st shot
647 */
648 SMS_INST.retrans = FALSE;
649 /*
650 * establish connection
651 */
652 tl_establish_connection(FALSE);
653 }
654 }
655 if (mem_avail_msg == FALSE)
656 {
657 #ifdef GPRS
658 cp_send_getunitdata_req ();
659 #endif
660 /*
661 * set state: READY
662 */
663 sms_data->ent_state = SMS_STATE_READY;
664 /*
665 * report ind to user
666 */
667 tl_mnsms_report_ind (SMS_STATE_READY);
668 }
669 /*
670 * init done
671 */
672 sms_data->init_done = TRUE;
673 }
674
675 /*
676 +--------------------------------------------------------------------+
677 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
678 | STATE : code ROUTINE : tl_convert_sim_error |
679 +--------------------------------------------------------------------+
680
681 PURPOSE : Converts a SIM error to the appropriate SMS failure code.
682
683 */
684
685 GLOBAL USHORT tl_convert_sim_error (USHORT sim_error)
686 {
687 #if 0
688 switch (sim_error)
689 {
690 case SIM_INVALID_PIN_1:
691 return SMS_ERR_SIM_PIN1_REQ;
692 case SIM_INVALID_PUK_1:
693 return SMS_ERR_SIM_PUK1_REQ;
694 case SIM_INVALID_PIN_2:
695 return SMS_ERR_SIM_PIN2_REQ;
696 case SIM_INVALID_PUK_2:
697 return SMS_ERR_SIM_PUK2_REQ;
698 case SIM_INVALID_OFFSET:
699 return SMS_ERR_INV_INDEX;
700 case SIM_FATAL_ERROR:
701 return SMS_ERR_SIM_MISSING;
702 default:
703 return SMS_ERR_SIM_FAIL;
704 }
705 #else
706 return sim_error; // prelimary
707 #endif
708 }
709
710 /*
711 +--------------------------------------------------------------------+
712 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
713 | STATE : code ROUTINE : tl_convert_mo_to_mem |
714 +--------------------------------------------------------------------+
715
716 PURPOSE : Prepare a MO-SM to be stored.
717
718 */
719
720 GLOBAL BOOL tl_convert_mo_to_mem (T_MMSMS_DATA_REQ *data_req,
721 UBYTE *data)
722 {
723 T_SIM_PDU *sim_pdu;
724 T_sms_sdu *sms_sdu;
725 MCAST (cp_data, U_CP_DATA);
726
727 TRACE_FUNCTION ("tl_convert_mo_to_mem()");
728
729 data_req->sdu.l_buf -= 8; // point to CP message type!
730 data_req->sdu.o_buf += 8;
731 if (ccd_decodeMsg (CCDENT_SMS, UPLINK,
732 (T_MSGBUF *)&data_req->sdu,
733 (UBYTE *)cp_data, NOT_PRESENT_8BIT) EQ ccdError)
734 {
735 return FALSE;
736 }
737 if (cp_data->msg_type NEQ U_CP_DATA OR
738 cp_data->cp_user_data_ul.rp_mti NEQ RP_DATA_UL)
739 {
740 return FALSE;
741 }
742 MALLOC (sim_pdu, sizeof(T_SIM_PDU));
743 MALLOC (sms_sdu, sizeof(T_sms_sdu));
744 sms_sdu->o_buf = 0;
745 sms_sdu->l_buf = SIM_PDU_LEN<<3;
746
747 sim_pdu->rp_addr = cp_data->cp_user_data_ul.rp_data_ul.rp_addr;
748 sim_pdu->tpdu = cp_data->cp_user_data_ul.rp_data_ul.rp_user_data.tpdu;
749 sim_pdu->tp_mti = SMS_SUBMIT;
750 sim_pdu->v_tpdu = TRUE;
751 sim_pdu->tp_vt_mti = SMS_VT_SIM_PDU;
752
753 ccd_codeMsg (CCDENT_SMS, DOWNLINK,
754 (T_MSGBUF *)sms_sdu,
755 (UBYTE *)sim_pdu, SMS_VT_SIM_PDU);
756
757 /* set status byte */
758 data[0] = SMS_RECORD_STO_SENT;
759 memcpy (&data[1], sms_sdu->buf, sms_sdu->l_buf >> 3);
760 memset (&data[(sms_sdu->l_buf >> 3) + 1], NOT_PRESENT_8BIT,
761 (SIZE_EF_SMS-1) - (sms_sdu->l_buf >> 3));
762
763 MFREE (sim_pdu);
764 MFREE (sms_sdu);
765 // CCD_END;
766 return TRUE;
767 }
768
769 /*
770 +--------------------------------------------------------------------+
771 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
772 | STATE : code ROUTINE : tl_convert_mt_to_mem |
773 +--------------------------------------------------------------------+
774
775 PURPOSE : Prepare a MT-SM to be stored.
776
777 */
778
779 GLOBAL void tl_convert_mt_to_mem (T_rp_data_dl *rp_data_dl,
780 UBYTE *data)
781 {
782 T_SIM_PDU *sim_pdu;
783 T_sms_sdu *sms_sdu;
784
785 TRACE_FUNCTION ("tl_convert_mt_to_mem()");
786
787 MALLOC (sim_pdu, sizeof(T_SIM_PDU));
788 MALLOC (sms_sdu, sizeof(T_sms_sdu));
789 sms_sdu->o_buf = 0;
790 sms_sdu->l_buf = SIM_PDU_LEN<<3;
791
792 sim_pdu->rp_addr = rp_data_dl->rp_addr;
793 sim_pdu->tpdu = rp_data_dl->rp_user_data.tpdu;
794 sim_pdu->tp_mti = SMS_DELIVER;
795 sim_pdu->v_tpdu = TRUE;
796 sim_pdu->tp_vt_mti = SMS_VT_SIM_PDU;
797
798 ccd_codeMsg (CCDENT_SMS, DOWNLINK,
799 (T_MSGBUF *)sms_sdu,
800 (UBYTE *)sim_pdu, SMS_VT_SIM_PDU);
801
802 data[0] = SMS_RECORD_REC_UNREAD;
803 memcpy (&data[1], sms_sdu->buf, sms_sdu->l_buf >> 3);
804 memset (&data[(sms_sdu->l_buf >> 3) + 1], NOT_PRESENT_8BIT,
805 (SIZE_EF_SMS-1) - (sms_sdu->l_buf >> 3));
806
807 MFREE (sim_pdu);
808 MFREE (sms_sdu);
809 }
810
811 /*
812 +--------------------------------------------------------------------+
813 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
814 | STATE : code ROUTINE : tl_get_free_space |
815 +--------------------------------------------------------------------+
816
817 PURPOSE : Checks the first not used record for SMS messages.
818 Returns the index of the first free record in the
819 range 1..max_record, if no free record exists 0 is returned.
820
821 */
822
823 GLOBAL UBYTE tl_get_free_space (UBYTE mem_type)
824 {
825 UBYTE i;
826 GET_INSTANCE_DATA;
827
828 T_BACKUP * backup;
829
830 TRACE_FUNCTION ("tl_get_free_space()");
831
832 if (mem_type EQ MEM_ME)
833 backup = &SMS_ME_PROP(sms_data);
834 else if (mem_type EQ MEM_SM)
835 backup = &SMS_SIM_PROP(sms_data);
836 else
837 return 0;
838
839 for (i = 1; i <= backup->max_record; i++)
840 {
841 if ((tl_get_status (backup, i-1) & 1) EQ 0)
842 return i;
843 }
844 return 0;
845 }
846
847
848
849 /*
850 +--------------------------------------------------------------------+
851 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
852 | STATE : code ROUTINE : tl_find_first |
853 +--------------------------------------------------------------------+
854
855 PURPOSE : Checks availability of SMS memory on SIM or ME memory.
856
857 */
858
859 GLOBAL void tl_find_first (UBYTE mem_type)
860 {
861 GET_INSTANCE_DATA;
862
863 TRACE_FUNCTION ("tl_find_first()");
864
865 if (mem_type EQ MEM_SM)
866 {
867 /*
868 * Start with index 1 on SIM card
869 */
870 tl_set_access_fifo (ACCESS_BY_MMI);
871 SET_STATE (STATE_MMI, MMI_FIND_FIRST);
872 tl_sim_read_record_req (1);
873 sms_data->sim_backup.any_valid = FALSE;
874 }
875 else
876 {
877 USHORT max_record;
878 UBYTE version;
879 UBYTE *sim_msg;
880 MALLOC (sim_msg, SIZE_EF_SMS);
881
882 sms_data->me_backup.any_valid = FALSE;
883 /*
884 * look at Mobile Memory
885 */
886 /* Implements Measure#32: Row 84 */
887 if (pcm_ReadRecord ((UBYTE *)ef_sms_id, 1, SIZE_EF_SMS,
888 sim_msg, &version, &max_record) EQ PCM_OK)
889 {
890 if (max_record > MAX_RECORD_ME)
891 max_record = MAX_RECORD_ME;
892 else if (max_record EQ 0)
893 max_record = 1;
894
895 sms_data->me_backup.max_record = (UBYTE)max_record;
896 if (tl_find_status_pid (MEM_ME, 1, sim_msg,
897 &sms_data->me_backup))
898 {
899 tl_message_ind_from_sim (MEM_ME, 1, (UBYTE)max_record, sim_msg);
900 }
901 }
902 else
903 {
904 /*
905 * No SMS in mobile memory
906 */
907 sms_data->me_backup.max_record = 0;
908 }
909 MFREE (sim_msg);
910 }
911 }
912 /*
913 +--------------------------------------------------------------------+
914 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
915 | STATE : code ROUTINE : tl_find_next |
916 +--------------------------------------------------------------------+
917
918 PURPOSE : Creates a copy of the status and protocol identifier
919 for the next entry.
920
921 */
922
923 GLOBAL void tl_find_next (UBYTE mem_type, UBYTE index)
924 {
925 GET_INSTANCE_DATA;
926
927 TRACE_FUNCTION ("tl_find_next()");
928
929 if (mem_type EQ MEM_SM)
930 {
931 /*
932 * Start with index on SIM card
933 */
934 tl_set_access_fifo (ACCESS_BY_MMI);
935 SET_STATE (STATE_MMI, MMI_FIND_NEXT);
936 tl_sim_read_record_req (index);
937 }
938 else
939 {
940 USHORT max_record;
941 UBYTE version;
942 UBYTE *sim_msg;
943 MALLOC (sim_msg, SIZE_EF_SMS);
944
945 /*
946 * look at Mobile Memory
947 */
948 /* Implements Measure#32: Row 86 */
949 if (pcm_ReadRecord ((UBYTE *)ef_sms_id, index, SIZE_EF_SMS,
950 sim_msg, &version, &max_record) EQ PCM_OK)
951 {
952 if (tl_find_status_pid (MEM_ME, index, sim_msg,
953 &sms_data->me_backup))
954 tl_message_ind_from_sim (MEM_ME, index, (UBYTE)max_record, sim_msg);
955 }
956 else
957 {
958 /*
959 * declare only the successfull records
960 * from previous attempts as available
961 */
962 sms_data->me_backup.max_record = index - 1;
963 }
964 MFREE (sim_msg);
965 }
966 }
967
968 /*
969 +--------------------------------------------------------------------+
970 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
971 | STATE : code ROUTINE : tl_get_pid_dcs |
972 +--------------------------------------------------------------------+
973
974 PURPOSE : Gets TP-PID and/or TP-DCS from any message type.
975 If something is not available, nothing is written to
976 *pid and *dcs.
977 */
978
979 GLOBAL void tl_get_pid_dcs (UBYTE status,
980 T_sms_sdu *sms_sdu,
981 UBYTE *pid,
982 UBYTE *dcs)
983 {
984 UBYTE *ptr;
985 int step, rpl;
986
987 TRACE_FUNCTION ("tl_get_pid_dcs()");
988
989 ptr = &sms_sdu->buf[rpl = sms_sdu->buf[0] + 1]; /* points to TP-MTI */
990 switch (status)
991 {
992 case SMS_RECORD_STO_UNSENT:
993 case SMS_RECORD_STO_SENT: /* MO-SM */
994 switch (*ptr & 3)
995 {
996 case SMS_SUBMIT:
997 ptr += (*(ptr + 2) + 1) / 2 + 4;
998 if (pid NEQ NULL)
999 *pid = *ptr;
1000 if (dcs NEQ NULL)
1001 *dcs = *(ptr + 2);
1002 break;
1003
1004 case SMS_COMMAND:
1005 if (pid NEQ NULL)
1006 *pid = *(ptr + 2);
1007 break;
1008
1009 default:
1010 break;
1011 }
1012 break;
1013
1014 case SMS_RECORD_REC_UNREAD:
1015 case SMS_RECORD_REC_READ: /* MT-SM */
1016 switch (*ptr & 3)
1017 {
1018 case SMS_DELIVER:
1019 ptr += (*(ptr + 1) + 1) / 2 + 3;
1020 if (pid NEQ NULL)
1021 *pid = *ptr;
1022 if (dcs NEQ NULL)
1023 *dcs = *(ptr + 2);
1024 break;
1025
1026 case SMS_STATUS_REPORT:
1027 if ((step = (*(ptr + 2) + 1) / 2 + 19) + rpl < (sms_sdu->l_buf >> 3))
1028 {
1029 ptr += step; /* TP-PI */
1030 if (pid NEQ NULL AND *ptr & 1)
1031 *pid = *(ptr + 1);
1032 if (dcs NEQ NULL AND *ptr & 2)
1033 *dcs = *(ptr + 2);
1034 }
1035 break;
1036
1037 default:
1038 break;
1039 }
1040 break;
1041
1042 default:
1043 break;
1044 }
1045 }
1046
1047 /*
1048 +--------------------------------------------------------------------+
1049 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1050 | STATE : code ROUTINE : tl_find_status_pid |
1051 +--------------------------------------------------------------------+
1052
1053 PURPOSE : Calculates status and protocol identifier of a SMS
1054 record and stores the values. Returns TRUE, when a
1055 valid message is recognized.
1056 */
1057
1058 GLOBAL BOOL tl_find_status_pid (UBYTE mem_type,
1059 UBYTE index,
1060 UBYTE * data,
1061 T_BACKUP * backup)
1062 {
1063 UBYTE *ptr;
1064 BOOL is_valid = FALSE;
1065
1066 TRACE_FUNCTION ("tl_find_status_pid()");
1067
1068 /*
1069 * Store status and clear pid
1070 */
1071 tl_store_status (backup, index-1, data[0]);
1072 tl_store_pid (backup, index-1, 0);
1073
1074 /*
1075 * mobile terminated message (bit 3 = 0) and used (bit 1 = 1)
1076 * check first byte with mask 00000101 = bit 3+1 = 5 must
1077 * be 1, that means bit 3 = 0 and bit 1 = 1.
1078 * skip service centre address and set to message type
1079 */
1080 ptr = &data[1] + data[1] + 1;
1081
1082 switch (data[0] & 5)
1083 {
1084 case 1: // MT-SM
1085 /*
1086 * check message type to be a SMS-DELIVER
1087 */
1088 if ((*ptr & 3) EQ SMS_DELIVER)
1089 {
1090 /*
1091 * skip message type and originator address,
1092 * *(ptr+1) contains the number of digits of the
1093 * originator address. The term (*p+1)/2 indicates
1094 * the number of bytes used for the digits. Plus 3 for
1095 * message type, the length field and TON/NPI field.
1096 */
1097 ptr += (*(ptr + 1) + 1) / 2 + 3;
1098
1099 /*
1100 * store protocol identifier
1101 */
1102 tl_store_pid (backup, index-1, *ptr);
1103
1104 /*
1105 * valid message found
1106 */
1107 backup->any_valid = TRUE;
1108 is_valid = TRUE;
1109 }
1110 else if((*ptr & 3) EQ SMS_STATUS_REPORT)
1111 {
1112 /*
1113 * Indicate that valid Status Report message is found in ME or SIM.
1114 * No need to store status & pid as only reading and delelting of
1115 * Status Report Message is allowed and not replacing of the message.
1116 *
1117 */
1118 backup->any_valid = TRUE;
1119 is_valid = TRUE;
1120 }
1121 else
1122 {
1123 /*
1124 * consider the record as free
1125 */
1126 tl_store_status (backup, index-1, 0);
1127 }
1128 break;
1129
1130 case 5: // MO-SM
1131 /*
1132 * mobile originated messages are not to be replaced,
1133 * but it is checked whether there is really a SMS-SUBMIT
1134 * stored on the SIM
1135 */
1136 if ((*ptr & 3) NEQ SMS_SUBMIT)
1137 {
1138 /*
1139 * consider the record as free
1140 */
1141 tl_store_status (backup, index-1, 0);
1142 }
1143 else
1144 {
1145 /*
1146 * valid message found
1147 */
1148 backup->any_valid = TRUE;
1149 is_valid = TRUE;
1150 }
1151 break;
1152
1153 default:
1154 break;
1155 }
1156 return is_valid;
1157 }
1158
1159 /*
1160 +--------------------------------------------------------------------+
1161 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1162 | STATE : code ROUTINE : tl_cphs_voice_mail |
1163 +--------------------------------------------------------------------+
1164
1165 PURPOSE : Checking whether a CPHS Voice Mail Indication is
1166 given, which shall not be stored.
1167 */
1168 #ifdef FF_CPHS
1169 LOCAL BOOL tl_cphs_voice_mail (T_TP_DELIVER *sms_deliver)
1170 {
1171 if (sms_deliver->tp_oa.digits NEQ 4 OR
1172 sms_deliver->tp_oa.ton NEQ SMS_TON_ALPHANUMERIC)
1173 return FALSE;
1174
1175 switch (sms_deliver->tp_dcs & 0xF0)
1176 {
1177 case SMS_DCS_GRP_DEF:
1178 case SMS_DCS_GRP_CLASS:
1179 if ((sms_deliver->tp_dcs & 0xC) EQ 0 OR
1180 (sms_deliver->tp_dcs & 0xC) EQ 0xC)
1181 break; /* GSM Default Alphabet */
1182 /*FALLTHROUGH*/ /*lint -fallthrough*/
1183 case SMS_DCS_GRP_COMPR:
1184 case SMS_DCS_GRP_CLASS_COMPR:
1185 case SMS_DCS_GRP_MW_STORE_UCS2:
1186 return FALSE; /* no GSM Default Alphabet */
1187 case SMS_DCS_DATA_CLASS:
1188 if (sms_deliver->tp_dcs & 0x4)
1189 return FALSE; /* no GSM Default Alphabet */
1190 }
1191 if (!sms_deliver->v_tp_ud)
1192 return FALSE; /* not only text present */
1193
1194 if (sms_deliver->tp_ud.length NEQ 1 OR
1195 (sms_deliver->tp_ud.data[0] & 0x7F) NEQ ' ')
1196 return FALSE; /* no single space */
1197
1198 TRACE_FUNCTION ("CPHS VMS: do not store");
1199
1200 return TRUE;
1201 }
1202 #endif
1203 /*
1204 +--------------------------------------------------------------------+
1205 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1206 | STATE : code ROUTINE : tl_check_network_on_sim |
1207 +--------------------------------------------------------------------+
1208
1209 PURPOSE : Checks the PLMN code as part of the IMSI and notices
1210 whether a certain network operator is present.
1211 */
1212 #ifdef FF_SMS_NW_RCG_SIM
1213 GLOBAL void tl_check_network_on_sim (UBYTE *data)
1214 {
1215 GET_INSTANCE_DATA;
1216 if (data NEQ NULL AND data[0] >= 3 AND
1217 (data[1] & 0xF7) EQ 0x21 /* ignore parity bit */
1218 AND data[2] EQ 0x43 AND data[3] EQ 0x03)
1219 SMS_NETWORK(sms_data) = NW_SIM_23430;
1220 else
1221 SMS_NETWORK(sms_data) = NW_SIM_NONE;
1222 }
1223 #endif
1224 /*
1225 +--------------------------------------------------------------------+
1226 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1227 | STATE : code ROUTINE : tl_handle_23430 |
1228 +--------------------------------------------------------------------+
1229
1230 PURPOSE : Special handling of an income Short Message according to
1231 specifications of operator 23430
1232 */
1233 #ifdef FF_SMS_23430
1234 GLOBAL BOOL tl_handle_23430 (T_TP_DELIVER *sms_deliver)
1235 {
1236 GET_INSTANCE_DATA;
1237 UBYTE record;
1238
1239 if (SMS_NETWORK(sms_data) NEQ NW_SIM_23430)
1240 return FALSE;
1241
1242 if ((sms_deliver->tp_dcs EQ 0 OR sms_deliver->tp_dcs EQ 0xF2)
1243 AND (int)sms_deliver->tp_oa.digits EQ sizeof(ref_nr_23430)
1244 AND sms_deliver->tp_oa.ton EQ SMS_TON_ALPHANUMERIC
1245 AND memcmp (sms_deliver->tp_oa.num, ref_nr_23430,
1246 sizeof(ref_nr_23430)) EQ 0)
1247 {
1248 record = tl_get_free_space (MEM_SM);
1249 if (record)
1250 {
1251 tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_PENDING);
1252 tl_sim_conv_update_req (record, SMS_RP_RCVD(sms_data));
1253
1254 tl_set_access_fifo (ACCESS_BY_NET);
1255 SET_STATE (STATE_NET, NET_23430_WRITE);
1256
1257 MFREE (SMS_RP_RCVD(sms_data));
1258 SMS_RP_RCVD(sms_data) = NULL;
1259 }
1260 else
1261 {
1262 tl_sms_memo_exceeded (FALSE);
1263 }
1264 return TRUE; /* the message has been handled */
1265 }
1266 switch (sms_deliver->tp_dcs & 0xF0)
1267 {
1268 case SMS_DCS_GRP_CLASS:
1269 case SMS_DCS_GRP_CLASS_COMPR:
1270 case SMS_DCS_DATA_CLASS:
1271 if ((sms_deliver->tp_dcs & 3) EQ 2 AND /* Class 2 */
1272 ((sms_deliver->v_tp_ud AND sms_deliver->tp_ud.length EQ 0) OR
1273 (sms_deliver->v_tp_udh_inc AND sms_deliver->tp_udh_inc.length EQ 0)))
1274 {
1275 if (tl_get_free_space (MEM_SM) NEQ 0)
1276 rl_report_req_ack (NULL);
1277 else
1278 tl_sms_memo_exceeded (FALSE);
1279 return TRUE; /* the message has been handled */
1280 }
1281 break;
1282 default:
1283 break;
1284 }
1285 return FALSE; /* no SIM specific message */
1286 }
1287 #endif
1288 /*
1289 +--------------------------------------------------------------------+
1290 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1291 | STATE : code ROUTINE : tl_store_special_sms |
1292 +--------------------------------------------------------------------+
1293
1294 PURPOSE : Checking the presence of a special message indication
1295 requiring the message to be stored.
1296 */
1297
1298 LOCAL BOOL tl_store_special_sms (T_TP_DELIVER *sms_deliver)
1299 {
1300 UBYTE *udh;
1301 int udh_len;
1302
1303 if (!sms_deliver->tp_udhi OR
1304 !sms_deliver->v_tp_udh_inc)
1305 return FALSE;
1306
1307 udh = &sms_deliver->tp_udh_inc.tp_udh.data[0];
1308 udh_len = (int)sms_deliver->tp_udh_inc.tp_udh.c_data;
1309
1310 while (udh_len > 0)
1311 {
1312 if (udh[0] EQ 0x01) /* tag Special Message Indication? */
1313 {
1314 if (udh[2] & 0x80) /* storing required? */
1315 {
1316 TRACE_FUNCTION ("tl_store_special_sms: found");
1317 return TRUE;
1318 }
1319 }
1320 udh_len -= (int)udh[1] + 2;
1321 udh += udh[1] + 2; /* next tag */
1322 }
1323 return FALSE;
1324 }
1325
1326 /*
1327 +--------------------------------------------------------------------+
1328 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1329 | STATE : code ROUTINE : tl_handle_message |
1330 +--------------------------------------------------------------------+
1331
1332 PURPOSE : Standard handling of an income Short Message according to
1333 GSM 03.40 and 03.38
1334 */
1335
1336 /*
1337 * DISPLAY display
1338 * MEM_ME store in ME
1339 * MEM_SM store in SIM
1340 * NOTHING do nothing
1341 */
1342
1343 static const UBYTE me_table_A [5][7] =
1344 { /* mt no class class 0 class 1 class 2 class 3 discard store */
1345 /* 0 */ { MEM_ME, MEM_ME, MEM_ME, MEM_SM, MEM_ME, MEM_ME, MEM_ME },
1346 /* 1 */ { MEM_ME, DISPLAY, MEM_ME, MEM_SM, MEM_ME, MEM_ME, MEM_ME },
1347 /* 2 */ { DISPLAY, DISPLAY, DISPLAY, MEM_SM, DISPLAY, DISPLAY, MEM_ME },
1348 /* 3 */ { MEM_ME, DISPLAY, MEM_ME, MEM_SM, DISPLAY, MEM_ME, MEM_ME },
1349 /* 4 */ { MEM_ME, DISPLAY, MEM_ME, MEM_SM, MEM_SM, DISPLAY, MEM_ME }
1350 };
1351
1352 static const UBYTE me_table_B [5][7] =
1353 { /* mt no class class 0 class 1 class 2 class 3 discard store */
1354 /* 0 */ { MEM_SM, DISPLAY, MEM_SM, NOTHING, NOTHING, DISPLAY, NOTHING },
1355 /* 1 */ { MEM_SM, IGNORE, MEM_SM, NOTHING, NOTHING, DISPLAY, NOTHING },
1356 /* 2 */ { NOTHING, IGNORE, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING },
1357 /* 3 */ { MEM_SM, IGNORE, MEM_SM, NOTHING, NOTHING, DISPLAY, NOTHING },
1358 /* 4 */ { MEM_SM, IGNORE, MEM_SM, NOTHING, MEM_ME, NOTHING, MEM_SM }
1359 };
1360
1361 static const UBYTE sm_table_A [5][7] =
1362 { /* mt no class class 0 class 1 class 2 class 3 discard store */
1363 /* 0 */ { MEM_SM, MEM_SM, MEM_SM, MEM_SM, MEM_SM, MEM_SM, MEM_SM },
1364 /* 1 */ { MEM_SM, DISPLAY, MEM_SM, MEM_SM, MEM_SM, MEM_SM, MEM_SM },
1365 /* 2 */ { DISPLAY, DISPLAY, DISPLAY, MEM_SM, DISPLAY, DISPLAY, MEM_SM },
1366 /* 3 */ { MEM_SM, DISPLAY, MEM_SM, MEM_SM, DISPLAY, MEM_SM, MEM_SM },
1367 /* 4 */ { MEM_SM, DISPLAY, MEM_ME, MEM_SM, MEM_SM, DISPLAY, MEM_SM }
1368 };
1369
1370 static const UBYTE sm_table_B [5][7] =
1371 { /* mt no class class 0 class 1 class 2 class 3 discard store */
1372 /* 0 */ { MEM_ME, DISPLAY, MEM_ME, NOTHING, NOTHING, DISPLAY, NOTHING },
1373 /* 1 */ { MEM_ME, IGNORE, MEM_ME, NOTHING, NOTHING, DISPLAY, NOTHING },
1374 /* 2 */ { NOTHING, IGNORE, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING },
1375 /* 3 */ { MEM_ME, IGNORE, MEM_ME, NOTHING, NOTHING, DISPLAY, NOTHING },
1376 /* 4 */ { MEM_ME, IGNORE, MEM_SM, NOTHING, MEM_ME, NOTHING, MEM_ME }
1377 };
1378
1379 GLOBAL void tl_handle_message (T_TP_DELIVER *sms_deliver)
1380 {
1381 GET_INSTANCE_DATA;
1382 UBYTE dcs_class;
1383 UBYTE record;
1384 UBYTE data[SIZE_EF_SMS];
1385
1386 TRACE_FUNCTION ("tl_handle_message()");
1387
1388 if (sms_data->pr_cntrl.delivery_state == SMS_DELIVER_STATUS_PAUSE)
1389 {
1390 /* user has blocked message receiption */
1391 TRACE_EVENT("User has paused MT message delivery");
1392
1393 tl_sms_memo_pause();
1394
1395 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1396 return;
1397 }
1398
1399 #ifdef FF_CPHS
1400 if (SMS_CPHS(sms_data) AND tl_cphs_voice_mail (sms_deliver))
1401 dcs_class = 5; /* discard message */
1402 else
1403 #endif
1404 if (tl_store_special_sms (sms_deliver))
1405 dcs_class = 6; /* store message */
1406 else if (sms_deliver->tp_pid EQ SMS_PID_ME_DOWNLOAD)
1407 dcs_class = 1 + 1; /* class 1 */
1408 else if (sms_deliver->tp_pid EQ SMS_PID_SIM_DOWNLOAD)
1409 dcs_class = 2 + 1; /* class 2 */
1410 else switch (sms_deliver->tp_dcs & 0xF0)
1411 {
1412 case SMS_DCS_GRP_CLASS:
1413 case SMS_DCS_GRP_CLASS_COMPR:
1414 case SMS_DCS_DATA_CLASS:
1415 dcs_class = (sms_deliver->tp_dcs & 3) + 1;
1416 break;
1417 case SMS_DCS_GRP_MW_DISCD:
1418 dcs_class = 5; /* discard message */
1419 break;
1420 case SMS_DCS_GRP_MW_STORE:
1421 case SMS_DCS_GRP_MW_STORE_UCS2:
1422 dcs_class = 6; /* store message */
1423 break;
1424 default:
1425 dcs_class = 0; // no class
1426 break;
1427 }
1428
1429 if (sms_data->mem3 EQ MEM_ME)
1430 {
1431 sms_data->use_mem_a = me_table_A [sms_data->mt][dcs_class];
1432 sms_data->use_mem_b = me_table_B [sms_data->mt][dcs_class];
1433 }
1434 else
1435 {
1436 sms_data->use_mem_a = sm_table_A [sms_data->mt][dcs_class];
1437 sms_data->use_mem_b = sm_table_B [sms_data->mt][dcs_class];
1438 }
1439
1440 /*
1441 * try alternative A
1442 */
1443 switch (sms_data->use_mem_a)
1444 {
1445 case DISPLAY:
1446 /*
1447 * Only display of the message
1448 */
1449
1450 TRACE_EVENT("TABLE A: DISPLAY");
1451
1452 SMS_EM_DISPLAY_MT_SHORT_MESSAGE;
1453
1454 tl_message_ind_from_net (NOT_PRESENT_8BIT, 0, 0,
1455 SMS_RP_RCVD(sms_data));
1456 {
1457 if (SMS_MT_ACK_MODE(sms_data) NEQ SMS_MHC_PH2PLUS)
1458 {
1459 rl_report_req_ack (NULL);
1460 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1461 }
1462 }
1463 MFREE (SMS_RP_RCVD(sms_data));
1464 SMS_RP_RCVD(sms_data) = NULL;
1465 return;
1466
1467 case MEM_ME:
1468 /*
1469 * memory type is mobile memory
1470 */
1471
1472 TRACE_EVENT("TABLE A: MEM_ME");
1473
1474 record = tl_get_free_space (MEM_ME);
1475 if (record NEQ 0)
1476 {
1477 tl_convert_mt_to_mem (SMS_RP_RCVD(sms_data), data);
1478 /*
1479 * store in mobile memory
1480 */
1481 /* Implements Measure#32: Row 87 */
1482 if (pcm_WriteRecord ((UBYTE *)ef_sms_id, record,
1483 SIZE_EF_SMS, data) NEQ PCM_OK)
1484 break;
1485 /*
1486 * update status byte and protocol identifier
1487 */
1488 tl_store_status (&SMS_ME_PROP(sms_data), record-1, SMS_RECORD_REC_UNREAD);
1489 tl_store_pid (&SMS_ME_PROP(sms_data), record-1, sms_deliver->tp_pid);
1490 /*
1491 * send indication to MMI
1492 */
1493 tl_message_ind_from_net (MEM_ME, record,
1494 sms_data->me_backup.max_record,
1495 SMS_RP_RCVD(sms_data));
1496 /*
1497 * acknowledge to the infrastructure
1498 */
1499 rl_report_req_ack (NULL);
1500 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1501
1502 MFREE (SMS_RP_RCVD(sms_data));
1503 SMS_RP_RCVD(sms_data) = NULL;
1504 return;
1505 }
1506 break;
1507
1508 case MEM_SM:
1509 /*
1510 * memory type is SIM card
1511 */
1512
1513 TRACE_EVENT("TABLE A: MEM_SM");
1514
1515 record = tl_get_free_space (MEM_SM);
1516 if (record)
1517 {
1518 tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_PENDING);
1519 tl_sim_conv_update_req (record, SMS_RP_RCVD(sms_data));
1520
1521 tl_set_access_fifo (ACCESS_BY_NET);
1522 SET_STATE (STATE_NET, NET_WRITE);
1523 return;
1524 }
1525 break;
1526 }
1527 /*
1528 * try alternative B
1529 */
1530 switch (sms_data->use_mem_b)
1531 {
1532 case DISPLAY:
1533 /*
1534 * Only display of the message
1535 */
1536
1537 TRACE_EVENT("TABLE B: DISPLAY");
1538
1539 tl_message_ind_from_net (NOT_PRESENT_8BIT, 0, 0,
1540 sms_data->rp_data_dl);
1541 {
1542 if (SMS_MT_ACK_MODE(sms_data) NEQ SMS_MHC_PH2PLUS)
1543 {
1544 rl_report_req_ack (NULL);
1545 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1546 }
1547 }
1548 MFREE (SMS_RP_RCVD(sms_data));
1549 SMS_RP_RCVD(sms_data) = NULL;
1550 break;
1551
1552 case MEM_ME:
1553 /*
1554 * memory type is mobile memory
1555 */
1556
1557 TRACE_EVENT("TABLE B: MEM_ME");
1558
1559 record = tl_get_free_space (MEM_ME);
1560 if (record)
1561 {
1562 tl_convert_mt_to_mem (SMS_RP_RCVD(sms_data), data);
1563 /*
1564 * store in mobile memory
1565 */
1566 /* Implements Measure#32: Row 89 */
1567 if (pcm_WriteRecord ((UBYTE *)ef_sms_id, record,
1568 SIZE_EF_SMS, data) EQ PCM_OK)
1569 {
1570 /*
1571 * update status byte
1572 */
1573 tl_store_status (&SMS_ME_PROP(sms_data), record-1, SMS_RECORD_REC_UNREAD);
1574 tl_store_pid (&SMS_ME_PROP(sms_data), record-1, sms_deliver->tp_pid);
1575 /*
1576 * send indication to MMI
1577 */
1578 tl_message_ind_from_net (MEM_ME, record,
1579 sms_data->me_backup.max_record,
1580 SMS_RP_RCVD(sms_data));
1581 /*
1582 * acknowledge to the infrastructure
1583 */
1584 rl_report_req_ack (NULL);
1585 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1586 SET_STATE (STATE_NET, NET_IDLE);
1587
1588 MFREE (SMS_RP_RCVD(sms_data));
1589 SMS_RP_RCVD(sms_data) = NULL;
1590 break;
1591 }
1592 }
1593 if (tl_get_free_space (MEM_SM)) /* SIM memory available? */
1594 {
1595 /*
1596 * RP_ERROR =>
1597 */
1598 rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, NULL);
1599 /*
1600 * RL_RELEASE_REQ ==>
1601 */
1602 rl_release_req(SMS_INST.ti);
1603
1604 /*
1605 * free instance
1606 */
1607 // FREE_SMS_INSTANCE (SMS_INST.ti);
1608 }
1609 else
1610 {
1611 /* change mem_cap_avail flag on SIM and return error */
1612 tl_sms_memo_exceeded (FALSE);
1613 }
1614
1615 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1616 SET_STATE (STATE_NET, NET_IDLE);
1617
1618 MFREE (SMS_RP_RCVD(sms_data));
1619 SMS_RP_RCVD(sms_data) = NULL;
1620 break;
1621
1622 case MEM_SM:
1623 /*
1624 * memory type is SIM card
1625 */
1626
1627 TRACE_EVENT("TABLE B: MEM_SM");
1628
1629 record = tl_get_free_space (MEM_SM);
1630 if (record)
1631 {
1632 tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_PENDING);
1633 tl_sim_conv_update_req (record, SMS_RP_RCVD(sms_data));
1634
1635 tl_set_access_fifo (ACCESS_BY_NET);
1636 SET_STATE (STATE_NET, NET_WRITE);
1637 break;
1638 }
1639 if (tl_get_free_space (MEM_ME)) /* other memory available? */
1640 {
1641 /*
1642 * RP_ERROR =>
1643 */
1644 rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, NULL);
1645 /*
1646 * RL_RELEASE_REQ ==>
1647 */
1648 rl_release_req(SMS_INST.ti);
1649
1650 /*
1651 * free instance
1652 */
1653 // FREE_SMS_INSTANCE (SMS_INST.ti);
1654 }
1655 else
1656 {
1657 /* change mem_cap_avail flag on SIM and return error */
1658 tl_sms_memo_exceeded (FALSE);
1659 }
1660
1661 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1662 SET_STATE (STATE_NET, NET_IDLE);
1663
1664 MFREE (SMS_RP_RCVD(sms_data));
1665 SMS_RP_RCVD(sms_data) = NULL;
1666 break;
1667
1668 case IGNORE:
1669
1670 TRACE_EVENT("TABLE B: IGNORE");
1671
1672 rl_report_req_ack (NULL);
1673 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1674
1675 MFREE (SMS_RP_RCVD(sms_data));
1676 SMS_RP_RCVD(sms_data) = NULL;
1677 break;
1678
1679 default: /* other memory available? */
1680
1681 TRACE_EVENT("TABLE B: OTHER?");
1682
1683 if (tl_get_free_space (MEM_ME) OR tl_get_free_space (MEM_SM))
1684 {
1685 /*
1686 * RP_ERROR =>
1687 */
1688 rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, NULL);
1689 /*
1690 * RL_RELEASE_REQ ==>
1691 */
1692 rl_release_req(SMS_INST.ti);
1693 /*
1694 * free instance
1695 */
1696 // FREE_SMS_INSTANCE (SMS_INST.ti);
1697 }
1698 else
1699 {
1700 /* change mem_cap_avail flag on SIM and return error */
1701 tl_sms_memo_exceeded (FALSE);
1702 }
1703
1704 SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
1705
1706 MFREE (SMS_RP_RCVD(sms_data));
1707 SMS_RP_RCVD(sms_data) = NULL;
1708 break;
1709 }
1710 sms_data->use_mem_b = NOTHING; // not reached if alternative B in progress
1711 }
1712
1713 /*
1714 +--------------------------------------------------------------------+
1715 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1716 | STATE : code ROUTINE : tl_sms_reserve_req_id |
1717 +--------------------------------------------------------------------+
1718
1719 PURPOSE : Finds a free entry in for SIM accesses and reserves it for use.
1720 */
1721
1722 GLOBAL BOOL tl_sms_reserve_req_id (UBYTE *acc_ix_ptr)
1723 {
1724 GET_INSTANCE_DATA;
1725 UBYTE sim_acc_ix;
1726
1727
1728 for (sim_acc_ix = 0;
1729 sim_acc_ix < SMS_MAX_SIM_ACCESS AND sms_data->sms_sim_access_info[sim_acc_ix].entry_used;
1730 ++sim_acc_ix);
1731
1732 if (sim_acc_ix < SMS_MAX_SIM_ACCESS)
1733 {
1734 *acc_ix_ptr = sim_acc_ix;
1735 sms_data->sms_sim_access_info[sim_acc_ix].entry_used = TRUE;
1736 return TRUE;
1737 }
1738 else
1739 {
1740 TRACE_ERROR("SMS SIM Access entries used up");
1741 return FALSE;
1742 }
1743 }
1744
1745 /*
1746 +--------------------------------------------------------------------+
1747 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1748 | STATE : code ROUTINE : tl_build_sim_update_req |
1749 +--------------------------------------------------------------------+
1750
1751 PURPOSE : Build and send the SIM_UPDATE_REQ.
1752
1753 */
1754
1755 GLOBAL void tl_build_sim_update_req (void)
1756 {
1757 GET_INSTANCE_DATA;
1758
1759 TRACE_FUNCTION ("tl_build_sim_update_req()");
1760
1761 /* Implements Measure# 14 */
1762 tl_send_sim_update_req (SMS_INST.tp_mr, 0);
1763 }
1764
1765 /*
1766 +--------------------------------------------------------------------+
1767 | PROJECT : GSM-PS (8410) MODULE : SMS_TL |
1768 | STATE : code ROUTINE : tl_message_ind_from_net |
1769 +--------------------------------------------------------------------+
1770
1771 PURPOSE : Builds from SIM data and sends the primitive
1772 MNSMS_MESSAGE_IND to ACI. A NULL pointer for parameter
1773 'data' generates an empty indication, which shall
1774 interpreted as existent but empty memory.
1775 */
1776
1777 GLOBAL void tl_message_ind_from_net (UBYTE mem_type,
1778 UBYTE record,
1779 UBYTE max_record,
1780 T_rp_data_dl *rp_data_dl)
1781 {
1782 T_SIM_PDU *sim_pdu;
1783
1784 TRACE_FUNCTION ("tl_message_ind_from_net");
1785
1786 if (rp_data_dl NEQ NULL)
1787 {
1788 PALLOC (message_ind, MNSMS_MESSAGE_IND);
1789 MALLOC (sim_pdu, sizeof(T_SIM_PDU));
1790 message_ind->sms_sdu.o_buf = 0;
1791 message_ind->sms_sdu.l_buf = SIM_PDU_LEN<<3;
1792
1793 message_ind->status = SMS_RECORD_REC_UNREAD;
1794 message_ind->mem_type = mem_type;
1795 message_ind->rec_num = record;
1796 message_ind->rec_max = max_record;
1797
1798 SMS_EM_STORE_MT_MESSAGE;
1799
1800 sim_pdu->rp_addr = rp_data_dl->rp_addr;
1801 sim_pdu->tpdu = rp_data_dl->rp_user_data.tpdu;
1802 sim_pdu->tp_mti = SMS_DELIVER;
1803 sim_pdu->v_tpdu = TRUE;
1804 sim_pdu->tp_vt_mti = SMS_VT_SIM_PDU;
1805
1806 ccd_codeMsg (CCDENT_SMS, DOWNLINK,
1807 (T_MSGBUF *)&message_ind->sms_sdu,
1808 (UBYTE *)sim_pdu, SMS_VT_SIM_PDU);
1809
1810 PSENDX (MMI, message_ind);
1811 MFREE (sim_pdu);
1812 }
1813 }
1814
1815 /*
1816 +--------------------------------------------------------------------+
1817 | PROJECT : GSM-PS (8410) MODULE : SMS_TL |
1818 | STATE : code ROUTINE : tl_message_ind_from_sim |
1819 +--------------------------------------------------------------------+
1820
1821 PURPOSE : Builds from SIM data and sends the primitive
1822 MNSMS_MESSAGE_IND to ACI. A NULL pointer for parameter
1823 'data' generates an empty indication, which shall
1824 interpreted as existent but empty memory.
1825 */
1826
1827 GLOBAL void tl_message_ind_from_sim (UBYTE mem_type,
1828 UBYTE record,
1829 UBYTE max_record,
1830 UBYTE *data)
1831 {
1832 PALLOC (message_ind, MNSMS_MESSAGE_IND);
1833
1834 TRACE_FUNCTION ("tl_message_ind_from_sim");
1835
1836 memset (message_ind, 0, sizeof (T_MNSMS_MESSAGE_IND));
1837 message_ind->mem_type = mem_type;
1838 message_ind->rec_max = max_record;
1839
1840 if (data NEQ NULL)
1841 {
1842 message_ind->rec_num = record;
1843 message_ind->status = data[0];
1844 memcpy (message_ind->sms_sdu.buf, &data[1], SIZE_EF_SMS-1);
1845 message_ind->sms_sdu.l_buf = (SIZE_EF_SMS-1) << 3;
1846 tl_adjust_message_len (SMS_VT_SIM_PDU, (BUF_tpdu *)&message_ind->sms_sdu);
1847 }
1848 PSENDX (MMI, message_ind);
1849 }
1850
1851 /*
1852 +--------------------------------------------------------------------+
1853 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1854 | STATE : code ROUTINE : tl_read_access_fifo |
1855 +--------------------------------------------------------------------+
1856
1857 PURPOSE : Processing the function TL_READ_ACCESS_FIFO.
1858
1859 */
1860
1861 GLOBAL UBYTE tl_read_access_fifo (void)
1862 {
1863 GET_INSTANCE_DATA;
1864 UBYTE id;
1865
1866 TRACE_FUNCTION ("tl_read_access_fifo()");
1867
1868 if (sms_data->access_fifo [1] NEQ ACCESS_EMPTY)
1869 {
1870 id = sms_data->access_fifo [1];
1871 sms_data->access_fifo [1] = ACCESS_EMPTY;
1872 }
1873 else
1874 {
1875 id = sms_data->access_fifo [0];
1876 sms_data->access_fifo [0] = ACCESS_EMPTY;
1877 }
1878
1879 return id;
1880 }
1881
1882 /*
1883 +--------------------------------------------------------------------+
1884 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
1885 | STATE : code ROUTINE : tl_read_me_memory |
1886 +--------------------------------------------------------------------+
1887
1888 PURPOSE : Processing the function TL_READ_ME_MEMORY.
1889
1890 */
1891
1892 GLOBAL void tl_read_me_memory (USHORT rec_num,
1893 UBYTE status)
1894 {
1895 GET_INSTANCE_DATA;
1896 int index;
1897
1898 TRACE_FUNCTION ("tl_read_me_memory()");
1899
1900 if (rec_num <= SMS_ME_PROP(sms_data).max_record)
1901 {
1902 SMS_REC_STATUS(sms_data) = tl_check_status_value (status);
1903 if (rec_num EQ SMS_RECORD_NOT_EXIST)
1904 {
1905 /*
1906 * find first record of given status
1907 */
1908 index = tl_search_record (&SMS_ME_PROP(sms_data), 1,
1909 SMS_REC_STATUS(sms_data));
1910 }
1911 else
1912 index = (int)rec_num;
1913
1914 if ((index NEQ SMS_RECORD_NOT_EXIST) AND
1915 (tl_get_status (&SMS_ME_PROP(sms_data), index-1) & 1))
1916 {
1917 USHORT max_record;
1918 UBYTE misc;
1919 UBYTE sim_msg[SIZE_EF_SMS];
1920 /*
1921 * valid index
1922 */
1923 /* Implements Measure#32: Row 84 */
1924 if (pcm_ReadRecord ((UBYTE *)ef_sms_id, (USHORT)index, SIZE_EF_SMS,
1925 sim_msg, &misc, &max_record) NEQ PCM_OK)
1926 {
1927 tl_mnsms_read_cnf (MEM_ME, (UBYTE)rec_num,
1928 NULL, SMS_CAUSE_MEM_FAIL);
1929 SMS_ME_PROP(sms_data).max_record = 0;
1930 return;
1931 }
1932 tl_store_status (&SMS_ME_PROP(sms_data), index-1, sim_msg[0]);
1933 if (sim_msg[0] & 1)
1934 {
1935
1936 SMS_EM_READ_SHORT_MESSAGE;
1937
1938 switch (sim_msg[0] & 7)
1939 {
1940 case SMS_RECORD_REC_UNREAD:
1941 /*
1942 * entry is changeable
1943 */
1944 switch (SMS_READ_MODE(sms_data))
1945 {
1946 case READ_STATUS_CHANGE:
1947 sim_msg[0] = SMS_RECORD_REC_READ;
1948 /* Implements Measure#32: Row 84 */
1949 pcm_WriteRecord ((UBYTE *)ef_sms_id, (USHORT)index,
1950 SIZE_EF_SMS, sim_msg);
1951 tl_store_status (&SMS_ME_PROP(sms_data), index-1, sim_msg[0]);
1952 tl_mnsms_read_cnf (MEM_ME, (UBYTE)index,
1953 NULL, SIM_NO_ERROR);
1954 break;
1955
1956 default:
1957 misc = sim_msg[0];
1958 sim_msg[0] = SMS_RECORD_REC_READ;
1959 /* Implements Measure#32: Row 84 */
1960 pcm_WriteRecord ((UBYTE *)ef_sms_id, (USHORT)index,
1961 SIZE_EF_SMS, sim_msg);
1962 tl_store_status (&SMS_ME_PROP(sms_data), index-1, sim_msg[0]);
1963 sim_msg[0] = misc;
1964 /*FALLTHROUGH*/ /*lint -fallthrough*/
1965 case READ_PREVIEW:
1966 tl_mnsms_read_cnf (MEM_ME, (UBYTE)index,
1967 sim_msg, SIM_NO_ERROR);
1968 break;
1969 }
1970 break;
1971
1972 case SMS_RECORD_STO_SENT:
1973 case SMS_RECORD_STO_UNSENT:
1974 /*
1975 * no status change for STORE_UNSENT!
1976 */
1977 if (SMS_READ_MODE(sms_data) EQ READ_STATUS_CHANGE)
1978 {
1979 tl_mnsms_read_cnf (MEM_ME, (UBYTE)rec_num,
1980 NULL, SMS_CAUSE_OPER_NOT_ALLW);
1981 return;
1982 }
1983 /*FALLTHROUGH*/ /*lint -fallthrough*/
1984 default:
1985 /*
1986 * Status Change is obsolete
1987 */
1988 tl_mnsms_read_cnf (MEM_ME, (UBYTE)index,
1989 sim_msg, SIM_NO_ERROR);
1990 break;
1991 }
1992 return;
1993 }
1994 }
1995 }
1996 else
1997 index = (int)rec_num;
1998 /*
1999 * index is wrong or other error
2000 */
2001 tl_mnsms_read_cnf (MEM_ME, (UBYTE)index, NULL,
2002 (USHORT)((SMS_ME_PROP(sms_data).max_record EQ 0)?
2003 SMS_CAUSE_MEM_FAIL: SMS_CAUSE_INV_INDEX));
2004 }
2005
2006 /*
2007 +--------------------------------------------------------------------+
2008 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2009 | STATE : code ROUTINE : tl_read_sim_memory |
2010 +--------------------------------------------------------------------+
2011
2012 PURPOSE : Processing the function TL_READ_SIM_MEMORY.
2013
2014 */
2015
2016 GLOBAL void tl_read_sim_memory (
2017 USHORT rec_num,
2018 UBYTE status)
2019 {
2020 GET_INSTANCE_DATA;
2021 int index;
2022
2023 TRACE_FUNCTION ("tl_read_sim_memory()");
2024
2025 if (rec_num <= (USHORT)SMS_SIM_PROP(sms_data).max_record)
2026 {
2027 SMS_REC_STATUS(sms_data) = tl_check_status_value (status);
2028 if (rec_num EQ SMS_RECORD_NOT_EXIST)
2029 {
2030 /*
2031 * find first record of given status
2032 */
2033 index = tl_search_record (&SMS_SIM_PROP(sms_data), 1,
2034 SMS_REC_STATUS(sms_data));
2035 }
2036 else
2037 index = (int)rec_num;
2038
2039 if ((index NEQ SMS_RECORD_NOT_EXIST) AND
2040 (tl_get_status (&SMS_SIM_PROP(sms_data), index-1) & 1))
2041 {
2042 /*
2043 * valid index
2044 */
2045 if (SMS_READ_MODE(sms_data) EQ READ_STATUS_CHANGE)
2046 {
2047 switch (tl_get_status (&SMS_SIM_PROP(sms_data), index-1) & 7)
2048 {
2049 case SMS_RECORD_REC_UNREAD:
2050 /*
2051 * entry is changeable
2052 */
2053 break;
2054
2055 case SMS_RECORD_STO_SENT:
2056 case SMS_RECORD_STO_UNSENT:
2057 /*
2058 * no status change for STORE_UNSENT!
2059 */
2060 tl_mnsms_read_cnf (MEM_SM, (UBYTE)rec_num,
2061 NULL, SMS_CAUSE_OPER_NOT_ALLW);
2062 return;
2063
2064 default:
2065 /*
2066 * Status Change is obsolete
2067 */
2068 tl_mnsms_read_cnf (MEM_SM, (UBYTE)rec_num,
2069 NULL, SIM_NO_ERROR);
2070 return;
2071 }
2072 }
2073 SMS_SEL_REC(sms_data) = (UBYTE)index;
2074 tl_set_access_fifo (ACCESS_BY_MMI);
2075 SET_STATE (STATE_MMI, MMI_READ);
2076 SMS_INST_SET_STATE (STATE_TL, TL_OTHER);
2077 tl_sim_read_record_req ((UBYTE)index);
2078 return;
2079 }
2080 }
2081 /*
2082 * index is wrong or other error
2083 */
2084 tl_mnsms_read_cnf (MEM_SM, (UBYTE)rec_num, NULL,
2085 (USHORT)((SMS_SIM_PROP(sms_data).max_record EQ 0)?
2086 SMS_CAUSE_MEM_FAIL: SMS_CAUSE_INV_INDEX));
2087 }
2088
2089 /*
2090 +--------------------------------------------------------------------+
2091 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2092 | STATE : code ROUTINE : tl_sim_read_req |
2093 +--------------------------------------------------------------------+
2094
2095 PURPOSE : Prepares and sends the primitive SIM_READ_REQ to read a
2096 binary file from SIM.
2097 */
2098
2099 GLOBAL void tl_sim_read_req (USHORT datafield,
2100 UBYTE length)
2101 {
2102 GET_INSTANCE_DATA;
2103
2104 UBYTE sim_acc_ix;
2105
2106 if (tl_sms_reserve_req_id(&sim_acc_ix))
2107 {
2108
2109 PALLOC (sim_read_req, SIM_READ_REQ);
2110 sim_read_req->source = SRC_SMS;
2111 sim_read_req->req_id = sim_acc_ix;
2112 sim_read_req->datafield =
2113 sms_data->sms_sim_access_info[sim_acc_ix].datafield = datafield;
2114 sim_read_req->v_path_info = FALSE;
2115 sim_read_req->offset = 0;
2116 sim_read_req->length = length;
2117 sim_read_req->max_length = 0;
2118 PSENDX (SIM, sim_read_req);
2119 }
2120 }
2121
2122 /*
2123 +--------------------------------------------------------------------+
2124 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2125 | STATE : code ROUTINE : tl_sim_read_record_req |
2126 +--------------------------------------------------------------------+
2127
2128 PURPOSE : Prepares and sends the primitive SIM_READ_RECORD_REQ to
2129 read the given record from EF(SMS).
2130 */
2131
2132 GLOBAL void tl_sim_read_record_req (UBYTE record)
2133 {
2134 GET_INSTANCE_DATA;
2135
2136 UBYTE sim_acc_ix;
2137
2138 if (tl_sms_reserve_req_id(&sim_acc_ix))
2139 {
2140
2141 PALLOC (sim_read_record_req, SIM_READ_RECORD_REQ);
2142
2143 sim_read_record_req->source = SRC_SMS;
2144 sim_read_record_req->req_id = sim_acc_ix;
2145 sim_read_record_req->v_path_info = FALSE;
2146 sim_read_record_req->datafield =
2147 sms_data->sms_sim_access_info[sim_acc_ix].datafield = SIM_SMS;
2148 sim_read_record_req->record =
2149 sms_data->sms_sim_access_info[sim_acc_ix].rec_num = record;
2150 sim_read_record_req->length = SIM_LENGTH_SMS_RECORD;
2151
2152 PSENDX (SIM, sim_read_record_req);
2153 }
2154
2155 }
2156
2157 /*
2158 +--------------------------------------------------------------------+
2159 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2160 | STATE : code ROUTINE : tl_sim_update_req |
2161 +--------------------------------------------------------------------+
2162
2163 PURPOSE : Prepares and sends the primitive SIM_READ_UPDATE_REQ to
2164 update the given record of EF(SMS). Parameter 'status' is
2165 written to the first byte of the record, the remaining
2166 bytes are filled with the parameter '*data'. When parameter
2167 'data' is NULL, then the remaining bytes are filled with
2168 pattern NOT_PRESENT_8BIT (0xFF).
2169 */
2170
2171 GLOBAL void tl_sim_update_req (UBYTE record,
2172 UBYTE status,
2173 UBYTE *data)
2174 {
2175 GET_INSTANCE_DATA;
2176
2177 UBYTE sim_acc_ix;
2178
2179 if (tl_sms_reserve_req_id(&sim_acc_ix))
2180 {
2181 PALLOC (update_record_req, SIM_UPDATE_RECORD_REQ);
2182 update_record_req->source = SRC_SMS;
2183 update_record_req->req_id = sim_acc_ix;
2184 update_record_req->v_path_info = FALSE;
2185 update_record_req->datafield =
2186 sms_data->sms_sim_access_info[sim_acc_ix].datafield = SIM_SMS;
2187 update_record_req->record =
2188 sms_data->sms_sim_access_info[sim_acc_ix].rec_num = record;
2189
2190 update_record_req->length = SIM_LENGTH_SMS_RECORD;
2191 if (data NEQ NULL)
2192 {
2193 update_record_req->linear_data[0] = status;
2194 memcpy (&update_record_req->linear_data[1],
2195 data, SIM_LENGTH_SMS_RECORD-1);
2196 }
2197 else
2198 {
2199 update_record_req->linear_data[0] = SMS_RECORD_FREE;
2200 memset (&update_record_req->linear_data[1],
2201 NOT_PRESENT_8BIT, SIM_LENGTH_SMS_RECORD-1);
2202 }
2203 PSENDX (SIM, update_record_req);
2204 }
2205 }
2206
2207 /*
2208 +--------------------------------------------------------------------+
2209 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2210 | STATE : code ROUTINE : tl_sim_conv_update_req |
2211 +--------------------------------------------------------------------+
2212
2213 PURPOSE : Prepares and sends the primitive SIM_READ_UPDATE_REQ to
2214 update the given record of EF(SMS). The data is extracted
2215 from the RP-DATA IE.
2216 */
2217
2218 GLOBAL void tl_sim_conv_update_req (UBYTE record,
2219 T_rp_data_dl *rp_data_dl)
2220 {
2221 GET_INSTANCE_DATA;
2222
2223 UBYTE sim_acc_ix;
2224
2225 if (tl_sms_reserve_req_id(&sim_acc_ix))
2226 {
2227 PALLOC (update_record_req, SIM_UPDATE_RECORD_REQ);
2228 update_record_req->source = SRC_SMS;
2229 update_record_req->req_id = sim_acc_ix;
2230 update_record_req->v_path_info = FALSE;
2231 update_record_req->datafield =
2232 sms_data->sms_sim_access_info[sim_acc_ix].datafield = SIM_SMS;
2233 update_record_req->record =
2234 sms_data->sms_sim_access_info[sim_acc_ix].rec_num = record;
2235 update_record_req->length = SIM_LENGTH_SMS_RECORD;
2236 tl_convert_mt_to_mem (rp_data_dl,
2237 update_record_req->linear_data);
2238
2239 PSENDX (SIM, update_record_req);
2240 }
2241
2242 }
2243
2244 /*
2245 +--------------------------------------------------------------------+
2246 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2247 | STATE : code ROUTINE : tl_check_replace_entry |
2248 +--------------------------------------------------------------------+
2249
2250 PURPOSE : Compares the service centre address and the originator
2251 address for two sms messages during replace procedure.
2252
2253 */
2254
2255 GLOBAL BOOL tl_check_replace_entry (UBYTE /*T_TP_DELIVER*/ *sms_addr,
2256 UBYTE /*T_TP_DELIVER*/ *sms_storage)
2257 {
2258 TRACE_FUNCTION ("tl_check_replace_entry()");
2259
2260 /*
2261 * skip service centre address
2262 */
2263 sms_storage += *sms_storage + 1;
2264 /*
2265 * check TP-MTI
2266 */
2267 if ((sms_storage[0] & 0x3) NEQ SMS_DELIVER)
2268 {
2269 return FALSE;
2270 }
2271 /*
2272 * compare originator address and protocol identifier
2273 */
2274 if (memcmp (sms_addr, &sms_storage[1], (*sms_addr + 1) / 2 + 3) EQ 0)
2275 {
2276 return TRUE;
2277 }
2278 return FALSE;
2279 }
2280
2281 /*
2282 +--------------------------------------------------------------------+
2283 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2284 | STATE : code ROUTINE : tl_replace_message |
2285 +--------------------------------------------------------------------+
2286
2287 PURPOSE : Checks the ME and SIM memory for replacing a short message.
2288 If protocol identifier, service centre address and
2289 originator address are equal the message will be replaced.
2290 Else normal handling is processed.
2291
2292 */
2293
2294 GLOBAL void tl_replace_message (T_TP_DELIVER *sms_deliver)
2295 {
2296 GET_INSTANCE_DATA;
2297 int i;
2298
2299 TRACE_FUNCTION ("tl_replace_message()");
2300
2301 /*
2302 * first check mobile memory
2303 */
2304 i = tl_check_mt_pid (&sms_data->me_backup, 1, sms_deliver->tp_pid);
2305 {
2306 if (i > 0) /* possible record found */
2307 {
2308 USHORT max_record;
2309 UBYTE version;
2310 UBYTE data[SIZE_EF_SMS];
2311 /*
2312 * look at Mobile Memory
2313 */
2314 /* Implements Measure#32: Row 84 */
2315 if (pcm_ReadRecord ((UBYTE *)ef_sms_id, (USHORT)i, SIZE_EF_SMS,
2316 data, &version, &max_record) EQ PCM_OK)
2317 {
2318 if (tl_check_replace_entry (&SMS_RP_RCVD(sms_data)->rp_user_data.tpdu.b_tpdu[1],
2319 &data[1]))
2320 {
2321 /*
2322 *record shall be replaced, store new one
2323 */
2324 tl_convert_mt_to_mem (sms_data->rp_data_dl, data);
2325
2326 /* Implements Measure#32: Row 84 */
2327 pcm_WriteRecord ((UBYTE *)ef_sms_id, (USHORT)i,
2328 SIZE_EF_SMS, data);
2329 /*
2330 * send indication to MMI
2331 */
2332 tl_message_ind_from_net (MEM_ME, (UBYTE)i,
2333 SMS_ME_PROP(sms_data).max_record,
2334 SMS_RP_RCVD(sms_data));
2335 /*
2336 * acknowledge to the infrastructure
2337 */
2338 rl_report_req_ack (NULL);
2339
2340 SMS_EM_REPLACE_SMS_IN_ME;
2341
2342 MFREE (SMS_RP_RCVD(sms_data));
2343 SMS_RP_RCVD(sms_data) = NULL;
2344 return;
2345 }
2346 }
2347 }
2348 }
2349
2350 /*
2351 * now look at the SIM card
2352 */
2353
2354 i = tl_check_mt_pid (&sms_data->sim_backup, 1, sms_deliver->tp_pid);
2355 if (i > 0)
2356 {
2357 tl_set_access_fifo (ACCESS_BY_NET);
2358 SET_STATE (STATE_NET, NET_READ);
2359 tl_sim_read_record_req ((UBYTE)i);
2360 }
2361 else
2362 {
2363 tl_handle_message (sms_deliver);
2364 }
2365 }
2366
2367 /*
2368 +--------------------------------------------------------------------+
2369 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2370 | STATE : code ROUTINE : tl_check_replace_pid |
2371 +--------------------------------------------------------------------+
2372
2373 PURPOSE : This function checks whether a given PID for a replacement
2374 message could match the entry described by backup and index.
2375 */
2376
2377 LOCAL BOOL tl_check_replace_pid (T_BACKUP *backup,
2378 unsigned index,
2379 UBYTE pid)
2380
2381 {
2382 if (backup->pid_field EQ NULL)
2383 return TRUE; /* Maybe of replacement type, further checks needed */
2384 return ((backup->pid_field[index >> 3] & (1 << (index & 0x7))) NEQ 0);
2385 }
2386
2387 /*
2388 +--------------------------------------------------------------------+
2389 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2390 | STATE : code ROUTINE : tl_store_pid |
2391 +--------------------------------------------------------------------+
2392
2393 PURPOSE : This function stores the information wheter the given
2394 MT PID is of the replacement type in compressed form.
2395
2396 */
2397
2398 GLOBAL void tl_store_pid (T_BACKUP *backup,
2399 unsigned index,
2400 UBYTE pid)
2401 {
2402 UBYTE mask;
2403
2404 #ifdef WIN32
2405 if (backup->mem_type EQ MEM_ME)
2406 assert (index < MAX_RECORD_ME);
2407 else if (backup->mem_type EQ MEM_SM)
2408 assert (index < MAX_RECORD_SIM);
2409 #endif /* #ifdef WIN32 */
2410
2411 if (backup->pid_field EQ NULL)
2412 return; /* No caching here */
2413
2414 mask = 1 << (index & 0x7);
2415
2416 switch (pid)
2417 {
2418 case SMS_PID_REP_SM_TYPE_1:
2419 case SMS_PID_REP_SM_TYPE_2:
2420 case SMS_PID_REP_SM_TYPE_3:
2421 case SMS_PID_REP_SM_TYPE_4:
2422 case SMS_PID_REP_SM_TYPE_5:
2423 case SMS_PID_REP_SM_TYPE_6:
2424 case SMS_PID_REP_SM_TYPE_7:
2425 case SMS_PID_RET_CALL_MSG:
2426 backup->pid_field[index >> 3] |= mask;
2427 break;
2428 default:
2429 backup->pid_field[index >> 3] &= ~mask;
2430 break;
2431 }
2432 }
2433
2434 /*
2435 +--------------------------------------------------------------------+
2436 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2437 | STATE : code ROUTINE : tl_store_status |
2438 +--------------------------------------------------------------------+
2439
2440 PURPOSE : This function stores the status into the backup data
2441 in compressed form.
2442
2443 */
2444
2445 GLOBAL void tl_store_status (T_BACKUP *backup,
2446 unsigned index,
2447 UBYTE status)
2448 {
2449 #ifdef WIN32
2450 if (backup->mem_type EQ MEM_ME)
2451 assert (index < MAX_RECORD_ME);
2452 else if (backup->mem_type EQ MEM_SM)
2453 assert (index < MAX_RECORD_SIM);
2454 #endif /* #ifdef WIN32 */
2455
2456 if (backup->status_field EQ NULL)
2457 return; /* No caching here */
2458
2459 backup->status_field[index] = status;
2460 }
2461
2462 /*
2463 +--------------------------------------------------------------------+
2464 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2465 | STATE : code ROUTINE : tl_get_status |
2466 +--------------------------------------------------------------------+
2467
2468 PURPOSE : This function gets the status. For the asynchronous
2469 interface to the SIM the presence of backup data is
2470 mandatory, for the synchronous (and fast) interface
2471 to the FFS the presence of backup data is optional.
2472
2473 */
2474
2475 GLOBAL UBYTE tl_get_status (T_BACKUP *backup,
2476 unsigned index)
2477 {
2478 USHORT max_record;
2479 UBYTE version;
2480
2481 #ifdef WIN32
2482 if (backup->mem_type EQ MEM_ME)
2483 assert (index < MAX_RECORD_ME);
2484 else if (backup->mem_type EQ MEM_SM)
2485 assert (index < MAX_RECORD_SIM);
2486 #endif /* #ifdef WIN32 */
2487
2488 switch (backup->mem_type)
2489 {
2490 case MEM_ME:
2491 if (backup->status_field EQ NULL)
2492 {
2493 UBYTE status = SMS_RECORD_FREE;
2494 UBYTE *sim_msg;
2495 MALLOC (sim_msg, SIZE_EF_SMS);
2496 /* Implements Measure#32: Row 84 */
2497 if (pcm_ReadRecord ((UBYTE *)ef_sms_id, (USHORT)(index + 1), SIZE_EF_SMS,
2498 sim_msg, &version, &max_record) EQ PCM_OK)
2499 status = sim_msg[0];
2500 MFREE (sim_msg);
2501 return status;
2502 }
2503 /*FALLTHROUGH*/ /*lint -fallthrough*/
2504 case MEM_SM:
2505 return backup->status_field[index];
2506
2507 default:
2508 return SMS_RECORD_FREE;
2509 }
2510 }
2511
2512 /*
2513 +--------------------------------------------------------------------+
2514 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2515 | STATE : code ROUTINE : tl_check_mt_pid |
2516 +--------------------------------------------------------------------+
2517
2518 PURPOSE : Checks the memory for replacing candidates.
2519 If protocol identifier and status (mt message) are okay
2520 the index of the record is returned.
2521
2522 */
2523
2524 GLOBAL int tl_check_mt_pid (T_BACKUP *backup,
2525 unsigned index,
2526 UBYTE pid)
2527
2528 {
2529 int i;
2530
2531 for (i = (int)index; i <= (int)backup->max_record; i++)
2532 {
2533 if (((tl_get_status (backup, i - 1) & 5) EQ 1) AND /* mt message */
2534 tl_check_replace_pid (backup, i - 1, pid)) /* replacement type pid */
2535 return i;
2536 }
2537 return 0;
2538 }
2539
2540 /*
2541 +--------------------------------------------------------------------+
2542 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2543 | STATE : code ROUTINE : tl_check_status_value |
2544 +--------------------------------------------------------------------+
2545
2546 PURPOSE : Checks and maps the parameter <status> according to the
2547 following rule:
2548 - SMS_RECORD_REC_UNREAD as is
2549 - SMS_RECORD_REC_READ as is
2550 - SMS_RECORD_STO_UNSENT as is
2551 - SMS_RECORD_STO_SENT as is
2552 - SMS_RECORD_STAT_UNRCVD to SMS_RECORD_STO_SENT
2553 - SMS_RECORD_STAT_UNSTRD to SMS_RECORD_STO_SENT
2554 - SMS_RECORD_STAT_STRD to SMS_RECORD_STO_SENT
2555 - any other value to NOT_PRESENT_8BIT
2556 In conjunction with 'tl_search_record' a memory location
2557 with comparable properties can be found
2558 */
2559
2560 GLOBAL UBYTE tl_check_status_value (UBYTE status)
2561 {
2562 switch (status)
2563 {
2564 case SMS_RECORD_REC_UNREAD:
2565 case SMS_RECORD_REC_READ:
2566 case SMS_RECORD_STO_UNSENT:
2567 case SMS_RECORD_STO_SENT:
2568 return status;
2569 case SMS_RECORD_STAT_UNRCVD:
2570 case SMS_RECORD_STAT_UNSTRD:
2571 case SMS_RECORD_STAT_STRD:
2572 return SMS_RECORD_STO_SENT;
2573 default:
2574 break;
2575 }
2576 return NOT_PRESENT_8BIT;
2577 }
2578
2579 /*
2580 +--------------------------------------------------------------------+
2581 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2582 | STATE : code ROUTINE : tl_search_record |
2583 +--------------------------------------------------------------------+
2584
2585 PURPOSE : Searches the memory for the next message with the given
2586 status.
2587 The following codes for parameter <status> are supported:
2588 - SMS_RECORD_FREE: next free record
2589 - SMS_RECORD_REC_UNREAD
2590 - SMS_RECORD_REC_READ
2591 - SMS_RECORD_STO_UNSENT
2592 - SMS_RECORD_STO_SENT: next record with any sent message
2593 - NOT_PRESENT_8BIT: any occupied record
2594 The index of the record is returned.
2595 */
2596
2597 GLOBAL int tl_search_record (T_BACKUP *backup,
2598 USHORT index,
2599 UBYTE status)
2600 {
2601 int i;
2602
2603 TRACE_FUNCTION ("tl_search_record()");
2604
2605 for (i = (int)index; i <= (int)backup->max_record; i++)
2606 {
2607 if (status EQ NOT_PRESENT_8BIT)
2608 { /* next occupied record */
2609 if ((tl_get_status (backup, i - 1) & 1) NEQ SMS_RECORD_FREE)
2610 return i;
2611 }
2612 else if ((status & 1) EQ SMS_RECORD_FREE)
2613 { /* next free record */
2614 if ((tl_get_status (backup, i - 1) & 1) EQ SMS_RECORD_FREE)
2615 return i;
2616 }
2617 else if ((status & 7) EQ (tl_get_status (backup, i - 1) & 7))
2618 return i;
2619 }
2620 return 0;
2621 }
2622
2623 /*
2624 +--------------------------------------------------------------------+
2625 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2626 | STATE : code ROUTINE : tl_search_record_for_delete|
2627 +--------------------------------------------------------------------+
2628
2629 PURPOSE : Searches the SMS DataBase for the next message to be deleted with the given
2630 status.
2631 The following codes for parameter <status> are supported:
2632 - CMGD_DEL_INDEX delete message only for the index given
2633 - CMGD_DEL_READ
2634 - CMGD_DEL_READ_SENT
2635 - CMGD_DEL_READ_SENT_UNSENT
2636 - CMGD_DEL_ALL next occupied record
2637 The index of the record is returned.
2638 */
2639
2640 GLOBAL UBYTE tl_search_record_for_delete (T_BACKUP *backup,
2641 UBYTE index,
2642 UBYTE status)
2643 {
2644 UBYTE i;
2645 UBYTE file_status;
2646
2647 TRACE_FUNCTION ("tl_search_record_for_delete()");
2648
2649 for (i = index; i <= backup->max_record; i++)
2650 {
2651 file_status = backup->status_field[i - 1] & 7;
2652 switch(status)
2653 {
2654 case CMGD_DEL_ALL:
2655 {
2656 if ((file_status & 1) NEQ SMS_RECORD_FREE)
2657 {
2658 return i;
2659 }
2660 break;
2661 }
2662 case CMGD_DEL_READ:
2663 {
2664 if (file_status EQ SMS_RECORD_REC_READ)
2665 {
2666 return i;
2667 }
2668 break;
2669 }
2670 case CMGD_DEL_READ_SENT:
2671 {
2672 if (file_status EQ SMS_RECORD_REC_READ ||
2673 file_status EQ SMS_RECORD_STO_SENT)
2674 {
2675 return i;
2676 }
2677 break;
2678 }
2679 case CMGD_DEL_READ_SENT_UNSENT:
2680 {
2681 if (file_status EQ SMS_RECORD_REC_READ ||
2682 file_status EQ SMS_RECORD_STO_SENT ||
2683 file_status EQ SMS_RECORD_STO_UNSENT)
2684 {
2685 return i;
2686 }
2687 break;
2688 }
2689 }
2690 }
2691 return SMS_RECORD_NOT_EXIST;
2692 }
2693
2694 /*
2695 +--------------------------------------------------------------------+
2696 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2697 | STATE : code ROUTINE : tl_set_access_fifo |
2698 +--------------------------------------------------------------------+
2699
2700 PURPOSE : Processing the function TL_SET_ACCESS_FIFO.
2701
2702 */
2703
2704 GLOBAL void tl_set_access_fifo (UBYTE access)
2705 {
2706 GET_INSTANCE_DATA;
2707
2708 TRACE_FUNCTION ("tl_set_access_fifo()");
2709
2710 sms_data->access_fifo[1] = sms_data->access_fifo[0];
2711 sms_data->access_fifo[0] = access;
2712 }
2713
2714 /*
2715 +--------------------------------------------------------------------+
2716 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2717 | STATE : code ROUTINE : tl_sms_memo_exceeded |
2718 +--------------------------------------------------------------------+
2719
2720 PURPOSE : Checks the SIM memory availability. If an update of
2721 EF(SMSS) is required, then TRUE is returned. If the memory
2722 has become full, then the appropriate RP-ERROR is generated.
2723 */
2724
2725 GLOBAL BOOL tl_sms_memo_exceeded (BOOL avail)
2726 {
2727 GET_INSTANCE_DATA;
2728 BOOL sim_update = FALSE;
2729 UBYTE sim_acc_ix;
2730
2731 TRACE_FUNCTION ("tl_sms_memo_exceeded()");
2732
2733 if ((sms_data->sim_phase >= 2) AND (sms_data->mem_cap_avail NEQ avail))
2734 {
2735
2736 if (tl_sms_reserve_req_id(&sim_acc_ix))
2737 {
2738 PALLOC (update_req, SIM_UPDATE_REQ);
2739 update_req->source = SRC_SMS;
2740 update_req->req_id = sim_acc_ix;
2741 update_req->v_path_info = FALSE;
2742 update_req->datafield = sms_data->sms_sim_access_info[sim_acc_ix].datafield = SIM_SMSS;
2743 update_req->length = 1;
2744 update_req->trans_data[0] = (avail)? 0xFF: 0xFE;
2745 update_req->offset = 1;
2746
2747 PSENDX (SIM, update_req);
2748
2749 if(sms_data->inst == INST_MO)
2750 tl_set_access_fifo (ACCESS_BY_MMI);
2751 else
2752 tl_set_access_fifo (ACCESS_BY_NET);
2753
2754 sim_update = TRUE;
2755 }
2756 }
2757 if (!(sms_data->mem_cap_avail = avail))
2758 {
2759 /*
2760 * RP_ERROR =>
2761 */
2762 rl_report_req_error (SMS_RP_CS_MEM_CAP_EXCEEDED, NULL);
2763 /*
2764 * RL_RELEASE_REQ ==>
2765 */
2766 rl_release_req(SMS_INST.ti);
2767 /*
2768 * no memory
2769 */
2770 }
2771
2772 /* inform the ACI about SIM-full/avail via SMS error indication */
2773 tl_mnsms_error_ind(avail ? SMS_CAUSE_MEM_AVAIL : SMS_CAUSE_MEM_FULL);
2774
2775 return sim_update;
2776 }
2777
2778 /*
2779 +--------------------------------------------------------------------+
2780 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2781 | STATE : code ROUTINE : tl_sms_memo_pause |
2782 +--------------------------------------------------------------------+
2783
2784 PURPOSE : used for <<user intiated memory full condition>> (by the
2785 MNSMS_PAUSE_REQ).
2786 - update sim notification flag (if not done already)
2787 - send RP-ERROR (MEM_CAPAPCITY_EXCEEDED) to network
2788 - release connection
2789 */
2790
2791 GLOBAL void tl_sms_memo_pause (void)
2792 {
2793 GET_INSTANCE_DATA;
2794 UBYTE sim_acc_ix;
2795 TRACE_FUNCTION ("tl_sms_memo_pause()");
2796
2797 /*
2798 * generate RP_ERROR(MEM_CAP_EXCEEDED)
2799 */
2800 rl_report_req_error (SMS_RP_CS_MEM_CAP_EXCEEDED,
2801 NULL);
2802 /*
2803 * RL_RELEASE_REQ ==>
2804 */
2805 rl_release_req(SMS_INST.ti);
2806 /*
2807 * update sim notification flag if necessary
2808 */
2809 if(sms_data->pr_cntrl.mem_full_sent EQ FALSE)
2810 {
2811 sms_data->pr_cntrl.mem_full_sent = TRUE;
2812
2813 if (sms_data->sim_phase >= 2)
2814 {
2815 if (tl_sms_reserve_req_id(&sim_acc_ix))
2816 {
2817 PALLOC (update_req, SIM_UPDATE_REQ);
2818 update_req->req_id = sim_acc_ix;
2819 update_req->v_path_info = FALSE;
2820 update_req->source = SRC_SMS;
2821 update_req->datafield =
2822 sms_data->sms_sim_access_info[sim_acc_ix].datafield = SIM_SMSS;
2823 update_req->length = 1;
2824 update_req->trans_data[0] = 0xFE; /* Notification Flag = TRUE */
2825 update_req->offset = 1;
2826 PSENDX (SIM, update_req);
2827 if(sms_data->inst == INST_MO)
2828 tl_set_access_fifo (ACCESS_BY_MMI);
2829 else
2830 tl_set_access_fifo (ACCESS_BY_NET);
2831 }
2832
2833 }
2834 }
2835 }
2836
2837 /*
2838 +--------------------------------------------------------------------+
2839 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2840 | STATE : code ROUTINE : tl_sms_memo_resume |
2841 +--------------------------------------------------------------------+
2842
2843 PURPOSE : used for release of <<user intiated memory full condition>>
2844 (by the MNSMS_RESUME_REQ).
2845 - update sim notification flag (set to false)
2846 */
2847
2848 GLOBAL void tl_sms_memo_resume (void)
2849 {
2850
2851 TRACE_FUNCTION ("tl_sms_memo_resume()");
2852
2853 /* Implements Measure# 14 */
2854 tl_send_sim_update_req(0xFF, 1);
2855 }
2856
2857
2858 /*
2859 +--------------------------------------------------------------------+
2860 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2861 | STATE : code ROUTINE : tl_mnsms_report_ind |
2862 +--------------------------------------------------------------------+
2863
2864 PURPOSE : Processing the function TL_MNSMS_REPORT_IND.
2865
2866 */
2867
2868 GLOBAL void tl_mnsms_report_ind (UBYTE ent_state)
2869 {
2870 PALLOC (report_ind, MNSMS_REPORT_IND);
2871
2872 report_ind->state = ent_state;
2873
2874 /*
2875 * Disable the v_cmms_mode flag as we are not sending current value of the
2876 * mode value for CMMS operation.
2877 */
2878
2879 report_ind->v_cmms_mode = FALSE;
2880
2881 PSENDX (MMI, report_ind);
2882 }
2883
2884 /*
2885 +--------------------------------------------------------------------+
2886 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2887 | STATE : code ROUTINE : tl_pause |
2888 +--------------------------------------------------------------------+
2889
2890 PURPOSE : execute sms delivery pause
2891
2892 DESCRIPTION: set marker for pause so that the next incoming sms
2893 will be responded with RP_ERROR (Cause: Memory
2894 Capacity Exceeded).
2895 */
2896 GLOBAL void tl_pause (void)
2897 {
2898 GET_INSTANCE_DATA;
2899 TRACE_FUNCTION ("tl_pause()");
2900
2901 if (sms_data->pr_cntrl.delivery_state NEQ SMS_DELIVER_STATUS_PAUSE)
2902 {
2903 sms_data->pr_cntrl.delivery_state = SMS_DELIVER_STATUS_PAUSE;
2904 sms_data->pr_cntrl.mem_full_sent = FALSE;
2905 }
2906 }
2907
2908 /*
2909 +--------------------------------------------------------------------+
2910 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2911 | STATE : code ROUTINE : tl_resume |
2912 +--------------------------------------------------------------------+
2913
2914 PURPOSE : execute sms delivery resumption
2915
2916 DESCRIPTION: reset marker for pause and initiate the sending of
2917 memory available message (SMMA) to network
2918 to indicate that we can receive sms again.
2919 */
2920 GLOBAL void tl_resume (void)
2921 {
2922 GET_INSTANCE_DATA;
2923 TRACE_FUNCTION ("tl_resume()");
2924
2925 if ( sms_data->pr_cntrl.delivery_state != SMS_DELIVER_STATUS_PAUSE )
2926 {
2927 tl_mnsms_resume_cnf(SMS_NO_ERROR);
2928 return;
2929 }
2930
2931 if ( sms_data->pr_cntrl.mem_full_sent == FALSE )
2932 {
2933 sms_data->pr_cntrl.delivery_state = SMS_DELIVER_STATUS_RESUME;
2934 tl_mnsms_resume_cnf(SMS_NO_ERROR);
2935 return;
2936 }
2937
2938 if (GET_STATE (STATE_MMI) NEQ MMI_IDLE)
2939 {
2940 TRACE_ERROR("Unable to process resume request");
2941 tl_mnsms_resume_cnf(SMS_CAUSE_ENTITY_BUSY);
2942 return;
2943 }
2944
2945 GET_MO_INSTANCE(sms_data);
2946 /*
2947 * TL state transition TL_ESTABLISH
2948 * EST state transition EST_SMMA
2949 * MMI state transition MMI_RESUME
2950 *
2951 */
2952 SET_STATE (STATE_MMI, MMI_RESUME);
2953 SET_STATE (STATE_EST, EST_SMMA);
2954 SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH);
2955 /*
2956 * 1st shot
2957 */
2958 SMS_INST.retrans = FALSE;
2959 /*
2960 * establish connection
2961 */
2962 tl_establish_connection(FALSE);
2963 }
2964
2965 /*
2966 +--------------------------------------------------------------------+
2967 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2968 | STATE : code ROUTINE : tl_query_deliver_status |
2969 +--------------------------------------------------------------------+
2970
2971 PURPOSE : handle sms status query for deliver state
2972
2973 */
2974 GLOBAL void tl_query_deliver_status (void)
2975 {
2976 GET_INSTANCE_DATA;
2977 TRACE_FUNCTION ("tl_query_deliver_status()");
2978
2979 tl_mnsms_query_cnf(SMS_QUERY_DELIVER_STATUS,sms_data->pr_cntrl.delivery_state);
2980 }
2981
2982 /*
2983 +--------------------------------------------------------------------+
2984 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
2985 | STATE : code ROUTINE : tl_concat_check |
2986 +--------------------------------------------------------------------+
2987
2988 PURPOSE : check for concatenated sms
2989
2990 */
2991 GLOBAL BOOL tl_concat_check ( T_sms_sdu *sms_sdu)
2992 {
2993 BYTE ccd_result;
2994 T_SIM_PDU *sim_pdu;
2995 T_TP_SUBMIT *submit;
2996 T_SMS_PDU_IE_HDR *ie_hdr;
2997 T_SMS_PDU_CONCAT_8BIT_HDR *concat_8_hdr;
2998 /* T_SMS_PDU_CONCAT_16BIT_HDR *concat_16_hdr; */
2999 T_SMS_CONCAT_HDR *concat_hdr = NULL;
3000
3001 MALLOC (sim_pdu, sizeof(*sim_pdu));
3002 MALLOC (submit, sizeof(*submit));
3003
3004 //CCD_START;
3005 /*
3006 * CCD: SMS SDU -> SIM PDU
3007 */
3008 ccd_result = ccd_decodeMsg (CCDENT_SMS,
3009 BOTH,
3010 (T_MSGBUF *)sms_sdu,
3011 (UBYTE *)sim_pdu,
3012 SMS_VT_SIM_PDU);
3013 if (ccd_result NEQ ccdOK)
3014 {
3015 /*
3016 * error understanding the sdu
3017 */
3018 TRACE_ERROR ("ccd error decoding sim pdu");
3019 /*
3020 * give up
3021 */
3022 // CCD_END;
3023 MFREE (sim_pdu);
3024 MFREE (submit);
3025 return FALSE;
3026 }
3027 if (sim_pdu->tp_mti NEQ SMS_SUBMIT)
3028 {
3029 /*
3030 * error understanding the sdu
3031 */
3032 TRACE_ERROR ("error not a <submit> in sim pdu");
3033 /*
3034 * give up
3035 */
3036 // CCD_END;
3037 MFREE (sim_pdu);
3038 MFREE (submit);
3039 return FALSE;
3040 }
3041 /*
3042 * CCD: SIM PDU -> SUBMIT
3043 */
3044 ccd_result = ccd_decodeMsg (CCDENT_SMS,
3045 UPLINK,
3046 (T_MSGBUF *)&sim_pdu->tpdu,
3047 (UBYTE *)submit,
3048 SMS_VT_SUBMIT);
3049 if (ccd_result NEQ ccdOK)
3050 {
3051 /*
3052 * error understanding the sdu
3053 */
3054 TRACE_ERROR ("ccd error decoding submit");
3055 //TISH, patch for ASTec32699,OMAPS00135322
3056 //start
3057 if (ccd_result NEQ ccdWarning)
3058 {
3059 /*
3060 * give up
3061 */
3062 // CCD_END;
3063 MFREE (sim_pdu);
3064 MFREE (submit);
3065 return FALSE;
3066 }
3067 //end
3068 }
3069 if (submit->tp_udhi EQ SMS_UDHI_INCLUDED)
3070 {
3071 TRACE_EVENT("UDH INCLUDED");
3072
3073 ie_hdr = (T_SMS_PDU_IE_HDR *)((UBYTE *)&submit->tp_udh_inc.tp_udh.data[0]);
3074
3075 if (ie_hdr->iei EQ 0x00 ) /* SMS_IEI_CONC_8BIT */
3076 {
3077 /*
3078 * Concatenation header for 8 bit ref nr
3079 */
3080 concat_8_hdr = (T_SMS_PDU_CONCAT_8BIT_HDR *)
3081 ((UBYTE *)&submit->tp_udh_inc.tp_udh.data[2]);
3082 TRACE_EVENT_P3("Concatenated: Ref %#x Seq %u Of %u",
3083 concat_8_hdr->ref_nr,
3084 concat_8_hdr->seq_nr,
3085 concat_8_hdr->max_nr);
3086 /*
3087 * safe contents of header in common header structure
3088 */
3089 MALLOC (concat_hdr, sizeof(*concat_hdr));
3090 concat_hdr->ref_nr = concat_8_hdr->ref_nr;
3091 concat_hdr->seq_nr = concat_8_hdr->seq_nr;
3092 concat_hdr->max_nr = concat_8_hdr->max_nr;
3093 }
3094 else
3095 {
3096 TRACE_ERROR ("could not find concat header");
3097 }
3098 }
3099 // CCD_END;
3100 /*
3101 * concat control
3102 */
3103 tl_concat_cntrl(concat_hdr);
3104 /*
3105 * clean up
3106 */
3107 if (concat_hdr)
3108 MFREE(concat_hdr);
3109 MFREE (sim_pdu);
3110 MFREE (submit);
3111 return TRUE;
3112 }
3113
3114 /*
3115 +--------------------------------------------------------------------+
3116 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
3117 | STATE : code ROUTINE : tl_concat_cntrl |
3118 +--------------------------------------------------------------------+
3119
3120 PURPOSE : control of concatenated sms
3121
3122 */
3123 GLOBAL void tl_concat_cntrl (
3124 T_SMS_CONCAT_HDR *concat_hdr /* may be NULL */)
3125 {
3126 GET_INSTANCE_DATA;
3127 if (sms_data->concat_cntrl.concatenation EQ FALSE)
3128 {
3129 /*
3130 * Concatenation currently not active
3131 */
3132 if (concat_hdr EQ NULL)
3133 {
3134 /*
3135 * nothing to be done
3136 */
3137 return;
3138 }
3139 else
3140 {
3141 if ((concat_hdr->seq_nr EQ 1) AND
3142 (concat_hdr->seq_nr < concat_hdr->max_nr))
3143 {
3144 /*
3145 * begin of concatenation series
3146 */
3147 TRACE_EVENT("concatenation series begin");
3148 sms_data->concat_cntrl.concatenation = TRUE;
3149 sms_data->concat_cntrl.release_pending = FALSE;
3150 sms_data->concat_cntrl.nr = *concat_hdr;
3151 }
3152 else
3153 {
3154 TRACE_ERROR("concatenation series implausible nr");
3155 }
3156 }
3157 }
3158 else
3159 {
3160 /*
3161 * Concatenation currently active
3162 */
3163 if (concat_hdr EQ NULL)
3164 {
3165 TRACE_ERROR("concatenation series ends unexpected");
3166 sms_data->concat_cntrl.release_pending = TRUE;
3167 sms_data->concat_cntrl.end = TRUE;
3168 }
3169 else if ((concat_hdr->seq_nr == concat_hdr->max_nr) AND
3170 (concat_hdr->seq_nr EQ sms_data->concat_cntrl.nr.seq_nr+1))
3171 {
3172 TRACE_EVENT("concatenation series end");
3173 sms_data->concat_cntrl.release_pending = TRUE;
3174 sms_data->concat_cntrl.end = TRUE;
3175 sms_data->concat_cntrl.nr = *concat_hdr;
3176 }
3177 else if (concat_hdr->seq_nr EQ sms_data->concat_cntrl.nr.seq_nr+1)
3178 {
3179 /*
3180 * plausible
3181 */
3182 TRACE_EVENT("concatenation series continued");
3183 sms_data->concat_cntrl.release_pending = TRUE;
3184 sms_data->concat_cntrl.end = FALSE;
3185 sms_data->concat_cntrl.nr = *concat_hdr;
3186 }
3187 else
3188 {
3189 TRACE_ERROR("concatenation series implausible nr");
3190 sms_data->concat_cntrl.release_pending = TRUE;
3191 sms_data->concat_cntrl.end = TRUE;
3192 sms_data->concat_cntrl.nr = *concat_hdr;
3193 }
3194 }
3195 }
3196
3197 /*
3198 +--------------------------------------------------------------------+
3199 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
3200 | STATE : code ROUTINE : tl_check_class_2 |
3201 +--------------------------------------------------------------------+
3202
3203 PURPOSE : Checks whether the data coding scheme is class 2.
3204
3205 */
3206
3207 #ifdef SIM_TOOLKIT
3208 GLOBAL UBYTE tl_check_class_2 (UBYTE dcs)
3209 {
3210 TRACE_FUNCTION ("tl_class_check()");
3211
3212 /*
3213 * check 00x1xx10
3214 */
3215 if ((dcs & 0xD3) EQ 0x12)
3216 return TRUE;
3217
3218 /*
3219 * check 1111xx10
3220 */
3221 if ((dcs & 0xF3) EQ 0xF2)
3222 return TRUE;
3223
3224 return FALSE;
3225 }
3226
3227 /*
3228 +--------------------------------------------------------------------+
3229 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
3230 | STATE : code ROUTINE : tl_build_envelope_sms_download |
3231 +--------------------------------------------------------------------+
3232
3233 PURPOSE : Builds an envelope command to the SIM card for SMS
3234 download.
3235
3236 */
3237
3238 GLOBAL BOOL tl_build_envelope_sms_download (T_rp_data_dl *rp_data_dl)
3239 {
3240 GET_INSTANCE_DATA;
3241 int ber_len, tpdu_len;
3242 int start_addr, start_tpdu;
3243 T_stk_cmd *stk_cmd;
3244 UBYTE *env;
3245
3246 MCAST (sim_pdu, SIM_PDU);
3247 PALLOC (sim_toolkit_req, SIM_TOOLKIT_REQ);
3248
3249 TRACE_FUNCTION ("tl_build_envelope_sms_download()");
3250
3251 if (rp_data_dl EQ NULL)
3252 {
3253 PFREE (sim_toolkit_req);
3254 return FALSE;
3255 }
3256 /*
3257 * make SIM PDU
3258 */
3259 sim_pdu->rp_addr = rp_data_dl->rp_addr;
3260 sim_pdu->tpdu = rp_data_dl->rp_user_data.tpdu;
3261 sim_pdu->tp_mti = SMS_DELIVER;
3262 sim_pdu->v_tpdu = TRUE;
3263 sim_pdu->tp_vt_mti = SMS_VT_SIM_PDU;
3264
3265 MALLOC (stk_cmd, sizeof(T_stk_cmd));
3266 stk_cmd->o_cmd = 0;
3267 stk_cmd->l_cmd = MAX_STK_CMD<<3;
3268
3269 ccd_codeMsg (CCDENT_SMS, DOWNLINK,
3270 (T_MSGBUF *)stk_cmd,
3271 (UBYTE *)sim_pdu, SMS_VT_SIM_PDU);
3272 /*
3273 * calculate variable length items of ENVELOPE
3274 */
3275 ber_len = 4; /* length of TLV device id */
3276 /*
3277 * find RP-ADDR (Service Centre) in SIM_PDU
3278 */
3279 start_addr = (int)stk_cmd->o_cmd >> 3;
3280 /* position of RP-ADDR length */
3281 ber_len += (int)stk_cmd->cmd[start_addr] + 2;
3282 /* add length of TLV address */
3283 /*
3284 * find TPDU in SIM PDU
3285 */
3286 start_tpdu = start_addr + (int)stk_cmd->cmd[start_addr] + 1;
3287 /* skip RP-Orig Address */
3288 tpdu_len = ((int)stk_cmd->l_cmd >> 3) - start_tpdu;
3289 /* length of RP-User-Data */
3290
3291 ber_len += tpdu_len + 2; /* add length of TLV SMS-TPDU */
3292 if (tpdu_len >= 128) /* 2 byte length coding required? */
3293 ber_len++; /* adjust */
3294 /*
3295 * prepare the primitive
3296 */
3297 sim_toolkit_req -> source = SRC_SMS;
3298 sim_toolkit_req -> req_id = 0;
3299
3300 sim_toolkit_req -> stk_cmd.o_cmd = 0;
3301 /*
3302 * BER-TLV Envelope SMS-PP Download
3303 */
3304 env = sim_toolkit_req -> stk_cmd.cmd;
3305 *env++ = 0xD1;
3306 if (ber_len >= 128) /* 2 byte length coding required */
3307 {
3308 *env++ = 0x81;
3309 sim_toolkit_req -> stk_cmd.l_cmd = (USHORT)((ber_len + 3) << 3);
3310 }
3311 else
3312 sim_toolkit_req -> stk_cmd.l_cmd = (USHORT)((ber_len + 2) << 3);
3313 *env++ = (UBYTE)ber_len;
3314 /*
3315 * TLV Device Identities
3316 */
3317 *env++ = 0x82; /* Tag */
3318 *env++ = 2; /* Length */
3319 *env++ = 0x83; /* Source Network */
3320 *env++ = 0x81; /* Destination SIM */
3321 /*
3322 * TLV Address
3323 */
3324 *env++ = 0x06; /* address tag, optional */
3325 memcpy (env, &stk_cmd->cmd[start_addr], /* copy length and content of RP-Orig Address */
3326 stk_cmd->cmd[start_addr] + 1);
3327 env += stk_cmd->cmd[start_addr] + 1; /* tag plus content */
3328 /*
3329 * env now points to the tag of the TLV SMS-TPDU
3330 */
3331 *env++ = 0x8B; /* SMS TPDU tag, mandatory */
3332 if (tpdu_len >= 128)
3333 *env++ = 0x81;
3334 *env++ = (UBYTE)tpdu_len;
3335 memcpy (env, &stk_cmd->cmd[start_tpdu], /* copy content of TPDU */
3336 tpdu_len);
3337 /*
3338 * Send to SIM card
3339 */
3340 PSENDX (SIM, sim_toolkit_req);
3341 MFREE (stk_cmd);
3342 /*
3343 * Set instance to assign answer from SIM card.
3344 */
3345 tl_set_access_fifo (ACCESS_BY_NET);
3346 SET_STATE (STATE_NET, NET_WRITE);
3347
3348 return TRUE;
3349 }
3350
3351
3352 /*
3353 +--------------------------------------------------------------------+
3354 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
3355 | STATE : code ROUTINE : tl_sim_toolkit_confirm |
3356 +--------------------------------------------------------------------+
3357
3358 PURPOSE : Getting the terminal response to a SMS - Download.
3359
3360 */
3361
3362 GLOBAL void tl_sim_toolkit_confirm (T_SIM_TOOLKIT_CNF *toolkit_cnf)
3363 {
3364 GET_INSTANCE_DATA;
3365 T_rp_user_data *rp_ud;
3366 union {
3367 T_TP_DLVR_REP_ACK *ack;
3368 T_TP_DLVR_REP_ERR *err;
3369 } dlvr_rep;
3370
3371 TRACE_FUNCTION ("tl_sim_toolkit_confirm()");
3372
3373 CCD_START;
3374
3375 switch (toolkit_cnf->cause)
3376 {
3377 case SIM_NO_ERROR:
3378 /*
3379 * The SIM responds with "90 00", the ME shall acknowledge the receipt
3380 * of the short message to the network using an RP-ACK message.
3381 *
3382 * or
3383 *
3384 * The SIM responds with "9F XX", the ME shall use the GET RESPONSE
3385 * command to the response data. The response data will be supplied by
3386 * the ME in the TP-User-Data Element of the RP-ACK message. It will be
3387 * send back to the network. The values of protocol identifier and data
3388 * coding scheme in RP-ACK shall be as in the original message.
3389 */
3390 {
3391 if (toolkit_cnf->stk_cmd.l_cmd > 0)
3392 {
3393 MALLOC (rp_ud, sizeof(T_rp_user_data));
3394 MALLOC (dlvr_rep.ack, sizeof(T_TP_DLVR_REP_ACK));
3395
3396 dlvr_rep.ack->tp_vt_mti = SMS_VT_DLVR_REP_ACK;
3397 dlvr_rep.ack->tp_udhi = SMS_UDHI_NOT_INCLUDED;
3398 dlvr_rep.ack->tp_mti = SMS_DELIVER_REPORT;
3399 dlvr_rep.ack->v_tp_udh_inc = FALSE;
3400 memcpy (dlvr_rep.ack->tp_ud.data,
3401 &toolkit_cnf->stk_cmd.cmd[toolkit_cnf->stk_cmd.o_cmd >> 3],
3402 (size_t)(toolkit_cnf->stk_cmd.l_cmd >> 3));
3403 dlvr_rep.ack->tp_ud.c_data = (UBYTE)(toolkit_cnf->stk_cmd.l_cmd >> 3);
3404 dlvr_rep.ack->tp_ud.length = (tl_udl_count_septet (SMS_DCS(sms_data)))?
3405 (UBYTE)(dlvr_rep.ack->tp_ud.c_data * 8 / 7):
3406 dlvr_rep.ack->tp_ud.c_data;
3407 dlvr_rep.ack->tp_ext = SMS_EXT_NOT_INCLUDED;
3408 dlvr_rep.ack->v_tp_ud = TRUE;
3409 dlvr_rep.ack->tp_udl_p = SMS_UD_INCLUDED;
3410 dlvr_rep.ack->tp_dcs = SMS_DCS(sms_data);
3411 dlvr_rep.ack->v_tp_dcs = TRUE;
3412 dlvr_rep.ack->tp_dcs_p = SMS_DCS_INCLUDED;
3413 dlvr_rep.ack->tp_pid = SMS_PID(sms_data);
3414 dlvr_rep.ack->v_tp_pid = TRUE;
3415 dlvr_rep.ack->tp_pid_p = SMS_PID_INCLUDED;
3416
3417 rp_ud->tpdu.o_tpdu = 0;
3418 rp_ud->tpdu.l_tpdu = TPDU_BIT_LEN;
3419 rp_ud->v_tpdu = (ccd_codeMsg (CCDENT_SMS, UPLINK,
3420 (T_MSGBUF *)&rp_ud->tpdu,
3421 (UBYTE *)dlvr_rep.ack,
3422 SMS_VT_DLVR_REP_ACK) EQ ccdOK);
3423 rp_ud->tp_mti = SMS_DELIVER_REPORT;
3424 MFREE (dlvr_rep.ack);
3425 }
3426 else
3427 rp_ud = NULL;
3428
3429 rl_report_req_ack (rp_ud);
3430 SET_STATE (STATE_NET, NET_IDLE);
3431
3432 SMS_EM_RECEIVE_SIM_TOOLKIT_DATA_DOWNLOAD;
3433
3434 if (rp_ud NEQ NULL)
3435 {
3436 MFREE (rp_ud);
3437 }
3438 }
3439 break;
3440
3441 case SIM_CAUSE_SAT_BUSY:
3442 /*
3443 * The SIM responds with "93 00", the ME shall either retry the command or
3444 * send back an RP-ERROR message to the network with the TP-FCS value
3445 * indicating "SIM Application Toolkit Busy).
3446 */
3447 {
3448 MALLOC (rp_ud, sizeof(T_rp_user_data));
3449
3450 rp_ud->tpdu.l_tpdu = 40; /* 5 bytes */
3451 rp_ud->tpdu.o_tpdu = 0;
3452
3453 rp_ud->tpdu.b_tpdu[0] = SMS_DELIVER_REPORT; /* MTI, no UDHI */
3454 rp_ud->tpdu.b_tpdu[1] = SMS_FCS_SAT_BUSY; /* SAT busy */
3455 rp_ud->tpdu.b_tpdu[2] = 0x03; /* PI: DCS and PID will follow, no UD */
3456 rp_ud->tpdu.b_tpdu[3] = SMS_PID(sms_data); /* set PID */
3457 rp_ud->tpdu.b_tpdu[4] = SMS_DCS(sms_data); /* set DCS */
3458
3459 rp_ud->tp_mti = SMS_DELIVER_REPORT;
3460 rp_ud->v_tpdu = TRUE;
3461
3462 /*
3463 * RP_ERROR
3464 */
3465 rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, rp_ud);
3466 /*
3467 * RL_RELEASE_REQ ==>
3468 */
3469 rl_release_req(SMS_INST.ti);
3470 SET_STATE (STATE_NET, NET_IDLE);
3471
3472 MFREE (rp_ud);
3473 }
3474 break;
3475
3476 case SIM_CAUSE_DNL_ERROR:
3477 /*
3478 * The ME has indicated in TERMINAL PROFILE that it supports the status
3479 * word "9E XX" and if the SIM responds with "9E XX", the ME shall use
3480 * the GET RESPONSE command to get the response data. The response data
3481 * from the SIM will be supplied by the ME in the TP-User data element
3482 * of the RP-ERROR message. It will be sent back to the network. The
3483 * values of protocol identifier and data coding scheme in RP-ERROR
3484 * shall be as in the original message. The value of TP-FCS element
3485 * of the RP-ERROR shall be "SIM data download error".
3486 */
3487 {
3488 MALLOC (rp_ud, sizeof(T_rp_user_data));
3489 MALLOC (dlvr_rep.err, sizeof(T_TP_DLVR_REP_ERR));
3490
3491 dlvr_rep.err->tp_vt_mti = SMS_VT_DLVR_REP_ERR;
3492 dlvr_rep.err->tp_udhi = SMS_UDHI_NOT_INCLUDED;
3493 dlvr_rep.err->tp_mti = SMS_DELIVER_REPORT;
3494 dlvr_rep.err->tp_fcs = SMS_FCS_SAT_DNL_ERROR;
3495 dlvr_rep.err->v_tp_udh_inc = FALSE;
3496 memcpy (dlvr_rep.err->tp_ud.data,
3497 &toolkit_cnf->stk_cmd.cmd[toolkit_cnf->stk_cmd.o_cmd >> 3],
3498 (size_t)(toolkit_cnf->stk_cmd.l_cmd >> 3));
3499 dlvr_rep.err->tp_ud.c_data = (UBYTE)(toolkit_cnf->stk_cmd.l_cmd >> 3);
3500 dlvr_rep.err->tp_ud.length = (tl_udl_count_septet (SMS_DCS(sms_data)))?
3501 (UBYTE)(dlvr_rep.err->tp_ud.c_data * 8 / 7):
3502 dlvr_rep.err->tp_ud.c_data;
3503 dlvr_rep.err->tp_ext = SMS_EXT_NOT_INCLUDED;
3504 dlvr_rep.err->v_tp_ud = TRUE;
3505 dlvr_rep.err->tp_udl_p = SMS_UD_INCLUDED;
3506 dlvr_rep.err->tp_dcs = SMS_DCS(sms_data);
3507 dlvr_rep.err->v_tp_dcs = TRUE;
3508 dlvr_rep.err->tp_dcs_p = SMS_DCS_INCLUDED;
3509 dlvr_rep.err->tp_pid = SMS_PID(sms_data);
3510 dlvr_rep.err->v_tp_pid = TRUE;
3511 dlvr_rep.err->tp_pid_p = SMS_PID_INCLUDED;
3512
3513 rp_ud->tpdu.o_tpdu = 0;
3514 rp_ud->tpdu.l_tpdu = TPDU_BIT_LEN;
3515 rp_ud->v_tpdu = (ccd_codeMsg (CCDENT_SMS, UPLINK,
3516 (T_MSGBUF *)&rp_ud->tpdu,
3517 (UBYTE *)dlvr_rep.err,
3518 SMS_VT_DLVR_REP_ERR) EQ ccdOK);
3519 rp_ud->tp_mti = SMS_DELIVER_REPORT;
3520 MFREE (dlvr_rep.err);
3521
3522 /*
3523 * RP_ERROR
3524 */
3525 rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, rp_ud);
3526 /*
3527 * RL_RELEASE_REQ ==>
3528 */
3529 rl_release_req(SMS_INST.ti);
3530 SET_STATE (STATE_NET, NET_IDLE);
3531 MFREE (rp_ud);
3532 }
3533 break;
3534
3535 default:
3536 break;
3537 }
3538 CCD_END;
3539 }
3540 #endif
3541
3542 /*
3543 +--------------------------------------------------------------------+
3544 | PROJECT : GSM-PS (8410) MODULE : SMS_TLF |
3545 | STATE : code ROUTINE : tl_cmms_start |
3546 +--------------------------------------------------------------------+
3547
3548 PURPOSE : Function used for starting the Timer TMMS and continuing
3549 the CMMS mode.
3550
3551 */
3552
3553 GLOBAL void tl_cmms_start(void)
3554 {
3555 TRACE_FUNCTION ("tl_cmms_start()");
3556
3557 if(sms_timer_check(TMMS))
3558 {
3559 sms_timer_stop(TMMS);
3560 }
3561 sms_timer_start(TMMS);
3562 }
3563
3564
3565 #endif