comparison g23m-gsm/sms/sms_tlf.c @ 0:75a11d740a02

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