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

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children 85a26478b7de
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-F&D (8411)
4 | Modul : SMS_FOR
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 formatter
18 | of the component SMS.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef SMS_FOR_C
23 #define SMS_FOR_C
24
25 #define ENTITY_SMS
26
27 /*==== INCLUDES ===================================================*/
28
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stddef.h>
32 #include "typedefs.h"
33 #include "pcm.h"
34 #include "vsi.h"
35 #include "custom.h"
36 #include "gsm.h"
37 #include "message.h"
38 #include "ccdapi.h"
39 #include "prim.h"
40 #include "cus_sms.h"
41 #include "cnf_sms.h"
42 #include "mon_sms.h"
43 #include "pei.h"
44 #include "tok.h"
45 #include "sms.h"
46 #include "sms_em.h"
47
48 /*==== EXPORT ======================================================*/
49
50 /*==== PRIVAT ======================================================*/
51
52 /*==== VARIABLES ===================================================*/
53
54 #if !defined (SHARED_CCD_BUF)
55 GLOBAL UBYTE _decodedMsg [MAX_MSTRUCT_LEN_SMS];
56 #else
57 GLOBAL UBYTE * _decodedMsg;
58 GLOBAL UBYTE _CCDbuf = FALSE;
59 #endif
60
61 /*==== FUNCTIONS ===================================================*/
62
63 /*
64 +--------------------------------------------------------------------+
65 | PROJECT : GSM-PS (8410) MODULE : SMS_FOR |
66 | STATE : code ROUTINE : for_init_sms |
67 +--------------------------------------------------------------------+
68
69 PURPOSE : Initialize the formatter (void)
70 */
71
72 GLOBAL void for_init_sms (void)
73 {
74 // TRACE_FUNCTION ("for_init_sms()");
75 }
76
77 /*
78 +--------------------------------------------------------------------+
79 | PROJECT : GSM-PS (8410) MODULE : SMS_FOR |
80 | STATE : code ROUTINE : for_get_pd_ti |
81 +--------------------------------------------------------------------+
82
83 PURPOSE : Get protocol discriminator and transaction identifier if
84 the incoming message is of sufficient length to contain
85 anythiny useful, this means at least PD, TI and message type.
86 */
87
88 LOCAL BOOL for_get_pd_ti (T_sdu *p_sdu, UBYTE *p_pd, UBYTE *p_ti)
89 {
90 if (p_sdu->l_buf >= 16)
91 {
92 *p_pd = p_sdu->buf[p_sdu->o_buf >> 3] & 0x0F;
93 *p_ti = p_sdu->buf[p_sdu->o_buf >> 3] >> 4;
94 *p_ti ^= 0x8;
95
96 p_sdu->o_buf += BSIZE_TI_PD;
97 p_sdu->l_buf -= BSIZE_TI_PD;
98
99 return TRUE;
100 }
101 TRACE_EVENT ("message too short");
102 return FALSE;
103 }
104
105 /*
106 +--------------------------------------------------------------------+
107 | PROJECT : GSM-PS (8410) MODULE : SMS_FOR |
108 | STATE : code ROUTINE : for_get_new_mt_instance |
109 +--------------------------------------------------------------------+
110
111 PURPOSE : This function gets a new MT instance. Basically the same
112 is done here as in GET_NEW_SMS_INSTANCE(), but additionally
113 the special case that the CP-Layer of an old MT transaction
114 waits for the last CP-ACK before the MMSMS_RELEASE_REQ is
115 sent is handled.
116
117 */
118
119 LOCAL T_SMS_DATA * for_get_new_mt_instance (UBYTE ti)
120 {
121 GET_INSTANCE_DATA;
122
123 TRACE_FUNCTION ("for_get_new_mt_instance()");
124
125 /*
126 * Check here whether we are awaiting the last CP-ACK for a MT transaction.
127 * If so, take the new MT message as implicit CP-ACK.
128 */
129 if (sms_data NEQ NULL) /*lint !e774 (sms_data NEQ NULL) always */
130 {
131 if (sms_data->data[INST_MT].ti NEQ 0)
132 {
133 /* Old MT instance still exists */
134 sms_data->inst = INST_MT;
135 switch (SMS_INST_GET_STATE (STATE_CP))
136 {
137 case CP_WAIT_FOR_ACK:
138 #ifdef GPRS
139 case CP_GSMS_MT_WAIT_FOR_CP_ACK:
140 #endif
141 if (SMS_INST.r_flag)
142 {
143 /*
144 * No further message for the old MT instance expected. Take the
145 * MMSMS_ESTABLISH_IND as implicit CP-ACK for the old instance.
146 */
147 TRACE_EVENT ("Implicit CP-ACK");
148 cp_data_ind_cp_ack ();
149 }
150 break;
151
152 default:
153 break; /* Do nothing */
154 }
155 }
156 }
157
158 sms_data = GET_NEW_SMS_INSTANCE(ti);
159
160 return sms_data;
161 }
162
163 /*
164 +--------------------------------------------------------------------+
165 | PROJECT : GSM-PS (8410) MODULE : SMS_FOR |
166 | STATE : code ROUTINE : for_ccd_rp_error_send |
167 +--------------------------------------------------------------------+
168
169 PURPOSE : Perform CCD Error check and send rp errors
170
171 */
172
173 LOCAL BOOL for_ccd_rp_error_send (T_D_CP_DATA *cp_data,
174 T_SMS_DATA *sms_data, UBYTE rp_error)
175 {
176 BOOL rp_error_send = FALSE;
177
178 MCAST (cp_data1, U_CP_DATA);
179
180 if((SMS_INST_GET_STATE (STATE_CP)) EQ CP_MM_CONNECTION_ESTABLISHED)
181 {
182 rp_error_send = TRUE;
183 rl_build_rp_error (cp_data->cp_user_data_dl.reference,
184 rp_error,cp_data1, NULL);
185 SMS_EM_SEND_RP_ERROR;
186 cp_data_req (cp_data1);
187 cp_send_release_req (SMS_INST.ti);
188
189 FREE_SMS_INSTANCE (SMS_INST.ti);
190 }
191 return rp_error_send;
192 }
193
194 /*
195 +--------------------------------------------------------------------+
196 | PROJECT : GSM-PS (8410) MODULE : SMS_FOR |
197 | STATE : code ROUTINE : for_ccd_error_check |
198 +--------------------------------------------------------------------+
199
200 PURPOSE : Perform CCD Error check and returns errors
201
202 */
203
204 LOCAL BOOL for_ccd_error_check (UBYTE *_decodedMsg,T_sdu *buf_sdu,
205 T_SMS_DATA *sms_data,UBYTE ti)
206 {
207 ULONG ccd_err = ERR_NO_MORE_ERROR;
208 T_CCD_ERR_ENTRY *ccd_err_entry;
209 UBYTE p_sdu;
210 UBYTE cp_error_cause = 0;
211 UBYTE length = 0;
212 BOOL cp_error_send = FALSE;
213 BOOL rp_error_send = FALSE;
214
215
216 ccd_err_entry = malloc(sizeof(T_CCD_ERR_ENTRY));
217 if(ccd_err_entry EQ NULL)
218 {
219 TRACE_EVENT("for_ccd_error_check(): MALLOC returned NULL");
220 return FALSE;
221 }
222 memset(ccd_err_entry,0, sizeof(ccd_err_entry));
223
224 /* Message offset value */
225 p_sdu = (buf_sdu->o_buf/8) - 1;
226
227 ccd_err = ccd_getFirstFault(&ccd_err_entry);
228 do
229 {
230 /*
231 * Need to set these values everytime we go through fault list of ccd
232 */
233 cp_error_send = FALSE;
234 rp_error_send = FALSE;
235 /*lint -e415 Likely access of out-of-bounds pointer*/
236 switch(ccd_err)
237 {
238 case ERR_ELEM_LEN: /* ignore message & send STATUS #96 */
239 /*
240 * This ccd error will come when there is any error in IE length.
241 * If cp user data length is greater than 249 Octets then this error
242 * is because CP Message IE, so send CP-ERROR
243 * if cp user data length is less than 249, then this ccd error is
244 * because of rp IE length, so RP-ERROR
245 */
246 switch(_decodedMsg[0])
247 {
248 case D_CP_DATA:
249 length = buf_sdu->buf[p_sdu+2];
250
251 /*
252 * If CP User data length is more than 249 then CCD error is because
253 * of CP Message IE else it will be becasue of RP message IE
254 * Send error accordingly
255 */
256 if(length < MAX_LEN_CP_USER_DATA)
257 {
258 rp_error_send = for_ccd_rp_error_send((T_D_CP_DATA *)_decodedMsg,
259 sms_data,
260 SMS_RP_CS_INV_MAND_INFO);
261 }
262 if(rp_error_send EQ FALSE)
263 {
264 cp_error_send = TRUE;
265 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
266 }
267 break;
268 /*
269 * If Message is CP-ACK or CP-ERROR then this ccd error is due to CP
270 * no need to differentiate between RP and CP, These two messages are
271 * intended for CP Layer, So send CP-ERROR
272 */
273 case B_CP_ACK:
274 case B_CP_ERROR:
275 /* This flag will become FALSE, in case there is CCD warning, so make it
276 * TRUE till we get CCD Error, especially this will happen in default case
277 */
278 cp_error_send = TRUE;
279 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
280 break;
281 }
282 break;
283
284 case ERR_COMPREH_REQUIRED: /* ignore message & send STATUS #96 */
285 /*
286 * This error will come when Comprehension bit required set is having error in
287 * IE.Comprehension bits can be set inside only CP-DATA message
288 * for RP-ERROR or RP-ACK
289 */
290 if(_decodedMsg[0] EQ D_CP_DATA)
291 {
292 /*
293 * Comprehension bit error is in RP_ERROR or RP_ACK after RP Cause element
294 */
295 rp_error_send = for_ccd_rp_error_send((T_D_CP_DATA *)_decodedMsg,
296 sms_data,
297 SMS_RP_CS_INV_MAND_INFO);
298 if(rp_error_send EQ FALSE)
299 {
300 cp_error_send = TRUE;
301 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
302 }
303 }
304 break;
305
306 case ERR_MAND_ELEM_MISS: /* ignore message & send STATUS #96 */
307 /* See bit postions to check whether it is CP or RP Error */
308 /*
309 * Checking whether this error is in CP message element or RP
310 * message element. This is required to check because both CP and RP
311 * Layer decoding is done inside same CCD function
312 */
313 /* This is for CP Message decoding error - in Length*/
314 length = (buf_sdu->l_buf/8);
315 switch(buf_sdu->buf[1])
316 {
317 case D_CP_DATA:
318 /* Evaluate length of Mandatory CP-DATA/CP-ERROR message */
319 if(length < MIN_CP_LEN)
320 {
321 cp_error_send = TRUE;
322 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
323 }
324 else
325 {
326 cp_error_send = FALSE;
327 }
328 break;
329
330 case B_CP_ERROR:/* This will not have RP DATA, so no need to check for RP */
331 /* Evaluate length of Mandatory CP-DATA/CP-ERROR message */
332 if(length < MIN_CP_LEN)
333 {
334 cp_error_send = TRUE;
335 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
336 }
337 break;
338
339 case B_CP_ACK:/* This will not have RP DATA, so no need to check for RP */
340 if(length < MIN_CP_ACK_LEN)
341 {
342 cp_error_send = TRUE;
343 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
344 }
345 break;
346
347 default:
348 cp_error_send = TRUE;
349 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
350 break;
351 }
352 break;
353
354 case ERR_INVALID_MID: /* ignore message & send STATUS #97 */
355 /*
356 * Checking whether this error is in CP message element or RP
357 * message element. This is required to check because both CP and RP
358 * Layer decoding is done inside same CCD function
359 */
360 /* See bit postions to check whether it is CP or RP Error */
361 /* This is for CP Message decoding error - in Length*/
362 if ((buf_sdu->buf[1] NEQ D_CP_DATA)||(buf_sdu->buf[1] NEQ B_CP_ACK)
363 ||(buf_sdu->buf[1] NEQ B_CP_ERROR))
364 {
365 cp_error_send = TRUE;
366 cp_error_cause = SMS_CP_CS_MSG_TYPE_NON_EXIST;
367 }
368 else
369 /* Let RP Layer Handle This ccd error, eventually RP Layer will
370 * send RP-ERROR
371 */
372 /* This is for RP Message decoding error - in Length*/
373 cp_error_send = FALSE;
374 break;
375
376 case ERR_MSG_LEN: /* ignore message & send STATUS #96 */
377 /* Send CP-ERROR, some problem with Message Length, whole message is garbled */
378 cp_error_send = TRUE;
379 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
380 break;
381
382 case ERR_LEN_MISMATCH: /* ignore message & send STATUS #96 */
383 /* Send CP-ERROR, some problem with Message Length, whole message is garbled */
384 cp_error_send = TRUE;
385 cp_error_cause = SMS_CP_CS_INV_MAND_INFO;
386 break;
387 default:
388 TRACE_EVENT_P1 ("Unexpected warnings/errors = %u", ccd_err);
389 /*
390 *Default warnings pass it to RP Layer, decoding at TP will take care of it
391 */
392 cp_error_send = FALSE;
393 break;
394 }
395 /*lint +e415 Likely access of out-of-bounds pointer*/
396 ccd_err = ccd_getNextFault(&ccd_err_entry);
397 }while(ccd_err != ERR_NO_MORE_ERROR);
398
399 if(cp_error_send)
400 {
401 cp_build_cp_error (cp_error_cause);
402 /*
403 * Check if the cmms_mode is enabled or not
404 * If enabled dont release the MM connection
405 */
406
407 if(!CMMS_ACTIVE)
408 {
409 cp_send_release_req (ti);
410 SMS_INST_SET_STATE (STATE_CP, CP_IDLE);
411 SMS_INST.r_flag = FALSE;
412 }
413 else
414 {
415 sms_data->cmms_release_pending = TRUE;
416 }
417
418 rl_error_ind (CAUSE_MAKE(DEFBY_STD, ORIGSIDE_MS,
419 SMSCP_ORIGINATING_ENTITY, cp_error_cause));
420
421
422 FREE_SMS_INSTANCE (ti);
423 }
424 /* These flags return value will decide whether to pass to rp layer further */
425 return (!rp_error_send && !cp_error_send);
426 }
427
428
429 /*---- PRIMITIVES --------------------------------------------------*/
430
431 /*
432 +--------------------------------------------------------------------+
433 | PROJECT : GSM-PS (8410) MODULE : SMS_FOR |
434 | STATE : code ROUTINE : for_mmsms_establish_ind |
435 +--------------------------------------------------------------------+
436
437 PURPOSE : Processing the primitive MMSMS_ESTABLISH_IND
438
439 */
440
441 GLOBAL void for_mmsms_establish_ind (T_MMSMS_ESTABLISH_IND *mmsms_establish_ind)
442 {
443 UBYTE ti;
444 UBYTE pd;
445 CHAR *msg_type;
446 BOOL pass_to_rp = TRUE;
447
448
449 /* Enable the PCO to correctly decode the message */
450 PPASS (mmsms_establish_ind, establish_ind, MMSMS_ESTABLISH_IND);
451
452 TRACE_FUNCTION ("for_mmsms_establish_ind()");
453
454 if (for_get_pd_ti (&establish_ind->sdu, &pd, &ti))
455 {
456 if ((ti & 0x8) AND (pd EQ PD_SMS))
457 {
458 register T_SMS_DATA *sms_data = for_get_new_mt_instance (ti);
459
460 TRACE_EVENT_P1 ("TI %u", ti);
461
462 if (sms_data)
463 {
464 #if defined (GPRS)
465 SMS_INST.downlink = SMS_DOWNLINK_MMSMS;
466 #endif
467
468 SMS_INST.cp_ack_pending = FALSE;
469
470 CCD_START;
471
472 if(ccd_decodeMsg (CCDENT_SMS,
473 DOWNLINK,
474 (T_MSGBUF *) &establish_ind->sdu,
475 (UBYTE *)_decodedMsg,
476 NOT_PRESENT_8BIT) EQ ccdError)
477 {
478 pass_to_rp = for_ccd_error_check(_decodedMsg,&establish_ind->sdu,sms_data,ti);
479 }
480
481 if(pass_to_rp)
482 {
483 switch (_decodedMsg[0])
484 {
485 case D_CP_DATA:
486 cp_est_ind_cp_data ((T_D_CP_DATA *)_decodedMsg);
487 msg_type = "D_CP_DATA";
488
489 SMS_EM_RECEIVE_CP_DATA;
490
491 break;
492
493 case B_CP_ERROR:
494 {
495 MCAST (error, B_CP_ERROR);
496
497 cp_est_ind_cp_error (error->cp_cause);
498 msg_type = "B_CP_ERROR";
499
500 SMS_EM_RECEIVE_CP_ERROR;
501
502 break;
503 }
504
505 case B_CP_ACK:
506 cp_est_ind_cp_ack ();
507 msg_type = "B_CP_ACK";
508 SMS_EM_RECEIVE_CP_ACKNOWLEDGE;
509
510 break;
511
512 default:
513 cp_est_ind_cp_unknown ();
514 msg_type = "UNKNOWN_MESSAGE";
515
516 SMS_EM_RECEIVE_UNKNOWN;
517
518 break;
519 }
520 TRACE_BINDUMP(sms_handle,
521 TC_USER4,
522 msg_type,
523 (&(establish_ind->sdu.buf[0]) + ((establish_ind->sdu.o_buf >> 3) -1)),
524 ((establish_ind->sdu.l_buf >> 3) + 1));
525 }
526 CCD_END;
527 }
528 else
529 {
530 /*
531 * no further instance available
532 */
533 CCD_START;
534
535 ccd_decodeMsg (CCDENT_SMS,
536 DOWNLINK,
537 (T_MSGBUF *) &establish_ind->sdu,
538 (UBYTE *) _decodedMsg,
539 NOT_PRESENT_8BIT);
540
541 switch (_decodedMsg[0])
542 {
543 case D_CP_DATA:
544 {
545 MCAST (d_cp_data, D_CP_DATA);
546 MCAST (cp_data, U_CP_DATA);
547 /*
548 * U_CP_DATA contains a maximum of 252 Bytes
549 */
550 PALLOC_SDU (data_req, MMSMS_DATA_REQ, LEN_U_CP_DATA);
551
552 data_req->sdu.o_buf = ENCODE_OFFSET;
553
554 rl_build_rp_error (d_cp_data->cp_user_data_dl.reference,
555 SMS_RP_CS_PROTOCOL_ERROR,
556 cp_data, NULL);
557
558 cp_data->msg_type = U_CP_DATA;
559
560 ccd_codeMsg (CCDENT_SMS,
561 UPLINK,
562 (T_MSGBUF *)&data_req->sdu,
563 (UBYTE *)cp_data,
564 NOT_PRESENT_8BIT);
565
566 cp_add_pd_ti (ti, &data_req->sdu);
567
568 TRACE_BINDUMP(sms_handle,
569 TC_USER4,
570 "U_CP_DATA",
571 (&(data_req->sdu.buf[0]) + ((data_req->sdu.o_buf >> 3) -1)),
572 ((data_req->sdu.l_buf >> 3) + 1));
573 PSENDX (MM, data_req);
574 break;
575 }
576 default:
577 TRACE_EVENT_P1 ("Unexpected Message = %u", _decodedMsg[0]);
578 break;
579 }
580 CCD_END;
581 {
582 PALLOC (release_req, MMSMS_RELEASE_REQ);
583
584 release_req->ti = ti;
585 PSENDX (MM, release_req);
586 }
587 SMS_EM_UNKNOWN_TRANSACTION;
588 }
589 }
590 else
591 {
592 TRACE_EVENT_P2 ("TI or PD wrong, PD=%d, TI=%d", pd, ti);
593 }
594 }
595 PFREE (establish_ind);
596 }
597
598 /*
599 +--------------------------------------------------------------------+
600 | PROJECT : GSM-PS (8410) MODULE : SMS_FOR |
601 | STATE : code ROUTINE : for_mmsms_data_ind |
602 +--------------------------------------------------------------------+
603
604 PURPOSE : Processing the primitive MMSMS_DATA_IND
605
606 */
607
608 GLOBAL void for_mmsms_data_ind (T_MMSMS_DATA_IND *mmsms_data_ind)
609 {
610 UBYTE ti;
611 UBYTE pd;
612 CHAR *msg_type;
613 BOOL pass_to_rp = TRUE;
614
615
616 /* Enable the PCO to correctly decode the message */
617 PPASS (mmsms_data_ind, data_ind, MMSMS_DATA_IND);
618
619 if (for_get_pd_ti (&data_ind->sdu, &pd, &ti))
620 {
621 TRACE_FUNCTION_P1 ("for_mmsms_data_ind(TI=%u)", ti);
622
623 if (/*((! ti) OR (ti >= 8)) AND*/ (pd EQ PD_SMS))
624 {
625 register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(ti);
626
627 if (sms_data)
628 {
629 CCD_START;
630
631 if(ccd_decodeMsg (CCDENT_SMS,
632 DOWNLINK,
633 (T_MSGBUF *) &data_ind->sdu,
634 (UBYTE *)_decodedMsg,
635 NOT_PRESENT_8BIT) EQ ccdError)
636 {
637 pass_to_rp = for_ccd_error_check(_decodedMsg,&data_ind->sdu,sms_data,ti);
638 }
639
640 if(pass_to_rp)
641 {
642 switch (_decodedMsg[0])
643 {
644 case D_CP_DATA:
645 cp_data_ind_cp_data ((T_D_CP_DATA *)_decodedMsg);
646 msg_type = "D_CP_DATA";
647 break ;
648
649 case B_CP_ERROR:
650 {
651 MCAST (error, B_CP_ERROR);
652
653 cp_data_ind_cp_error (error->cp_cause);
654 msg_type = "B_CP_ERROR";
655 break ;
656 }
657
658 case B_CP_ACK:
659 cp_data_ind_cp_ack ();
660 msg_type = "B_CP_ACK";
661 break ;
662 default:
663 cp_data_ind_cp_unknown ();
664 msg_type = "UNKNOWN MESSAGE";
665 break ;
666 }
667 TRACE_BINDUMP(sms_handle,
668 TC_USER4,
669 msg_type,
670 (&(data_ind->sdu.buf[0]) + ((data_ind->sdu.o_buf >> 3) -1)),
671 ((data_ind->sdu.l_buf >> 3) + 1));
672 }
673 CCD_END;
674 }
675 }
676 else
677 {
678 TRACE_EVENT_P1 ("PD wrong, PD=%d", pd);
679 }
680 }
681 else
682 {
683 TRACE_ERROR("for_mmsms_data_ind() error evaluating PD TI");
684 }
685 PFREE (data_ind) ;
686 }
687
688 #if defined (GPRS)
689 /*
690 +--------------------------------------------------------------------+
691 | PROJECT : GSM-PS (8410) MODULE : SMS_CP |
692 | STATE : code ROUTINE : cp_ll_unitdata_ind |
693 +--------------------------------------------------------------------+
694
695 PURPOSE : Processing the signal LL_UNITDATA_IND (GSMS only).
696
697 */
698 GLOBAL void for_ll_unitdata_ind (T_LL_UNITDATA_IND *ll_unitdata_ind)
699 {
700
701 UBYTE ti;
702 UBYTE pd;
703 CHAR *msg_type;
704
705 T_SMS_DATA *sms_global = GET_INSTANCE(0);
706
707 /* Enable the PCO to correctly decode the message */
708 PPASS (ll_unitdata_ind, unitdata_ind, LL_UNITDATA_IND);
709
710 TRACE_FUNCTION ("for_ll_unitdata_ind()");
711
712 if (!(unitdata_ind->sapi EQ LL_SAPI_7))
713 {
714 TRACE_EVENT ("SAPI not LL_SAPI_7");
715 PFREE (unitdata_ind);
716 return;
717 }
718
719 if (sms_global) /*lint !e774 (sms_global) always */
720 {
721 if (SMS_SMS_FLOW(sms_global) NEQ SMS_FLOW_AVAILABLE)
722 {
723 TRACE_ERROR ("unexpected primitive");
724 }
725
726 /*
727 * data has been received, mark flow status as busy
728 */
729 SMS_SMS_FLOW(sms_global) = SMS_FLOW_BUSY;
730 }
731
732 if (for_get_pd_ti (&unitdata_ind->sdu, &pd, &ti))
733 {
734 if (/*((! ti) OR (ti >= 8)) AND*/ (pd EQ PD_SMS))
735 {
736 register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(ti);
737
738 if (sms_data)
739 {
740 CCD_START;
741
742 ccd_decodeMsg (CCDENT_SMS,
743 DOWNLINK,
744 (T_MSGBUF *) &unitdata_ind->sdu,
745 (UBYTE *) _decodedMsg,
746 NOT_PRESENT_8BIT);
747
748 switch (_decodedMsg[0])
749 {
750 case D_CP_DATA:
751 cp_data_ind_cp_data ((T_D_CP_DATA *)_decodedMsg);
752 msg_type = "D_CP_DATA";
753 break ;
754
755 case B_CP_ERROR:
756 {
757 MCAST (error, B_CP_ERROR);
758
759 cp_data_ind_cp_error (error->cp_cause);
760 msg_type = "B_CP_ERROR";
761 break ;
762 }
763
764 case B_CP_ACK:
765 cp_data_ind_cp_ack ();
766 msg_type = "B_CP_ACK";
767 break ;
768 default:
769 cp_data_ind_cp_unknown ();
770 msg_type = "UNKNOWN MESSAGE";
771 break ;
772 }
773 CCD_END;
774 TRACE_BINDUMP(sms_handle,
775 TC_USER4,
776 msg_type,
777 (&(unitdata_ind->sdu.buf[0]) + ((unitdata_ind->sdu.o_buf >> 3) -1)),
778 ((unitdata_ind->sdu.l_buf >> 3) + 1));
779 }
780 else
781 {
782 /*
783 * no SMS instance associated with pid, try to create new one
784 */
785 if (ti & 0x8)
786 {
787 register T_SMS_DATA *sms_data = for_get_new_mt_instance (ti);
788
789 if (sms_data)
790 {
791 CCD_START;
792
793 ccd_decodeMsg (CCDENT_SMS,
794 DOWNLINK,
795 (T_MSGBUF *) &unitdata_ind->sdu,
796 (UBYTE *) _decodedMsg,
797 NOT_PRESENT_8BIT);
798
799 SMS_INST_SET_STATE (STATE_CP, CP_GSMS_IDLE);
800 SMS_INST.downlink = SMS_DOWNLINK_LL;
801
802 switch (_decodedMsg[0])
803 {
804 case D_CP_DATA:
805 cp_data_ind_cp_data ((T_D_CP_DATA*) _decodedMsg);
806 msg_type = "D_CP_DATA";
807 break ;
808
809 case B_CP_ERROR:
810 {
811 MCAST (error, B_CP_ERROR);
812
813 cp_data_ind_cp_error (error->cp_cause);
814 msg_type = "B_CP_ERROR";
815 }
816 break ;
817
818 case B_CP_ACK:
819 cp_data_ind_cp_ack ();
820 msg_type = "B_CP_ACK";
821 break ;
822
823 default:
824 cp_data_ind_cp_unknown ();
825 msg_type = "UNKNOWN MESSAGE";
826 break ;
827 }
828 CCD_END;
829 TRACE_BINDUMP(sms_handle,
830 TC_USER4,
831 msg_type,
832 (&(unitdata_ind->sdu.buf[0]) + ((unitdata_ind->sdu.o_buf >> 3) -1)),
833 ((unitdata_ind->sdu.l_buf >> 3) + 1));
834 }
835 else
836 {
837 /*
838 * no further instance available, send rp error message
839 */
840 register T_SMS_DATA* sms_data_main = GET_INSTANCE(0);
841 CCD_START;
842
843 ccd_decodeMsg (CCDENT_SMS,
844 DOWNLINK,
845 (T_MSGBUF *) &unitdata_ind->sdu,
846 (UBYTE *) _decodedMsg,
847 NOT_PRESENT_8BIT);
848 if (sms_data_main) /*lint !e774 (sms_data_main) always */
849 {
850 if ((_decodedMsg[0] EQ D_CP_DATA) &&
851 (sms_data_main->llc_flow EQ SMS_LLC_AVAILABLE))
852 {
853 UBYTE msg_ref;
854
855 MCAST (d_cp_data, D_CP_DATA);
856 MCAST (cp_data, U_CP_DATA);
857 /*
858 * U_CP_DATA contains a maximum of 252 Bytes
859 */
860 PALLOC_SDU (unitdata_req, LL_UNITDATA_REQ, LEN_U_CP_DATA);
861
862 cp_init_ll_unitdata_req (unitdata_req);
863 msg_ref = d_cp_data->cp_user_data_dl.reference;
864
865 rl_build_rp_error_gprs (ti, unitdata_req, SMS_RP_CS_PROTOCOL_ERROR,
866 msg_ref, cp_data, NULL);
867 sms_data_main->llc_flow = SMS_LLC_BUSY;
868 TRACE_BINDUMP(sms_handle,
869 TC_USER4,
870 "U_CP_DATA",
871 (&(unitdata_req->sdu.buf[0]) + ((unitdata_req->sdu.o_buf >> 3) -1)),
872 ((unitdata_req->sdu.l_buf >> 3) + 1));
873 PSENDX (LLC, unitdata_req);
874 }
875 }
876 CCD_END;
877 }
878 }
879 else
880 {
881 TRACE_EVENT_P1 ("Unknown TI with response flag set, TI=%d", ti);
882 }
883 }
884 }
885 else
886 {
887 TRACE_EVENT_P1 ("PD wrong, PD=%d", pd);
888 }
889 }
890
891 PFREE (unitdata_ind);
892
893 /*
894 * Receive ready, if sending is not blocked
895 */
896 // if (SMS_LLC_FLOW(sms_global) NEQ SMS_LLC_BUSY_WAITING)
897 {
898 cp_send_getunitdata_req ();
899 }
900 }
901
902 /*
903 +--------------------------------------------------------------------+
904 | PROJECT : GSM-PS (8410) MODULE : SMS_CP |
905 | STATE : code ROUTINE : for_ll_unitready_ind |
906 +--------------------------------------------------------------------+
907
908 PURPOSE : Processing the signal LL_UNITREADY_IND (GSMS only).
909 */
910
911 GLOBAL void for_ll_unitready_ind (T_LL_UNITREADY_IND *unitready_ind)
912 {
913 GET_INSTANCE_DATA;
914
915 TRACE_FUNCTION ("ll_unitready_ind()");
916
917 if ((unitready_ind->sapi NEQ LL_SAPI_7) || !sms_data) /*lint !e774 (!sms_data) never */
918 {
919 TRACE_EVENT ("ll_unitready_ind(): SAPI not LL_SAPI_7 or no SMS instance");
920 PFREE (unitready_ind);
921 return;
922 }
923
924 if (SMS_LLC_FLOW(sms_data) EQ SMS_LLC_BUSY_WAITING)
925 {
926 /*
927 * find the message waiting for LLC
928 */
929 GET_MO_INSTANCE(sms_data);
930
931 if (SMS_INST_GET_STATE (STATE_CP) EQ CP_GSMS_IDLE)
932 {
933 switch (SMS_CP_ACK_TYPE(sms_data))
934 {
935 case SMS_CP_ACK:
936 cp_build_cp_ack ();
937 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY;
938
939 if (SMS_CP_UDL(sms_data) NEQ NULL)
940 {
941 rl_data_ind (SMS_CP_UDL(sms_data));
942 MFREE(SMS_CP_UDL(sms_data));
943 SMS_CP_UDL(sms_data) = NULL;
944 }
945 if (SMS_INST.r_flag)
946 {
947 /*
948 * terminate SMS instance
949 */
950 SMS_INST_SET_STATE (STATE_CP, CP_IDLE);
951 SMS_INST.r_flag = FALSE;
952 FREE_SMS_INSTANCE (SMS_INST.ti);
953 }
954 break;
955
956 case SMS_CP_ERROR:
957 cp_build_cp_error (SMS_CP_CAUSE(sms_data));
958 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY;
959 /*
960 * terminate SMS instance
961 */
962 SMS_INST_SET_STATE (STATE_CP, CP_IDLE);
963 SMS_INST.r_flag = FALSE;
964 FREE_SMS_INSTANCE (SMS_INST.ti);
965 break;
966
967 default:
968 SMS_LLC_FLOW(sms_data) = SMS_LLC_AVAILABLE;
969 break;
970 }
971 SMS_CP_ACK_TYPE(sms_data) = SMS_CP_NONE;
972 }
973 else
974 {
975 SMS_LLC_FLOW(sms_data) = SMS_LLC_AVAILABLE;
976 }
977 if (SMS_LLC_FLOW(sms_data) EQ SMS_LLC_AVAILABLE)
978 {
979 GET_MT_INSTANCE(sms_data);
980
981 switch (SMS_INST_GET_STATE (STATE_CP))
982 {
983 case CP_GSMS_IDLE:
984 case CP_GSMS_MT_WAIT_FOR_RP_ACK:
985 case CP_GSMS_MT_WAIT_FOR_CP_ACK:
986 switch (SMS_CP_ACK_TYPE(sms_data))
987 {
988 case SMS_CP_ACK:
989 cp_build_cp_ack ();
990 if (SMS_INST_GET_STATE (STATE_CP) EQ CP_GSMS_MT_WAIT_FOR_CP_ACK)
991 { /* stored CP-DATA will follow */
992 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY_WAITING;
993 }
994 else
995 {
996 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY;
997 }
998 break;
999
1000 case SMS_CP_ERROR:
1001 cp_build_cp_error (SMS_CP_CAUSE(sms_data));
1002 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY;
1003 /*
1004 * terminate SMS instance
1005 */
1006 SMS_INST_SET_STATE (STATE_CP, CP_IDLE);
1007 SMS_INST.r_flag = FALSE;
1008 FREE_SMS_INSTANCE (SMS_INST.ti);
1009 break;
1010
1011 default:
1012 if (SMS_INST_GET_STATE (STATE_CP) EQ CP_GSMS_MT_WAIT_FOR_CP_ACK
1013 AND SMS_DATA_REQ(sms_data) NEQ 0)
1014 {
1015 cp_send_data_gsms ();
1016 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY;
1017 }
1018 break;
1019
1020 }
1021 SMS_CP_ACK_TYPE(sms_data) = SMS_CP_NONE;
1022 break;
1023
1024 default:
1025 break;
1026 }
1027 }
1028 if (SMS_LLC_FLOW(sms_data) EQ SMS_LLC_AVAILABLE)
1029 {
1030 GET_MO_INSTANCE(sms_data);
1031
1032 switch (SMS_INST_GET_STATE (STATE_CP))
1033 {
1034 case CP_GSMS_MO_WAIT_FOR_CP_ACK:
1035 cp_send_data_gsms ();
1036
1037 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY;
1038 break;
1039
1040 case CP_GSMS_IDLE:
1041 cp_send_data_gsms ();
1042 rl_proceed ();
1043
1044 SMS_INST.r_flag = TRUE;
1045 SMS_INST_SET_STATE (STATE_CP, CP_GSMS_MO_WAIT_FOR_CP_ACK);
1046 SMS_LLC_FLOW(sms_data) = SMS_LLC_BUSY;
1047 break;
1048
1049 default:
1050 break;
1051 }
1052 }
1053 }
1054 else
1055 {
1056 SMS_LLC_FLOW(sms_data) = SMS_LLC_AVAILABLE;
1057 }
1058 PFREE (unitready_ind);
1059
1060 // cp_send_getunitdata_req (sms_data);
1061 }
1062
1063 #endif /* GPRS */
1064
1065 #endif /* #ifndef SMS_FOR_C */