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

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