comparison src/g23m-aci/aci/cmh_smf.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 :
4 | Modul :
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 module defines the functions used by the command
18 | handler for GPRS session management ( SM ).
19 +-----------------------------------------------------------------------------
20 */
21
22 #if defined (GPRS) && defined (DTI)
23
24 #ifndef CMH_SMF_C
25 #define CMH_SMF_C
26 #endif
27
28 #include "aci_all.h"
29 /*==== INCLUDES ===================================================*/
30 #include "gprs.h"
31
32 #include "dti.h" /* functionality of the dti library */
33 #include "aci_cmh.h"
34 #include "ati_cmd.h"
35 #include "aci_cmd.h"
36 #include "aci_lst.h"
37 #include "aci_mem.h"
38 #include "aci.h"
39
40 #include "dti_conn_mng.h"
41 #include "dti_cntrl_mng.h"
42
43 #include "gaci.h"
44 #include "gaci_cmh.h"
45 #include "psa.h"
46 #include "psa_gmm.h"
47 #include "psa_sm.h"
48 #include "psa_gppp.h"
49
50 #include "phb.h"
51 #include "cmh.h"
52 #include "cmh_gmm.h"
53
54 #include "cmh_sm.h"
55 #include "cmh_gppp.h"
56 #include "gaci_srcc.h"
57 #include "psa_cc.h"
58
59 #if defined (CO_UDP_IP) OR defined (FF_GPF_TCPIP)
60 #include "wap_aci.h"
61 #include "psa_tcpip.h"
62 #include "cmh_ipa.h"
63 #endif /* WAP OR FF_GPF_TCPIP OR SAT E */
64
65 #ifdef SIM_TOOLKIT
66 #include "psa_sat.h"
67 #include "cmh_sat.h"
68 #endif
69
70 #include "psa_sim.h"
71 #include "cmh_sim.h"
72
73 #include "cmh_sm.h"
74 /* temp needed because of use of ATI functions here: should eventually disappear */
75 #include "ati_int.h"
76
77 #ifdef FF_GPF_TCPIP
78 #include "dcm_utils.h"
79 #include "dcm_state.h"
80 #include "dcm_env.h"
81 #endif
82 #include "dcm_f.h"
83 #include "psa_uart.h"
84
85
86 /*==== CONSTANTS ==================================================*/
87
88 /*==== TYPES ======================================================*/
89 typedef struct
90 {
91 T_CGEREP_EVENT event;
92 T_CGEREP_EVENT_REP_PARAM parm;
93
94 } T_CGERP_EVENT_BUFFER;
95
96 typedef enum
97 {
98 T_CDS_IDLE,
99 T_CDS_RUNNING
100
101 } T_CONTEXTS_DEACTIVATION_STATUS;
102
103 typedef struct
104 {
105 T_CONTEXTS_DEACTIVATION_STATUS state;
106 USHORT nsapi_set;
107 T_ACI_CMD_SRC srcId;
108 U8 cid_set;
109
110 } T_CONTEXTS_DEACTIVATION_INFORMATION;
111
112 /*==== EXPORT =====================================================*/
113
114 /*==== VARIABLES ==================================================*/
115 static T_CGSMS_SERVICE m_service;
116 static T_CGERP_EVENT_BUFFER gprs_event_buffer[GPRS_EVENT_REPORTING_BUFFER_SIZE];
117 static SHORT gprs_eb_current_p, gprs_eb_oldest_p;
118 static BOOL m_mt_te_link;
119 static BOOL call_waits_in_table;
120 static T_CONTEXTS_DEACTIVATION_INFORMATION working_cgact_actions;
121 EXTERN T_PDP_CONTEXT_INTERNAL *p_pdp_context_list;
122 /*==== FUNCTIONS ==================================================*/
123
124 /*
125 * functions for ATA and ATH
126 */
127 static BOOL cmhSM_sAT_A_H_intern( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret, SHORT mode );
128
129
130 /*
131 +--------------------------------------------------------------------+
132 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
133 | STATE : finished ROUTINE : cmhSM_Init |
134 +--------------------------------------------------------------------+
135
136 PURPOSE : Fill variables for the own use with default values.
137 */
138 GLOBAL void cmhSM_Init (void)
139 {
140
141 UBYTE default_pco[] = {
142 0x80,0x80,0x21,0x10,0x01,0x01,0x00,0x10,0x81,0x06,
143 0x00,0x00,0x00,0x00,0x83,0x06,0x00,0x00,0x00,0x00
144 };
145
146 T_PDP_CONTEXT default_pdp_context = { "",
147 "",
148 NAS_is_ip_not_present,0,
149 PDP_CONTEXT_D_COMP_OMITTED,
150 PDP_CONTEXT_H_COMP_OMITTED,
151 PDP_CONTEXT_CID_OMITTED };
152
153
154 /* SM CMH global parameter */
155 smEntStat.curCmd = AT_CMD_NONE;
156 smEntStat.entOwn = CMD_SRC_NONE;
157
158 memset( &pdp_context_default, 0, sizeof(T_PDP_CONTEXT_INTERNAL) );
159
160 memset( work_cids, PDP_CONTEXT_CID_INVALID, sizeof(work_cids) );
161
162 pdp_context_default.ctrl_qos = PS_is_R97;
163 pdp_context_default.ctrl_min_qos = PS_is_min_qos_not_present;
164
165
166 //set default context values initial !
167 memcpy( &pdp_context_default.attributes, &default_pdp_context , sizeof(T_PDP_CONTEXT) );
168 strcpy( pdp_context_default.attributes.pdp_type, "IP" );
169
170 memcpy( &pdp_context_default.internal_data.user_pco.pco, &default_pco, sizeof( default_pco ) );
171 pdp_context_default.internal_data.user_pco.len = sizeof( default_pco );
172
173 /* GPRS event reporting */
174 memset( gprs_event_buffer, 0, sizeof(T_CGERP_EVENT_BUFFER) * GPRS_EVENT_REPORTING_BUFFER_SIZE );
175
176 gprs_eb_current_p = 0;
177 gprs_eb_oldest_p = 0;
178
179 cmhSM_empty_call_table();
180
181 /* used for network requested context reactivation */
182 call_waits_in_table = FALSE;
183
184 working_cgact_actions.state = T_CDS_IDLE;
185 working_cgact_actions.nsapi_set = 0;
186 working_cgact_actions.srcId = CMD_SRC_NONE;
187 working_cgact_actions.cid_set = 0;
188
189 m_mt_te_link = FALSE;
190 }
191
192 /*
193 +-------------------------------------------------------------------------+
194 | PROJECT : MODULE : CMH_SMF |
195 | STATE : ROUTINE : cmhSM_ResetNonWorkingContexts |
196 +-------------------------------------------------------------------------+
197
198 PURPOSE :
199 */
200 GLOBAL void cmhSM_ResetNonWorkingContexts( void )
201 {
202
203 UBYTE cid = 0;
204 T_PDP_CONTEXT_STATE pdp_context_state;
205 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
206 UBYTE k = 0;
207
208 UBYTE gprs_default_pco[] = {
209 0x80,0x80,0x21,0x10,0x01,0x01,0x00,0x10,0x81,0x06,
210 0x00,0x00,0x00,0x00,0x83,0x06,0x00,0x00,0x00,0x00
211 };
212
213 T_PDP_CONTEXT default_pdp_context = { "",
214 "",
215 NAS_is_ip_not_present,0,
216 PDP_CONTEXT_D_COMP_OMITTED,
217 PDP_CONTEXT_H_COMP_OMITTED,
218 PDP_CONTEXT_CID_OMITTED };
219
220 TRACE_FUNCTION("cmhSM_ResetNonWorkingContexts()");
221
222
223 /****************************************************************************
224 The reset of PDP contexts to factory setting of causes:
225 - Any defined context to be deactivated.
226 - The default context and QoS is set to initial values.
227 ***************************************************************************/
228
229 p_pdp_context_node = p_pdp_context_list;
230
231 while( p_pdp_context_node AND k < PDP_CONTEXT_CID_MAX )
232 {
233 cid = p_pdp_context_node->cid;
234 pdp_context_state = pdp_context_get_state_for_cid( cid );
235
236 if( pdp_context_state EQ PDP_CONTEXT_STATE_DEFINED )
237 {
238 if( !pdp_context_cid_used_by_other( cid ) )
239 {
240 pdp_context_remove_node( cid );
241 TRACE_EVENT("ATZ: UDEFINED the defined PDP Context");
242 }
243 else
244 {
245 TRACE_ERROR("PDP Context Not Found");
246 }
247 }
248 k++;
249 p_pdp_context_node = p_pdp_context_node->p_next;
250
251 }
252
253 TRACE_EVENT("ATZ: Command Initiated Restting all the Factory Defined Values");
254
255 /* set default context parameter */
256 memset( &pdp_context_default, 0, sizeof(T_PDP_CONTEXT_INTERNAL) );
257
258 memset( work_cids, PDP_CONTEXT_CID_INVALID, sizeof(work_cids) );
259 cid_pointer = 0;
260
261 //set default context values initial !
262 memcpy( &pdp_context_default.attributes, &default_pdp_context , sizeof(T_PDP_CONTEXT) );
263 strcpy( pdp_context_default.attributes.pdp_type, "IP" );
264
265 pdp_context_default.ctrl_qos = PS_is_R97;
266 pdp_context_default.ctrl_min_qos = (T_PS_ctrl_min_qos)PS_is_R97;
267
268 memcpy( &pdp_context_default.internal_data.user_pco.pco, &gprs_default_pco, sizeof( gprs_default_pco ) );
269 pdp_context_default.internal_data.user_pco.len = sizeof( gprs_default_pco );
270
271 /* mode of CGAUTO*/
272 automatic_response_mode = 3;
273
274 m_service = CGSMS_SERVICE_CS_PREFERRED;
275
276 /* GPRS event reporting */
277 sm_cgerep_mode = CGEREP_MODE_BUFFER;
278 sm_cgerep_bfr = CGEREP_BFR_CLEAR;
279 sm_cgsms_service = CGSMS_SERVICE_CS_PREFERRED;
280 }
281
282 GLOBAL void cmhSM_Reset( void )
283 {
284
285
286 /* SMF CMH local parameter */
287
288 memset( work_cids, PDP_CONTEXT_CID_INVALID, sizeof(work_cids) );
289
290 cid_pointer = 0;
291
292 /* set default context parameter */
293
294 /* mode of CGAUTO*/
295 automatic_response_mode = 3;
296
297 m_service = CGSMS_SERVICE_CS_PREFERRED;
298
299 /* GPRS event reporting */
300 sm_cgerep_mode = CGEREP_MODE_BUFFER;
301 sm_cgerep_bfr = CGEREP_BFR_CLEAR;
302 sm_cgsms_service = CGSMS_SERVICE_CS_PREFERRED;
303 sm_cgerep_srcId = (T_ACI_CMD_SRC)CMD_SRC_ATI;
304 }
305
306 /*
307 +--------------------------------------------------------------------+
308 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
309 | STATE : finished ROUTINE : cmhSM_empty_call_table |
310 +--------------------------------------------------------------------+
311
312 PURPOSE : Fill variables for the own use with default values.
313 */
314 GLOBAL void cmhSM_empty_call_table (void)
315 {
316 memset( gprs_call_table, 0, sizeof(T_GPRS_CALL_TABLE) *MAX_GPRS_CALL_TABLE_ENTRIES );
317 current_gprs_ct_index = 0;
318 gprs_ct_index = 0;
319 gprs_call_table[0].sm_ind.ti = UNDEFINED_TI;
320 }
321
322
323 /*
324 +-------------------------------------------------------------------------------+
325 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
326 | STATE : code ROUTINE : cmhSM_getSrcIdOfRunningCGACTDeactivation |
327 +-------------------------------------------------------------------------------+
328
329 PURPOSE : Returns a source ID if the given cid is requested to deactivate
330 by +CGACT. The source ID indicates where the +CGACT was started.
331 */
332 GLOBAL T_ACI_CMD_SRC cmhSM_getSrcIdOfRunningCGACTDeactivation(U8 cid)
333 {
334 if( ( 1 << cid ) & working_cgact_actions.cid_set )
335 {
336 return working_cgact_actions.srcId;
337 }
338 return CMD_SRC_NONE;
339 }
340
341 /*
342 +----------------------------------------------------------------------+
343 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
344 | STATE : code ROUTINE : cmhSM_connection_down |
345 +----------------------------------------------------------------------+
346
347 PURPOSE : Control the answer of context deactivations
348 started by an AT command.
349 */
350 GLOBAL void cmhSM_connection_down( UBYTE dti_id )
351 {
352 SHORT cid = gaci_get_cid_over_dti_id( dti_id );
353
354 TRACE_FUNCTION("cmhSM_connection_down");
355
356 switch( working_cgact_actions.state )
357 {
358 case T_CDS_RUNNING:
359 TRACE_EVENT_P1("T_CDS_RUNNING, nsapi:%d", CID_TO_NSAPI(cid));
360 if ( ( 1 << CID_TO_NSAPI(cid) ) & working_cgact_actions.nsapi_set )
361 { /* nsapi deactivation is requested */
362
363 working_cgact_actions.nsapi_set &= (USHORT) ~(1U << CID_TO_NSAPI(cid));
364 if ( ! working_cgact_actions.nsapi_set )
365 {
366 R_AT( RAT_OK, working_cgact_actions.srcId ) ( AT_CMD_CGACT );
367 working_cgact_actions.state = T_CDS_IDLE;
368 }
369 else
370 {
371 TRACE_EVENT_P1("NO OK: nsapi_set:%d",working_cgact_actions.nsapi_set);
372 }
373 }
374 else
375 {
376 TRACE_EVENT_P1("meets not the nsapi_set: %d",working_cgact_actions.nsapi_set);
377 }
378 break;
379 case T_CDS_IDLE:
380 TRACE_EVENT("T_CDS_IDLE");
381 break;
382 }
383 }
384
385 /*
386 +--------------------------------------------------------------------+
387 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
388 | STATE : finished ROUTINE : cmhSM_contextDeactivated |
389 +--------------------------------------------------------------------+
390
391 PURPOSE : Detach mobile if necessary? Only possible if all context are disconnected.
392 cmhSM_automatic_detach is called after SM is deactivated (either MS initiated or
393 network initiated)
394 */
395 GLOBAL void cmhSM_contextDeactivated ( void )
396 {
397
398 if( ! cmhSM_isContextActive() )
399 {
400 cmhGMM_allContextsDeactivated();
401 }
402 }
403
404 /*
405 +-------------------------------------------------------------------------------+
406 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
407 | STATE : code ROUTINE : isContextDeactivationRequestedByCGACT |
408 +-------------------------------------------------------------------------------+
409
410 PURPOSE : Returns TRUE if +CGACT is running on the given cid -> NO_CARRIER
411 FALSE if no CGACT was running on this cid -> CME_ERROR
412 */
413 GLOBAL BOOL isContextDeactivationRequestedByCGACT(SHORT cid)
414 {
415 TRACE_FUNCTION("***isContextDeactivationRequestedByCGACT");
416
417 switch( working_cgact_actions.state )
418 {
419 case T_CDS_RUNNING:
420 if ( (1 << (cid - 1)) & working_cgact_actions.cid_set )
421 {
422 return TRUE;
423 }
424 }
425 return FALSE;
426 }
427
428
429 /*
430 +--------------------------------------------------------------------+
431 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
432 | STATE : finished ROUTINE : cmhSM_Get_pdp_type |
433 +--------------------------------------------------------------------+
434
435 PURPOSE : Give the PDP type of the current PDP context that will build.
436 */
437 GLOBAL UBYTE cmhSM_Get_pdp_type( void )
438 {
439 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
440
441 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
442
443 if( p_pdp_context_node )
444 {
445 if( !strcmp( p_pdp_context_node->attributes.pdp_type, "PPP" ) )
446 return SMREG_PDP_PPP;
447 if( !strcmp( p_pdp_context_node->attributes.pdp_type, "IP") )
448 return SMREG_PDP_IPV4;
449 if( !strcmp( p_pdp_context_node->attributes.pdp_type, "IPV6") )
450 return SMREG_PDP_IPV6;
451
452 /* Otherwise return an empty pdp_type. */
453 return SMREG_PDP_EMPTY;
454 }
455
456 return 0;
457 }
458
459 /*
460 +--------------------------------------------------------------------+
461 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
462 | STATE : finished ROUTINE : cmhSM_Get_pdp_address |
463 +--------------------------------------------------------------------+
464
465 PURPOSE : Give the PDP address of the current PDP context that will build.
466 */
467 GLOBAL void cmhSM_Get_pdp_address ( T_NAS_ip_address *pdp_address, T_NAS_ctrl_ip_address * ctrl_ip_address )
468 {
469
470 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
471
472 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
473 if( p_pdp_context_node )
474 {
475 * ctrl_ip_address = p_pdp_context_node->attributes.pdp_addr.ctrl_ip_address;
476 if (p_pdp_context_node->attributes.pdp_addr.ctrl_ip_address EQ NAS_is_ipv4)
477 {
478 memcpy( &(pdp_address->ipv4_addr.a4), &p_pdp_context_node->attributes.pdp_addr.ip_address.ipv4_addr.a4, NAS_SIZE_IPv4_ADDR);
479 }
480 else if(p_pdp_context_node->attributes.pdp_addr.ctrl_ip_address EQ NAS_is_ipv6)
481 {
482 memcpy( &(pdp_address->ipv6_addr.a6), &p_pdp_context_node->attributes.pdp_addr.ip_address.ipv6_addr.a6, NAS_SIZE_IPv6_ADDR);
483 }
484 else
485 {
486 TRACE_EVENT("Dynamic IP Address");
487 }
488 }
489 else
490 {
491 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_Get_pdp_address" );
492 }
493
494 }
495
496 /*
497 +--------------------------------------------------------------------+
498 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
499 | STATE : finished ROUTINE : cmhSM_pdp_address_to_ip |
500 +--------------------------------------------------------------------+
501
502 PURPOSE : Transform a PDP address to 4 BYTE IP form.
503 */
504 GLOBAL UBYTE cmhSM_pdp_address_to_ip( T_PDP_TYPE pdp_type, T_NAS_ip *pdp_addr_str, U8 *pdp_addr )
505 {
506
507 UBYTE addr_len = 0;
508
509 switch( cmhSM_transform_pdp_type(pdp_type))
510 {
511 case PDP_T_IP:
512 addr_len = 4;
513 break;
514 case PDP_T_IPV6:
515 addr_len = 16;
516 break;
517 default:
518 addr_len = 0;
519 break;
520 }
521 if (addr_len)
522 {
523 memcpy(pdp_addr, pdp_addr_str, addr_len);
524 }
525 else
526 {
527 *pdp_addr = 0;
528 }
529
530 return addr_len;
531 }
532
533
534 /*
535 +-------------------------------------------------------------------+
536 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
537 | STATE : finished ROUTINE : convert_netaddr_to_apn |
538 +-------------------------------------------------------------------+
539
540 PURPOSE : converts a domain name into an APN
541
542 Technical Information:
543
544 The APN contains out of labels separated by dots.
545 (e.g. xxx.yyy.zzz)
546
547 This string representation must be translated to a network
548 representation.
549
550 The APN network representation contains out of a sequence of
551 a length field (not ASCII) followed by a ASCII string.
552
553 xxx.yyy.zzz => 3xxx3yyy3zzz
554 */
555
556 LOCAL void convert_netaddr_to_apn ( T_SMREG_apn *apn)
557 {
558 UBYTE counter = 0,
559 buffer = apn->apn_buf[0],
560 *pdest = apn->apn_buf + apn->c_apn_buf,
561 *psource = pdest - 1;
562
563 if(apn->c_apn_buf EQ 0)
564 {
565 return;
566 }
567
568 if(apn->c_apn_buf >= sizeof apn->apn_buf)
569 {
570 apn->c_apn_buf = 0;
571 TRACE_EVENT_P2 ("convert_netaddr_to_apn: array out of bounds exeption (%d >= %d)", apn->c_apn_buf, sizeof apn->apn_buf);
572 return;
573 }
574
575 /* The network representation is 1 byte longer. */
576 apn->c_apn_buf++;
577
578 /* A sentinel */
579 apn->apn_buf[0] = '.';
580
581 /* Algorithm: copy from back to front! */
582 while(pdest > apn->apn_buf )
583 {
584 counter = 0;
585 while(*psource NEQ '.')
586 {
587 *(pdest--) = *(psource--);
588 counter++;
589 }
590 *(pdest--) = counter;
591 psource--;
592 }
593
594 /* Correction according to the sentinel */
595
596 apn->apn_buf[1] = buffer;
597 apn->apn_buf[0] = ++counter;
598
599 /* Modify special empty APN to the need of SMREG_SAP */
600 if ((apn->c_apn_buf EQ 2) AND (apn->apn_buf[0] EQ 1) AND (apn->apn_buf[1] EQ 255))
601 {
602 apn->c_apn_buf = 1; /* Special SMREG_SAP indicating that there is an APN present but empty */
603 apn->apn_buf[0]= 0;
604 }
605 }
606 /*
607 +--------------------------------------------------------------------+
608 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
609 | STATE : finished ROUTINE : cmhSM_Get_smreg_apn |
610 +--------------------------------------------------------------------+
611
612 PURPOSE : Give the APN of the current PDP context that will build.
613 */
614 GLOBAL void cmhSM_Get_smreg_apn( T_SMREG_apn *smreg_apn )
615 {
616
617 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
618
619 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
620 if( p_pdp_context_node )
621 {
622 smreg_apn->c_apn_buf = strlen(p_pdp_context_node->attributes.pdp_apn);
623 strncpy((char *)smreg_apn->apn_buf, (const char *)p_pdp_context_node->attributes.pdp_apn, smreg_apn->c_apn_buf);
624 convert_netaddr_to_apn(smreg_apn);
625 }
626 else
627 {
628 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_Get_smreg_apn" );
629 }
630
631 #ifdef _SIMULATION_
632 memset( smreg_apn->apn_buf + smreg_apn->c_apn_buf, 0, sizeof(smreg_apn->apn_buf) - smreg_apn->c_apn_buf );
633 #endif
634 }
635
636 /*
637 +--------------------------------------------------------------------+
638 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
639 | STATE : finished ROUTINE : cmhSM_Get_h_comp |
640 +--------------------------------------------------------------------+
641
642 PURPOSE : Give the h_comp of the current PDP context that will build.
643 */
644 GLOBAL UBYTE cmhSM_Get_h_comp ( void )
645 {
646
647 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
648
649 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
650 if( p_pdp_context_node )
651 {
652 return (UBYTE) p_pdp_context_node->attributes.h_comp;
653 }
654
655 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_Get_h_comp" );
656 return 0;
657
658 }
659
660 /*
661 +--------------------------------------------------------------------+
662 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
663 | STATE : finished ROUTINE : cmhSM_Get_d_comp |
664 +--------------------------------------------------------------------+
665
666 PURPOSE : Give the d_comp of the current PDP context that will build.
667 */
668 GLOBAL UBYTE cmhSM_Get_d_comp( void )
669 {
670
671 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
672
673 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
674 if( p_pdp_context_node )
675 {
676 return (UBYTE) p_pdp_context_node->attributes.d_comp;
677 }
678
679 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_Get_d_comp" );
680 return 0;
681
682 }
683
684 /*
685 +--------------------------------------------------------------------+
686 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
687 | STATE : finished ROUTINE : cmhSM_change_def_QOS |
688 +--------------------------------------------------------------------+
689
690 PURPOSE : Set the quality of service (requested) of default context.
691
692 */
693 GLOBAL void cmhSM_change_def_QOS( T_PS_qos *qos, T_PS_ctrl_qos ctrl_qos )
694 {
695
696 pdp_context_default.ctrl_qos = ctrl_qos;
697
698 if(ctrl_qos EQ PS_is_R97) {
699 memcpy( &pdp_context_default.qos.qos_r97, &(qos->qos_r97), sizeof(T_PS_qos_r97) );
700 }
701 else {
702 memcpy( &pdp_context_default.qos.qos_r99, &(qos->qos_r99), sizeof(T_PS_qos_r99) );
703 }
704
705 }
706
707
708 /*
709 +--------------------------------------------------------------------+
710 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
711 | STATE : finished ROUTINE : cmhSM_change_def_QOS_min |
712 +--------------------------------------------------------------------+
713
714 PURPOSE : Set the quality of service (min.) of default context.
715
716 */
717 GLOBAL void cmhSM_change_def_QOS_min( T_PS_min_qos *qos, T_PS_ctrl_min_qos ctrl_min_qos )
718 {
719
720 pdp_context_default.ctrl_min_qos = ctrl_min_qos;
721
722 if(ctrl_min_qos EQ PS_is_min_R97) {
723 memcpy( &pdp_context_default.min_qos.qos_r97, &(qos->qos_r97), sizeof(T_PS_qos_r97) );
724 }
725 else {
726 memcpy( &pdp_context_default.min_qos.qos_r99, &(qos->qos_r99), sizeof(T_PS_qos_r99) );
727 }
728
729 }
730
731
732 /*
733 +--------------------------------------------------------------------+
734 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
735 | STATE : finished ROUTINE : cmhSM_Set_default_QOS |
736 +--------------------------------------------------------------------+
737
738 PURPOSE : Set the quality of service of the spezified PDP context
739 to default.
740 */
741 GLOBAL void cmhSM_Set_default_QOS( U8 cid )
742 {
743 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
744
745 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
746 if( p_pdp_context_node )
747 {
748 p_pdp_context_node->ctrl_qos = pdp_context_default.ctrl_qos;
749 memcpy( &p_pdp_context_node->qos, &pdp_context_default.qos, sizeof(T_PS_qos) );
750 }
751 else
752 {
753 TRACE_ERROR(" ERROR: PDP context not found, in function cmhSM_Set_default_QOS ");
754 }
755
756 }
757
758
759 /*
760 +--------------------------------------------------------------------+
761 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
762 | STATE : finished ROUTINE : cmhSM_Set_default_QOS |
763 +--------------------------------------------------------------------+
764
765 PURPOSE : Set the quality of service of the spezified PDP context
766 to default.
767 */
768 GLOBAL void cmhSM_Set_default_QOS_min ( U8 cid )
769 {
770 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
771
772 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
773 if( p_pdp_context_node )
774 {
775 p_pdp_context_node->ctrl_min_qos = pdp_context_default.ctrl_min_qos;
776 memcpy( &p_pdp_context_node->min_qos, &pdp_context_default.min_qos, sizeof(T_PS_min_qos) );
777 }
778 else
779 {
780 TRACE_ERROR(" ERROR: PDP context not found, in function cmhSM_Set_default_QOS_min");
781 }
782
783 }
784
785
786 /*
787 +--------------------------------------------------------------------+
788 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
789 | STATE : changed, smn ROUTINE : cmhSM_Get_QOS |
790 +--------------------------------------------------------------------+
791
792 PURPOSE : Give the requested quality of service of the current
793 PDP context that will build.
794 */
795 GLOBAL void cmhSM_Get_QOS( T_PS_qos *dest_qos )
796 {
797 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
798
799 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
800 if( p_pdp_context_node )
801 memcpy( dest_qos, &p_pdp_context_node->qos, sizeof(T_PS_qos) );
802 else
803 TRACE_ERROR( "ERROR: PDP context not found, in funciton cmhSM_Get_QOS" );
804
805 } /* End: cmhSM_Get_QOS */
806
807
808 /*
809 +--------------------------------------------------------------------+
810 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
811 | STATE : changed, smn ROUTINE : cmhSM_Get_QOS_min |
812 +--------------------------------------------------------------------+
813
814 PURPOSE : Give the minimum acceptable quality of service of the
815 current PDP context that will build.
816 */
817 GLOBAL void cmhSM_Get_QOS_min ( T_PS_min_qos *dest_qos_min )
818 {
819 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
820
821 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
822 if( p_pdp_context_node )
823 memcpy( dest_qos_min, &p_pdp_context_node->min_qos, sizeof(T_PS_min_qos) );
824 else
825 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_Get_QOS_min" );
826
827 } /* End: cmhSM_Get_QOS_min */
828
829
830
831 GLOBAL USHORT cmhSM_pdp_typ_to_string ( UBYTE pdp_typ_no, char* string )
832 {
833 switch ( pdp_typ_no )
834 {
835 case 0:
836 strcpy (string, "X_121");
837 return 5;
838 case 33:
839 strcpy (string, "IP_V_4");
840 return 6;
841 case 87:
842 strcpy (string, "IP_V_6");
843 return 6;
844 default:
845 strcpy (string, "");
846 return 0;
847 }
848 }
849
850 /*
851 +--------------------------------------------------------------------+
852 | PROJECT : MODULE : CMH_SMF |
853 | STATE : ROUTINE : cmhSM_pdp_type_to_string |
854 +--------------------------------------------------------------------+
855
856 PURPOSE :
857 */
858 GLOBAL SHORT cmhSM_pdp_type_to_string ( UBYTE pdp_type_no, char* string )
859 {
860 SHORT i;
861
862 switch ( pdp_type_no )
863 {
864 case 0:
865 strcpy (string, "X_121");
866 i = 5;
867 break;
868 case 33:
869 strcpy (string, "IP_V_4");
870 i = 6;
871 break;
872 case 87:
873 strcpy (string, "IP_V_6");
874 i = 6;
875 break;
876 default:
877 strcpy (string, "");
878 i = 0;
879 }
880
881 return i;
882 }
883
884
885 /*
886 +--------------------------------------------------------------------+
887 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
888 | STATE : finished ROUTINE : cmhSM_ring_gprs_par |
889 +--------------------------------------------------------------------+
890
891 PURPOSE : Return the information for CRING.
892 */
893 GLOBAL char* cmhSM_ring_gprs_par ( void )
894 {
895 static char string[MAX_CRING_INFORMATION_LENGTH] = "\"";
896 unsigned int i = 1;
897
898 i += cmhSM_pdp_typ_to_string(gprs_call_table[current_gprs_ct_index].sm_ind.pdp_type, string + i);
899 string[i++] = '\"';
900
901 string[i++] = ',';
902
903 string[i++] = '\"';
904 if (gprs_call_table[current_gprs_ct_index].sm_ind.ctrl_ip_address EQ NAS_is_ipv4)
905 {
906 memcpy (string + i, gprs_call_table[current_gprs_ct_index].sm_ind.ip_address.ipv4_addr.a4, NAS_SIZE_IPv4_ADDR);
907 i += NAS_SIZE_IPv4_ADDR + 1;
908 }
909 else
910 {
911 memcpy (string + i, gprs_call_table[current_gprs_ct_index].sm_ind.ip_address.ipv6_addr.a6, NAS_SIZE_IPv6_ADDR);
912 i += NAS_SIZE_IPv6_ADDR + 1;
913 }
914
915
916 string[i++] = '\"';
917
918 if ( *gprs_call_table[current_gprs_ct_index].L2P )
919 {
920 string[i++] = ',';
921
922 string[i++] = '\"';
923 strcpy (string + i, gprs_call_table[current_gprs_ct_index].L2P);
924 i += strlen (gprs_call_table[current_gprs_ct_index].L2P);
925 string[i++] = '\"';
926 }
927
928 string[i] = 0;
929
930 return string;
931 }
932
933 /*
934 +--------------------------------------------------------------------+
935 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
936 | STATE : finished ROUTINE : cmhSM_call_answer |
937 +--------------------------------------------------------------------+
938
939 PURPOSE : Return TRUE in this case, if an auto answer is needed.
940 */
941 GLOBAL BOOL cmhSM_call_answer ( UBYTE ring_counter, T_ACI_CRING_MOD mode )
942 {
943
944 switch(automatic_response_mode)
945 {
946 case 0: /* GPRS off, GSM controlled by S0 */
947 if( mode NEQ CRING_MOD_Gprs AND
948 at.S[0] AND
949 at.S[0] <= ring_counter )
950 return TRUE;
951 break;
952
953 case 1: /* GPRS on, GSM controlled by S0 */
954 if( mode EQ CRING_MOD_Gprs )
955 return TRUE;
956
957 if( at.S[0] AND
958 at.S[0] <= ring_counter )
959 return TRUE;
960 break;
961
962 case 2: /* modem copatibility mode, GPRS on, GSM off */
963 if ( mode NEQ CRING_MOD_Gprs )
964 break;
965
966 /*lint -fallthrough*/
967 /*lint -fallthrough*/
968 case 3: /* modem copatibility mode, GPRS on, GSM on */
969 if (at.S[0] AND ring_counter >= at.S[0])
970 return TRUE;
971 }
972
973 return FALSE;
974 }
975
976
977 /*
978 +--------------------------------------------------------------------+
979 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
980 | STATE : finished ROUTINE : cmhSM_call_reject |
981 +--------------------------------------------------------------------+
982
983 PURPOSE : Return TRUE in this case, if an auto reject is needed.
984 */
985 GLOBAL BOOL cmhSM_call_reject ( UBYTE ring_counter, T_ACI_CRING_MOD mode )
986 {
987 switch(automatic_response_mode)
988 {
989 case 0: /* GPRS off, GSM controlled by S0 */
990 return FALSE;
991 case 1: /* GPRS on, GSM controlled by S0 */
992 if (at.S99 AND mode EQ CRING_MOD_Gprs )
993 return TRUE;
994 break;
995 case 2: /* modem copatibility mode, GPRS on, GSM off */
996 case 3: /* modem copatibility mode, GPRS on, GSM on */
997 if ( mode NEQ CRING_MOD_Gprs )
998 break;
999 if (at.S99 AND ring_counter >= at.S99)
1000 return TRUE;
1001 }
1002
1003 return FALSE;
1004 }
1005
1006
1007
1008
1009 /*
1010 +--------------------------------------------------------------------+
1011 | PROJECT : MODULE : CMH_SMF |
1012 | STATE : ROUTINE : is_GSM_call_active |
1013 +--------------------------------------------------------------------+
1014
1015 PURPOSE :
1016 */
1017
1018 LOCAL BOOL is_GSM_call_active (void)
1019 {
1020 SHORT ctbIdx; /* holds call table index */
1021
1022 for( ctbIdx = 0; ctbIdx < MAX_CALL_NR; ctbIdx++ )
1023 {
1024 if (ccShrdPrm.ctb[ctbIdx] NEQ NULL)
1025 {
1026 return (TRUE);
1027 }
1028 }
1029
1030 return (FALSE);
1031 }
1032
1033 /*
1034 +--------------------------------------------------------------------+
1035 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
1036 | STATE : finished ROUTINE : cmhSM_sAT_H |
1037 +--------------------------------------------------------------------+
1038
1039 PURPOSE : handle GPRS calls and return FALSE if a circuit switched
1040 call need a handle.
1041 */
1042 GLOBAL BOOL cmhSM_sAT_H( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret )
1043 {
1044
1045 SHORT cid_array[1] = { PDP_CONTEXT_CID_INVALID };
1046 T_ATI_SRC_PARAMS *src_params = find_element (ati_src_list, (UBYTE)srcId, search_ati_src_id);
1047
1048 if ( ( at.rngPrms.isRng EQ TRUE ) AND ( at.rngPrms.mode EQ CRING_MOD_Gprs) )
1049 {
1050 /*
1051 * brz patch: In the case of context reactivation over SMREG_PDP_ACTIVATE_IND with an used ti
1052 * the GPRS ATH command doesn't do anything!
1053 *
1054 * Why? Because the Windows Dial-Up Networking client send every time an ATH after termination
1055 * of the connection and with this a context reactivation was impossible.
1056 */
1057 if ( gprs_call_table[current_gprs_ct_index].reactivation EQ GCTT_NORMAL )
1058 {
1059 return cmhSM_sAT_A_H_intern(srcId, aci_ret, 0);
1060 }
1061 return TRUE;
1062 }
1063 else
1064 {
1065 if (is_GSM_call_active())
1066 {
1067 return (FALSE);
1068 }
1069 /* if AT_H has been called and no RING is active, then disconnect the active
1070 context */
1071 #ifdef FF_GPF_TCPIP
1072 if(is_gpf_tcpip_call())
1073 {
1074 T_DCM_STATUS_IND_MSG err_ind_msg;
1075 err_ind_msg.hdr.msg_id = DCM_ERROR_IND_MSG;
1076 err_ind_msg.result = DCM_PS_CONN_BROKEN;
1077 dcm_send_message(err_ind_msg, DCM_SUB_NO_ACTION);
1078 }
1079 #endif
1080 *aci_ret = sAT_PlusCGACT ( srcId, CGACT_STATE_DEACTIVATED, cid_array );
1081
1082 switch (*aci_ret)
1083 {
1084 case (AT_CMPL): /*operation completed*/
1085 return FALSE; /* return false, so that GSM calls will be canceled */
1086
1087 case (AT_EXCT):
1088 src_params->curAtCmd = AT_CMD_CGACT;
1089 return TRUE;
1090
1091 default:
1092 cmdCmeError(CME_ERR_Unknown); /*Command failed*/
1093 return FALSE;
1094 }
1095 }
1096 }
1097
1098 /*
1099 +--------------------------------------------------------------------+
1100 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
1101 | STATE : finished ROUTINE : cmhSM_sAT_A |
1102 +--------------------------------------------------------------------+
1103
1104 PURPOSE : handle GPRS calls and return FALSE if a circuit switched
1105 call need a handle.
1106 */
1107 GLOBAL BOOL cmhSM_sAT_A( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret )
1108 {
1109 BOOL b;
1110
1111 b = cmhSM_sAT_A_H_intern(srcId, aci_ret, 1);
1112
1113 if ( *aci_ret EQ AT_EXCT )
1114 cmdErrStr = NULL;
1115
1116 return b;
1117 }
1118
1119 /*
1120 +--------------------------------------------------------------------+
1121 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
1122 | STATE : finished ROUTINE : cmhSM_sAT_A_H_intern |
1123 +--------------------------------------------------------------------+
1124
1125 PURPOSE : handle sAT_A and cAT_H for GPRS
1126 */
1127 static BOOL cmhSM_sAT_A_H_intern ( T_ACI_CMD_SRC srcId, T_ACI_RETURN *aci_ret, SHORT mode)
1128 {
1129 if ( at.rngPrms.isRng EQ TRUE )
1130 {
1131 if ( at.rngPrms.mode EQ CRING_MOD_Gprs)
1132 {
1133 *aci_ret = automatic_response_mode > 1 ? /* modem copatibility mode possible */
1134 sAT_PlusCGANS(srcId, mode, NULL, PDP_CONTEXT_CID_OMITTED): AT_FAIL;
1135 }
1136 else /* circuit switched call */
1137 {
1138 return FALSE;
1139 }
1140 }
1141 else
1142 {
1143 return FALSE;
1144 }
1145 return TRUE;
1146 }
1147
1148
1149
1150 /*
1151 +----------------------------------------------------------------------+
1152 | PROJECT : UMTS MODULE : CMH_SMF |
1153 | STATE : ROUTINE : pdp_context_type_omitted |
1154 +----------------------------------------------------------------------+
1155
1156 PURPOSE : check if the pdp context type is omitted.
1157 */
1158 GLOBAL BOOL pdp_context_type_omitted( char *p_type )
1159 {
1160 BOOL omitted = TRUE;
1161 char i;
1162
1163 for( i = 0; i < MAX_PDP_CONTEXT_TYPE_LEN; i++ )
1164 {
1165 if( *(p_type + i) NEQ 0 )
1166 omitted = FALSE;
1167 }
1168
1169 return omitted;
1170 }
1171
1172
1173 /*
1174 +----------------------------------------------------------------------+
1175 | PROJECT : UMTS MODULE : CMH_SMF |
1176 | STATE : ROUTINE : pdp_context_addr_omitted |
1177 +----------------------------------------------------------------------+
1178
1179 PURPOSE : check if the pdp context apn is omitted.
1180 */
1181 GLOBAL BOOL pdp_context_apn_omitted( char *p_apn )
1182 {
1183 BOOL omitted = TRUE;
1184 int i;
1185
1186 for( i = 0; i < MAX_PDP_CONTEXT_APN_LEN; i++ )
1187 {
1188 if( *(p_apn + i) NEQ 0 )
1189 omitted = FALSE;
1190 }
1191
1192 return omitted;
1193 }
1194
1195
1196 /*
1197 +----------------------------------------------------------------------+
1198 | PROJECT : UMTS MODULE : CMH_SMF |
1199 | STATE : ROUTINE : pdp_context_addr_omitted |
1200 +----------------------------------------------------------------------+
1201
1202 PURPOSE : check if the pdp context addr is omitted.
1203 */
1204 GLOBAL BOOL pdp_context_addr_omitted( T_NAS_ip *p_addr )
1205 {
1206 return (p_addr->ctrl_ip_address EQ NAS_is_ip_not_present);
1207 }
1208
1209
1210 /*
1211 +----------------------------------------------------------------------+
1212 | PROJECT : UMTS MODULE : CMH_SMF |
1213 | STATE : ROUTINE : pdp_context_type_valid |
1214 +----------------------------------------------------------------------+
1215
1216 PURPOSE : check pdp context type, return false if not valid.
1217 */
1218 GLOBAL BOOL pdp_context_type_valid( char *p_type )
1219 {
1220 BOOL valid = FALSE;
1221
1222 if( !strcmp( p_type, "IP") )
1223 valid = TRUE;
1224
1225 if( !strcmp( p_type, "IPV6") )
1226 valid = TRUE;
1227
1228 if( !strcmp( p_type, "PPP") )
1229 {
1230 /* For EDGE we are not supporting PDP_TYPE "PPP" */
1231 valid = FALSE;
1232 }
1233
1234 return valid;
1235 }
1236
1237
1238 /*
1239 +----------------------------------------------------------------------+
1240 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
1241 | STATE : finished ROUTINE : pdp_context_apn_vaild |
1242 +----------------------------------------------------------------------+
1243
1244 PURPOSE : check APN of well formed
1245 */
1246 GLOBAL BOOL pdp_context_apn_valid( char *p_apn )
1247 {
1248 SHORT i = 0;
1249 SHORT length = strlen( p_apn );
1250 char *no_start_labels[] = {"rac","lac","sgsn"}, *start, *end, *mark;
1251 T_PDP_CONTEXT_APN apn;
1252
1253 strcpy( apn, p_apn );
1254 start = apn;
1255
1256 /* change charcter of string to lower cases */
1257 for( i = 0; i < length; i++ )
1258 apn[i] = tolower( apn[i] );
1259
1260 /* The Network Identifier shall not start with this labels */
1261 for( i = 0; i < 3; i++ )
1262 {
1263 if( apn EQ strstr(apn, no_start_labels[i]) )
1264 return FALSE;
1265 }
1266
1267 /* the Wild Card APN */
1268 if ( length EQ 1 AND *start EQ '*' )
1269 return TRUE;
1270
1271 /* the APN with no name */
1272 if ( length EQ 1 AND *start EQ /*lint -e(743)*/ '\x0ff' )
1273 return TRUE;
1274
1275 /* Oporater Identifer is optional and the Network Identifer */
1276 mark = strrchr( apn, '.' );
1277 if( mark )
1278 if( strstr(mark + 1, "gprs") )
1279 {
1280 /* APN Operator Identifier contained (optional) */
1281 if( length < 18 )
1282 return FALSE;
1283
1284 mark = start + length - 18; /* start of the APN Operator Identifier */
1285 /* check APN Operator Identifier: "mncXXX.mccXXX.gprs" */
1286 if( mark NEQ strstr(mark, "mnc") )
1287 return FALSE;
1288
1289 if ( mark + 6 NEQ strstr(mark, ".mcc") )
1290 return FALSE;
1291 strtol(mark + 3, &end, 10);
1292
1293 if ( end NEQ mark + 6 )
1294 return FALSE;
1295 strtol(mark + 10, &end, 10);
1296
1297 if ( end NEQ mark + 13 )
1298 return FALSE;
1299 /* check character between APN Network Identifier and the Operator Identifer */
1300 mark--;
1301
1302 if ( *mark NEQ '.' )
1303 return FALSE;
1304 /* set stop mark */
1305 *mark = 0;
1306 }
1307 else
1308 mark = 0;
1309
1310 /* check APN Network Identifier */
1311
1312 /* shall not end in ".gprs" */
1313 end = strrchr(apn, '.');
1314 if ( end )
1315 if ( strstr(end + 1, "gprs") )
1316 return FALSE;
1317
1318 /* parse all labels */
1319 while ( *start )
1320 {
1321 /* in first at least one Label */
1322 while ( (*start >= 'a' AND *start <= 'z') OR (*start >= '0' AND *start <= '9') OR *start EQ '-' )
1323 start ++;
1324
1325 /* next Label or nothing */
1326 if ( *start EQ '.' )
1327 start ++;
1328 else
1329 if ( *start NEQ 0)
1330 return FALSE;
1331 }
1332
1333 /* The APN Network Identifier shall have a maximum length of 63 octets. */
1334 if ( start - apn > 63 )
1335 return FALSE;
1336
1337 /* clear stop mark */
1338 if ( mark )
1339 *mark = '.';
1340
1341 return TRUE;
1342 }
1343
1344
1345
1346 /*
1347 +----------------------------------------------------------------------+
1348 | PROJECT : UMTS MODULE : CMH_SMF |
1349 | STATE : ROUTINE : pdp_context_addr_valid |
1350 +----------------------------------------------------------------------+
1351
1352 PURPOSE : check pdp context address, return false if not valid.
1353 */
1354 GLOBAL BOOL pdp_context_addr_valid( T_NAS_ip * p_addr )
1355 {
1356 BOOL valid = TRUE;
1357 int i = 0;
1358
1359 if (p_addr->ctrl_ip_address EQ NAS_is_ip_not_present)
1360 return FALSE;
1361
1362 if (p_addr->ctrl_ip_address EQ NAS_is_ipv4)
1363 {
1364 if (( p_addr->ip_address.ipv4_addr.a4[0] EQ 0 ) OR //According to RFC3330 first digit must not be ZERO
1365 ( p_addr->ip_address.ipv4_addr.a4[0] EQ 127 ) OR //According to RFC3330 first digit 127 means LOOPBACK
1366 ((p_addr->ip_address.ipv4_addr.a4[0] >= 224 ) AND (p_addr->ip_address.ipv4_addr.a4[0] < 240)) ) //According to RFC3330 224.0.0.0/4 is reserved for multicast
1367 {
1368 valid = FALSE;
1369 }
1370 }
1371 else
1372 {
1373 switch( p_addr->ip_address.ipv6_addr.a6[0] )
1374 {
1375 case 0:
1376 if( p_addr->ip_address.ipv6_addr.a6[11] EQ 0 AND p_addr->ip_address.ipv6_addr.a6[12] NEQ 0
1377 AND p_addr->ip_address.ipv6_addr.a6[12] NEQ 127 AND p_addr->ip_address.ipv6_addr.a6[12] NEQ 255 )
1378 {
1379 /* this could be an ip v4 address embedded in ip v6 */
1380 break;
1381 }
1382
1383 for(i = 1; i < PDP_CONTEXT_ADDR_LEN_MAX; i++)
1384 {
1385 if( p_addr->ip_address.ipv6_addr.a6[i] EQ 0 )
1386 valid = FALSE;
1387 }
1388 break;
1389
1390 case 127: /* local host address */
1391 valid = FALSE;
1392 break;
1393
1394 case 254: /* invalid for an ip v6 address, the rest of the address must be '0' */
1395 for(i = 4; i < PDP_CONTEXT_ADDR_LEN_MAX; i++)
1396 {
1397 if( p_addr->ip_address.ipv6_addr.a6[i] NEQ 0 )
1398 valid = FALSE;
1399 }
1400 break;
1401
1402 // case 255: /* omitted 255.255...255.255 */
1403 // for( i = 1; i < PDP_CONTEXT_ADDR_LEN_MAX; i++ )
1404 // {
1405 // if( p_addr->ip_address.ipv6_addr.a6[i] NEQ 255 )
1406 // {
1407 // valid = FALSE;
1408 // }
1409 // }
1410 // break;
1411
1412 default:
1413 /* the address is valid */
1414 break;
1415
1416 }
1417 }
1418 return valid;
1419 }
1420
1421
1422 /*
1423 +--------------------------------------------------------------------+
1424 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
1425 | STATE : finished ROUTINE : cmhSM_transform_pdp_type |
1426 +--------------------------------------------------------------------+
1427
1428 PURPOSE : transform pdp_type
1429 */
1430 GLOBAL USHORT cmhSM_transform_pdp_type( char *pdp_type_str )
1431 {
1432 T_GACI_PDP_TYPE pdp_type = PDP_T_NONE;
1433
1434 if( !strcmp(pdp_type_str, "IP") )
1435 pdp_type = PDP_T_IP;
1436
1437 if( !strcmp(pdp_type_str, "IPV6") )
1438 pdp_type = PDP_T_IPV6;
1439
1440 if( !strcmp(pdp_type_str, "PPP") )
1441 pdp_type = PDP_T_PPP;
1442
1443 return pdp_type;
1444 }
1445
1446
1447 /*
1448 +-------------------------------------------------------------------------+
1449 | PROJECT : UMTS MODULE : CMH_SMF |
1450 | STATE : ROUTINE : pdp_context_get_state_for_cid |
1451 +-------------------------------------------------------------------------+
1452
1453 PURPOSE : return the PDP context state for the given <cid>.
1454 */
1455 GLOBAL T_PDP_CONTEXT_STATE pdp_context_get_state_for_cid( U8 cid )
1456 {
1457 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1458 T_PDP_CONTEXT_STATE pdp_context_state = PDP_CONTEXT_STATE_INVALID;
1459
1460 TRACE_FUNCTION("pdp_context_get_state_from_cid()");
1461
1462 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1463 if( p_pdp_context_node )
1464 pdp_context_state = p_pdp_context_node->internal_data.state;
1465
1466 return pdp_context_state;
1467 }
1468
1469
1470 /*
1471 +-------------------------------------------------------------------------+
1472 | PROJECT : UMTS MODULE : CMH_SMF |
1473 | STATE : ROUTINE : pdp_context_cid_used_by_other |
1474 +-------------------------------------------------------------------------+
1475
1476 PURPOSE : return true if the context id is used
1477 */
1478 GLOBAL BOOL pdp_context_cid_used_by_other( U8 cid )
1479 {
1480 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1481
1482 TRACE_FUNCTION("pdp_context_cid_used_by_other()");
1483
1484 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1485
1486 while( p_pdp_context_node )
1487 {
1488 if( p_pdp_context_node->attributes.p_cid < PDP_CONTEXT_CID_MIN AND
1489 p_pdp_context_node->attributes.p_cid > PDP_CONTEXT_CID_MAX )
1490 {
1491 return TRUE;
1492 }
1493 p_pdp_context_node = p_pdp_context_node->p_next;
1494 }
1495
1496 return FALSE;
1497 }
1498
1499 GLOBAL void set_state_over_cid ( U8 cid, T_PDP_CONTEXT_STATE state )
1500 {
1501 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1502
1503 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1504 if( p_pdp_context_node )
1505 {
1506 p_pdp_context_node->internal_data.state = state;
1507 }
1508 }
1509
1510
1511 /*
1512 +---------------------------------------------------------------------+
1513 | PROJECT : MODULE : CMH_SMF |
1514 | STATE : ROUTINE : get_state_over_cid |
1515 +---------------------------------------------------------------------+
1516
1517 PURPOSE :
1518 */
1519
1520 GLOBAL T_PDP_CONTEXT_STATE get_state_over_cid( U8 cid )
1521 {
1522
1523 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1524
1525 TRACE_FUNCTION("get_state_over_cid()");
1526
1527 if ( (cid >= 1) AND (cid <= PDP_CONTEXT_CID_MAX) )
1528 {
1529 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1530 if( p_pdp_context_node )
1531 {
1532 return p_pdp_context_node->internal_data.state;
1533 }
1534 }
1535
1536 TRACE_EVENT("invalid cid detected!");
1537 return PDP_CONTEXT_STATE_INVALID;
1538
1539 }
1540
1541
1542 /*
1543 +---------------------------------------------------------------------+
1544 | PROJECT : MODULE : CMH_SMF |
1545 | STATE : ROUTINE : get_state_working_cid |
1546 +---------------------------------------------------------------------+
1547
1548 PURPOSE :
1549 */
1550
1551 GLOBAL T_PDP_CONTEXT_STATE get_state_working_cid( void )
1552 {
1553 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1554
1555 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
1556 if( p_pdp_context_node )
1557 {
1558 return p_pdp_context_node->internal_data.state;
1559 }
1560 else
1561 {
1562 TRACE_ERROR( "ERROR: PDP context not found, in function get_state_working_cid" );
1563 return PDP_CONTEXT_STATE_INVALID;
1564 }
1565
1566 }
1567
1568
1569 /*
1570 +------------------------------------------------------------------------------+
1571 | PROJECT : MODULE : CMH_SMF |
1572 | STATE : ROUTINE : set_conn_param_on_working_cids |
1573 +------------------------------------------------------------------------------+
1574
1575 PURPOSE :
1576 */
1577 GLOBAL void set_conn_param_on_working_cid ( UBYTE owner, T_DTI_ENTITY_ID entity_id )
1578 {
1579 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1580 TRACE_FUNCTION("set_conn_param_on_working_cid()");
1581
1582 p_pdp_context_node = pdp_context_find_node_from_cid(work_cids[cid_pointer]);
1583
1584 if( p_pdp_context_node )
1585 {
1586 p_pdp_context_node->internal_data.owner = (T_ACI_CMD_SRC)owner;
1587 p_pdp_context_node->internal_data.entity_id = entity_id;
1588 }
1589 else
1590 {
1591 TRACE_ERROR( "ERROR: PDP context not found, in function set_conn_param_on_working_cid " );
1592 return;
1593 }
1594 }
1595
1596
1597
1598 /*
1599 +------------------------------------------------------------------------------+
1600 | PROJECT : MODULE : CMH_SMF |
1601 | STATE : ROUTINE : set_conn_param_on_all_working_cids |
1602 +------------------------------------------------------------------------------+
1603
1604 PURPOSE :
1605 */
1606 GLOBAL void set_conn_param_on_all_working_cids ( UBYTE owner, T_DTI_ENTITY_ID entity_id )
1607 {
1608 U8 *pcid = &(work_cids[cid_pointer]);
1609 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1610
1611 TRACE_FUNCTION("set_conn_param_on_all_working_cids()");
1612
1613 while(INVALID_CID NEQ *pcid) {
1614
1615 p_pdp_context_node = pdp_context_find_node_from_cid((U8)*pcid);
1616
1617 if( p_pdp_context_node )
1618 {
1619 p_pdp_context_node->internal_data.owner = (T_ACI_CMD_SRC)owner;
1620 p_pdp_context_node->internal_data.entity_id = entity_id;
1621 }
1622 pcid ++;
1623 }
1624 }
1625
1626 /*
1627 +---------------------------------------------------------------------+
1628 | PROJECT : MODULE : CMH_SMF |
1629 | STATE : ROUTINE : set_state_working_cid |
1630 +---------------------------------------------------------------------+
1631
1632 PURPOSE :
1633 */
1634
1635 GLOBAL void set_state_working_cid( T_PDP_CONTEXT_STATE c_state )
1636 {
1637 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1638
1639 TRACE_FUNCTION("set_state_working_cid()");
1640
1641 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
1642 if( p_pdp_context_node )
1643 {
1644 p_pdp_context_node->internal_data.state = c_state;
1645 }
1646 else
1647 {
1648 TRACE_ERROR( "ERROR: PDP context not found, invalid cid, in function set_state_working_cid" );
1649 }
1650 }
1651
1652
1653 /*
1654 +---------------------------------------------------------------------+
1655 | PROJECT : MODULE : CMH_SMF |
1656 | STATE : ROUTINE : get_state_over_nsapi_set |
1657 +---------------------------------------------------------------------+
1658
1659 PURPOSE :
1660 */
1661
1662 GLOBAL T_PDP_CONTEXT_STATE get_state_over_nsapi_set ( USHORT *nsapi_set, U8 *cid )
1663 {
1664 USHORT nsapi = 0;
1665 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1666
1667 TRACE_FUNCTION("get_state_over_nsapi_set()");
1668 while( nsapi < SMH_LAST_FREE_NSAPIS AND !((*nsapi_set >> nsapi) & 1) )
1669 nsapi++;
1670
1671 if( !(*nsapi_set & ( 1 << nsapi )) )
1672 {
1673 return PDP_CONTEXT_STATE_INVALID;
1674 }
1675
1676 TRACE_EVENT_P1("NSAPI: %d", nsapi);
1677
1678 TRACE_EVENT_P1("NSAPI: %4d", nsapi);
1679
1680 *nsapi_set &= ~( 1U << nsapi );
1681
1682 p_pdp_context_node = pdp_context_find_node_from_cid( NSAPI_TO_CID( nsapi ) );
1683 if( !p_pdp_context_node )
1684 {
1685 TRACE_ERROR( "ERROR: PDP context not found, invalid cid, in function get_state_over_nsapi_set" );
1686 return PDP_CONTEXT_STATE_INVALID;
1687 }
1688
1689 *cid = p_pdp_context_node->cid;
1690
1691 return get_state_over_cid( *cid );
1692
1693 }
1694
1695
1696 /*
1697 +---------------------------------------------------------------------+
1698 | PROJECT : MODULE : CMH_SMF |
1699 | STATE : ROUTINE : cmhSM_Give_nsapi_set |
1700 +---------------------------------------------------------------------+
1701
1702 PURPOSE :
1703 */
1704
1705 GLOBAL USHORT cmhSM_Give_nsapi_set ( U8 cid )
1706 {
1707 return (1 << CID_TO_NSAPI(cid) );
1708 }
1709
1710
1711 /*
1712 +---------------------------------------------------------------------+
1713 | PROJECT : MODULE : CMH_SMF |
1714 | STATE : ROUTINE : get_owner_over_cid |
1715 +---------------------------------------------------------------------+
1716
1717 PURPOSE :
1718 */
1719
1720 GLOBAL T_ACI_CAL_OWN get_owner_over_cid( U8 cid )
1721 {
1722
1723 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1724
1725 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1726 if( p_pdp_context_node )
1727 {
1728 return (T_ACI_CAL_OWN)p_pdp_context_node->internal_data.owner;
1729 }
1730 else
1731 {
1732 TRACE_ERROR( "ERROR: PDP context not found, in function get_owner_over_cid" );
1733 return CAL_OWN_NONE;
1734 }
1735 }
1736
1737
1738 /*
1739 +--------------------------------------------------------------------------+
1740 | PROJECT : MODULE : CMH_SMF |
1741 | STATE : ROUTINE : cmhGPPP_send_establish_request |
1742 +--------------------------------------------------------------------------+
1743
1744 PURPOSE :
1745 */
1746
1747 GLOBAL void cmhGPPP_send_establish_request ( UBYTE peer, UBYTE prot )
1748 {
1749 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1750 // T_PPP_ESTABLISH_REQ est_req;
1751
1752 PALLOC (ppp_establish_req, PPP_ESTABLISH_REQ);
1753
1754 TRACE_FUNCTION( "cmhGPPP_send_establish_request" );
1755 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
1756 if( p_pdp_context_node )
1757 {
1758
1759 if(!strcmp(p_pdp_context_node->attributes.pdp_type, "PPP"))
1760 ppp_establish_req->mode = PPP_TRANSPARENT;
1761 else
1762 ppp_establish_req->mode = PPP_SERVER;
1763
1764 ppp_establish_req->mru = PPP_MRU_DEFAULT;
1765 ppp_establish_req->ap = gpppShrdPrm.ppp_authentication_protocol;
1766 ppp_establish_req->accm = gpppShrdPrm.accm;
1767 ppp_establish_req->rt = gpppShrdPrm.restart_timer;
1768 ppp_establish_req->mc = gpppShrdPrm.max_configure;
1769 ppp_establish_req->mt = gpppShrdPrm.max_terminate;
1770 ppp_establish_req->mf = gpppShrdPrm.max_failure;
1771 ppp_establish_req->ip = p_pdp_context_node->attributes.pdp_addr.ip_address.ipv4_addr.a4[0] << 24;
1772 ppp_establish_req->ip += p_pdp_context_node->attributes.pdp_addr.ip_address.ipv4_addr.a4[1] << 16;
1773 ppp_establish_req->ip += p_pdp_context_node->attributes.pdp_addr.ip_address.ipv4_addr.a4[2] << 8;
1774 ppp_establish_req->ip += p_pdp_context_node->attributes.pdp_addr.ip_address.ipv4_addr.a4[3];
1775
1776 ppp_establish_req->peer_direction = DTI_CHANNEL_TO_LOWER_LAYER;
1777 ppp_establish_req->prot_direction = DTI_CHANNEL_TO_HIGHER_LAYER;
1778
1779 ppp_establish_req->peer_link_id = p_pdp_context_node->internal_data.link_id_uart;
1780 ppp_establish_req->prot_link_id = p_pdp_context_node->internal_data.link_id;
1781
1782
1783 #ifdef _SIMULATION_
1784 memset (ppp_establish_req->peer_channel.peer_entity, 0, CHANNEL_NAME_LENGTH);
1785 memset (ppp_establish_req->protocol_channel.protocol_entity, 0, CHANNEL_NAME_LENGTH);
1786 #endif /* _SIMULATION_ */
1787
1788 strcpy ( (char *) ppp_establish_req->protocol_channel.protocol_entity, SNDCP_NAME);
1789
1790 switch (peer)
1791 {
1792 #ifdef BT_ADAPTER
1793 case DTI_ENTITY_BLUETOOTH:
1794 strcpy ( (char *)(&(ppp_establish_req->peer_channel)), BTI_NAME);
1795 break;
1796 #endif
1797 case DTI_ENTITY_UART:
1798 strcpy ( (char *)(&(ppp_establish_req->peer_channel)), UART_NAME);
1799 break;
1800
1801 #ifdef FF_PSI
1802 case DTI_ENTITY_PSI:
1803 strcpy ( (char *)(&(ppp_establish_req->peer_channel)), PSI_NAME);
1804 break;
1805 #endif /*FF_PSI*/
1806
1807 case DTI_ENTITY_AAA:
1808 strcpy ( (char *)(&(ppp_establish_req->peer_channel)), RIV_NAME);
1809 break;
1810
1811 default:
1812 TRACE_ERROR ("[cmhGPPP_send_establish_request()] Unexpected peer!");
1813 return;
1814 }
1815
1816 psaGPPP_Establish ( ppp_establish_req );
1817
1818 switch (get_state_working_cid())
1819 {
1820 case PDP_CONTEXT_STATE_ACTIVATED:
1821 set_state_working_cid( PDP_CONTEXT_STATE_ACTIVATED_ESTABLISH_1 );
1822 break;
1823 default:
1824 set_state_working_cid( PDP_CONTEXT_STATE_ESTABLISH_1 );
1825 break;
1826 }
1827
1828 }
1829 else
1830 {
1831 TRACE_ERROR( "PDP context not found, in function cmhGPPP_send_establish_request" );
1832 }
1833 }
1834
1835
1836 /*
1837 +-----------------------------------------------------------------+
1838 | PROJECT : MODULE : CMH_SMF |
1839 | STATE : ROUTINE : cmhSM_cgerep_buffer |
1840 +-----------------------------------------------------------------+
1841 PURPOSE :
1842 */
1843
1844 GLOBAL void cmhSM_cgerep_buffer ( void )
1845 {
1846
1847 switch (sm_cgerep_bfr)
1848 {
1849 case CGEREP_BFR_CLEAR:
1850 memset(gprs_event_buffer, 0, sizeof(T_CGERP_EVENT_BUFFER) * GPRS_EVENT_REPORTING_BUFFER_SIZE);
1851 break;
1852 case CGEREP_BFR_FLUSH:
1853 if ( uart_is_mt_te_link EQ FALSE)
1854 {
1855 while ( gprs_eb_oldest_p NEQ gprs_eb_current_p )
1856 {
1857 R_AT( RAT_CGEREP, (T_ACI_CMD_SRC)sm_cgerep_srcId )
1858 ( gprs_event_buffer[gprs_eb_oldest_p].event, gprs_event_buffer[gprs_eb_oldest_p].parm );
1859
1860 gprs_eb_oldest_p++;
1861 }
1862 }
1863 break;
1864 case CGEREP_BFR_OMITTED:
1865 case CGEREP_BFR_INVALID:
1866 default:
1867 break;
1868 }
1869 }
1870
1871
1872 /*
1873 +-----------------------------------------------------------------+
1874 | PROJECT : MODULE : CMH_SMF |
1875 | STATE : ROUTINE : cmhSM_save_event |
1876 +-----------------------------------------------------------------+
1877
1878 PURPOSE :
1879 */
1880
1881 GLOBAL void cmhSM_save_event( T_CGEREP_EVENT event, T_CGEREP_EVENT_REP_PARAM *param )
1882 {
1883
1884 /* save event */
1885 gprs_event_buffer[gprs_eb_current_p].event = event;
1886 if (param)
1887 memcpy (&gprs_event_buffer[gprs_eb_current_p].parm, param, sizeof(T_CGEREP_EVENT_REP_PARAM));
1888
1889 /* is buffer full */
1890 if ( gprs_eb_oldest_p EQ gprs_eb_current_p )
1891 gprs_eb_oldest_p = -1;
1892
1893 /* new current pointer */
1894 gprs_eb_current_p++;
1895 if ( gprs_eb_current_p EQ GPRS_EVENT_REPORTING_BUFFER_SIZE )
1896 gprs_eb_current_p = 0;
1897
1898 /* if buffer full correct pointer to oldest event */
1899 if ( gprs_eb_oldest_p EQ -1 )
1900 gprs_eb_oldest_p = gprs_eb_current_p;
1901
1902 }
1903
1904
1905 /*
1906 +-----------------------------------------------------------------+
1907 | PROJECT : MODULE : CMH_SMF |
1908 | STATE : ROUTINE : cmhSM_set_sms_service |
1909 +-----------------------------------------------------------------+
1910
1911 PURPOSE :
1912 */
1913
1914 GLOBAL void cmhSM_set_sms_service( T_CGSMS_SERVICE service )
1915 {
1916
1917 {
1918 PALLOC (mnsms_mo_serv_req, MNSMS_MO_SERV_REQ);
1919
1920 /* fill in primitive parameter: command request */
1921 mnsms_mo_serv_req -> mo_sms_serv = (UBYTE) service;
1922
1923 PSENDX (SMS, mnsms_mo_serv_req);
1924 }
1925
1926 m_service = service;
1927 }
1928
1929
1930 /*
1931 +-------------------------------------------------------------------+
1932 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
1933 | STATE : finnished ROUTINE : cmhSM_sms_service_changed |
1934 +-------------------------------------------------------------------+
1935
1936 PURPOSE : indicates a network initiated PDP context modification
1937
1938 */
1939 GLOBAL void cmhSM_sms_service_changed ( UBYTE service )
1940 {
1941
1942 TRACE_FUNCTION ("cmhSM_sms_service_changed()");
1943
1944 /*
1945 *-------------------------------------------------------------------
1946 * check for command context
1947 *-------------------------------------------------------------------
1948 */
1949 if ( smEntStat.curCmd EQ AT_CMD_CGSMS )
1950 {
1951 if ( m_service EQ service )
1952 {
1953 sm_cgsms_service = m_service;
1954 R_AT( RAT_OK, smEntStat.entOwn ) ( smEntStat.curCmd );
1955 }
1956 else
1957 {
1958 R_AT( RAT_CME, smEntStat.entOwn ) ( smEntStat.curCmd, CME_ERR_Unknown );
1959 /* log result */
1960 cmh_logRslt ( smEntStat.entOwn, RAT_CME, smEntStat.curCmd,
1961 -1, BS_SPEED_NotPresent, CME_ERR_Unknown );
1962 }
1963
1964 smEntStat.curCmd = AT_CMD_NONE;
1965 }
1966 }
1967
1968
1969 /*
1970 +-----------------------------------------------------------------+
1971 | PROJECT : MODULE : CMH_SMF |
1972 | STATE : ROUTINE : cmhSM_GprsAttached |
1973 +-----------------------------------------------------------------+
1974
1975 PURPOSE : Handling of changed GMM attach state.
1976 PARAMETERS : state - TRUE is GPRS attached.
1977 FALSE is GPRS detached.
1978 */
1979
1980 GLOBAL void cmhSM_GprsAttached( T_GPRS_ATTACH_STATE state )
1981 {
1982 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1983 TRACE_FUNCTION ("cmhSM_GprsAttached()");
1984
1985 /*
1986 * Do nothing if no context action is in progress (no cmd is running).
1987 */
1988 if (work_cids[cid_pointer] EQ PDP_CONTEXT_CID_INVALID)
1989 return;
1990
1991
1992 if ( state EQ GPRS_ATTACH )
1993 { /* mobile is attached */
1994 switch ( get_state_working_cid( ) )
1995 {
1996 case PDP_CONTEXT_STATE_ATTACHING:
1997 /* The first cid in work_cids should continue activation after the attach */
1998 if (gpppEntStat.curCmd EQ AT_CMD_CGDATA)
1999 {
2000 /* Continue establishing the data link context */
2001 cmhSM_data_link_context();
2002 break;
2003 }
2004 else if (smEntStat.curCmd EQ AT_CMD_CGACT)
2005 {
2006 /* Continue activating the context */
2007 cmhSM_activate_context();
2008 break;
2009 }
2010 default:
2011 /* Do nothing since no context is forcing the attach. */
2012 break;
2013 }
2014 }
2015 else
2016 {
2017 /* attach failed or the network has indicated detach. */
2018
2019 p_pdp_context_node = pdp_context_find_node_from_cid((U8)(work_cids[cid_pointer]));
2020 if( p_pdp_context_node NEQ NULL )
2021 {
2022 switch ( get_state_working_cid() )
2023 {
2024 case PDP_CONTEXT_STATE_ATTACHING:
2025 /* The attach was rejected. Set state back to defined and return no carrier */
2026
2027 if (smEntStat.curCmd EQ AT_CMD_CGACT)
2028 {
2029 p_pdp_context_node->internal_data.owner = smEntStat.entOwn;
2030 }
2031 else
2032 {
2033 p_pdp_context_node->internal_data.owner = gpppEntStat.entOwn;
2034 }
2035
2036 if (gpppEntStat.curCmd EQ AT_CMD_CGDATA)
2037 {
2038 gaci_RAT_caller ( RAT_NO_CARRIER, work_cids[cid_pointer], AT_CMD_DATA, 0 );
2039 }
2040 else if (smEntStat.curCmd EQ AT_CMD_CGACT)
2041 {
2042 gaci_RAT_caller ( RAT_CME, work_cids[cid_pointer], AT_CMD_CGACT, CME_ERR_GPRSUnspec );
2043 }
2044
2045 set_state_working_cid( PDP_CONTEXT_STATE_DEFINED );
2046
2047 gpppEntStat.curCmd = AT_CMD_NONE;
2048 smEntStat.curCmd = AT_CMD_NONE;
2049 work_cids[0] = PDP_CONTEXT_CID_INVALID;
2050 cid_pointer = 0;
2051
2052 break;
2053 case PDP_CONTEXT_STATE_ESTABLISH_1:
2054 /*
2055 * Context not activated towards SM, but PPP has to be terminated.
2056 */
2057 cmhSM_deactivateAContext( smEntStat.entOwn, work_cids[cid_pointer] );
2058
2059 gpppEntStat.curCmd = AT_CMD_NONE;
2060 gpppEntStat.entOwn = CMD_SRC_NONE;
2061 break;
2062 default:
2063 /* Do nothing. Context is deactivated from SM */
2064 break;
2065 }
2066 }
2067 }
2068 }
2069
2070
2071 /*
2072 +-------------------------------------------------------------------+
2073 | PROJECT : MODULE : CMH_SMF |
2074 | STATE : ROUTINE : cmhSM_activate_context |
2075 +-------------------------------------------------------------------+
2076
2077 PURPOSE : Activates a context without user plane.
2078 */
2079
2080 GLOBAL void cmhSM_activate_context(void)
2081 {
2082 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2083 U8 hcomp;
2084 U8 dcomp;
2085
2086 TRACE_FUNCTION ("cmhSM_activate_context()");
2087
2088 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
2089 if( !p_pdp_context_node )
2090 {
2091 TRACE_ERROR( "PDP context not found, in function cmhSM_activate_context" );
2092 return;
2093 }
2094
2095
2096 /* hcomp value being changed according to spec 27.007 */
2097 hcomp = cmhSM_Get_h_comp() ;
2098 dcomp = cmhSM_Get_d_comp() ;
2099
2100 /*
2101 * Activate the primary or secondary context
2102 */
2103 if( p_pdp_context_node->type EQ PDP_CONTEXT_TYPE_PRIMARY )
2104 {
2105 psaSM_smreg_pdp_activate_req( work_cids[cid_pointer],
2106 hcomp,
2107 dcomp);
2108 }
2109 #ifdef REL99
2110 else if( p_pdp_context_node->type EQ PDP_CONTEXT_TYPE_SECONDARY )
2111 {
2112 psaSM_smreg_pdp_activate_sec_req( work_cids[cid_pointer] );
2113 }
2114 #endif
2115
2116 set_state_working_cid( PDP_CONTEXT_STATE_ACTIVATING );
2117 }
2118
2119
2120 #if defined (CO_UDP_IP) OR defined (FF_GPF_TCPIP)
2121 /*
2122 +----------------------------------------------------------------------+
2123 | PROJECT : GPRS (8441) MODULE : cmh_smf |
2124 | STATE : initial ROUTINE : cmhSM_IP_activate_cb |
2125 +----------------------------------------------------------------------+
2126
2127 PURPOSE : callback function for WAP over GPRS.
2128 While handling the command ATD*98# in function atGD()
2129 the function psaTCPIP_Activate() is called for WAP handling.
2130 psaTCPIP_Activate() has this function as parameter for
2131 call backs.
2132 */
2133 void cmhSM_IP_activate_cb(T_ACI_RETURN result)
2134 {
2135 U8 cid = gaci_get_cid_over_dti_id(wap_dti_id);
2136 TRACE_FUNCTION("cmhSM_IP_activate_cb");
2137 TRACE_EVENT_P1("wap_state: %s",wap_state_to_string(wap_state));
2138 #ifndef FF_SAT_E
2139 ACI_ASSERT(DTI_DTI_ID_NOTPRESENT NEQ wap_dti_id);
2140 ACI_ASSERT(cid >= GPRS_CID_1 AND cid < GPRS_CID_INVALID);
2141 ACI_ASSERT(result NEQ AT_FAIL);
2142 #endif /* not FF_SAT_E */
2143
2144 if ( result EQ AT_FAIL )
2145 {
2146 /* IP activation failed. */
2147 TRACE_EVENT("UDP/TCP/IP activation/configuration returned AT_FAIL");
2148
2149 if (DTI_DTI_ID_NOTPRESENT NEQ wap_dti_id)
2150 {
2151 dti_cntrl_close_dpath_from_dti_id (wap_dti_id);
2152 cmhSM_disconnect_cid(cid, GC_TYPE_WAP );
2153 }
2154
2155 /* reset work_cids */
2156 set_state_over_cid(cid, PDP_CONTEXT_STATE_DEFINED);
2157
2158 sAT_PercentWAP((T_ACI_CMD_SRC)smShrdPrm.owner, 0);
2159 smEntStat.curCmd = AT_CMD_NONE;
2160
2161 dti_cntrl_erase_entry(wap_dti_id);
2162 cmdCmeError(CME_ERR_Unknown);
2163
2164 #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E)
2165 if( cmhSAT_OpChnGPRSPend( PDP_CONTEXT_CID_INVALID, OPCH_EST_REQ ))
2166 {
2167 cmhSAT_OpChnUDPDeactGprs();
2168 }
2169 #endif /* SIM_TOOLKIT */
2170 return;
2171 }
2172
2173 switch(wap_state)
2174 {
2175 // in case CO_UDP_IP and FF_GPF_TCPIP is defined this is a fall through case
2176 UDPIP_STATEMENT(case IPA_Activated:)
2177 GPF_TCPIP_STATEMENT(case TCPIP_Activation:)
2178
2179 if(is_gpf_tcpip_call()) {
2180 GPF_TCPIP_STATEMENT(set_conn_param_on_working_cid(
2181 (UBYTE)smEntStat.entOwn, DTI_ENTITY_TCPIP));
2182 }
2183 else {
2184 UDPIP_STATEMENT(set_conn_param_on_working_cid(
2185 (UBYTE)smEntStat.entOwn, DTI_ENTITY_IP));
2186 }
2187 cmhSM_activate_context_For_WAP();
2188 return;
2189
2190 UDPIP_STATEMENT(case UDPA_Configurated:)
2191 GPF_TCPIP_STATEMENT(case TCPIP_Configurated:)
2192
2193 //smEntStat.curCmd = AT_CMD_NONE;
2194 #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E)
2195 if( cmhSAT_OpChnGPRSPend( PDP_CONTEXT_CID_INVALID, OPCH_EST_REQ ))
2196 {
2197 cmhSAT_OpChnUDPConfGprs();
2198 }
2199 else
2200 #endif /* SIM_TOOLKIT */
2201 {
2202 R_AT ( RAT_CONNECT, smEntStat.entOwn )( AT_CMD_CGACT, -1, wapId, FALSE );
2203 }
2204 smEntStat.curCmd = AT_CMD_NONE;
2205 smEntStat.entOwn = CMD_SRC_NONE;
2206 #ifdef FF_GPF_TCPIP
2207 if(is_gpf_tcpip_call())
2208 {
2209 T_DCM_STATUS_IND_MSG msg;
2210 msg.hdr.msg_id = DCM_NEXT_CMD_READY_MSG;
2211 dcm_send_message(msg, DCM_SUB_WAIT_CGACT_CNF);
2212 }
2213 #endif
2214 break;
2215
2216 UDPIP_STATEMENT(case IPA_Deactivated:)
2217 GPF_TCPIP_STATEMENT(case TCPIP_Deactivated:)
2218
2219 TRACE_EVENT_P1("cmhSM_IP_activate_cb, no connection, dti_id = %d", wap_dti_id);
2220
2221 #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E)
2222 if( cmhSAT_OpChnGPRSPend( PDP_CONTEXT_CID_INVALID, OPCH_NONE ))
2223 {
2224 cmhSAT_OpChnUDPDeactGprs();
2225 }
2226 else
2227 #endif /* SIM_TOOLKIT */
2228 {
2229 #ifdef FF_GPF_TCPIP
2230 /* Don't send NO CARRIER if it is TCPIP call */
2231 if (!is_gpf_tcpip_call())
2232 #endif
2233
2234 /* TC GACIWAP232 */
2235 gaci_RAT_caller ( RAT_NO_CARRIER, cid, AT_CMD_CGACT, 0 );
2236 }
2237 dti_cntrl_close_dpath_from_dti_id (wap_dti_id);
2238 cmhSM_connection_down(wap_dti_id);
2239 /*Decrease the count for the corresponding link if it is a TCPIP call */
2240 #ifdef FF_GPF_TCPIP
2241 if (is_gpf_tcpip_call())
2242 {
2243 GPF_TCPIP_STATEMENT(srcc_delete_count(SRCC_TCPIP_SNDCP_LINK ));
2244 }
2245 else
2246 #endif
2247 {
2248
2249 cmhSM_disconnect_cid(cid, GC_TYPE_WAP );
2250 }
2251 sAT_PercentWAP((T_ACI_CMD_SRC)smShrdPrm.owner, 0);
2252 if(work_cids[cid_pointer] EQ cid)
2253 {
2254 smEntStat.curCmd = AT_CMD_NONE;
2255 *work_cids = 0;
2256 cid_pointer = 0;
2257 }
2258 #ifdef FF_GPF_TCPIP
2259 if(is_gpf_tcpip_call())
2260 {
2261 T_DCM_STATUS_IND_MSG msg;
2262 msg.hdr.msg_id = DCM_NEXT_CMD_READY_MSG;
2263 dcm_send_message(msg, DCM_SUB_WAIT_CGDEACT_CNF);
2264 }
2265 #endif
2266 break;
2267
2268 default:
2269 TRACE_EVENT("Unexpected wap state in cmhSM_IP_activate_cb()");
2270 if(is_gpf_tcpip_call()) {
2271 GPF_TCPIP_STATEMENT(srcc_delete_count(SRCC_TCPIP_SNDCP_LINK ));
2272 }
2273 else {
2274 UDPIP_STATEMENT(srcc_delete_count(SRCC_IP_SNDCP_LINK ));
2275 }
2276 dti_cntrl_erase_entry(wap_dti_id);
2277 sAT_PercentWAP((T_ACI_CMD_SRC)smShrdPrm.owner, 0);
2278 smEntStat.curCmd = AT_CMD_NONE;
2279
2280 #if defined (SIM_TOOLKIT) AND defined (FF_SAT_E)
2281 if( cmhSAT_OpChnGPRSPend( PDP_CONTEXT_CID_INVALID, OPCH_NONE ))
2282 {
2283 cmhSAT_OpChnUDPDeactGprs();
2284 }
2285 else
2286 #endif /* SIM_TOOLKIT */
2287 {
2288 cmdCmeError(CME_ERR_Unknown);
2289 }
2290 break;
2291 }
2292 return;
2293 }
2294
2295 GLOBAL T_ACI_RETURN cmhSM_activate_context_For_WAP(void)
2296 {
2297 TRACE_FUNCTION ("cmhSM_activate_context_For_WAP()");
2298
2299 if( AT_CMPL EQ cmhGMM_attach_if_necessary( smEntStat.entOwn, AT_CMD_CGDATA ) )
2300 {
2301 cmhSM_connect_working_cid();
2302 }
2303 else /* AT_EXCT -> class BX class change requested (NOMIII) */
2304 {
2305 /* For TC ACTSAT 510
2306 Activating the context for WAP
2307 */
2308 gpppEntStat.curCmd = AT_CMD_CGDATA;
2309 set_state_working_cid( PDP_CONTEXT_STATE_ATTACHING );
2310 }
2311 return (AT_EXCT);
2312 }
2313 /*
2314 +----------------------------------------------------------------------+
2315 | PROJECT : GPRS (8441) MODULE : cmh_smf |
2316 | STATE : initial ROUTINE : cmhSM_IP_Enable |
2317 +----------------------------------------------------------------------+
2318
2319 PURPOSE : enables IP dti connection.
2320 */
2321 GLOBAL void cmhSM_IP_Enable ( T_DTI_CONN_LINK_ID link_id)
2322 {
2323 TRACE_FUNCTION("cmhSM_IP_Enable");
2324
2325 #ifdef _SIMULATION_
2326 cmhSM_connect_context ( gaci_get_cid_over_link_id( link_id ),
2327 DTI_ENTITY_IP );
2328 #else /* _SIMULATION_ */
2329 cmhSM_connect_context ( gaci_get_cid_over_link_id( link_id ),
2330 DTI_ENTITY_IP );
2331 #endif /* _SIMULATION_ */
2332 }
2333
2334
2335 /*
2336 +----------------------------------------------------------------------+
2337 | PROJECT : GPRS (8441) MODULE : cmh_smf |
2338 | STATE : initial ROUTINE : cmhSM_IP_Disable |
2339 +----------------------------------------------------------------------+
2340
2341 PURPOSE : disables IP dti connection.
2342 */
2343 GLOBAL void cmhSM_IP_Disable ()
2344 {
2345 TRACE_FUNCTION("cmhSM_IP_Disable");
2346 }
2347
2348 #endif /* WAP OR FF_GPF_TCPIP OR SAT E */
2349
2350 /*
2351 +-------------------------------------------------------------------+
2352 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2353 | STATE : finnished ROUTINE : cmhSM_data_link_context |
2354 +-------------------------------------------------------------------+
2355 */
2356
2357 GLOBAL void cmhSM_data_link_context(void)
2358 {
2359 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2360
2361 TRACE_FUNCTION ("cmhSM_data_link_context()");
2362
2363 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
2364 if( p_pdp_context_node )
2365 {
2366 #if defined FF_WAP
2367 if(!Wap_Call)
2368 {
2369 R_AT( RAT_CONNECT, p_pdp_context_node->internal_data.owner )
2370 ( AT_CMD_CGDATA, 0, 0, FALSE );
2371 }
2372 #else
2373 R_AT( RAT_CONNECT, p_pdp_context_node->internal_data.owner )
2374 ( AT_CMD_CGDATA, 0, 0, FALSE );
2375 #endif /* WAP OR SAT E */
2376 }
2377 else
2378 {
2379 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_data_link_context" );
2380 }
2381
2382
2383
2384 /* log result */
2385 if( p_pdp_context_node )
2386 cmh_logRslt ( p_pdp_context_node->internal_data.owner,
2387 RAT_CONNECT, AT_CMD_CGDATA, -1, BS_SPEED_NotPresent,CME_ERR_NotPresent );
2388
2389 cmhSM_connect_working_cid();
2390
2391 }
2392
2393 /*
2394 +-------------------------------------------------------------------+
2395 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2396 | STATE : finnished ROUTINE : cmhSM_next_work_cid |
2397 +-------------------------------------------------------------------+
2398
2399 PURPOSE : start the next context activation if requested
2400
2401 */
2402 GLOBAL BOOL cmhSM_next_work_cid ( T_ACI_AT_CMD curCmd )
2403 {
2404
2405 TRACE_EVENT_P1("cmhSM_next_work_cid, cid_pointer: %d", cid_pointer);
2406
2407 cid_pointer ++;
2408
2409 if ( work_cids[cid_pointer] EQ PDP_CONTEXT_CID_INVALID )
2410 {
2411 smEntStat.curCmd = AT_CMD_NONE;
2412 gpppEntStat.curCmd = AT_CMD_NONE;
2413
2414 cid_pointer = 0;
2415 memset( work_cids, PDP_CONTEXT_CID_INVALID, sizeof(work_cids) ); // *work_cids = 0;
2416
2417 return FALSE;
2418 }
2419
2420 switch ( curCmd )
2421 {
2422 case AT_CMD_CGDATA:
2423 cmhSM_data_link_context();
2424 break;
2425 case AT_CMD_CGACT:
2426 cmhSM_activate_context();
2427 break;
2428 default:
2429 cid_pointer = 0;
2430 *work_cids = 0;
2431 return FALSE;
2432 }
2433 return TRUE;
2434 }
2435
2436
2437
2438 /*
2439 +-------------------------------------------------------------------+
2440 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2441 | STATE : finnished ROUTINE : cmhSM_make_active_cid_list |
2442 +-------------------------------------------------------------------+
2443
2444 PURPOSE : moves cids into work_cids list, verifies cid range,
2445 checks for duplicated cids and checks that the context
2446 is active. If no cids are specified, all active cids are
2447 put into the work_cids list.
2448 Used by the sAT_PlusCGCMOD command.
2449 RETURN : Number of cids in work_cids list.
2450
2451 */
2452 GLOBAL SHORT cmhSM_make_active_cid_list ( T_ACI_CMD_SRC srcId, U8 *cids )
2453 {
2454 U8 i, j;
2455
2456 cid_pointer = 0;
2457 if( cids[0] NEQ PDP_CONTEXT_CID_INVALID )
2458 {
2459 /* A number of cids are listed in *cids */
2460 i = 0;
2461 while( (i<PDP_CONTEXT_CID_MAX) AND (cids[i] NEQ PDP_CONTEXT_CID_INVALID) )
2462 {
2463 /* Check for duplicated cids (no check the first time). */
2464 for (j=0; j<i; j++)
2465 if (work_cids[j] EQ cids[i]) return 0;
2466
2467 /* Check for valid cid range */
2468 if( (cids[i] < PDP_CONTEXT_CID_MIN) OR (cids[i] > PDP_CONTEXT_CID_MAX) )
2469 return 0;
2470
2471 /* Check that context state for cid is Active */
2472 if( (get_state_over_cid( (U8)(i+1) ) NEQ PDP_CONTEXT_STATE_ACTIVATED) AND
2473 (get_state_over_cid( (U8)(i+1) ) NEQ PDP_CONTEXT_STATE_DATA_LINK) )
2474 return 0;
2475
2476 /* This cid is OK: store in works_cids list */
2477 work_cids[i] = cids[i];
2478 i++;
2479 }
2480 work_cids[i] = PDP_CONTEXT_CID_INVALID;
2481 /* Success!!! */
2482 return i;
2483 }
2484 else
2485 {
2486 /* No cids are listed in *cids. Apply cids for all Active context (check not necessary). */
2487 j = 0;
2488 i = 1;
2489 while (i<=PDP_CONTEXT_CID_MAX)
2490 {
2491 if( (get_state_over_cid(i) EQ PDP_CONTEXT_STATE_ACTIVATED) OR
2492 (get_state_over_cid(i) EQ PDP_CONTEXT_STATE_DATA_LINK) )
2493 {
2494 work_cids[j] = i;
2495 j++;
2496 }
2497 i++;
2498 }
2499 work_cids[j] = PDP_CONTEXT_CID_INVALID;
2500 return j;
2501 }
2502 }
2503
2504 /*
2505 +-------------------------------------------------------------------+
2506 | PROJECT : UMTS MODULE : CMH_SMR |
2507 | STATE : finnished ROUTINE : cmhSM_Set_pdp_type |
2508 +-------------------------------------------------------------------+
2509
2510 PURPOSE : Set the pdp_type for a given cid.
2511 RETURN : -
2512 */
2513 GLOBAL void cmhSM_Set_pdp_type( U8 cid, char *pdp_type )
2514 {
2515 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2516
2517 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
2518
2519 if( p_pdp_context_node )
2520 {
2521 memcpy( p_pdp_context_node->attributes.pdp_type, pdp_type, sizeof(T_PDP_TYPE) );
2522 }
2523 else
2524 {
2525 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_Set_pdp_type");
2526 }
2527
2528 }
2529
2530
2531 /*
2532 +----------------------------------------------------------------------+
2533 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2534 | STATE : finnished ROUTINE : cmhSM_get_pdp_addr_for_CGPADDR |
2535 +----------------------------------------------------------------------+
2536
2537 PURPOSE : return the PDP_address to one cid for the GPRS CGPADDR AT command
2538
2539 */
2540 GLOBAL U8 cmhSM_get_pdp_addr_for_CGPADDR( U8 cid, T_NAS_ip * pdp_adress )
2541 {
2542 T_PDP_CONTEXT_STATE c_state; /* state of context */
2543 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2544
2545 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
2546
2547 if( p_pdp_context_node )
2548 {
2549
2550 c_state = get_state_over_cid( cid );
2551
2552 if ( c_state EQ PDP_CONTEXT_STATE_INVALID )
2553 {
2554 //*pdp_adress = 0;
2555 pdp_adress->ctrl_ip_address = NAS_is_ip_not_present;
2556 return PDP_CONTEXT_CID_INVALID;
2557 }
2558
2559 if ( c_state EQ PDP_CONTEXT_STATE_ACTIVATED OR c_state EQ PDP_CONTEXT_STATE_DATA_LINK )
2560 {
2561 memcpy(pdp_adress, &(p_pdp_context_node->internal_data.pdp_address_allocated), sizeof(T_NAS_ip));
2562 }
2563 else
2564 {
2565 memcpy(pdp_adress, &(p_pdp_context_node->attributes.pdp_addr), sizeof(T_NAS_ip));
2566 }
2567
2568 return cid;
2569 }
2570 else
2571 {
2572 pdp_adress->ctrl_ip_address = NAS_is_ip_not_present;
2573 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_get_pdp_addr_for_CGPADDR" );
2574 return PDP_CONTEXT_CID_INVALID;
2575 }
2576
2577 }
2578
2579 /*
2580 +----------------------------------------------------------------------+
2581 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2582 | STATE : finnished ROUTINE : cmhSM_is_smreg_ti_used |
2583 +----------------------------------------------------------------------+
2584
2585 PURPOSE : handle for used ti
2586
2587 */
2588 GLOBAL BOOL cmhSM_is_smreg_ti_used ( U8 ti, U8 *cid )
2589 {
2590 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2591
2592 p_pdp_context_node = pdp_context_find_node_from_smreg_ti( ti );
2593 if( p_pdp_context_node )
2594 {
2595 psaSM_PDP_Deactivate( (USHORT) (1 << CID_TO_NSAPI(p_pdp_context_node->cid) ), PS_REL_IND_YES );
2596 psaGPPP_Terminate( PPP_LOWER_LAYER_UP );
2597
2598 call_waits_in_table = TRUE;
2599 set_state_over_cid( p_pdp_context_node->cid, PDP_CONTEXT_STATE_REACTIVATION_1 );
2600 *cid = p_pdp_context_node->cid;
2601 return TRUE;
2602 }
2603
2604 return FALSE;
2605 }
2606
2607 /*
2608 +----------------------------------------------------------------------+
2609 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2610 | STATE : finnished ROUTINE : cmhSM_context_reactivation |
2611 +----------------------------------------------------------------------+
2612
2613 PURPOSE :
2614
2615 */
2616 GLOBAL void cmhSM_context_reactivation ( void )
2617 {
2618 T_CGEREP_EVENT_REP_PARAM event;
2619 T_SMREG_PDP_ACTIVATE_IND *sm_ind;
2620 SHORT i = 0;
2621
2622 if ( call_waits_in_table EQ TRUE )
2623 {
2624 call_waits_in_table = FALSE;
2625 /*
2626 * GPRS event reporting
2627 */
2628 sm_ind = &gprs_call_table[current_gprs_ct_index].sm_ind;
2629
2630 cmhSM_pdp_typ_to_string(sm_ind->pdp_type, (char*) &event.act.pdp_type);
2631 memcpy(&event.act.pdp_addr, &sm_ind->ip_address.ipv4_addr.a4, NAS_SIZE_IPv4_ADDR);
2632 event.act.cid = gprs_call_table[current_gprs_ct_index].cid;
2633 for( i = 0 ; i < CMD_SRC_MAX; i++ )
2634 {
2635 R_AT( RAT_CRING,(T_ACI_CMD_SRC)i ) ( CRING_MOD_Gprs, CRING_SERV_TYP_GPRS, CRING_SERV_TYP_NotPresent );
2636 R_AT( RAT_CGEREP, (T_ACI_CMD_SRC)i ) ( CGEREP_EVENT_NW_REACT, &event );
2637 R_AT( RAT_P_CGEV, (T_ACI_CMD_SRC)i ) ( CGEREP_EVENT_NW_REACT, &event );
2638 }
2639 }
2640 else
2641 {
2642 cmhSM_next_call_table_entry();
2643 }
2644 }
2645
2646 /*
2647 +----------------------------------------------------------------------+
2648 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2649 | STATE : finnished ROUTINE : cmhSM_stop_context_reactivation |
2650 +----------------------------------------------------------------------+
2651
2652 PURPOSE :
2653
2654 */
2655 GLOBAL void cmhSM_stop_context_reactivation ( void )
2656 {
2657
2658 call_waits_in_table = FALSE;
2659 }
2660
2661 GLOBAL void cmhSM_next_call_table_entry( void )
2662 {
2663 current_gprs_ct_index++;
2664
2665 if ( current_gprs_ct_index >= gprs_ct_index )
2666 {
2667 cmhSM_empty_call_table();
2668 }
2669 else
2670 {
2671 cmhSM_context_reactivation();
2672 }
2673 }
2674
2675 /*
2676 +----------------------------------------------------------------------+
2677 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2678 | STATE : finnished ROUTINE : cmhSM_init_GPRS_DTI_list |
2679 +----------------------------------------------------------------------+
2680
2681 PURPOSE : Init all DTI identifier for GPRS.
2682 */
2683 GLOBAL SHORT cmhSM_connect_working_cid ( void )
2684 {
2685
2686 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2687 UBYTE dti_id;
2688
2689 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[cid_pointer] );
2690
2691 if( p_pdp_context_node )
2692 {
2693 switch ( p_pdp_context_node->internal_data.entity_id )
2694 {
2695 case DTI_ENTITY_PPPS:
2696 {
2697
2698 srcc_new_count( SRCC_PPPS_SNDCP_LINK );
2699
2700 if( IS_SRC_BT(p_pdp_context_node->internal_data.owner) )
2701 {
2702 #if defined TI_GPRS OR TI_DUAL_MODE
2703 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_BLUETOOTH, DTI_ENTITY_PPPS, DTI_ENTITY_UPM, DTI_ENTITY_SNDCP};
2704 #else /* TI_GPRS OR TI_DUAL_MODE */
2705 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_BLUETOOTH, DTI_ENTITY_PPPS, DTI_ENTITY_SNDCP};
2706 #endif /* TI_GPRS OR TI_DUAL_MODE */
2707
2708
2709 dti_id = dti_cntrl_new_dti( DTI_DTI_ID_NOTPRESENT );
2710 dti_cntrl_est_dpath ( dti_id,
2711 entity_list,
2712 GET_NUM_OF_DTI_ENTITIES(entity_list),
2713 SPLIT,
2714 PPP_UART_connect_dti_cb);
2715 }
2716 else
2717 {
2718 #if defined TI_GPRS OR TI_DUAL_MODE
2719 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_PPPS, DTI_ENTITY_UPM, DTI_ENTITY_SNDCP};
2720 #else /* TI_GPRS OR TI_DUAL_MODE */
2721 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_PPPS, DTI_ENTITY_SNDCP};
2722 #endif /* TI_GPRS OR TI_DUAL_MODE */
2723
2724 dti_cntrl_est_dpath_indirect( (UBYTE)p_pdp_context_node->internal_data.owner,
2725 entity_list,
2726 GET_NUM_OF_DTI_ENTITIES(entity_list),
2727 SPLIT,
2728 PPP_UART_connect_dti_cb,
2729 DTI_CPBLTY_SER,
2730 (UBYTE)work_cids[cid_pointer] );
2731
2732 }
2733
2734 m_mt_te_link = TRUE;
2735 break;
2736 }
2737
2738 case DTI_ENTITY_IP:
2739 #if defined CO_UDP_IP
2740 {
2741 #if defined TI_GPRS OR TI_DUAL_MODE
2742 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_IP, DTI_ENTITY_UPM, DTI_ENTITY_SNDCP};
2743 #else /* TI_GPRS OR TI_DUAL_MODE */
2744 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_IP, DTI_ENTITY_SNDCP};
2745 #endif /* TI_GPRS OR TI_DUAL_MODE */
2746 #ifdef FF_SAT_E
2747 if ( satShrdPrm.opchStat EQ OPCH_EST_REQ )
2748 dti_id = simShrdPrm.sat_class_e_dti_id;
2749 else
2750 #endif /* FF_SAT_E */
2751 dti_id = wap_dti_id;
2752
2753 /* link_id should be created in atGD already, so just connect: */
2754 if( !dti_cntrl_est_dpath( dti_id,
2755 entity_list,
2756 GET_NUM_OF_DTI_ENTITIES(entity_list),
2757 APPEND,
2758 IP_UDP_connect_dti_cb) )
2759 {
2760 TRACE_EVENT("cmhSM_connect_working_cid: dti_cntrl_est_dpath returned FALSE");
2761 return 0;
2762 }
2763 }
2764 #endif /* CO_UDP_IP */
2765 break;
2766 #ifdef FF_SAT_E
2767 case DTI_ENTITY_SIM:
2768 {
2769 #if defined TI_GPRS OR TI_DUAL_MODE
2770 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_SIM, DTI_ENTITY_UPM, DTI_ENTITY_SNDCP};
2771 #else /* TI_GPRS OR TI_DUAL_MODE */
2772 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_SIM, DTI_ENTITY_SNDCP};
2773 #endif /* TI_GPRS OR TI_DUAL_MODE */
2774
2775 if ( simShrdPrm.sat_class_e_dti_id EQ DTI_DTI_ID_NOTPRESENT )
2776 {
2777 simShrdPrm.sat_class_e_dti_id = dti_cntrl_new_dti(DTI_DTI_ID_NOTPRESENT);
2778 TRACE_EVENT_P1("sat_class_e_dti_id = %d", simShrdPrm.sat_class_e_dti_id);
2779 }
2780
2781 srcc_new_count( SRCC_SIM_SNDCP_LINK );
2782
2783 p_pdp_context_node->internal_data.link_id = dti_conn_compose_link_id( 0, 0, simShrdPrm.sat_class_e_dti_id, DTI_TUPLE_NO_NOTPRESENT );
2784 dti_cntrl_est_dpath( simShrdPrm.sat_class_e_dti_id,
2785 entity_list,
2786 GET_NUM_OF_DTI_ENTITIES(entity_list),
2787 SPLIT,
2788 SIM_SNDCP_connect_dti_cb );
2789
2790 break;
2791 }
2792 #endif /* FF_SAT_E */
2793
2794 #if defined (FF_GPF_TCPIP)
2795 case DTI_ENTITY_TCPIP:
2796 {
2797 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_TCPIP, DTI_ENTITY_SNDCP};
2798 UBYTE dti_id;
2799 dti_id = wap_dti_id;
2800 /* link_id should be created in atGD already, so just connect: */
2801 if (!dti_cntrl_est_dpath( dti_id,
2802 entity_list,
2803 2,
2804 SPLIT,
2805 TCPIP_connect_dti_cb))
2806 {
2807 TRACE_EVENT("cmhSM_connect_working_cid: dti_cntrl_est_dpath returned FALSE");
2808 return 0;
2809 }
2810 }
2811 break;
2812 #endif // FF_GPF_TCPIP
2813
2814
2815 #if defined(FF_PKTIO) OR defined(FF_TCP_IP) OR defined (FF_PSI)
2816 case DTI_ENTITY_INVALID:
2817 {
2818 #if defined TI_GPRS OR TI_DUAL_MODE
2819 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_UPM, DTI_ENTITY_SNDCP};
2820 #else /* TI_GPRS OR TI_DUAL_MODE */
2821 T_DTI_ENTITY_ID entity_list[] = {DTI_ENTITY_SNDCP};
2822 #endif /* TI_GPRS OR TI_DUAL_MODE */
2823
2824 srcc_new_count( SRCC_PKTIO_SNDCP_LINK );
2825
2826 dti_cntrl_est_dpath_indirect( (UBYTE)p_pdp_context_node->internal_data.owner,
2827 entity_list,
2828 GET_NUM_OF_DTI_ENTITIES(entity_list),
2829 SPLIT,
2830 PKTIO_SNDCP_connect_dti_cb,
2831 DTI_CPBLTY_PKT,
2832 (UBYTE)work_cids[cid_pointer] );
2833
2834 /*
2835 Issue 31781 - If the PDP context is not activated then activate the context.
2836 */
2837 switch ( get_state_working_cid( ) )
2838 {
2839 case PDP_CONTEXT_STATE_DEFINED:
2840 case PDP_CONTEXT_STATE_ATTACHING:
2841 {
2842 cmhSM_activate_context();
2843 }
2844 break;
2845 }
2846 break;
2847 }
2848 #else /* FF_PKTIO OR FF_TCP_IP OR FF_PSI */
2849 case DTI_ENTITY_INVALID:
2850 {
2851 TRACE_ERROR("cmhSM_connect_working_cid(): DTI_ENTITY_INVALID is illegal for this product!!!");
2852 break;
2853 }
2854 #endif /* FF_PKTIO OR FF_TCP_IP */
2855
2856 default:
2857 return 0;
2858
2859 }
2860 }
2861
2862 return 1;
2863 }
2864
2865
2866 /*
2867 +----------------------------------------------------------------------+
2868 | PROJECT : MODULE : CMH_SMF |
2869 | STATE : ROUTINE : cmhSM_disconnect_cid |
2870 +----------------------------------------------------------------------+
2871
2872 PURPOSE :
2873 */
2874 GLOBAL void cmhSM_disconnect_cid ( SHORT cid, T_GPRS_CONNECT_TYPE type )
2875 {
2876 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2877
2878 TRACE_FUNCTION("cmhSM_disconnect_cid");
2879
2880 p_pdp_context_node = pdp_context_find_node_from_cid((U8) cid );
2881
2882 if( p_pdp_context_node )
2883 {
2884
2885 if ( DTI_LINK_ID_NOTPRESENT NEQ p_pdp_context_node->internal_data.link_id)
2886 {
2887 switch ( type )
2888 {
2889 case GC_TYPE_DATA_LINK:
2890 srcc_delete_count( SRCC_PPPS_SNDCP_LINK );
2891 p_pdp_context_node->internal_data.link_id = DTI_LINK_ID_NOTPRESENT;
2892 p_pdp_context_node->internal_data.link_id_uart = DTI_LINK_ID_NOTPRESENT;
2893 m_mt_te_link = FALSE;
2894 break;
2895
2896 #if defined (FF_WAP) OR defined (FF_SAT_E)
2897 case GC_TYPE_WAP:
2898 srcc_delete_count( SRCC_IP_SNDCP_LINK );
2899 p_pdp_context_node->internal_data.link_id = DTI_LINK_ID_NOTPRESENT;
2900 break;
2901 #endif /* FF_WAP OR SAT E */
2902
2903 case GC_TYPE_NULL:
2904 case GC_TYPE_EMAIL:
2905 switch ( p_pdp_context_node->internal_data.entity_id )
2906 {
2907 case DTI_ENTITY_IP:
2908 srcc_delete_count( SRCC_IP_SNDCP_LINK);
2909 p_pdp_context_node->internal_data.link_id = DTI_LINK_ID_NOTPRESENT;
2910 break;
2911 #if defined(FF_PKTIO) OR defined(FF_TCP_IP) OR defined(FF_GPF_TCPIP) OR defined (FF_PSI)
2912 case DTI_ENTITY_PKTIO:
2913 case DTI_ENTITY_PSI:
2914 case DTI_ENTITY_AAA:
2915 srcc_delete_count( SRCC_PKTIO_SNDCP_LINK );
2916 p_pdp_context_node->internal_data.link_id = DTI_LINK_ID_NOTPRESENT;
2917 break;
2918 #endif /* FF_PKTIO OR FF_TCP_IP OR FF_GPF_TCPIP OR FF_PSI */
2919 }
2920 break;
2921 }
2922 }
2923 }
2924 else
2925 {
2926 TRACE_ERROR( "PDP context not found" );
2927 }
2928 }
2929
2930
2931 /*
2932 +----------------------------------------------------------------------+
2933 | PROJECT : MODULE : CMH_SMF |
2934 | STATE : ROUTINE : uart_is_mt_te_link |
2935 +----------------------------------------------------------------------+
2936
2937 PURPOSE :
2938 */
2939 GLOBAL BOOL uart_is_mt_te_link( void )
2940 {
2941
2942 return m_mt_te_link;
2943 }
2944
2945
2946 /*
2947 +----------------------------------------------------------------------+
2948 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
2949 | STATE : finnished ROUTINE : cmhSM_connect_context |
2950 +----------------------------------------------------------------------+
2951
2952 PURPOSE : Activate the context or if the context is already activated
2953 then activate the user plane.
2954 (PPP_ACTIVATE_IND is just received).
2955 */
2956 GLOBAL SHORT cmhSM_connect_context ( U8 cid, T_DTI_ENTITY_ID peer )
2957 {
2958 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2959 U8 hcomp;
2960 U8 dcomp;
2961
2962 TRACE_FUNCTION( "cmhSM_connect_context()" );
2963
2964 /* hcomp value being changed according to spec 27.007 */
2965 hcomp = cmhSM_Get_h_comp() ;
2966 dcomp = cmhSM_Get_d_comp() ;
2967
2968
2969 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
2970 /*
2971 * Activate the context if not already activated.
2972 */
2973 if (p_pdp_context_node)
2974 {
2975 switch (get_state_over_cid(cid))
2976 {
2977 case PDP_CONTEXT_STATE_ESTABLISH_1:
2978 if( p_pdp_context_node->type EQ PDP_CONTEXT_TYPE_PRIMARY )
2979 {
2980 psaSM_smreg_pdp_activate_req( cid,
2981 hcomp,
2982 dcomp);
2983 /*,
2984 PS_RAT_UMTS_FDD);*/
2985 }
2986 #ifdef REL99
2987 else if( p_pdp_context_node->type EQ PDP_CONTEXT_TYPE_SECONDARY )
2988 {
2989 psaSM_smreg_pdp_activate_sec_req( cid );
2990 }
2991 #endif
2992 return 1;
2993 default:
2994 TRACE_ERROR("cmhSM_connect_context: Wrong state!!!");
2995 return 0;
2996 }
2997 }
2998 else
2999 {
3000 TRACE_ERROR( "ERROR: PDP context not found, in function cmhSM_connect_context" );
3001 return 0;
3002 }
3003 }
3004
3005
3006
3007 /*
3008 +----------------------------------------------------------------------+
3009 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3010 | STATE : finnished ROUTINE : cmhSM_set_PCO |
3011 +----------------------------------------------------------------------+
3012
3013 PURPOSE : Set a PCO in the context of the cid.
3014 */
3015 GLOBAL void cmhSM_set_PCO( U8 cid, T_PCO_TYPE pco_type, UBYTE* buf_addr, UBYTE length )
3016 {
3017 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3018
3019 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3020 if( p_pdp_context_node )
3021 {
3022 switch( pco_type )
3023 {
3024 case PCO_USER:
3025 {
3026 /*lint -e(644) */ /* all possible types defined */
3027 memcpy( &p_pdp_context_node->internal_data.user_pco.pco, buf_addr, length );
3028 p_pdp_context_node->internal_data.user_pco.len = length;
3029 break;
3030 }
3031
3032 case PCO_NETWORK:
3033 {
3034 memcpy( &p_pdp_context_node->internal_data.network_pco.pco, buf_addr, length );
3035 p_pdp_context_node->internal_data.network_pco.len = length;
3036 break;
3037 }
3038
3039 }
3040
3041 }
3042 else
3043 {
3044 TRACE_ERROR( "ERROR: PDP context not found, invalid cid" );
3045 }
3046
3047 }
3048
3049 /*
3050 +--------------------------------------------------------------------+
3051 | PROJECT : GSM-PS (8441) MODULE : CMH_SMF |
3052 | STATE : finished ROUTINE : cmhSM_CGPCO_HEX |
3053 +--------------------------------------------------------------------+
3054
3055 PURPOSE : This is the functional counterpart to the %CGPCO= AT
3056 command to set protocol configuration options for the
3057 PDP context activation.
3058 */
3059
3060 GLOBAL T_ACI_RETURN cmhSM_CGPCO_HEX (U8 cid,
3061 UBYTE *pco_array,
3062 UBYTE pco_len )
3063 {
3064 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3065 T_ACI_RETURN ret = AT_CMPL;
3066 U8 i;
3067
3068 TRACE_FUNCTION("cmhSM_CGPCO_HEX");
3069
3070 if (pco_len EQ 0)
3071 {
3072 if( cid EQ PDP_CONTEXT_CID_OMITTED )
3073 {
3074 /* For later contexts */
3075 pdp_context_default.internal_data.user_pco.len = 0;
3076 memset( &pdp_context_default.internal_data.user_pco, 0, sizeof(T_PDP_CONTEXT_PCO) );
3077
3078 /* For defined contexts */
3079 for( i = PDP_CONTEXT_CID_MIN; i <= PDP_CONTEXT_CID_MAX; i++)
3080 {
3081 p_pdp_context_node = pdp_context_find_node_from_cid( i );
3082
3083 if( p_pdp_context_node )
3084 {
3085 p_pdp_context_node->internal_data.user_pco.len = 0;
3086 memset( &p_pdp_context_node->internal_data.user_pco, 0, sizeof(T_PDP_CONTEXT_PCO) );
3087 }
3088 }
3089 }
3090 else
3091 {
3092 /* For specified context */
3093 p_pdp_context_node = pdp_context_find_node_from_cid( (U8)cid );
3094
3095 if( p_pdp_context_node )
3096 {
3097 p_pdp_context_node->internal_data.user_pco.len = 0;
3098 memset( &p_pdp_context_node->internal_data.user_pco, 0, sizeof(T_PDP_CONTEXT_PCO) );
3099 }
3100 else
3101 {
3102 TRACE_EVENT_P1("PDP context for cid = %d not found.", cid );
3103 ret = AT_FAIL;
3104 }
3105 }
3106 }
3107 else
3108 {
3109 if( cid EQ PDP_CONTEXT_CID_OMITTED )
3110 {
3111 /* For later contexts */
3112 pdp_context_default.internal_data.user_pco.len = pco_len;
3113 memcpy( &pdp_context_default.internal_data.user_pco, pco_array, pco_len );
3114
3115 /* For defined contexts */
3116 for( i = PDP_CONTEXT_CID_MIN; i <= PDP_CONTEXT_CID_MAX; i++)
3117 {
3118 p_pdp_context_node = pdp_context_find_node_from_cid( i );
3119
3120 if( p_pdp_context_node )
3121 {
3122 p_pdp_context_node->internal_data.user_pco.len = pco_len;
3123 memcpy( &p_pdp_context_node->internal_data.user_pco.pco, pco_array, pco_len );
3124 }
3125 }
3126 }
3127 else
3128 {
3129 /* For specified context */
3130 p_pdp_context_node = pdp_context_find_node_from_cid( (U8)cid );
3131
3132 if( p_pdp_context_node )
3133 {
3134 p_pdp_context_node->internal_data.user_pco.len = pco_len;
3135 memcpy( &p_pdp_context_node->internal_data.user_pco.pco, pco_array, pco_len );
3136 }
3137 else
3138 {
3139 TRACE_EVENT_P1("PDP context for cid = %d not found.", cid );
3140 ret = AT_FAIL;
3141 }
3142 }
3143 }
3144 return (ret);
3145 }
3146
3147
3148 /*
3149 +----------------------------------------------------------------------+
3150 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3151 | STATE : finnished ROUTINE : cmhSM_get_dti_UPM_peer |
3152 +----------------------------------------------------------------------+
3153
3154 PURPOSE : Give back the link_id for the UPM peer.
3155 */
3156 GLOBAL ULONG cmhSM_get_link_id_UPM_peer( U8 cid )
3157 {
3158 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3159
3160 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3161 if( p_pdp_context_node )
3162 {
3163 return p_pdp_context_node->internal_data.link_id;
3164 }
3165
3166 return DTI_LINK_ID_NOTPRESENT;
3167 }
3168
3169 /*
3170 +----------------------------------------------------------------------+
3171 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3172 | STATE : code ROUTINE : cmhSM_context_deactivated |
3173 +----------------------------------------------------------------------+
3174
3175 PURPOSE : Control the answer of context deactivations
3176 started by an AT command.
3177 */
3178 GLOBAL void cmhSM_context_deactivated( USHORT nsapi_set )
3179 {
3180
3181 switch( working_cgact_actions.state )
3182 {
3183 case T_CDS_RUNNING:
3184 /* For TC ACISAT531
3185 We do not need OK for SAT invoked context !
3186 */
3187 #if defined (FF_SAT_E)
3188 if( ( satShrdPrm.chnTb.chnUsdFlg ) AND
3189 ( satShrdPrm.chnTb.chnType EQ B_GPRS ) )
3190 {
3191 if( nsapi_set EQ (1U << CID_TO_NSAPI(satShrdPrm.chnTb.chnRefId) ) )
3192 {
3193 working_cgact_actions.nsapi_set &= ~nsapi_set;
3194 if ( ! working_cgact_actions.nsapi_set )
3195 {
3196 working_cgact_actions.state = T_CDS_IDLE;
3197 return;
3198 }
3199 }
3200 }
3201 #endif /* SAT Class E */
3202
3203 if ( nsapi_set & working_cgact_actions.nsapi_set )
3204 { /* nsapi deactivation is requested */
3205 working_cgact_actions.nsapi_set &= ~nsapi_set;
3206 if ( ! working_cgact_actions.nsapi_set )
3207 {
3208 R_AT( RAT_OK, working_cgact_actions.srcId ) ( AT_CMD_CGACT );
3209 working_cgact_actions.state = T_CDS_IDLE;
3210 }
3211 }
3212 break;
3213 case T_CDS_IDLE:
3214 break;
3215 }
3216 }
3217
3218 /*
3219 +----------------------------------------------------------------------+
3220 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
3221 | STATE : finnished ROUTINE : deactivateAContextForCGACT |
3222 +----------------------------------------------------------------------+
3223
3224 PURPOSE : deactivate a context for CGACT
3225
3226 RETURN VALUE : TRUE - AT_EXCT have to be returned for this context
3227 FALSE - AT_CMPL have to be reported for this context
3228
3229 */
3230 T_ACI_RETURN deactivateAContextForCGACT(U8 cid)
3231 {
3232
3233 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3234
3235 TRACE_FUNCTION("deactivateAContextForCGACT()");
3236
3237 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3238 if( !p_pdp_context_node )
3239 {
3240 TRACE_EVENT("ERROR: PDP context not defined");
3241 return( AT_FAIL );
3242 }
3243
3244 #if defined (CO_UDP_IP) OR defined (FF_GPF_TCPIP)
3245 /*
3246 * additinal behaviour for WAP
3247 * abort ATD*98# before context activation requested
3248 * 2003.05.06 brz
3249 */
3250 if( TRUE NEQ srcc_reserve_sources( SRCC_IP_SNDCP_LINK, 1 ) AND
3251 DTI_LINK_ID_NOTPRESENT NEQ p_pdp_context_node->internal_data.link_id_new AND
3252 cid EQ work_cids[cid_pointer] OR
3253 p_pdp_context_node->internal_data.entity_id EQ DTI_ENTITY_IP )
3254 {
3255 /* tell WAP ACI that contextactivation was rejected */
3256 TRACE_EVENT("Tell WAP ACI that contextactivation was rejected");
3257 psaTCPIP_Deactivate(cmhSM_IP_activate_cb);
3258
3259 if ( PDP_CONTEXT_STATE_DEFINED EQ p_pdp_context_node->internal_data.state )
3260 {
3261 if(is_gpf_tcpip_call()) {
3262 GPF_TCPIP_STATEMENT(wap_state = TCPIP_Deactivation);
3263 }
3264 else {
3265 wap_state = UDPA_Deactivation;
3266 }
3267 dti_cntrl_close_dpath_from_dti_id(
3268 EXTRACT_DTI_ID(p_pdp_context_node->internal_data.link_id));
3269 }
3270
3271 /* srcc_delete_count(SRCC_IP_SNDCP_LINK); */
3272 return cmhSM_deactivateAContext(CMD_SRC_NONE, cid);
3273 }
3274 else
3275 #endif /* CO_UDP_IP OR FF_GPF_TCPIP */
3276 if( PDP_CONTEXT_STATE_DEFINED NEQ p_pdp_context_node->internal_data.state AND
3277 PDP_CONTEXT_STATE_INVALID NEQ p_pdp_context_node->internal_data.state )
3278 {
3279 return cmhSM_deactivateAContext(CMD_SRC_NONE, cid);
3280 }
3281 return AT_CMPL;
3282 }
3283
3284 /*
3285 +----------------------------------------------------------------------+
3286 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3287 | STATE : finnished ROUTINE : cmhSM_deactivateAContext |
3288 +----------------------------------------------------------------------+
3289
3290 PURPOSE : deactivate some contexts (able for serial multiplexer mode).
3291 */
3292 GLOBAL T_ACI_RETURN cmhSM_deactivateContexts( T_ACI_CMD_SRC srcId, SHORT *cids)
3293 {
3294 T_ACI_RETURN ret_value = AT_CMPL;
3295 USHORT nsapi_set = 0;
3296 U8 cid_set = 0;
3297 SHORT i = 0;
3298 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3299
3300 TRACE_FUNCTION("cmhSM_deactivateContexts");
3301
3302 if( T_CDS_RUNNING EQ working_cgact_actions.state) {
3303 TRACE_EVENT("cgact_ation is running: bussy returned");
3304 return AT_FAIL; /* AT_BUSY */
3305 }
3306
3307 cid_pointer = 0;
3308 if( *cids EQ PDP_CONTEXT_CID_INVALID )
3309 { /* all available contexts */
3310
3311 p_pdp_context_node = p_pdp_context_list;
3312 while( p_pdp_context_node )
3313 {
3314 work_cids[i] = p_pdp_context_node->cid;
3315 i++;
3316 p_pdp_context_node = p_pdp_context_node->p_next;
3317 }
3318
3319 work_cids[i] = PDP_CONTEXT_CID_INVALID;
3320
3321 if( work_cids[0] EQ PDP_CONTEXT_CID_INVALID )
3322 {
3323 return AT_CMPL;
3324 }
3325 }
3326 else
3327 { /* copy cid list */
3328
3329 for( i = 0; cids[i] NEQ PDP_CONTEXT_CID_INVALID; i++ )
3330 {
3331 work_cids[i] = (U8)cids[i];
3332 }
3333 }
3334
3335 for(i = 0; work_cids[i] NEQ PDP_CONTEXT_CID_INVALID; i++)
3336 {
3337 p_pdp_context_node = pdp_context_find_node_from_cid( work_cids[i] );
3338
3339 if( !p_pdp_context_node )
3340 continue;
3341
3342 if(AT_EXCT EQ deactivateAContextForCGACT( work_cids[i] ))
3343 {
3344 ret_value = AT_EXCT;
3345 nsapi_set |= ( 1 << CID_TO_NSAPI (work_cids[i]) );
3346 cid_set |= ( 1 << work_cids[i] );
3347 }
3348 }
3349
3350 if( nsapi_set ) {
3351 working_cgact_actions.state = T_CDS_RUNNING;
3352 working_cgact_actions.nsapi_set = nsapi_set;
3353 working_cgact_actions.srcId = srcId;
3354 working_cgact_actions.cid_set = cid_set;
3355 }
3356
3357 cmhSM_stop_context_reactivation();
3358
3359 return ret_value;
3360 }
3361
3362 /*
3363 +----------------------------------------------------------------------+
3364 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3365 | STATE : finnished ROUTINE : cmhSM_CGACT_start |
3366 +----------------------------------------------------------------------+
3367
3368 PURPOSE : Set specific +CGACT command parameter.
3369 */
3370 GLOBAL void cmhSM_CGACT_start( T_CGACT_STATE state, USHORT nsapi_set )
3371 {
3372
3373 working_cgact_actions.state = (T_CONTEXTS_DEACTIVATION_STATUS)state;
3374 working_cgact_actions.nsapi_set = nsapi_set;
3375
3376 }
3377
3378
3379
3380 /*
3381 +----------------------------------------------------------------------+
3382 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3383 | STATE : finnished ROUTINE : cmhSM_getCurQOS |
3384 +----------------------------------------------------------------------+
3385
3386 PURPOSE : This function returns the current QOS settings.
3387 */
3388 #ifdef FF_SAT_E
3389 GLOBAL T_PS_qos* cmhSM_getCurQOS( U8 cid )
3390 {
3391 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3392 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3393 if (p_pdp_context_node)
3394 return &p_pdp_context_node->qos;
3395 return NULL;
3396 }
3397 #endif /* FF_SAT_E */
3398
3399 /*
3400 +----------------------------------------------------------------------+
3401 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3402 | STATE : finnished ROUTINE : cmhSM_deactivateAContext |
3403 +----------------------------------------------------------------------+
3404
3405 PURPOSE : deactivate a contexts (able for serial multiplexer mode).
3406 */
3407 GLOBAL T_ACI_RETURN cmhSM_deactivateAContext( T_ACI_CMD_SRC srcId, U8 cid )
3408 {
3409 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3410
3411 TRACE_FUNCTION("cmhSM_deactivateAContext()") ;
3412
3413 switch( get_state_over_cid( cid ) )
3414 {
3415 case PDP_CONTEXT_STATE_INVALID:
3416 case PDP_CONTEXT_STATE_DEFINED:
3417 /*
3418 * context ís deactivated -> not action necessary
3419 */
3420 break;
3421
3422 case PDP_CONTEXT_STATE_ATTACHING:
3423 /*
3424 * +CGDATA or +CGACT has started the attach procedure and which is stopped.
3425 */
3426 set_state_over_cid( cid, PDP_CONTEXT_STATE_DEFINED );
3427 psaGMM_Detach( GMMREG_DT_GPRS );
3428 gpppEntStat.curCmd = AT_CMD_NONE;
3429 smEntStat.curCmd = AT_CMD_NONE;
3430 work_cids[0] = PDP_CONTEXT_CID_INVALID;
3431 cid_pointer = 0;
3432 if( CMD_SRC_NONE EQ srcId )
3433 {
3434 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3435 p_pdp_context_node->internal_data.owner = gpppEntStat.entOwn;
3436 gaci_RAT_caller ( RAT_NO_CARRIER, cid, AT_CMD_CGDATA, 0 );
3437 }
3438 return AT_CMPL;
3439
3440 case PDP_CONTEXT_STATE_ESTABLISH_1:
3441 /*
3442 * context not activated, but PPP has to be terminated
3443 */
3444 set_state_over_cid( cid, PDP_CONTEXT_STATE_ABORT_ESTABLISH );
3445 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3446 dti_cntrl_entity_disconnected( p_pdp_context_node->internal_data.link_id_new, DTI_ENTITY_SNDCP );
3447 if (uartShrdPrm.escape_seq EQ UART_DETECT_ESC)
3448 {
3449 psaGPPP_Terminate( PPP_LOWER_LAYER_DOWN );
3450 }
3451 else
3452 {
3453 psaGPPP_Terminate( PPP_LOWER_LAYER_UP );
3454 }
3455 uartShrdPrm.escape_seq = UART_DETECT_DTR;
3456 /* The user plane will be closed when the PPP_TERMINATE_IND is received */
3457 return AT_EXCT;
3458
3459 case PDP_CONTEXT_STATE_DATA_LINK:
3460 case PDP_CONTEXT_STATE_ESTABLISH_2:
3461 case PDP_CONTEXT_STATE_ESTABLISH_3:
3462 case PDP_CONTEXT_STATE_ACTIVATED_ESTABLISH_1:
3463 /*
3464 * context has to be deactivated and PPP has to be terminated
3465 */
3466 set_state_over_cid( cid, PDP_CONTEXT_STATE_REACTIVATION_1 );
3467 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3468 psaSM_PDP_Deactivate( (USHORT) (1 << CID_TO_NSAPI( cid )), PS_REL_IND_NO);
3469 /* The terminate request to PPP entitiy will be done in DTI for the
3470 disconnection when PSI is enabled */
3471 #ifndef FF_PSI
3472 psaGPPP_Terminate( PPP_LOWER_LAYER_UP );
3473 #endif /* FF_PSI */
3474 return AT_EXCT;
3475
3476 case PDP_CONTEXT_STATE_ACTIVATED:
3477 case PDP_CONTEXT_STATE_ACTIVATING:
3478 /*
3479 * +CGACT aborted
3480 */
3481 set_state_over_cid( cid, PDP_CONTEXT_STATE_DEACTIVATE_NORMAL );
3482 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3483 psaSM_PDP_Deactivate( (USHORT) (1 << CID_TO_NSAPI( cid )), PS_REL_IND_NO);
3484
3485 if( p_pdp_context_node->internal_data.entity_id EQ DTI_ENTITY_PKTIO )
3486 {
3487 /* For PKTIO we are not maintaining any other states other than
3488 PDP_CONTEXT_STATE_ACTIVATED and PDP_CONTEXT_STATE_ACTIVATING
3489 and in this case after entering data mode if we deactivate the
3490 PDP context, we are not taking care of freeing the DTI links
3491 between PKTIO and other Neighboring entity
3492 This is done if the entity is PKTIO.
3493 As for PPP the DTI link free is taken care by PPP
3494 primitives between ACI and PPP
3495 */
3496 TRACE_EVENT("cmhSM_deactivateAContext: Free the DTI Links fpr PKTIO Entity after CGACT=0,1");
3497 TRACE_EVENT("States: PDP_CONTEXT_STATE_ACTIVATED OR PDP_CONTEXT_STATE_ACTIVATING");
3498 dti_cntrl_close_dpath_from_dti_id (EXTRACT_DTI_ID(p_pdp_context_node->internal_data.link_id));
3499 }
3500 return AT_EXCT;
3501
3502 case PDP_CONTEXT_STATE_ABORT_ESTABLISH:
3503 case PDP_CONTEXT_STATE_DEACTIVATE_NORMAL:
3504 case PDP_CONTEXT_STATE_BREAKDOWN_LINK_NORMAL:
3505 /*
3506 * context is during deactivation procedure -> not action necessary
3507 */
3508 return AT_EXCT;
3509
3510 case PDP_CONTEXT_STATE_REACTIVATION_1:
3511 case PDP_CONTEXT_STATE_REACTIVATION_2:
3512 /*
3513 * context is during deactivation procedure
3514 * -> not action for context deactivation or PPP termination necessary
3515 */
3516 return AT_EXCT;
3517 }
3518
3519 return AT_FAIL;
3520 }
3521
3522
3523 GLOBAL BOOL cmhSM_isContextActive( void )
3524 {
3525
3526 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3527
3528 p_pdp_context_node = p_pdp_context_list;
3529
3530 while( p_pdp_context_node )
3531 {
3532 if( p_pdp_context_node->internal_data.state EQ PDP_CONTEXT_STATE_ACTIVATED OR
3533 p_pdp_context_node->internal_data.state EQ PDP_CONTEXT_STATE_ACTIVATED_ESTABLISH_1 OR
3534 p_pdp_context_node->internal_data.state EQ PDP_CONTEXT_STATE_ACTIVATED_MODIFYING OR
3535 p_pdp_context_node->internal_data.state EQ PDP_CONTEXT_STATE_DATA_LINK OR
3536 p_pdp_context_node->internal_data.state EQ PDP_CONTEXT_STATE_DATA_LINK_MODIFYING )
3537
3538 return TRUE;
3539 else
3540 p_pdp_context_node = p_pdp_context_node->p_next;
3541 }
3542
3543 return FALSE;
3544
3545 }
3546
3547
3548 LOCAL void cmhSM_free_pdpcontext_tft(T_TFT_INTERNAL * pdp_tft)
3549 {
3550 TRACE_FUNCTION("cmhSM_free_pdpcontext_tft");
3551 if(pdp_tft->p_next)
3552 {
3553 cmhSM_free_pdpcontext_tft(pdp_tft->p_next);
3554 }
3555 ACI_MFREE(pdp_tft);
3556
3557 }
3558
3559
3560 LOCAL void cmhSM_free_pdpcontext( T_PDP_CONTEXT_INTERNAL * p_pdp_context)
3561 {
3562 //recursive call so that the contexts will be deallocated from last to first.
3563 //when p_next pointer is null, it will proceed to deallocate the PDP context itself
3564 TRACE_FUNCTION("cmhSM_free_pdpcontext");
3565 if (p_pdp_context->p_next)
3566 {
3567 cmhSM_free_pdpcontext(p_pdp_context->p_next);
3568 }
3569 //If one exist, it shall be deallocated together with the PDP context
3570 if (p_pdp_context->internal_data.p_pdp_activate_cnf)
3571 {
3572 ACI_MFREE(p_pdp_context->internal_data.p_pdp_activate_cnf);
3573 }
3574
3575 if (p_pdp_context->p_tft_pf)
3576 {
3577 cmhSM_free_pdpcontext_tft(p_pdp_context->p_tft_pf);
3578 }
3579
3580 ACI_MFREE(p_pdp_context);
3581 }
3582
3583
3584 GLOBAL void cmhSM_free_pdpcontext_list(void)
3585 {
3586 TRACE_FUNCTION("cmhSM_free_pdpcontext_list");
3587 if (p_pdp_context_list)
3588 cmhSM_free_pdpcontext(p_pdp_context_list);
3589 }
3590
3591 /*
3592 +----------------------------------------------------------------------+
3593 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3594 | STATE : finnished ROUTINE : cmhSM_mapSM2ACI_Cause() |
3595 +----------------------------------------------------------------------+
3596
3597 PURPOSE : The below function is used to MAP the SMREG cause values
3598 sent by N/W to the ACI specific ERROR's. Refer 27.007
3599 Section 9.2.
3600 */
3601
3602 GLOBAL UBYTE cmhSM_mapSM2ACI_Cause(U16 cause_value)
3603 {
3604 TRACE_FUNCTION("cmhSM_mapSM2ACI_Cause");
3605
3606 switch(cause_value)
3607 {
3608 case CAUSE_NWSM_USER_AUTH_FAILED :
3609 return CME_ERR_GPRSPdpAuth;
3610
3611 case CAUSE_NWSM_SERVICE_NOT_SUPPORTED :
3612 return CME_ERR_GPRSSerOptNsup;
3613
3614 case CAUSE_NWSM_SERVICE_NOT_SUBSCRIBED :
3615 return CME_ERR_GPRSSerOptNsub;
3616
3617 case CAUSE_NWSM_SERVICE_TEMP_OUT_OF_ORDER :
3618 return CME_ERR_GPRSSerOptOOO;
3619
3620 default:
3621 return CME_ERR_GPRSUnspec;
3622 }
3623 }
3624
3625
3626 /*
3627 +----------------------------------------------------------------------+
3628 | PROJECT : GPRS (8441) MODULE : CMH_SMF |
3629 | STATE : finnished ROUTINE : cmhSM_clear_work_cids |
3630 +----------------------------------------------------------------------+
3631
3632 PURPOSE : The below function will decide whether to clear work_cids
3633 and cid_pointer variables.
3634 */
3635
3636 GLOBAL void cmhSM_clear_work_cids(U8 cid)
3637 {
3638 U8 index = 0;
3639
3640 TRACE_FUNCTION("cmhSM_clear_work_cids()");
3641
3642 while( index < PDP_CONTEXT_CID_MAX )
3643 {
3644 if(cid NEQ work_cids[index])
3645 {
3646 index++;
3647 }
3648 else if( pdp_context_get_state_for_cid(cid) EQ PDP_CONTEXT_STATE_DEFINED )
3649 {
3650 /*
3651 If the state of the cid is other than PDP_CONTEXT_STATE_DEFINED then
3652 don't clear the work_cids[].
3653 */
3654 TRACE_EVENT_P2("cmhSM_clear_work_cids(): Clear the work_cid value for the cid and for the location work_cids[index]= %d, %d", cid, index);
3655 work_cids[index++] = PDP_CONTEXT_CID_INVALID;
3656 }
3657 else
3658 {
3659 index++;
3660 }
3661 }
3662
3663 /*
3664 Check whether the work_cids[] contains any valid cids which are in the
3665 state, other than PDP_CONTEXT_CID_INVALID.
3666 */
3667 while ( ( index < PDP_CONTEXT_CID_MAX ) AND ( work_cids[index] EQ PDP_CONTEXT_CID_INVALID ) )
3668 {
3669 index++;
3670 }
3671
3672 /*
3673 After scnaing whole work_cids[] if we didn't find any valid cids in the
3674 work_cids[] list, then clear the work_cids[].
3675 */
3676 if (index >= PDP_CONTEXT_CID_MAX)
3677 {
3678 TRACE_EVENT("cmhSM_clear_work_cids(): Clear the whole work_cid[] list and cid_pointer");
3679 *work_cids = PDP_CONTEXT_CID_INVALID;
3680 cid_pointer = 0;
3681 smEntStat.curCmd = AT_CMD_NONE;
3682 }
3683 }
3684
3685 #endif /* GPRS */
3686 /*==== EOF ========================================================*/