comparison gsm-fw/g23m-aci/aci/cmh_sms.c @ 775:eedbf248bac0

gsm-fw/g23m-aci subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 12 Oct 2014 01:45:14 +0000
parents
children
comparison
equal deleted inserted replaced
774:40a721fd9854 775:eedbf248bac0
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 implements the set fuinctions related to the
18 | protocol stack adapter for GPRS session management ( SM ).
19 +-----------------------------------------------------------------------------
20 */
21
22 #if defined (GPRS) && defined (DTI)
23
24 #ifndef CMH_SMS_C
25 #define CMH_SMS_C
26 #endif
27
28 #include "aci_all.h"
29
30 /*==== INCLUDES ===================================================*/
31 #include "dti.h" /* functionality of the dti library */
32 #include "aci_cmh.h"
33 #include "ati_cmd.h"
34 #include "aci_cmd.h"
35 #include "aci_io.h"
36
37 #include "dti_conn_mng.h"
38 #include "dti_cntrl_mng.h"
39
40 #include "gaci.h"
41 #include "gaci_cmh.h"
42 #include "psa.h"
43 #include "psa_sm.h"
44 #include "psa_gppp.h"
45 #include "psa_gmm.h"
46 #include "psa_tcpip.h"
47
48 #include "cmh.h"
49 #include "cmh_sm.h"
50 #include "cmh_gppp.h"
51 #include "cmh_gmm.h"
52 #include "gaci_srcc.h"
53 #include "aci_mem.h"
54
55 #include "cl_inline.h"
56 #include "phb.h"
57 #include "wap_aci.h"
58
59 /*==== CONSTANTS ==================================================*/
60
61 /*==== EXPORT =====================================================*/
62
63 /*==== VARIABLES ==================================================*/
64 EXTERN T_PDP_CONTEXT_INTERNAL *p_pdp_context_list;
65
66
67 /*==== FUNCTIONS ==================================================*/
68 LOCAL void string_to_dns(CHAR* dns, ULONG *dns_long);
69 /*
70 +--------------------------------------------------------------------+
71 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
72 | STATE : finnished ROUTINE : sAT_PlusCGQREQ |
73 +--------------------------------------------------------------------+
74
75 PURPOSE : This is the functional counterpart to the +CGQREQ= AT
76 command which sets the requested QOS.
77 */
78 GLOBAL T_ACI_RETURN sAT_PlusCGQREQ( T_ACI_CMD_SRC srcId, U8 cid ,T_PS_qos *qos)
79 {
80 T_ACI_RETURN retCd; /* holds return code */
81 T_PDP_CONTEXT_STATE context_state; /* state of context */
82 T_PS_qos_r99 temp_qos; /* Temp. var to hold R99 input parameters for conversion */
83 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
84
85 TRACE_FUNCTION ("sAT_PlusCGQREQ()");
86
87 /* Need work to fit into R99 QoS SMNEW 05032001
88 *-------------------------------------------------------------------
89 * check entity status
90 *-------------------------------------------------------------------
91 */
92 if( smEntStat.curCmd NEQ AT_CMD_NONE )
93
94 return( AT_BUSY );
95
96 /*
97 *-------------------------------------------------------------------
98 * check parameter
99 *-------------------------------------------------------------------
100 */
101 if ( ((cid < PDP_CONTEXT_CID_MIN) OR (cid > PDP_CONTEXT_CID_MAX)) AND (cid NEQ PDP_CONTEXT_CID_OMITTED) )
102 {
103 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
104 return AT_FAIL;
105 }
106
107 if( qos )
108 {
109 if( (qos->qos_r97.preced > 3) AND
110 (qos->qos_r97.preced NEQ PDP_CONTEXT_QOS_OMITTED) )
111 {
112 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
113 return( AT_FAIL );
114 }
115
116 if( (qos->qos_r97.delay > 4) AND
117 (qos->qos_r97.delay NEQ PDP_CONTEXT_QOS_OMITTED ))
118 {
119 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
120 return( AT_FAIL );
121 }
122 if( (qos->qos_r97.relclass > 5) AND
123 (qos->qos_r97.relclass NEQ PDP_CONTEXT_QOS_OMITTED ))
124 {
125 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
126 return( AT_FAIL );
127 }
128 if( (qos->qos_r97.peak > 9) AND
129 (qos->qos_r97.peak NEQ PDP_CONTEXT_QOS_OMITTED ))
130 {
131 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
132 return( AT_FAIL );
133 }
134 if( (qos->qos_r97.mean > 18) AND
135 (qos->qos_r97.mean NEQ 31) AND
136 (qos->qos_r97.mean NEQ PDP_CONTEXT_QOS_OMITTED ))
137 {
138 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
139 return( AT_FAIL );
140 }
141 }
142
143 /*
144 *-------------------------------------------------------------------
145 * process parameter
146 *-------------------------------------------------------------------
147 */
148 if (cid EQ PDP_CONTEXT_CID_OMITTED )
149 /*
150 * cid omitted: A special form of the set command that is not defined in the Spec.
151 * This set the default value of QoS.
152 */
153 {
154 cmhSM_change_def_QOS( qos, PS_is_R97 );
155
156 retCd = AT_CMPL;
157 }
158 else
159 {
160 context_state = pdp_context_get_state_for_cid( cid );
161
162 if ( !qos OR ( qos->qos_r97.preced EQ PDP_CONTEXT_QOS_OMITTED AND
163 qos->qos_r97.delay EQ PDP_CONTEXT_QOS_OMITTED AND
164 qos->qos_r97.relclass EQ PDP_CONTEXT_QOS_OMITTED AND
165 qos->qos_r97.peak EQ PDP_CONTEXT_QOS_OMITTED AND
166 qos->qos_r97.mean EQ PDP_CONTEXT_QOS_OMITTED ) )
167
168 { /* QoS omitted -> undefine the requested QOS */
169 if ( context_state EQ PDP_CONTEXT_STATE_INVALID )
170 {
171 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
172 return( AT_FAIL );
173 }
174
175 cmhSM_Set_default_QOS( cid );
176
177 retCd = AT_CMPL;
178 }
179 else
180 { /* define the requested QOS */
181 if ( context_state EQ PDP_CONTEXT_STATE_INVALID )
182 {
183 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
184 return( AT_FAIL );
185 }
186
187 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
188 if( p_pdp_context_node )
189 {
190 if( p_pdp_context_node->ctrl_qos EQ PS_is_R99 )
191 {
192 /* Convert existing R99 parameters to R97 parameters */
193 memcpy( &temp_qos, &p_pdp_context_node->qos.qos_r99, sizeof(T_PS_qos_r99) );
194 if( !cl_qos_convert_r99_to_r97( &temp_qos, &p_pdp_context_node->qos.qos_r97) )
195 return( AT_FAIL );
196 }
197
198 p_pdp_context_node->ctrl_qos = PS_is_R97;
199
200 if( qos->qos_r97.preced NEQ PDP_CONTEXT_QOS_OMITTED )
201 p_pdp_context_node->qos.qos_r97.preced = qos->qos_r97.preced;
202 if( qos->qos_r97.delay NEQ PDP_CONTEXT_QOS_OMITTED )
203 p_pdp_context_node->qos.qos_r97.delay = qos->qos_r97.delay;
204 if( qos->qos_r97.relclass NEQ PDP_CONTEXT_QOS_OMITTED )
205 p_pdp_context_node->qos.qos_r97.relclass = qos->qos_r97.relclass;
206 if( qos->qos_r97.peak NEQ PDP_CONTEXT_QOS_OMITTED )
207 p_pdp_context_node->qos.qos_r97.peak = qos->qos_r97.peak;
208 if( qos->qos_r97.mean NEQ PDP_CONTEXT_QOS_OMITTED )
209 p_pdp_context_node->qos.qos_r97.mean = qos->qos_r97.mean;
210
211 retCd = AT_CMPL;
212 }
213 else
214 {
215 retCd = AT_FAIL;
216 }
217
218 }
219
220 }
221
222 return retCd;
223 }
224
225 /*
226 +--------------------------------------------------------------------+
227 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
228 | STATE : finnished ROUTINE : sAT_PlusCGQMIN |
229 +--------------------------------------------------------------------+
230
231 PURPOSE : This is the functional counterpart to the +CGQMIN= AT
232 command which sets the minimum acceptable QOS.
233 */
234 GLOBAL T_ACI_RETURN sAT_PlusCGQMIN( T_ACI_CMD_SRC srcId, U8 cid ,T_PS_min_qos *qos)
235 {
236 T_ACI_RETURN retCd; /* holds return code */
237 T_PDP_CONTEXT_STATE context_state; /* state of context */
238 T_PS_qos_r99 temp_qos; /* Temp. var to hold R99 input parameters for conversion */
239 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
240
241 TRACE_FUNCTION ("sAT_PlusCGQMIN()");
242
243 /*
244 *-------------------------------------------------------------------
245 * check entity status
246 *-------------------------------------------------------------------
247 */
248 if( smEntStat.curCmd NEQ AT_CMD_NONE )
249
250 return( AT_BUSY );
251
252 /*
253 *-------------------------------------------------------------------
254 * check parameter
255 *-------------------------------------------------------------------
256 */
257 if ( ((cid < PDP_CONTEXT_CID_MIN) OR (cid > PDP_CONTEXT_CID_MAX)) AND (cid NEQ PDP_CONTEXT_CID_OMITTED) )
258 {
259 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
260 return AT_FAIL;
261 }
262
263 if ( qos )
264 {
265 if( (qos->qos_r97.preced > 3) AND
266 (qos->qos_r97.preced NEQ PDP_CONTEXT_QOS_OMITTED ))
267 {
268 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
269 return( AT_FAIL );
270 }
271
272 if( (qos->qos_r97.delay > 4) AND
273 (qos->qos_r97.delay NEQ PDP_CONTEXT_QOS_OMITTED ))
274 {
275 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
276 return( AT_FAIL );
277 }
278 if( (qos->qos_r97.relclass > 5) AND
279 (qos->qos_r97.relclass NEQ PDP_CONTEXT_QOS_OMITTED ))
280 {
281 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
282 return( AT_FAIL );
283 }
284 if( (qos->qos_r97.peak > 9) AND
285 (qos->qos_r97.peak NEQ PDP_CONTEXT_QOS_OMITTED ))
286 {
287 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
288 return( AT_FAIL );
289 }
290 if( (qos->qos_r97.mean > 18) AND
291 (qos->qos_r97.mean NEQ 31) AND
292 (qos->qos_r97.mean NEQ PDP_CONTEXT_QOS_OMITTED ))
293 {
294 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
295 return( AT_FAIL );
296 }
297 }
298
299 /*
300 *-------------------------------------------------------------------
301 * process parameter
302 *-------------------------------------------------------------------
303 */
304 if( cid EQ PDP_CONTEXT_CID_OMITTED )
305 /*
306 * cid omitted: A special form of the set command that is not defined in the Spec.
307 * This set the default value of QoS.
308 */
309 {
310 cmhSM_change_def_QOS_min( qos, (T_PS_ctrl_min_qos)PS_is_R97 );
311
312 retCd = (T_ACI_RETURN)AT_CMPL;
313 }
314 else
315 {
316 context_state = pdp_context_get_state_for_cid( cid );
317
318 if ( !qos OR ( qos->qos_r97.preced EQ PDP_CONTEXT_QOS_OMITTED AND
319 qos->qos_r97.delay EQ PDP_CONTEXT_QOS_OMITTED AND
320 qos->qos_r97.relclass EQ PDP_CONTEXT_QOS_OMITTED AND
321 qos->qos_r97.peak EQ PDP_CONTEXT_QOS_OMITTED AND
322 qos->qos_r97.mean EQ PDP_CONTEXT_QOS_OMITTED ) )
323 { /* QoS omitted -> undefine the requested QOS */
324
325 if ( context_state EQ PDP_CONTEXT_STATE_INVALID )
326 {
327 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
328 return( AT_FAIL );
329 }
330
331 cmhSM_Set_default_QOS_min( cid );
332
333 retCd = AT_CMPL;
334 }
335 else
336 { /* define the requested QOS */
337
338 if ( context_state EQ PDP_CONTEXT_STATE_INVALID )
339 {
340 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
341 return( AT_FAIL );
342 }
343
344 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
345
346 if( p_pdp_context_node )
347 {
348
349 if( p_pdp_context_node->ctrl_min_qos EQ (T_PS_ctrl_min_qos)PS_is_R99 )
350 {
351 /* Convert existing R99 parameters to R97 parameters */
352 memcpy( &temp_qos, &p_pdp_context_node->min_qos.qos_r99, sizeof(T_PS_qos_r99) );
353 if( !cl_qos_convert_r99_to_r97( &temp_qos, &p_pdp_context_node->min_qos.qos_r97) )
354 return( AT_FAIL );
355 }
356
357 p_pdp_context_node->ctrl_min_qos = (T_PS_ctrl_min_qos)PS_is_R97;
358
359 /* Set input values for context or keep the previous/converted values if omitted */
360 if( qos->qos_r97.preced EQ PDP_CONTEXT_QOS_OMITTED )
361 p_pdp_context_node->min_qos.qos_r97.preced = PS_PRECED_SUB;
362 else
363 p_pdp_context_node->min_qos.qos_r97.preced = qos->qos_r97.preced;
364
365 if( qos->qos_r97.delay EQ PDP_CONTEXT_QOS_OMITTED )
366 p_pdp_context_node->min_qos.qos_r97.delay = PS_DELAY_SUB;
367 else
368 p_pdp_context_node->min_qos.qos_r97.delay = qos->qos_r97.delay;
369
370 if( qos->qos_r97.relclass EQ PDP_CONTEXT_QOS_OMITTED )
371 p_pdp_context_node->min_qos.qos_r97.relclass = PS_RELCLASS_SUB;
372 else
373 p_pdp_context_node->min_qos.qos_r97.relclass = qos->qos_r97.relclass;
374
375 if( qos->qos_r97.peak EQ PDP_CONTEXT_QOS_OMITTED )
376 p_pdp_context_node->min_qos.qos_r97.peak = PS_PEAK_SUB;
377 else
378 p_pdp_context_node->min_qos.qos_r97.peak = qos->qos_r97.peak;
379
380 if( qos->qos_r97.mean EQ PDP_CONTEXT_QOS_OMITTED )
381 p_pdp_context_node->min_qos.qos_r97.mean = PS_MEAN_SUB;
382 else
383 p_pdp_context_node->min_qos.qos_r97.mean = qos->qos_r97.mean;
384
385 retCd = AT_CMPL;
386 }
387 else
388 {
389 retCd = AT_FAIL;
390 }
391
392 }
393
394 }
395
396 return retCd;
397 }
398
399 #ifdef REL99
400 /*
401 +--------------------------------------------------------------------+
402 | PROJECT : UMTS MODULE : CMH_SMS |
403 | STATE : devellopment ROUTINE : sAT_PlusCGEQREQ |
404 +--------------------------------------------------------------------+
405
406 PURPOSE : This is the functional counterpart to the +CGEQREQ= AT
407 command which sets the 3G requested QOS parameters.
408 */
409 GLOBAL T_ACI_RETURN sAT_PlusCGEQREQ( T_ACI_CMD_SRC srcId, U8 cid, T_PS_qos *qos )
410 {
411 T_ACI_RETURN retCd; /* holds return code */
412 T_PDP_CONTEXT_STATE c_state; /* state of context */
413 BOOL outOfRange; /* TRUE if one or more parameters are out of range */
414 U16 tempComp; /* Used for range check of SDU error ratio and bit error ratio */
415 T_PS_qos_r97 temp_qos; /* Temp. var to hold R97 input parameters for conversion */
416 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
417
418 TRACE_FUNCTION( "sAT_PlusCGEQREQ()" );
419
420 outOfRange = FALSE;
421
422 if( smEntStat.curCmd NEQ AT_CMD_NONE )
423 return( AT_BUSY );
424
425 /*
426 *-------------------------------------------------------------------
427 * Parameter range check.
428 *-------------------------------------------------------------------
429 */
430 if ( ((cid < PDP_CONTEXT_CID_MIN) OR (cid > PDP_CONTEXT_CID_MAX)) AND (cid NEQ PDP_CONTEXT_CID_OMITTED) )
431 {
432 outOfRange = TRUE;
433 }
434
435 if ( qos AND (outOfRange EQ FALSE) )
436 {
437 if( (qos->qos_r99.tc > 4 ) AND
438 (qos->qos_r99.tc NEQ QOS_R99_TC_OMITTED) ) /* 4 = subscribed value */
439 outOfRange = TRUE;
440
441 if( (qos->qos_r99.max_rate_ul > 2048 ) AND
442 (qos->qos_r99.max_rate_ul NEQ QOS_R99_MAX_BR_UL_OMITTED) ) /* 0 = subscribed value */
443 outOfRange = TRUE;
444
445 if( (qos->qos_r99.max_rate_dl > 2048 ) AND
446 (qos->qos_r99.max_rate_dl NEQ QOS_R99_MAX_BR_DL_OMITTED )) /* 0 = subscribed value */
447 outOfRange = TRUE;
448
449 if( (qos->qos_r99.guar_br_ul > 2048 ) AND
450 (qos->qos_r99.guar_br_ul NEQ QOS_R99_GUAR_BR_UL_OMITTED )) /* 0 = subscribed value */
451 outOfRange = TRUE;
452
453 if( (qos->qos_r99.guar_br_dl > 2048 ) AND
454 (qos->qos_r99.guar_br_dl NEQ QOS_R99_GUAR_BR_DL_OMITTED )) /* 0 = subscribed value */
455 outOfRange = TRUE;
456
457 if( (qos->qos_r99.order > 2 ) AND
458 (qos->qos_r99.order NEQ QOS_R99_ORDER_OMITTED )) /* 2 = subscribed value */
459 outOfRange = TRUE;
460
461 if( (qos->qos_r99.xfer_delay > 65534 ) AND
462 (qos->qos_r99.xfer_delay NEQ QOS_R99_XFER_DELAY_OMITTED )) /* 0 = subscribed value */
463 outOfRange = TRUE;
464
465 if( (qos->qos_r99.del_err_sdu > 3 ) AND
466 (qos->qos_r99.del_err_sdu NEQ QOS_R99_DEL_ERR_SDU_OMITTED )) /* 3 = subscribed value */
467 outOfRange = TRUE;
468
469 if( (qos->qos_r99.handling_pri > 3 ) AND
470 (qos->qos_r99.handling_pri NEQ QOS_R99_HANDLING_PRIO_OMITTED )) /* 0 = subscribed value */
471 outOfRange = TRUE;
472
473 if( cid NEQ PDP_CONTEXT_CID_OMITTED )
474 {
475 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
476 if( p_pdp_context_node )
477 {
478 if( !strcmp( p_pdp_context_node->attributes.pdp_type, "PPP") )
479 {
480 if( (qos->qos_r99.max_sdu > 1502 ) AND
481 (qos->qos_r99.max_sdu NEQ QOS_R99_MAX_SDU_OMITTED )) /* 0 = subscribed value, 1502 for PPP */
482 outOfRange = TRUE;
483 }
484 else
485 {
486 if( (qos->qos_r99.max_sdu > 1500 ) AND
487 (qos->qos_r99.max_sdu NEQ QOS_R99_MAX_SDU_OMITTED )) /* 0 = subscribed value */
488 outOfRange = TRUE;
489 }
490 }
491 else
492 {
493 TRACE_ERROR( "ERROR: PDP context not found, in function sAT_PlusCGEQREQ" );
494 outOfRange = TRUE;
495 }
496 }
497 else
498 {
499 /* It is decided that the max_sdu for the default qos is 1500 and NOT 1502 since 1500 is valid for both ppp and ip */
500 if( (qos->qos_r99.max_sdu > 1500 ) AND
501 (qos->qos_r99.max_sdu NEQ QOS_R99_MAX_SDU_OMITTED )) /* 0 = subscribed value, 1502 for PPP */
502 outOfRange = TRUE;
503 }
504
505 /* to simplify the parameter range check the to bytes are joined in to a U16. */
506
507 tempComp = (U16) qos->qos_r99.sdu_err_ratio.ratio_mant;
508 tempComp = tempComp << 8;
509 tempComp = tempComp | qos->qos_r99.sdu_err_ratio.ratio_exp;
510
511 if( tempComp NEQ 0 AND
512 tempComp NEQ ((QOS_R99_RATIO_MANT_OMITTED<<8) + QOS_R99_RATIO_EXP_OMITTED) ) /* Check parameter range if "sdu_err_ratio" NEQ subscribed value or omitted. */
513 {
514 switch( qos->qos_r99.tc )
515 {
516 case PS_TC_CONV: /* Conversational class */
517 if( tempComp NEQ 0x0102 AND
518 tempComp NEQ 0x0703 AND
519 tempComp NEQ 0x0103 AND
520 tempComp NEQ 0x0104 AND
521 tempComp NEQ 0x0105 ) /* 0x0102 = 1 * 10^-2 */
522 outOfRange = TRUE;
523 break;
524
525 case PS_TC_STREAM: /* Streaming class */
526 if( tempComp NEQ 0x0101 AND
527 tempComp NEQ 0x0102 AND
528 tempComp NEQ 0x0703 AND
529 tempComp NEQ 0x0103 AND
530 tempComp NEQ 0x0104 AND
531 tempComp NEQ 0x0105 )
532 outOfRange = TRUE;
533 break;
534
535 case PS_TC_INTER: /* Interactive class */
536 case PS_TC_BG: /* Background class */
537 if( tempComp NEQ 0x0103 AND
538 tempComp NEQ 0x0104 AND
539 tempComp NEQ 0x0106 )
540 outOfRange = TRUE;
541 break;
542
543 case PS_TC_SUB: /* Subscribed value */
544 case QOS_R99_TC_OMITTED:
545 if( tempComp NEQ 0x0101 AND
546 tempComp NEQ 0x0102 AND
547 tempComp NEQ 0x0703 AND
548 tempComp NEQ 0x0103 AND
549 tempComp NEQ 0x0104 AND
550 tempComp NEQ 0x0105 AND
551 tempComp NEQ 0x0106 )
552 outOfRange = TRUE;
553 break;
554
555 default:
556 outOfRange = TRUE;
557 break;
558 }
559 }
560
561 tempComp = (U16) qos->qos_r99.ber.ratio_mant;
562 tempComp = tempComp << 8;
563 tempComp = tempComp | qos->qos_r99.ber.ratio_exp;
564
565 if( tempComp NEQ 0 AND
566 tempComp NEQ ((QOS_R99_RATIO_MANT_OMITTED<<8) + QOS_R99_RATIO_EXP_OMITTED) ) /* Check parameter range if "ber" NEQ subscribed value or omitted. */
567 {
568 switch( qos->qos_r99.tc )
569 {
570 case PS_TC_CONV: /* Conversational class */
571 if( tempComp NEQ 0x0502 AND
572 tempComp NEQ 0x0102 AND
573 tempComp NEQ 0x0503 AND
574 tempComp NEQ 0x0103 AND
575 tempComp NEQ 0x0104 AND
576 tempComp NEQ 0x0106 )
577 outOfRange = TRUE;
578 break;
579
580 case PS_TC_STREAM: /* Streaming class */
581 if( tempComp NEQ 0x0502 AND
582 tempComp NEQ 0x0102 AND
583 tempComp NEQ 0x0503 AND
584 tempComp NEQ 0x0103 AND
585 tempComp NEQ 0x0104 AND
586 tempComp NEQ 0x0105 AND
587 tempComp NEQ 0x0106 )
588 outOfRange = TRUE;
589 break;
590
591 case PS_TC_INTER: /* Interactive class */
592 case PS_TC_BG: /* Background class */
593 if( tempComp NEQ 0x0403 AND
594 tempComp NEQ 0x0105 AND
595 tempComp NEQ 0x0608 )
596 outOfRange = TRUE;
597 break;
598
599 case PS_TC_SUB: /* Subscribed value */
600 case QOS_R99_TC_OMITTED:
601 if( tempComp NEQ 0x0502 AND
602 tempComp NEQ 0x0102 AND
603 tempComp NEQ 0x0503 AND
604 tempComp NEQ 0x0403 AND
605 tempComp NEQ 0x0103 AND
606 tempComp NEQ 0x0104 AND
607 tempComp NEQ 0x0105 AND
608 tempComp NEQ 0x0106 )
609 outOfRange = TRUE;
610 break;
611
612 default:
613 outOfRange = TRUE;
614 break;
615 }
616 }
617 }
618
619 if( outOfRange EQ TRUE )
620 {
621 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
622 return( AT_FAIL );
623 }
624
625 /*
626 *-------------------------------------------------------------------
627 * process parameter
628 *-------------------------------------------------------------------
629 */
630 if(cid EQ PDP_CONTEXT_CID_OMITTED )
631 /*
632 * cid omitted: A special form of the set command that is not defined in the Spec.
633 * This set the default value of QoS.
634 */
635 {
636 cmhSM_change_def_QOS( qos, PS_is_R99 );
637
638 retCd = AT_CMPL;
639 }
640 else
641 {
642 /*
643 * Check that a context is defined before changing the QoS.
644 */
645 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
646 if( ! p_pdp_context_node )
647 {
648 return AT_FAIL;
649 }
650
651 c_state = get_state_over_cid( cid );
652 switch (c_state)
653 {
654 case PDP_CONTEXT_STATE_INVALID:
655 /* Wrong context state (not defined): Reject command */
656 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
657 return( AT_FAIL );
658 default: ;
659 /* Context is defined: Continue */
660 }
661
662 if( !qos OR ( qos->qos_r99.tc EQ QOS_R99_TC_OMITTED AND
663 qos->qos_r99.order EQ QOS_R99_ORDER_OMITTED AND
664 qos->qos_r99.del_err_sdu EQ QOS_R99_DEL_ERR_SDU_OMITTED AND
665 qos->qos_r99.max_sdu EQ QOS_R99_MAX_SDU_OMITTED AND
666 qos->qos_r99.max_rate_ul EQ QOS_R99_MAX_BR_UL_OMITTED AND
667 qos->qos_r99.max_rate_dl EQ QOS_R99_MAX_BR_DL_OMITTED AND
668 qos->qos_r99.xfer_delay EQ QOS_R99_XFER_DELAY_OMITTED AND
669 qos->qos_r99.handling_pri EQ QOS_R99_HANDLING_PRIO_OMITTED AND
670 qos->qos_r99.guar_br_ul EQ QOS_R99_GUAR_BR_UL_OMITTED AND
671 qos->qos_r99.guar_br_dl EQ QOS_R99_GUAR_BR_DL_OMITTED AND
672 qos->qos_r99.ber.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED AND
673 qos->qos_r99.ber.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED AND
674 qos->qos_r99.sdu_err_ratio.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED AND
675 qos->qos_r99.sdu_err_ratio.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED ) )
676
677 {
678 /*
679 * QoS omitted -> undefine the requested QOS
680 */
681 cmhSM_Set_default_QOS( cid );
682
683 /* If the default parameters is in R97 format, it must be converted to R99 */
684 if( p_pdp_context_node->ctrl_qos EQ PS_is_R97)
685 {
686 memcpy( &temp_qos, &p_pdp_context_node->qos.qos_r97, sizeof(T_PS_qos_r97) );
687 cl_qos_convert_r97_to_r99( &temp_qos, &p_pdp_context_node->qos.qos_r99 );
688 p_pdp_context_node->ctrl_qos = PS_is_R99;
689 }
690
691 retCd = AT_CMPL;
692 }
693 else
694 {
695 /*
696 * Define the requested QOS
697 */
698 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
699 if( p_pdp_context_node )
700 {
701
702 if( p_pdp_context_node->ctrl_qos EQ PS_is_R97 )
703 {
704 /* Convert existing R97 parameters to R99 parameters */
705 p_pdp_context_node->ctrl_qos = PS_is_R99;
706 memcpy( &temp_qos, &p_pdp_context_node->qos.qos_r97, sizeof(T_PS_qos_r97) );
707 if( !cl_qos_convert_r97_to_r99( &temp_qos, &p_pdp_context_node->qos.qos_r99) )
708 return( AT_FAIL );
709 }
710 else
711 p_pdp_context_node->ctrl_qos = PS_is_R99; //FDU - 13082003
712
713
714 /* Set the new values for context or keep the old values if omitted */
715 if( qos->qos_r99.tc NEQ QOS_R99_TC_OMITTED )
716 p_pdp_context_node->qos.qos_r99.tc = qos->qos_r99.tc;
717
718 if( qos->qos_r99.order NEQ QOS_R99_ORDER_OMITTED )
719 p_pdp_context_node->qos.qos_r99.order = qos->qos_r99.order;
720
721 if( qos->qos_r99.del_err_sdu NEQ QOS_R99_DEL_ERR_SDU_OMITTED )
722 p_pdp_context_node->qos.qos_r99.del_err_sdu = qos->qos_r99.del_err_sdu;
723
724 if( qos->qos_r99.max_sdu NEQ QOS_R99_MAX_SDU_OMITTED )
725 p_pdp_context_node->qos.qos_r99.max_sdu = qos->qos_r99.max_sdu;
726
727 if( qos->qos_r99.max_rate_ul NEQ QOS_R99_MAX_BR_UL_OMITTED )
728 p_pdp_context_node->qos.qos_r99.max_rate_ul = qos->qos_r99.max_rate_ul;
729
730 if( qos->qos_r99.max_rate_dl NEQ QOS_R99_MAX_BR_DL_OMITTED )
731 p_pdp_context_node->qos.qos_r99.max_rate_dl = qos->qos_r99.max_rate_dl;
732
733 if( qos->qos_r99.xfer_delay NEQ QOS_R99_XFER_DELAY_OMITTED )
734 p_pdp_context_node->qos.qos_r99.xfer_delay = qos->qos_r99.xfer_delay;
735
736 if( qos->qos_r99.handling_pri NEQ QOS_R99_HANDLING_PRIO_OMITTED )
737 p_pdp_context_node->qos.qos_r99.handling_pri = qos->qos_r99.handling_pri;
738
739 if( qos->qos_r99.guar_br_ul NEQ QOS_R99_GUAR_BR_UL_OMITTED )
740 p_pdp_context_node->qos.qos_r99.guar_br_ul = qos->qos_r99.guar_br_ul;
741
742 if( qos->qos_r99.guar_br_dl NEQ QOS_R99_GUAR_BR_DL_OMITTED )
743 p_pdp_context_node->qos.qos_r99.guar_br_dl = qos->qos_r99.guar_br_dl;
744
745 if( qos->qos_r99.ber.ratio_mant NEQ QOS_R99_RATIO_MANT_OMITTED )
746 p_pdp_context_node->qos.qos_r99.ber.ratio_mant = qos->qos_r99.ber.ratio_mant;
747
748 if( qos->qos_r99.ber.ratio_exp NEQ QOS_R99_RATIO_EXP_OMITTED )
749 p_pdp_context_node->qos.qos_r99.ber.ratio_exp = qos->qos_r99.ber.ratio_exp;
750
751 if( qos->qos_r99.sdu_err_ratio.ratio_mant NEQ QOS_R99_RATIO_MANT_OMITTED )
752 p_pdp_context_node->qos.qos_r99.sdu_err_ratio.ratio_mant = qos->qos_r99.sdu_err_ratio.ratio_mant;
753
754 if( qos->qos_r99.sdu_err_ratio.ratio_exp NEQ QOS_R99_RATIO_EXP_OMITTED )
755 p_pdp_context_node->qos.qos_r99.sdu_err_ratio.ratio_exp = qos->qos_r99.sdu_err_ratio.ratio_exp;
756 }
757 else
758 {
759 return( AT_FAIL );
760 }
761 }
762
763 retCd = AT_CMPL;
764
765 }
766
767 return retCd;
768 }
769
770
771 /*
772 +--------------------------------------------------------------------+
773 | PROJECT : UMTS MODULE : CMH_SMS |
774 | STATE : devellopment ROUTINE : sAT_PlusCGEQMIN |
775 +--------------------------------------------------------------------+
776
777 PURPOSE : This is the functional counterpart to the +CGEQMIN= AT
778 command which sets the 3G requested QOS min. parameters.
779 */
780 GLOBAL T_ACI_RETURN sAT_PlusCGEQMIN( T_ACI_CMD_SRC srcId, U8 cid, T_PS_qos *qos )
781 {
782 T_ACI_RETURN retCd; /* holds return code */
783 T_PDP_CONTEXT_STATE c_state; /* state of context */
784 BOOL outOfRange; /* TRUE if one or more parameters are out of range */
785 U16 tempComp; /* Used for range check of SDU error ratio and bit error ratio */
786 T_PS_qos_r97 temp_qos; /* Temp. var to hold R97 input parameters for conversion */
787 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
788
789 TRACE_FUNCTION( "sAT_PlusCGEQMIN()" );
790
791 outOfRange = FALSE;
792
793 if( smEntStat.curCmd NEQ AT_CMD_NONE )
794 return( AT_BUSY );
795
796 /*
797 *-------------------------------------------------------------------
798 * check parameter
799 *-------------------------------------------------------------------
800 */
801 if ( ((cid < PDP_CONTEXT_CID_MIN) OR (cid > PDP_CONTEXT_CID_MAX)) AND (cid NEQ PDP_CONTEXT_CID_OMITTED) )
802 {
803 outOfRange = TRUE;
804 }
805 if ( qos EQ NULL)
806 {
807 return( AT_FAIL );
808 }
809 if ( qos AND (outOfRange EQ FALSE) )
810 {
811 if( (qos->qos_r99.tc > 3) AND
812 (qos->qos_r99.tc NEQ QOS_R99_TC_OMITTED ))
813 outOfRange = TRUE;
814
815 if( (qos->qos_r99.max_rate_ul < 1 OR
816 qos->qos_r99.max_rate_ul > 2048) AND
817 qos->qos_r99.max_rate_ul NEQ QOS_R99_MAX_BR_UL_OMITTED )
818 outOfRange = TRUE;
819
820 if( (qos->qos_r99.max_rate_dl < 1 OR
821 qos->qos_r99.max_rate_dl > 2048) AND
822 qos->qos_r99.max_rate_dl NEQ QOS_R99_MAX_BR_DL_OMITTED )
823 outOfRange = TRUE;
824
825 if( (qos->qos_r99.guar_br_ul < 1 OR
826 qos->qos_r99.guar_br_ul > 2048) AND
827 qos->qos_r99.guar_br_ul NEQ QOS_R99_GUAR_BR_UL_OMITTED )
828 outOfRange = TRUE;
829
830 if( (qos->qos_r99.guar_br_dl < 1 OR
831 qos->qos_r99.guar_br_dl > 2048) AND
832 qos->qos_r99.guar_br_dl NEQ QOS_R99_GUAR_BR_DL_OMITTED )
833 outOfRange = TRUE;
834
835 if( (qos->qos_r99.order > 1) AND
836 (qos->qos_r99.order NEQ QOS_R99_ORDER_OMITTED ))
837 outOfRange = TRUE;
838
839 if( (qos->qos_r99.xfer_delay > 65534) AND
840 (qos->qos_r99.xfer_delay NEQ QOS_R99_XFER_DELAY_OMITTED ))
841 outOfRange = TRUE;
842
843 if( (qos->qos_r99.del_err_sdu > 2) AND
844 (qos->qos_r99.del_err_sdu NEQ QOS_R99_DEL_ERR_SDU_OMITTED ))
845 outOfRange = TRUE;
846
847 if( (qos->qos_r99.handling_pri < 1 OR
848 qos->qos_r99.handling_pri > 3) AND
849 qos->qos_r99.handling_pri NEQ QOS_R99_HANDLING_PRIO_OMITTED )
850 outOfRange = TRUE;
851
852 if( cid NEQ PDP_CONTEXT_CID_OMITTED )
853 {
854 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
855 if( p_pdp_context_node )
856 {
857 if( !strcmp( p_pdp_context_node->attributes.pdp_type, "PPP") )
858 {
859 if( (qos->qos_r99.max_sdu > 1502) AND
860 (qos->qos_r99.max_sdu NEQ QOS_R99_MAX_SDU_OMITTED )) /* 0 = subscribed value, 1502 for PPP */
861 outOfRange = TRUE;
862 }
863 else
864 {
865 if( (qos->qos_r99.max_sdu > 1500) AND
866 (qos->qos_r99.max_sdu NEQ QOS_R99_MAX_SDU_OMITTED )) /* 0 = subscribed value */
867 outOfRange = TRUE;
868 }
869 }
870 else
871 {
872 TRACE_ERROR( "ERROR: PDP context not found, in function sAT_PlusCGEQMIN" );
873 outOfRange = TRUE;
874 }
875 }
876 else
877 {
878 if( (qos->qos_r99.max_sdu > 1500) AND
879 (qos->qos_r99.max_sdu NEQ QOS_R99_MAX_SDU_OMITTED )) /* 0 = subscribed value */
880 outOfRange = TRUE;
881 }
882
883 /* to simplify the parameter range check the to bytes are joined in to a U16. */
884
885 tempComp = (U16) qos->qos_r99.sdu_err_ratio.ratio_mant;
886 tempComp = tempComp << 8;
887 tempComp = tempComp | qos->qos_r99.sdu_err_ratio.ratio_exp;
888
889 if( tempComp NEQ 0 AND
890 tempComp NEQ ((QOS_R99_RATIO_MANT_OMITTED<<8) + QOS_R99_RATIO_EXP_OMITTED) ) /* Check parameter range if "sdu_err_ratio" NEQ subscribed value or omitted. */
891 {
892 switch( qos->qos_r99.tc )
893 {
894 case PS_TC_CONV: /* Conversational class */
895 if( tempComp NEQ 0x0102 AND
896 tempComp NEQ 0x0703 AND
897 tempComp NEQ 0x0103 AND
898 tempComp NEQ 0x0104 AND
899 tempComp NEQ 0x0105 ) /* 0x0102 = 1 * 10^-2 */
900 outOfRange = TRUE;
901 break;
902
903 case PS_TC_STREAM: /* Streaming class */
904 if( tempComp NEQ 0x0101 AND
905 tempComp NEQ 0x0102 AND
906 tempComp NEQ 0x0703 AND
907 tempComp NEQ 0x0103 AND
908 tempComp NEQ 0x0104 AND
909 tempComp NEQ 0x0105 )
910 outOfRange = TRUE;
911 break;
912
913 case PS_TC_INTER: /* interactive class */
914 if( tempComp NEQ 0x0103 AND
915 tempComp NEQ 0x0104 AND
916 tempComp NEQ 0x0106 )
917 outOfRange = TRUE;
918 break;
919
920 case PS_TC_BG: /* Background class */
921 if( tempComp NEQ 0x0103 AND
922 tempComp NEQ 0x0104 AND
923 tempComp NEQ 0x0106 )
924 outOfRange = TRUE;
925 break;
926
927 case PS_TC_SUB: /* Subscribed value */
928 case QOS_R99_TC_OMITTED:
929 if( tempComp NEQ 0x0101 AND
930 tempComp NEQ 0x0102 AND
931 tempComp NEQ 0x0703 AND
932 tempComp NEQ 0x0103 AND
933 tempComp NEQ 0x0104 AND
934 tempComp NEQ 0x0105 AND
935 tempComp NEQ 0x0106 )
936 outOfRange = TRUE;
937 break;
938
939 default:
940 outOfRange = TRUE;
941 break;
942 }
943 }
944
945 tempComp = (U16) qos->qos_r99.ber.ratio_mant;
946 tempComp = tempComp << 8;
947 tempComp = tempComp | qos->qos_r99.ber.ratio_exp;
948
949 if( tempComp NEQ 0 AND
950 tempComp NEQ ((QOS_R99_RATIO_MANT_OMITTED<<8) + QOS_R99_RATIO_EXP_OMITTED) ) /* Check parameter range if "ber" NEQ subscribed value or omitted. */
951 {
952 switch( qos->qos_r99.tc )
953 {
954 case PS_TC_CONV: /* Conversational class */
955 if( tempComp NEQ 0x0502 AND
956 tempComp NEQ 0x0102 AND
957 tempComp NEQ 0x0503 AND
958 tempComp NEQ 0x0103 AND
959 tempComp NEQ 0x0104 AND
960 tempComp NEQ 0x0106 )
961 outOfRange = TRUE;
962 break;
963
964 case PS_TC_STREAM: /* Streaming class */
965 if( tempComp NEQ 0x0502 AND
966 tempComp NEQ 0x0102 AND
967 tempComp NEQ 0x0503 AND
968 tempComp NEQ 0x0103 AND
969 tempComp NEQ 0x0104 AND
970 tempComp NEQ 0x0105 AND
971 tempComp NEQ 0x0106 )
972 outOfRange = TRUE;
973 break;
974
975 case PS_TC_INTER: /* Interactive class */
976 if( tempComp NEQ 0x0403 AND
977 tempComp NEQ 0x0105 AND
978 tempComp NEQ 0x0608 )
979 outOfRange = TRUE;
980 break;
981
982 case PS_TC_BG: /* Background class */
983 if( tempComp NEQ 0x0403 AND
984 tempComp NEQ 0x0105 AND
985 tempComp NEQ 0x0608 )
986 outOfRange = TRUE;
987 break;
988
989 case PS_TC_SUB: /* Subscribed value */
990 case QOS_R99_TC_OMITTED:
991 if( tempComp NEQ 0x0502 AND
992 tempComp NEQ 0x0102 AND
993 tempComp NEQ 0x0503 AND
994 tempComp NEQ 0x0403 AND
995 tempComp NEQ 0x0103 AND
996 tempComp NEQ 0x0104 AND
997 tempComp NEQ 0x0105 AND
998 tempComp NEQ 0x0106 )
999 outOfRange = TRUE;
1000 break;
1001
1002 default:
1003 outOfRange = TRUE;
1004 break;
1005 }
1006 }
1007
1008 }
1009
1010 if( outOfRange EQ TRUE )
1011 {
1012 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1013 return( AT_FAIL );
1014 }
1015
1016 /*
1017 *-------------------------------------------------------------------
1018 * process parameter
1019 *-------------------------------------------------------------------
1020 */
1021 if(cid EQ PDP_CONTEXT_CID_OMITTED )
1022 /*
1023 * cid omitted: A special form of the set command that is not defined in the Spec.
1024 * This set the default value of QoS.
1025 */
1026 {
1027 /* Replace omitted values with subscribed values to avoid check in SM (subscribed=accept parameter from network unconditionally) */
1028 if( qos->qos_r99.tc EQ QOS_R99_TC_OMITTED ) qos->qos_r99.tc = PS_TC_SUB;
1029 if( qos->qos_r99.order EQ QOS_R99_ORDER_OMITTED ) qos->qos_r99.order = PS_ORDER_SUB;
1030 if( qos->qos_r99.del_err_sdu EQ QOS_R99_DEL_ERR_SDU_OMITTED ) qos->qos_r99.del_err_sdu = PS_DEL_ERR_SUB;
1031 if( qos->qos_r99.max_sdu EQ QOS_R99_MAX_SDU_OMITTED ) qos->qos_r99.max_sdu = PS_MAX_SDU_SUB;
1032 if( qos->qos_r99.max_rate_ul EQ QOS_R99_MAX_BR_UL_OMITTED ) qos->qos_r99.max_rate_ul = PS_MAX_BR_UL_SUB;
1033 if( qos->qos_r99.max_rate_dl EQ QOS_R99_MAX_BR_DL_OMITTED ) qos->qos_r99.max_rate_dl = PS_MAX_BR_DL_SUB;
1034 if( qos->qos_r99.xfer_delay EQ QOS_R99_XFER_DELAY_OMITTED ) qos->qos_r99.xfer_delay = PS_XFER_DELAY_SUB;
1035 if( qos->qos_r99.handling_pri EQ QOS_R99_HANDLING_PRIO_OMITTED ) qos->qos_r99.handling_pri = PS_HANDLING_PRI_SUB;
1036 if( qos->qos_r99.guar_br_ul EQ QOS_R99_GUAR_BR_UL_OMITTED ) qos->qos_r99.guar_br_ul = PS_GUAR_BR_UL_SUB;
1037 if( qos->qos_r99.guar_br_dl EQ QOS_R99_GUAR_BR_DL_OMITTED ) qos->qos_r99.guar_br_dl = PS_GUAR_BR_DL_SUB;
1038 if( qos->qos_r99.ber.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED ) qos->qos_r99.ber.ratio_mant = 0; /* '0' is the subscribed value */
1039 if( qos->qos_r99.ber.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED ) qos->qos_r99.ber.ratio_exp = 0; /* '0' is the subscribed value */
1040 if( qos->qos_r99.sdu_err_ratio.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED ) qos->qos_r99.sdu_err_ratio.ratio_mant = 0; /* '0' is the subscribed value */
1041 if( qos->qos_r99.sdu_err_ratio.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED ) qos->qos_r99.sdu_err_ratio.ratio_exp = 0; /* '0' is the subscribed value */
1042 cmhSM_change_def_QOS_min( (T_PS_min_qos *)qos, (T_PS_ctrl_min_qos)PS_is_R99 );
1043
1044 retCd = AT_CMPL;
1045 }
1046 else
1047 {
1048 /*
1049 * Check that a context is defined before changing the QoS.
1050 */
1051 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1052 if( !p_pdp_context_node )
1053 {
1054 return AT_FAIL;
1055 }
1056
1057 c_state = get_state_over_cid( cid );
1058 switch (c_state)
1059 {
1060 case PDP_CONTEXT_STATE_INVALID:
1061 /* Wrong context state (not defined): Reject command */
1062 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1063 return( AT_FAIL );
1064 default: ;
1065 /* Context is defined: Continue */
1066 }
1067
1068 if( !qos OR ( qos->qos_r99.tc EQ QOS_R99_TC_OMITTED AND
1069 qos->qos_r99.order EQ QOS_R99_ORDER_OMITTED AND
1070 qos->qos_r99.del_err_sdu EQ QOS_R99_DEL_ERR_SDU_OMITTED AND
1071 qos->qos_r99.max_sdu EQ QOS_R99_MAX_SDU_OMITTED AND
1072 qos->qos_r99.max_rate_ul EQ QOS_R99_MAX_BR_UL_OMITTED AND
1073 qos->qos_r99.max_rate_dl EQ QOS_R99_MAX_BR_DL_OMITTED AND
1074 qos->qos_r99.xfer_delay EQ QOS_R99_XFER_DELAY_OMITTED AND
1075 qos->qos_r99.handling_pri EQ QOS_R99_HANDLING_PRIO_OMITTED AND
1076 qos->qos_r99.guar_br_ul EQ QOS_R99_GUAR_BR_UL_OMITTED AND
1077 qos->qos_r99.guar_br_dl EQ QOS_R99_GUAR_BR_DL_OMITTED AND
1078 qos->qos_r99.ber.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED AND
1079 qos->qos_r99.ber.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED AND
1080 qos->qos_r99.sdu_err_ratio.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED AND
1081 qos->qos_r99.sdu_err_ratio.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED ) )
1082
1083 {
1084 /*
1085 * QoS omitted -> undefine the requested QOS
1086 */
1087 cmhSM_Set_default_QOS_min( cid );
1088
1089 /* If the default parameters is in R97 format, is must be converted to R99 */
1090 if( p_pdp_context_node->ctrl_min_qos EQ (T_PS_ctrl_min_qos)PS_is_R97)
1091 {
1092 memcpy( &temp_qos, &p_pdp_context_node->min_qos.qos_r97, sizeof(T_PS_qos_r97) );
1093 cl_qos_convert_r97_to_r99( &temp_qos, &p_pdp_context_node->min_qos.qos_r99 );
1094 p_pdp_context_node->ctrl_min_qos = (T_PS_ctrl_min_qos)PS_is_R99;
1095 }
1096
1097 retCd = AT_CMPL;
1098 }
1099 else
1100 {
1101 /*
1102 * Define the requested QOS
1103 */
1104
1105 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1106 if( p_pdp_context_node )
1107 {
1108 /* Conversion of old R97 to R99 is not necessary because +CGEQMIN always specifies all parameters (omitting=not checking). */
1109 p_pdp_context_node->ctrl_min_qos = (T_PS_ctrl_min_qos)PS_is_R99;
1110
1111 /* Copy the checked parameters directly to pdp_context */
1112 memcpy( &p_pdp_context_node->min_qos.qos_r99, qos, sizeof(T_PS_qos_r99) );
1113
1114 /* Replace omitted values with subscribed values to avoid check in SM (subscribed=accept parameter from network unconditionally) */
1115 if( qos->qos_r99.tc EQ QOS_R99_TC_OMITTED )
1116 p_pdp_context_node->min_qos.qos_r99.tc = PS_TC_SUB;
1117
1118 if( qos->qos_r99.order EQ QOS_R99_ORDER_OMITTED )
1119 p_pdp_context_node->min_qos.qos_r99.order = PS_ORDER_SUB;
1120
1121 if( qos->qos_r99.del_err_sdu EQ QOS_R99_DEL_ERR_SDU_OMITTED )
1122 p_pdp_context_node->min_qos.qos_r99.del_err_sdu = PS_DEL_ERR_SUB;
1123
1124 if( qos->qos_r99.max_sdu EQ QOS_R99_MAX_SDU_OMITTED )
1125 p_pdp_context_node->min_qos.qos_r99.max_sdu = PS_MAX_SDU_SUB;
1126
1127 if( qos->qos_r99.max_rate_ul EQ QOS_R99_MAX_BR_UL_OMITTED )
1128 p_pdp_context_node->min_qos.qos_r99.max_rate_ul = PS_MAX_BR_UL_SUB;
1129
1130 if( qos->qos_r99.max_rate_dl EQ QOS_R99_MAX_BR_DL_OMITTED )
1131 p_pdp_context_node->min_qos.qos_r99.max_rate_dl = PS_MAX_BR_DL_SUB;
1132
1133 if( qos->qos_r99.xfer_delay EQ QOS_R99_XFER_DELAY_OMITTED )
1134 p_pdp_context_node->min_qos.qos_r99.xfer_delay = PS_XFER_DELAY_SUB;
1135
1136 if( qos->qos_r99.handling_pri EQ QOS_R99_HANDLING_PRIO_OMITTED )
1137 p_pdp_context_node->min_qos.qos_r99.handling_pri = PS_HANDLING_PRI_SUB;
1138
1139 if( qos->qos_r99.guar_br_ul EQ QOS_R99_GUAR_BR_UL_OMITTED )
1140 p_pdp_context_node->min_qos.qos_r99.guar_br_ul = PS_GUAR_BR_UL_SUB;
1141
1142 if( qos->qos_r99.guar_br_dl EQ QOS_R99_GUAR_BR_DL_OMITTED )
1143 p_pdp_context_node->min_qos.qos_r99.guar_br_dl = PS_GUAR_BR_DL_SUB;
1144
1145 if( qos->qos_r99.ber.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED )
1146 p_pdp_context_node->min_qos.qos_r99.ber.ratio_mant = 0; /* '0' is the subscribed value */
1147
1148 if( qos->qos_r99.ber.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED )
1149 p_pdp_context_node->min_qos.qos_r99.ber.ratio_exp = 0; /* '0' is the subscribed value */
1150
1151 if( qos->qos_r99.sdu_err_ratio.ratio_mant EQ QOS_R99_RATIO_MANT_OMITTED )
1152 p_pdp_context_node->min_qos.qos_r99.sdu_err_ratio.ratio_mant = 0; /* '0' is the subscribed value */
1153
1154 if( qos->qos_r99.sdu_err_ratio.ratio_exp EQ QOS_R99_RATIO_EXP_OMITTED )
1155 p_pdp_context_node->min_qos.qos_r99.sdu_err_ratio.ratio_exp = 0; /* '0' is the subscribed value */
1156 }
1157 else
1158 {
1159 return( AT_FAIL );
1160 }
1161
1162 retCd = AT_CMPL;
1163 }
1164
1165 }
1166
1167 return retCd;
1168 }
1169 #endif /* REL99 */
1170
1171 /*
1172 +--------------------------------------------------------------------+
1173 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
1174 | STATE : finnished ROUTINE : sAT_PlusCGDCONT |
1175 +--------------------------------------------------------------------+
1176
1177 PURPOSE : This is the functional counterpart to the +CGDCONT= AT
1178 command which sets the current setting for each context.
1179
1180 GACI Context Definition GSM - 7.60 10.2.1
1181
1182 Special case +CGDCONT=<n> undefines context n
1183 is handled as separate function call
1184
1185 otherwise:
1186
1187 +CGDCONT=[<cid> [,<PDP_TYPE> [,<APN> [,<PDP_addr> [,<h_comp> [,<d_comp>]]]]]]
1188
1189 Issue of what happens if user changes data of an active context.
1190
1191 Take simple approach, do not renegotiate current context.
1192 Undefinition is more complex, reject attempt if context is active?
1193
1194 Current pdp address is left alone and only reset when context is
1195 explicitly undefined.
1196 See GSM 7.60 10.2.7.
1197
1198 */
1199 GLOBAL T_ACI_RETURN sAT_PlusCGDCONT( T_ACI_CMD_SRC srcId, U8 cid, T_PDP_CONTEXT *pdp_context_input )
1200 {
1201 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1202 T_PDP_CONTEXT_STATE pdp_context_state;
1203
1204 enum
1205 {
1206 PDP_CONTEXT_UNDEFINE = 0,
1207 PDP_CONTEXT_DEFINE = 1,
1208 PDP_CONTEXT_DEFINE_DEFAULT = 2
1209 } pdp_context_action = PDP_CONTEXT_DEFINE;
1210
1211 TRACE_FUNCTION ("sAT_PlusCGDCONT()");
1212
1213
1214
1215 /*
1216 *-------------------------------------------------------------------
1217 * check parameter
1218 *-------------------------------------------------------------------
1219 */
1220 if( (cid < PDP_CONTEXT_CID_MIN OR
1221 cid > PDP_CONTEXT_CID_MAX) AND (cid NEQ PDP_CONTEXT_CID_OMITTED ))
1222 {
1223 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1224 return AT_FAIL;
1225 }
1226
1227 /* right now data compression is not supported, add PDP_CONTEXT_D_COMP_ON condition
1228 * if enabled in the future
1229 */
1230 if( pdp_context_input->d_comp NEQ PDP_CONTEXT_D_COMP_OMITTED AND
1231 pdp_context_input->d_comp >= PDP_CONTEXT_D_COMP_INVALID)
1232 {
1233 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1234 return( AT_FAIL );
1235 }
1236
1237 if( pdp_context_input->h_comp NEQ PDP_CONTEXT_H_COMP_OMITTED AND
1238 pdp_context_input->h_comp >= PDP_CONTEXT_H_COMP_INVALID)
1239 {
1240 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1241 return( AT_FAIL );
1242 }
1243
1244 if( ! pdp_context_type_omitted( pdp_context_input->pdp_type ) )
1245 {
1246 if( ! pdp_context_type_valid( pdp_context_input->pdp_type ) )
1247 {
1248 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1249 return( AT_FAIL );
1250 }
1251 }
1252
1253 if( ! pdp_context_apn_omitted( pdp_context_input->pdp_apn ) )
1254 {
1255 if( ! pdp_context_apn_valid( pdp_context_input->pdp_apn ) )
1256 {
1257 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1258 return( AT_FAIL );
1259 }
1260 }
1261
1262 if( ! pdp_context_addr_omitted( &pdp_context_input->pdp_addr ) )
1263 {
1264 if( ! pdp_context_addr_valid( &pdp_context_input->pdp_addr ) )
1265 {
1266 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1267 return( AT_FAIL );
1268 }
1269 }
1270
1271 /*
1272 *-------------------------------------------------------------------
1273 * A special form of set command
1274 *-------------------------------------------------------------------
1275 */
1276 if( cid NEQ PDP_CONTEXT_CID_OMITTED AND
1277 pdp_context_type_omitted( pdp_context_input->pdp_type ) AND
1278 pdp_context_apn_omitted( pdp_context_input->pdp_apn ) AND
1279 pdp_context_addr_omitted( &pdp_context_input->pdp_addr ) AND
1280 pdp_context_input->d_comp EQ PDP_CONTEXT_D_COMP_OMITTED AND
1281 pdp_context_input->h_comp EQ PDP_CONTEXT_H_COMP_OMITTED )
1282 {
1283 pdp_context_action = PDP_CONTEXT_UNDEFINE;
1284 } /* end if ... the special form of the set command */
1285 else if( (cid EQ PDP_CONTEXT_CID_OMITTED) AND(
1286 !pdp_context_type_omitted( pdp_context_input->pdp_type ) OR
1287 !pdp_context_apn_omitted( pdp_context_input->pdp_apn ) OR
1288 !pdp_context_addr_omitted( &pdp_context_input->pdp_addr ) OR
1289 !((T_PDP_CONTEXT_D_COMP)pdp_context_input->d_comp EQ PDP_CONTEXT_D_COMP_OMITTED) OR
1290 !((T_PDP_CONTEXT_H_COMP)pdp_context_input->h_comp EQ PDP_CONTEXT_H_COMP_OMITTED) ))
1291 {
1292 pdp_context_action = PDP_CONTEXT_DEFINE_DEFAULT;
1293 }
1294 else
1295 {
1296
1297 /*
1298 *-------------------------------------------------------------------
1299 * default parameter
1300 *-------------------------------------------------------------------
1301 */
1302 if( pdp_context_input->d_comp EQ PDP_CONTEXT_D_COMP_OMITTED )
1303 pdp_context_input->d_comp = PDP_CONTEXT_D_COMP_OFF;
1304
1305 if( pdp_context_input->h_comp EQ PDP_CONTEXT_H_COMP_OMITTED )
1306 pdp_context_input->h_comp = PDP_CONTEXT_H_COMP_OFF;
1307
1308 if ( pdp_context_type_omitted( pdp_context_input->pdp_type ) )
1309 strcpy(pdp_context_input->pdp_type, "IP");
1310 }
1311
1312 /*
1313 *-------------------------------------------------------------------
1314 * process parameter
1315 *-------------------------------------------------------------------
1316 */
1317
1318 switch ( pdp_context_action )
1319 {
1320 case PDP_CONTEXT_UNDEFINE:
1321 {
1322 pdp_context_state = pdp_context_get_state_for_cid( cid );
1323
1324 if( pdp_context_state EQ PDP_CONTEXT_STATE_DEFINED )
1325 {
1326 if( !pdp_context_cid_used_by_other( cid ) )
1327 {
1328 pdp_context_remove_node( cid );
1329 }
1330 else
1331 {
1332 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1333 return( AT_FAIL );
1334 }
1335 }
1336 else
1337 {
1338 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
1339 return( AT_FAIL );
1340 }
1341 break;
1342 }
1343 case PDP_CONTEXT_DEFINE:
1344 {
1345 p_pdp_context_node = pdp_context_create_node( cid );
1346 if( p_pdp_context_node )
1347 {
1348 set_state_over_cid( cid, PDP_CONTEXT_STATE_DEFINED );
1349 }
1350 else
1351 {
1352 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1353
1354 if( p_pdp_context_node)
1355 {
1356 switch(p_pdp_context_node->internal_data.state)
1357 {
1358 /* every time allowed */
1359 case PDP_CONTEXT_STATE_INVALID:
1360 case PDP_CONTEXT_STATE_DEFINED:
1361 p_pdp_context_node->internal_data.state = PDP_CONTEXT_STATE_DEFINED;
1362 break;
1363 /* allowed during context deactivation, but
1364 WITHOUT state change */
1365 case PDP_CONTEXT_STATE_ABORT_ESTABLISH:
1366 case PDP_CONTEXT_STATE_DEACTIVATE_NORMAL:
1367 case PDP_CONTEXT_STATE_BREAKDOWN_LINK_NORMAL:
1368 case PDP_CONTEXT_STATE_REACTIVATION_1:
1369 case PDP_CONTEXT_STATE_REACTIVATION_2:
1370 break;
1371 /* Not allowed during context activation or
1372 for activated context */
1373 case PDP_CONTEXT_STATE_ATTACHING:
1374 case PDP_CONTEXT_STATE_ESTABLISH_1:
1375 case PDP_CONTEXT_STATE_ESTABLISH_2:
1376 case PDP_CONTEXT_STATE_ESTABLISH_3:
1377 case PDP_CONTEXT_STATE_ACTIVATING:
1378 case PDP_CONTEXT_STATE_ACTIVATED:
1379 case PDP_CONTEXT_STATE_DATA_LINK:
1380 default:
1381 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow );
1382 return( AT_FAIL );
1383 }
1384 }
1385 }
1386
1387 cmhSM_Set_default_QOS( cid );
1388 cmhSM_Set_default_QOS_min( cid );
1389
1390 sAT_PlusCGDCONT_exec( cid, pdp_context_input );
1391
1392 if ( p_pdp_context_node NEQ NULL )
1393 {
1394 set_state_over_cid( cid, p_pdp_context_node->internal_data.state );
1395 }
1396
1397 break;
1398 }
1399 case PDP_CONTEXT_DEFINE_DEFAULT:
1400 {
1401 memcpy(&pdp_context_default.attributes, pdp_context_input, sizeof(T_PDP_CONTEXT));
1402 }
1403 }
1404
1405 return AT_CMPL;
1406 }
1407
1408
1409 /*
1410 +--------------------------------------------------------------------+
1411 | PROJECT : UMTS MODULE : CMH_SMS |
1412 | STATE : - ROUTINE : sAT_PlusCGDCONT_exec |
1413 +--------------------------------------------------------------------+
1414 */
1415 GLOBAL void sAT_PlusCGDCONT_exec( U8 cid, T_PDP_CONTEXT *p_pdp_context_input)
1416 {
1417
1418 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1419 /*lint -e662 (Warning:Possible creation of out-of-bounds pointe)*/
1420
1421 TRACE_FUNCTION("sAT_PlusCGDCONT_exec");
1422
1423 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1424 if( p_pdp_context_node )
1425 {
1426 p_pdp_context_node->type = PDP_CONTEXT_TYPE_PRIMARY;
1427
1428 //if context type is omitted, use the one from the default context
1429 if(pdp_context_type_omitted( p_pdp_context_input->pdp_type ))
1430 {
1431 memcpy( &(p_pdp_context_node->attributes.pdp_type),
1432 &(pdp_context_default.attributes.pdp_type),
1433 sizeof(T_PDP_CONTEXT_PDP_TYPE) );
1434 }
1435 else
1436 {
1437 memcpy( &(p_pdp_context_node->attributes.pdp_type),
1438 &(p_pdp_context_input->pdp_type),
1439 sizeof(T_PDP_CONTEXT_PDP_TYPE) );
1440 }
1441
1442 //if pdp apn is omitted, use the one from the default context
1443 if (pdp_context_apn_omitted( p_pdp_context_input->pdp_apn ))
1444 {
1445 memcpy( &(p_pdp_context_node->attributes.pdp_apn),
1446 &(pdp_context_default.attributes.pdp_apn),
1447 sizeof(T_PDP_CONTEXT_APN) );
1448 }
1449 else
1450 {
1451 memcpy( &(p_pdp_context_node->attributes.pdp_apn),
1452 &(p_pdp_context_input->pdp_apn),
1453 sizeof(T_PDP_CONTEXT_APN) );
1454 }
1455
1456 //if context address is omitted, use the one from the default context
1457 if (pdp_context_addr_omitted( &p_pdp_context_input->pdp_addr ) )
1458 {
1459 memcpy( &(p_pdp_context_node->attributes.pdp_addr),
1460 &(pdp_context_default.attributes.pdp_addr),
1461 sizeof(T_NAS_ip) );
1462 }
1463 else
1464 {
1465 memcpy( &(p_pdp_context_node->attributes.pdp_addr),
1466 &(p_pdp_context_input->pdp_addr),
1467 sizeof(T_NAS_ip) );
1468 }
1469
1470 //copy default pco setting to context
1471 memcpy(&(p_pdp_context_node->internal_data.network_pco), &(pdp_context_default.internal_data.network_pco), sizeof(T_PDP_CONTEXT_PCO));
1472 memcpy(&(p_pdp_context_node->internal_data.user_pco), &(pdp_context_default.internal_data.user_pco), sizeof(T_PDP_CONTEXT_PCO));
1473
1474 if(p_pdp_context_input->d_comp EQ PDP_CONTEXT_D_COMP_OMITTED)
1475 p_pdp_context_node->attributes.d_comp = pdp_context_default.attributes.d_comp;
1476 else
1477 p_pdp_context_node->attributes.d_comp = p_pdp_context_input->d_comp;
1478
1479 if (p_pdp_context_input->h_comp EQ PDP_CONTEXT_H_COMP_OMITTED)
1480 p_pdp_context_node->attributes.h_comp = pdp_context_default.attributes.h_comp;
1481 else
1482 p_pdp_context_node->attributes.h_comp = p_pdp_context_input->h_comp;
1483 }
1484 }
1485
1486 #ifdef REL99
1487 /*
1488 +--------------------------------------------------------------------+
1489 | PROJECT : UMTS MODULE : CMH_SMS |
1490 | STATE : - ROUTINE : sAT_PlusCGDSCONT |
1491 +--------------------------------------------------------------------+
1492
1493 PURPOSE : This is the functional counterpart to the +CGDSCONT=
1494 AT command which sets the current setting for each secondary
1495 PDP context.
1496
1497 Special case: +CGDSCONT=<cid> undefines a secondary PDP context
1498
1499 +CGDSCONT=<cid> [,<p_cid> [,<h_comp> [,<d_comp>]]]
1500 */
1501 GLOBAL T_ACI_RETURN sAT_PlusCGDSCONT( T_ACI_CMD_SRC srcId, U8 cid, T_PDP_CONTEXT *p_pdp_context_input )
1502 {
1503
1504 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1505
1506 enum
1507 {
1508 PDP_CONTEXT_UNDEFINE = 0,
1509 PDP_CONTEXT_DEFINE = 1
1510
1511 } pdp_context_action = PDP_CONTEXT_DEFINE;
1512
1513 TRACE_FUNCTION ("sAT_PlusCGDSCONT()");
1514
1515 /*
1516 *-------------------------------------------------------------------
1517 * check entity status
1518 *-------------------------------------------------------------------
1519 */
1520 if( smEntStat.curCmd NEQ AT_CMD_NONE )
1521 return( AT_BUSY );
1522
1523 /*
1524 *-------------------------------------------------------------------
1525 * check parameter
1526 *-------------------------------------------------------------------
1527 */
1528 if ( ((cid < PDP_CONTEXT_CID_MIN) OR (cid > PDP_CONTEXT_CID_MAX)) AND (cid NEQ PDP_CONTEXT_CID_OMITTED) )
1529 {
1530 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1531 return AT_FAIL;
1532 }
1533
1534 if( p_pdp_context_input->p_cid NEQ PDP_CONTEXT_CID_OMITTED )
1535 {
1536 if( p_pdp_context_input->p_cid >= PDP_CONTEXT_CID_MIN AND
1537 p_pdp_context_input->p_cid <= PDP_CONTEXT_CID_MAX )
1538 {
1539 p_pdp_context_node = pdp_context_find_node_from_cid( p_pdp_context_input->p_cid );
1540 if( p_pdp_context_node )
1541 {
1542 if( p_pdp_context_node->type NEQ PDP_CONTEXT_TYPE_PRIMARY )
1543 {
1544 /* The PDP context found is not a primary PDP context */
1545 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1546 return AT_FAIL;
1547 }
1548 }
1549 else
1550 {
1551 /* The primary PDP context has not been created */
1552 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1553 return AT_FAIL;
1554 }
1555 }
1556 }
1557
1558 /* right now data compression is not supported, add PDP_CONTEXT_D_COMP_ON condition
1559 * if enabled in the future
1560 */
1561 if( p_pdp_context_input->d_comp NEQ PDP_CONTEXT_D_COMP_OMITTED AND
1562 p_pdp_context_input->d_comp >= PDP_CONTEXT_D_COMP_INVALID)
1563 {
1564 /* d_comp out of range */
1565 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1566 return( AT_FAIL );
1567 }
1568
1569 if( p_pdp_context_input->h_comp NEQ PDP_CONTEXT_H_COMP_OMITTED AND
1570 p_pdp_context_input->h_comp >= PDP_CONTEXT_H_COMP_INVALID )
1571 {
1572 /* h_copm out of range */
1573 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1574 return( AT_FAIL );
1575 }
1576 /*
1577 p_pdp_context_node = pdp_context_find_node_from_cid( p_pdp_context_input->p_cid );
1578 if( !p_pdp_context_node )
1579 {
1580 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1581 return( AT_FAIL );
1582 }
1583 */
1584 /*
1585 *-------------------------------------------------------------------
1586 * A special form of set command, that causes the context to become
1587 * undefined.
1588 *-------------------------------------------------------------------
1589 */
1590
1591 if( cid NEQ PDP_CONTEXT_CID_OMITTED AND
1592 p_pdp_context_input->p_cid EQ PDP_CONTEXT_CID_OMITTED AND
1593 p_pdp_context_input->d_comp EQ PDP_CONTEXT_D_COMP_OMITTED AND
1594 p_pdp_context_input->h_comp EQ PDP_CONTEXT_H_COMP_OMITTED )
1595 {
1596 pdp_context_action = PDP_CONTEXT_UNDEFINE;
1597 } /* end if ... the special form of the set command */
1598
1599 /*
1600 *-------------------------------------------------------------------
1601 * default parameter
1602 *-------------------------------------------------------------------
1603 */
1604 if( pdp_context_action EQ PDP_CONTEXT_DEFINE )
1605 {
1606 if( p_pdp_context_input->d_comp EQ PDP_CONTEXT_D_COMP_OMITTED )
1607 {
1608 p_pdp_context_input->d_comp = PDP_CONTEXT_D_COMP_OFF;
1609 }
1610
1611 if( p_pdp_context_input->h_comp EQ PDP_CONTEXT_H_COMP_OMITTED )
1612 {
1613 p_pdp_context_input->h_comp = PDP_CONTEXT_H_COMP_OFF;
1614 }
1615 }
1616
1617 /*
1618 *-------------------------------------------------------------------
1619 * process parameter
1620 *-------------------------------------------------------------------
1621 */
1622
1623 switch ( pdp_context_action )
1624 {
1625 case PDP_CONTEXT_UNDEFINE:
1626 {
1627 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1628
1629 if( !p_pdp_context_node->p_tft_pf )
1630 {
1631 if( !pdp_context_remove_node( cid ) )
1632 {
1633 TRACE_ERROR( "ERROR: Failed to remove secondary PDP context" );
1634 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1635 return( AT_FAIL );
1636 }
1637 }
1638 else
1639 {
1640 TRACE_ERROR( "ERROR: TFT Packet Filter not removed" );
1641 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1642 return( AT_FAIL );
1643 }
1644
1645 return( AT_CMPL );
1646 }
1647
1648 case PDP_CONTEXT_DEFINE:
1649 {
1650 if( sAT_PlusCGDSCONT_exec( cid, p_pdp_context_input ) )
1651 {
1652 set_state_over_cid( cid, PDP_CONTEXT_STATE_DEFINED );
1653 cmhSM_Set_default_QOS( cid );
1654 cmhSM_Set_default_QOS_min( cid );
1655 return( AT_CMPL );
1656 }
1657 else
1658 return( AT_FAIL );
1659 }
1660 }
1661
1662 return( AT_FAIL );
1663 }
1664
1665
1666 /*
1667 +--------------------------------------------------------------------+
1668 | PROJECT : UMTS MODULE : CMH_SMS |
1669 | STATE : - ROUTINE : sAT_PlusCGDSCONT_exec |
1670 +--------------------------------------------------------------------+
1671 If the function fails to create the secondary PDP context
1672 FALSE is returned otherwise TRUE.
1673
1674 */
1675 GLOBAL BOOL sAT_PlusCGDSCONT_exec( U8 cid, T_PDP_CONTEXT *p_pdp_context_input)
1676 {
1677
1678 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1679 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node_primary = NULL;
1680
1681 TRACE_FUNCTION("sAT_PlusCGDSCONT_exec");
1682
1683 p_pdp_context_node = pdp_context_create_node( cid );
1684 p_pdp_context_node_primary = pdp_context_find_node_from_cid( p_pdp_context_input->p_cid );
1685
1686 if( p_pdp_context_node AND p_pdp_context_node_primary )
1687 {
1688 p_pdp_context_node->type = PDP_CONTEXT_TYPE_SECONDARY;
1689 p_pdp_context_node->attributes.p_cid = p_pdp_context_input->p_cid;
1690
1691 memcpy( &(p_pdp_context_node->attributes.pdp_type),
1692 &(p_pdp_context_node_primary->attributes.pdp_type),
1693 sizeof(T_PDP_CONTEXT_PDP_TYPE) );
1694
1695 memcpy( &(p_pdp_context_node->attributes.pdp_apn),
1696 &(p_pdp_context_node_primary->attributes.pdp_apn),
1697 sizeof(T_PDP_CONTEXT_APN) );
1698
1699 memcpy( &(p_pdp_context_node->attributes.pdp_addr),
1700 &(p_pdp_context_node_primary->attributes.pdp_addr),
1701 sizeof(T_NAS_ip) );
1702
1703 p_pdp_context_node->attributes.d_comp = p_pdp_context_input->d_comp;
1704 p_pdp_context_node->attributes.h_comp = p_pdp_context_input->h_comp;
1705 }
1706 else
1707 {
1708 return FALSE;
1709 }
1710
1711 return TRUE;
1712
1713 }
1714
1715
1716 /*
1717 +--------------------------------------------------------------------+
1718 | PROJECT : UMTS MODULE : CMH_SMS |
1719 | STATE : - ROUTINE : sAT_PlusCGTFT |
1720 +--------------------------------------------------------------------+
1721
1722 PURPOSE : This is the functional counterpart to the +CGTFT= AT command
1723 which defines a PF for a TFT.
1724
1725
1726 */
1727 GLOBAL T_ACI_RETURN sAT_PlusCGTFT( T_ACI_CMD_SRC srcId, U8 cid, T_NAS_tft_pf *p_tft_pf_input )
1728 {
1729
1730 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1731 T_TFT_INTERNAL *p_tft_pf = NULL;
1732
1733 U8 pdp_context_cids[PDP_CONTEXT_CID_MAX]; /* containds cids of contexts associated to the same PDP address */
1734 int i = 0;
1735
1736 TRACE_FUNCTION("sAT_PlusCGTFT()");
1737
1738 memset( pdp_context_cids, 0, sizeof( pdp_context_cids ) );
1739
1740 /*
1741 *-------------------------------------------------------------------
1742 * check entity status
1743 *-------------------------------------------------------------------
1744 */
1745
1746 if( smEntStat.curCmd NEQ AT_CMD_NONE )
1747 {
1748 return( AT_BUSY );
1749 }
1750
1751
1752 /*
1753 *-------------------------------------------------------------------
1754 * check parameter
1755 *-------------------------------------------------------------------
1756 */
1757
1758 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1759 if( !p_pdp_context_node )
1760 {
1761 TRACE_EVENT("ERROR: PDP context not defined");
1762 return( AT_FAIL );
1763 }
1764
1765 if( p_tft_pf_input->tft_pf_id < TFT_PF_ID_MIN OR p_tft_pf_input->tft_pf_id > TFT_PF_ID_MAX )
1766 {
1767 TRACE_EVENT("ERROR: PF identifier out of range");
1768 return( AT_FAIL );
1769 }
1770
1771 /* Check the evaluation precedence index. */
1772 /* The precedence index must be unike within the same PDP address. */
1773
1774 /* Is is a secondary PDP context */
1775 switch( p_pdp_context_node->type )
1776 {
1777 case PDP_CONTEXT_TYPE_PRIMARY:
1778 pdp_context_cids[i++] = p_pdp_context_node->cid;
1779 break;
1780
1781 case PDP_CONTEXT_TYPE_SECONDARY:
1782 pdp_context_cids[i++] = p_pdp_context_node->attributes.p_cid;
1783 p_pdp_context_node = pdp_context_find_node_from_cid( p_pdp_context_node->attributes.p_cid );
1784 break;
1785
1786 default:
1787 TRACE_EVENT("ERROR: PDP context type error");
1788 return( AT_FAIL );
1789 }
1790
1791
1792 /* Search throug all defined PDP contexts. */
1793 /* Since the primary PDP context must be defined before defining a */
1794 /* secondary PDP context, the search is performed form the primary context */
1795 while( p_pdp_context_node )
1796 {
1797 if( p_pdp_context_node->attributes.p_cid EQ pdp_context_cids[0] )
1798 {
1799 pdp_context_cids[i] = p_pdp_context_node->cid;
1800 if( p_pdp_context_node->p_next )
1801 i++;
1802 }
1803 p_pdp_context_node = p_pdp_context_node->p_next;
1804 }
1805
1806 i--;
1807 while( i >= (PDP_CONTEXT_CID_MIN - 1) AND i < PDP_CONTEXT_CID_MAX )
1808 {
1809 p_pdp_context_node = pdp_context_find_node_from_cid( pdp_context_cids[i] );
1810
1811 p_tft_pf = p_pdp_context_node->p_tft_pf;
1812
1813 while( p_tft_pf )
1814 {
1815 if( p_tft_pf->pf_attributes.tft_pf_precedence NEQ p_tft_pf_input->tft_pf_precedence )
1816 {
1817 p_tft_pf = p_tft_pf->p_next;
1818 }
1819 else
1820 {
1821 TRACE_EVENT("ERROR: Precedence index in use");
1822 return( AT_FAIL );
1823 }
1824 }
1825
1826 i--;
1827 }
1828
1829
1830 /*
1831 * Check for omitted parameters. If all, except cid and tft_pf_id, are omitted the TFT PF must be removed.
1832 */
1833 if( cid AND
1834 p_tft_pf_input->tft_pf_id AND
1835 ! p_tft_pf_input->tft_pf_precedence AND
1836 ! p_tft_pf_input->tft_pf_valid_bits )
1837 {
1838 if( ! pdp_context_del_tft_pf( cid, p_tft_pf_input->tft_pf_id ) )
1839 {
1840 return AT_FAIL;
1841 }
1842 }
1843 else
1844 {
1845
1846 /* Check if the TFT PF is already created */
1847 p_tft_pf = pdp_context_find_tft_pf( cid, p_tft_pf_input->tft_pf_id );
1848 if( p_tft_pf )
1849 {
1850 /* The TFT PF is already created, overwrite existing attrributes */
1851
1852 memset( &p_tft_pf->pf_attributes, 0, sizeof(T_NAS_tft_pf) );
1853 memcpy( &p_tft_pf->pf_attributes, p_tft_pf_input, sizeof( T_NAS_tft_pf ) );
1854
1855 if( get_state_over_cid(cid) EQ PDP_CONTEXT_STATE_ACTIVATED OR
1856 get_state_over_cid(cid) EQ PDP_CONTEXT_STATE_DATA_LINK )
1857 {
1858
1859 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1860 if( p_pdp_context_node )
1861 {
1862 p_pdp_context_node->tft_changed = TRUE;
1863 }
1864 }
1865
1866 }
1867 else
1868 {
1869 p_tft_pf = pdp_context_add_tft_pf( cid, p_tft_pf_input->tft_pf_id );
1870 if( p_tft_pf )
1871 {
1872 memcpy( &p_tft_pf->pf_attributes, p_tft_pf_input, sizeof( T_NAS_tft_pf ) );
1873
1874 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
1875 if( p_pdp_context_node )
1876 {
1877 p_pdp_context_node->tft_changed = TRUE;
1878 }
1879
1880 }
1881 else
1882 {
1883 return( AT_FAIL );
1884 }
1885 }
1886 }
1887
1888 return AT_CMPL;
1889
1890 }
1891 #endif /* REL99 */
1892 /*
1893 +--------------------------------------------------------------------+
1894 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
1895 | STATE : finnished ROUTINE : sAT_PlusCGACT |
1896 +--------------------------------------------------------------------+
1897
1898 PURPOSE : This is the functional counterpart to the +CGACT= AT
1899 command which causes the cids specified in the cids list to
1900 be activated or deactivated according to state.
1901
1902 An empty list will cause all defined contexts to be
1903 activated or deactivated. If taken literally, this means that
1904 if more contexts are defined than supported, each will be
1905 activated, resulting in 'no resource' errors for the late ones
1906 as the GACI SEM will reject requests for more activations
1907 than it can cope with.
1908
1909 Note that the context is/are activated, but no CONNECT is sent
1910 to the TE. This is the difference between ACT and DATA commands.
1911
1912 SMREG activate req does not need l2p to be sent, but in this case
1913 the PDP config options are undefined (see below).
1914
1915 How does a DATA call bind these 'orphan' connections to a TE given
1916 that a cid definition is a 'template' due to its ambiguity.
1917
1918 Practically, the activate form of this command has little meaning in the
1919 case of PPP and loopback protocols (only ones supported at present).
1920
1921 Simplest option at the moment is not to support the activate form until
1922 a protocol type is supported can make real use of it. The deactivate form
1923 is of use in switching off a Loopback connection.
1924
1925 If activation before protocol establishment is supported, a NULL protocol service
1926 will have to be provided which supplies a default (empty?) PCO list to SMREG for
1927 activation and stores the network PCO response until a CGDATA is issued, must then
1928 convert the protocol into that requested by the CGDATA command.
1929 For future implementation
1930
1931
1932 Other issues for multiple context activation :
1933
1934 - need to add a para onto GACI activate to tell it whether
1935 to do a CONNECT or an OK callback on activation.
1936
1937 */
1938 GLOBAL T_ACI_RETURN sAT_PlusCGACT( T_ACI_CMD_SRC srcId, T_CGACT_STATE state, SHORT *cids )
1939 {
1940 T_PDP_CONTEXT_STATE pdp_context_state;
1941 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
1942 U8 i = 0;
1943 U8 j = 0;
1944
1945
1946 char * number= "*99#";
1947 T_ACI_RETURN ret_val;
1948 TRACE_FUNCTION ("sAT_PlusCGACT()");
1949
1950 /*
1951 *-------------------------------------------------------------------
1952 * check command source
1953 *-------------------------------------------------------------------
1954 */
1955 if(!cmh_IsVldCmdSrc (srcId))
1956 {
1957 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1958 return( AT_FAIL );
1959 }
1960
1961 /*
1962 *-------------------------------------------------------------------
1963 * check parameter
1964 *-------------------------------------------------------------------
1965 */
1966 if ( (state < CGACT_STATE_OMITTED) OR (state >= CGACT_STATE_INVALID) )
1967 {
1968 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1969 return AT_FAIL;
1970 }
1971
1972 i = 0;
1973 while ((i<PDP_CONTEXT_CID_MAX) AND (cids[i] NEQ PDP_CONTEXT_CID_INVALID))
1974 {
1975 if ( (cids[i] < PDP_CONTEXT_CID_MIN OR cids[i] > PDP_CONTEXT_CID_MAX) )
1976 {
1977 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1978 return( AT_FAIL );
1979 }
1980 i++;
1981 }
1982
1983 /*
1984 *-------------------------------------------------------------------
1985 * default parameter
1986 *-------------------------------------------------------------------
1987 */
1988 if ( state EQ CGACT_STATE_OMITTED )
1989 { /* state is not optional */
1990 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
1991 return AT_FAIL;
1992 }
1993
1994 /*
1995 *-------------------------------------------------------------------
1996 * enable +CGACT to deactivate a context during activation
1997 *-------------------------------------------------------------------
1998 */
1999 if( CGACT_STATE_DEACTIVATED EQ state )
2000 {
2001 ret_val = cmhSM_deactivateContexts(srcId, cids);
2002 switch(ret_val)
2003 {
2004 case AT_EXCT:
2005 smEntStat.curCmd = AT_CMD_CGACT;
2006 smEntStat.entOwn = srcId;
2007 smShrdPrm.owner = (UBYTE) srcId;
2008 return AT_EXCT;
2009 default:
2010 return ret_val;
2011 }
2012 }
2013
2014 /*
2015 *-------------------------------------------------------------------
2016 * check entity status
2017 *-------------------------------------------------------------------
2018 */
2019 if( smEntStat.curCmd NEQ AT_CMD_NONE )
2020 return( AT_BUSY );
2021
2022 if( gpppEntStat.curCmd EQ AT_CMD_CGDATA )
2023 return( AT_BUSY );
2024
2025 /* FDN check */
2026 if (pb_get_fdn_mode () EQ FDN_ENABLE AND state EQ CGACT_STATE_ACTIVATED)
2027 {
2028 if (pb_check_fdn (FDN, (UBYTE*)number) NEQ 1)
2029 {
2030 TRACE_EVENT("sAT_PlusCGACT: Entry not found in FDN, GPRS not allowed.");
2031 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow);
2032 return (AT_FAIL);
2033 }
2034 TRACE_EVENT("sAT_PlusCGACT: Entry found in FDN, GPRS allowed.");
2035 }
2036
2037 /*
2038 *-------------------------------------------------------------------
2039 * process parameter
2040 *-------------------------------------------------------------------
2041 */
2042
2043 cid_pointer = 0;
2044
2045 if( *cids EQ PDP_CONTEXT_CID_INVALID ) /* all defined or activated contexts (dependent by state) */
2046 {
2047 p_pdp_context_node = p_pdp_context_list;
2048 while( p_pdp_context_node )
2049 {
2050 if( p_pdp_context_node->internal_data.state EQ PDP_CONTEXT_STATE_DEFINED )
2051 {
2052 work_cids[j] = p_pdp_context_node->cid;
2053 j++;
2054 }
2055 p_pdp_context_node = p_pdp_context_node->p_next;
2056 }
2057 work_cids[j] = PDP_CONTEXT_CID_INVALID;
2058
2059 if( work_cids[0] EQ PDP_CONTEXT_CID_INVALID )
2060 {
2061 return AT_CMPL;
2062 }
2063 }
2064 else /* all declarated contexts */
2065 {
2066 /* copy cid list */
2067 for( i = 0; cids[i] NEQ PDP_CONTEXT_CID_INVALID; i++ )
2068 {
2069 if( (cids[i] < PDP_CONTEXT_CID_MIN OR cids[i] > PDP_CONTEXT_CID_MAX) OR i >= PDP_CONTEXT_CID_MAX )
2070 {
2071 TRACE_EVENT("not a valid cid!!!");
2072 work_cids[0] = PDP_CONTEXT_CID_INVALID;
2073 return AT_FAIL;
2074 }
2075 else
2076 {
2077 work_cids[i] = (U8)cids[i];
2078 }
2079 }
2080 work_cids[i] = PDP_CONTEXT_CID_INVALID;
2081
2082 for(j = 0; work_cids[j] NEQ PDP_CONTEXT_CID_INVALID; j++)
2083 {
2084 pdp_context_state = get_state_over_cid( work_cids[j] );
2085 if( pdp_context_state EQ PDP_CONTEXT_STATE_INVALID )
2086 { /* Context not defined, define it. */
2087 if( sAT_PlusCGDCONT( srcId, work_cids[j], &pdp_context_default.attributes ) EQ AT_FAIL )
2088 {
2089 return AT_FAIL;
2090 }
2091 }
2092 else
2093 {
2094 if ( pdp_context_state NEQ PDP_CONTEXT_STATE_DEFINED )
2095 {
2096 cid_pointer = 0;
2097 work_cids[0] = PDP_CONTEXT_CID_INVALID;
2098 return ( AT_FAIL );
2099 }
2100 }
2101 }
2102 }
2103 TRACE_EVENT("activating context!");
2104
2105 smEntStat.curCmd = AT_CMD_CGACT;
2106 smEntStat.entOwn = srcId;
2107 smShrdPrm.owner = (UBYTE) srcId;
2108
2109 smShrdPrm.direc = CGEREP_EVENT_ME_ACT;
2110
2111 set_conn_param_on_all_working_cids( (UBYTE)srcId, DTI_ENTITY_INVALID );
2112
2113 /*
2114 *-------------------------------------------------------------------
2115 * Check the PS attach state and attach if necessary.
2116 *-------------------------------------------------------------------
2117 */
2118 switch (cmhGMM_attach_if_necessary( srcId, AT_CMD_CGACT ))
2119 {
2120 case AT_EXCT:
2121 {
2122 /* Performing the attach procedure */
2123 set_state_working_cid( PDP_CONTEXT_STATE_ATTACHING );
2124 break;
2125 }
2126 case AT_CMPL:
2127 {
2128 /* Already attached -> activate the context */
2129 cmhSM_activate_context();
2130 break;
2131 }
2132 default:
2133 {
2134 smEntStat.curCmd = AT_CMD_NONE;
2135 return AT_FAIL;
2136 }
2137 }
2138
2139 return AT_EXCT;
2140 }
2141
2142 /*
2143 +--------------------------------------------------------------------+
2144 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
2145 | STATE : finnished ROUTINE : sAT_PlusCGDATA |
2146 +--------------------------------------------------------------------+
2147
2148 PURPOSE : This is the functional counterpart to the +CGDATA= AT
2149 command which establish the communication.
2150 */
2151 GLOBAL T_ACI_RETURN sAT_PlusCGDATA( T_ACI_CMD_SRC srcId, char *L2P, U8 *p_cid_array )
2152 {
2153 U8 i = 0;
2154 U8 j = 0;
2155 U8 k = 0;
2156
2157 U8 contexts_to_activate[PDP_CONTEXT_CID_MAX]; // old work_cid
2158 T_DTI_ENTITY_ID connectToEntity = DTI_ENTITY_INVALID;
2159 T_PDP_CONTEXT_INTERNAL *p_pdp_context_prim_node = NULL; /* Primary PDP context node */
2160 T_PDP_CONTEXT_INTERNAL *p_pdp_context_sec_node = NULL; /* Secondary PDP context node */
2161 T_PDP_CONTEXT_STATE pdp_context_state_prim;
2162
2163 TRACE_FUNCTION ("sAT_PlusCGDATA()");
2164
2165 memset( &contexts_to_activate, PDP_CONTEXT_CID_INVALID, sizeof( contexts_to_activate ) );
2166
2167 /*
2168 *-------------------------------------------------------------------
2169 * check command source
2170 *-------------------------------------------------------------------
2171 */
2172 if(!cmh_IsVldCmdSrc (srcId))
2173 {
2174 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2175 return( AT_FAIL );
2176 }
2177
2178
2179 /*
2180 *-------------------------------------------------------------------
2181 * check entity status
2182 *-------------------------------------------------------------------
2183 */
2184 if( smEntStat.curCmd NEQ AT_CMD_NONE )
2185
2186 return( AT_BUSY );
2187
2188 if( gpppEntStat.curCmd NEQ AT_CMD_NONE )
2189
2190 return( AT_BUSY );
2191
2192 if (pb_get_fdn_mode () EQ FDN_ENABLE)
2193 {
2194
2195
2196
2197 if (pb_check_fdn (0, (const UBYTE *)"*99#") NEQ PHB_OK)
2198 {
2199 TRACE_EVENT("sAT_PlusCGDATA: Entry not found in FDN, GPRS not allowed.");
2200 ACI_ERR_DESC( ACI_ERR_CLASS_Cme, CME_ERR_OpNotAllow);
2201 return (AT_FAIL);
2202 }
2203 TRACE_EVENT("sAT_PlusCGDATA: Entry found in FDN, GPRS allowed.");
2204 }
2205
2206 /*
2207 *-------------------------------------------------------------------
2208 * check parameter
2209 *-------------------------------------------------------------------
2210 */
2211 if ( L2P[0] EQ 0 )
2212 strcpy (L2P, "PPP"); /* default value */
2213
2214 if ( (!strcmp(L2P, "PPP")) OR (!strcmp(L2P, "IP")) )
2215 {
2216 #if defined(FF_PKTIO) OR defined(FF_TCP_IP)
2217 if ( TRUE NEQ srcc_reserve_sources( SRCC_PKTIO_SNDCP_LINK, 1 ) )
2218 return ( AT_FAIL );
2219 #endif
2220 /* if ( FALSE EQ srcc_reserve_sources( SRCC_PPPS_SNDCP_LINK, 1 ) )
2221 return ( AT_FAIL );*/
2222 connectToEntity = DTI_ENTITY_PPPS;
2223 }
2224 #if defined(FF_PKTIO) OR defined(FF_TCP_IP) OR defined(FF_PSI)
2225 else if( !strcmp(L2P, "M-PKT") OR !strcmp(L2P, "M-IP"))
2226 {
2227 if ( FALSE EQ srcc_reserve_sources( SRCC_PKTIO_SNDCP_LINK, 1 ) )
2228 return ( AT_FAIL );
2229 }
2230 #endif /* FF_PKTIO OR FF_TCP_IP OR FF_PSI */
2231 else
2232 {
2233 return ( AT_FAIL );
2234 }
2235
2236 /*
2237 *-----------------------------------------------------------------
2238 * cid parameter range check
2239 *-----------------------------------------------------------------
2240 */
2241 i=0;
2242 while ((i<PDP_CONTEXT_CID_MAX) AND (p_cid_array[i] NEQ PDP_CONTEXT_CID_INVALID))
2243 {
2244 if (p_cid_array[i] > PDP_CONTEXT_CID_INVALID)
2245 return (AT_FAIL);
2246 i++;
2247 }
2248
2249 /*
2250 *-----------------------------------------------------------------
2251 * Validate the cid array, primary PDP before secondary contexts
2252 *-----------------------------------------------------------------
2253 */
2254
2255 while( p_cid_array[i] NEQ PDP_CONTEXT_CID_INVALID )
2256 {
2257 p_pdp_context_sec_node = pdp_context_find_node_from_cid( p_cid_array[i] );
2258 if( p_pdp_context_sec_node )
2259 {
2260 if( p_pdp_context_sec_node->type EQ PDP_CONTEXT_TYPE_SECONDARY )
2261 {
2262 pdp_context_state_prim = pdp_context_get_state_for_cid( p_pdp_context_sec_node->attributes.p_cid );
2263 if( pdp_context_state_prim NEQ PDP_CONTEXT_STATE_ACTIVATED AND
2264 pdp_context_state_prim NEQ PDP_CONTEXT_STATE_DATA_LINK )
2265 {
2266 k = 0;
2267 while( k <= j )
2268 {
2269 if( p_pdp_context_sec_node->attributes.p_cid EQ contexts_to_activate[k] )
2270 {
2271 contexts_to_activate[j] = p_cid_array[i];
2272 j++;
2273 break;
2274 }
2275 else
2276 {
2277 k++;
2278 }
2279 }
2280 if( k > j )
2281 {
2282 /* since k > j the primary context was not privious entered */
2283 return( AT_FAIL );
2284 }
2285 }
2286 p_pdp_context_prim_node = pdp_context_find_node_from_cid( p_pdp_context_sec_node->attributes.p_cid );
2287 if( p_pdp_context_prim_node )
2288 {
2289 if( !p_pdp_context_sec_node->p_tft_pf AND !p_pdp_context_prim_node->p_tft_pf )
2290 {
2291 return( AT_FAIL );
2292 }
2293 }
2294 else
2295 {
2296 return( AT_FAIL );
2297 }
2298 }
2299 else
2300 {
2301 contexts_to_activate[j] = p_cid_array[i];
2302 j++;
2303 }
2304 }
2305
2306 i++;
2307
2308 }
2309
2310
2311 /*
2312 *-------------------------------------------------------------------
2313 * process parameter
2314 *-------------------------------------------------------------------
2315 */
2316
2317 memset (work_cids, PDP_CONTEXT_CID_INVALID, PDP_CONTEXT_CID_MAX);
2318 cid_pointer=0;
2319
2320 i = 0;
2321 while( i < PDP_CONTEXT_CID_MAX AND p_cid_array[i] NEQ PDP_CONTEXT_CID_INVALID )
2322 {
2323 switch( pdp_context_get_state_for_cid( p_cid_array[i] ) )
2324 {
2325 case PDP_CONTEXT_STATE_INVALID:
2326 /* define pdp context and */
2327 /* add pdp context cid to the work_cids array */
2328
2329 if( sAT_PlusCGDCONT( srcId, p_cid_array[i], &pdp_context_default.attributes ) EQ AT_FAIL )
2330 {
2331 return AT_FAIL;
2332 }
2333 else
2334 {
2335 work_cids[i] = p_cid_array[i];
2336 }
2337
2338 break;
2339
2340 case PDP_CONTEXT_STATE_DEFINED:
2341 case PDP_CONTEXT_STATE_ACTIVATED:
2342 /* add pdp context cid to the activation list */
2343
2344 work_cids[i] = p_cid_array[i];
2345 break;
2346
2347 default:
2348 TRACE_FUNCTION("sAT_PlusCGDATA: Invalid state for cid");
2349 break;
2350 }
2351
2352 i++;
2353 }
2354
2355 /*
2356 *-------------------------------------------------------------------
2357 * check if any cids to activate in work_cids.
2358 *-------------------------------------------------------------------
2359 */
2360 if (work_cids[0] EQ PDP_CONTEXT_CID_INVALID)
2361 return AT_FAIL;
2362
2363
2364 /*
2365 *-------------------------------------------------------------------
2366 * check number of context
2367 *-------------------------------------------------------------------
2368 */
2369 #if defined(FF_PKTIO) OR defined(FF_TCP_IP)
2370 if ( TRUE NEQ srcc_reserve_sources( SRCC_PKTIO_SNDCP_LINK, j ) ) // j is not used !!!
2371 return ( AT_FAIL );
2372 #endif
2373 /* process function
2374 *-------------------------------------------------------------------
2375 */
2376
2377 /* APN validation */
2378
2379 /*
2380 *-------------------------------------------------------------------
2381 * Store the command and entity parameters.
2382 *-------------------------------------------------------------------
2383 */
2384 set_conn_param_on_working_cid( (UBYTE)srcId, connectToEntity );
2385 if (connectToEntity EQ DTI_ENTITY_PPPS)
2386 {
2387 gpppEntStat.curCmd = AT_CMD_CGDATA;
2388 gpppEntStat.entOwn = srcId;
2389 gpppShrdPrm.owner = (UBYTE) srcId;
2390 }
2391 else
2392 {
2393 smEntStat.curCmd = AT_CMD_CGDATA;
2394 smEntStat.entOwn = srcId;
2395 smShrdPrm.owner = (UBYTE) srcId;
2396 }
2397
2398 smShrdPrm.direc = CGEREP_EVENT_ME_ACT;
2399
2400 /*
2401 *-------------------------------------------------------------------
2402 * Check the PS attach state and attach if necessary.
2403 *-------------------------------------------------------------------
2404 */
2405 switch (cmhGMM_attach_if_necessary( srcId, AT_CMD_CGDATA ))
2406 {
2407 case AT_EXCT:
2408 {
2409 /* Performing the attach procedure */
2410 set_state_working_cid( PDP_CONTEXT_STATE_ATTACHING );
2411 break;
2412 }
2413 case AT_CMPL:
2414 {
2415 cmhSM_data_link_context();
2416 break;
2417 }
2418 default:
2419 {
2420 smEntStat.curCmd = AT_CMD_NONE;
2421 gpppEntStat.curCmd = AT_CMD_NONE;
2422 return AT_FAIL;
2423 }
2424 }
2425 return AT_EXCT;
2426
2427 }
2428
2429 /*
2430 +--------------------------------------------------------------------+
2431 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
2432 | STATE : finnished ROUTINE : sAT_PlusCGPADDR |
2433 +--------------------------------------------------------------------+
2434
2435 PURPOSE : This is the functional counterpart to the +CGPADDR= AT
2436 command which give the PDP address back.
2437 */
2438 GLOBAL T_ACI_RETURN sAT_PlusCGPADDR ( T_ACI_CMD_SRC srcId, SHORT *cids, T_NAS_ip *pdp_adress )
2439 {
2440 U8 index = 0;
2441 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2442
2443 TRACE_FUNCTION ("sAT_PlusCGPADDR()");
2444
2445 p_pdp_context_node = p_pdp_context_list;
2446
2447 /*
2448 *-------------------------------------------------------------------
2449 * check entity status
2450 *-------------------------------------------------------------------
2451 */
2452 if( smEntStat.curCmd NEQ AT_CMD_NONE )
2453 return( AT_BUSY );
2454
2455 /*
2456 *-------------------------------------------------------------------
2457 * process parameter
2458 *-------------------------------------------------------------------
2459 */
2460 if( *cids EQ PDP_CONTEXT_CID_OMITTED )
2461 {
2462 /*
2463 * the PDP addresse for all defined contexts are returned
2464 */
2465
2466 while( p_pdp_context_node )
2467 {
2468 cids[index] = cmhSM_get_pdp_addr_for_CGPADDR( p_pdp_context_node->cid, &pdp_adress[index] );
2469
2470 p_pdp_context_node = p_pdp_context_node->p_next;
2471 index++;
2472 }
2473
2474 cids[index] = PDP_CONTEXT_CID_INVALID;
2475
2476 }
2477 else
2478 {
2479 /*
2480 * the PDP addresse for all specified contexts are returned
2481 */
2482
2483 while( cids[index] NEQ PDP_CONTEXT_CID_INVALID )
2484 {
2485 p_pdp_context_node = pdp_context_find_node_from_cid( (U8)cids[index] );
2486 if( p_pdp_context_node )
2487 {
2488 cids[index] = cmhSM_get_pdp_addr_for_CGPADDR( p_pdp_context_node->cid, &pdp_adress[index] );
2489 }
2490 else
2491 {
2492 return (AT_FAIL);
2493 }
2494 index++;
2495 }
2496 }
2497
2498 return AT_CMPL;
2499 }
2500
2501 /*
2502 +--------------------------------------------------------------------+
2503 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
2504 | STATE : finnished ROUTINE : sAT_PlusCGAUTO |
2505 +--------------------------------------------------------------------+
2506
2507 PURPOSE : This is the functional counterpart to the +CGAUTO= AT
2508 command which set the mode of automatic response to
2509 network request for PDP context activation.
2510 */
2511 GLOBAL T_ACI_RETURN sAT_PlusCGAUTO ( T_ACI_CMD_SRC srcId, T_CGAUTO_N n )
2512 {
2513 TRACE_FUNCTION ("sAT_PlusCGAUTO()");
2514
2515 /*
2516 *-------------------------------------------------------------------
2517 * check entity status
2518 *-------------------------------------------------------------------
2519 */
2520 if( smEntStat.curCmd NEQ AT_CMD_NONE )
2521
2522 return( AT_BUSY );
2523
2524 /*
2525 *-------------------------------------------------------------------
2526 * check parameter
2527 *-------------------------------------------------------------------
2528 */
2529 if ( (n < CGAUTO_N_OMITTED) OR (n >= CGAUTO_N_INVALID) )
2530 {
2531 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2532 return AT_FAIL;
2533 }
2534
2535 /*
2536 *-------------------------------------------------------------------
2537 * default parameter
2538 *-------------------------------------------------------------------
2539 */
2540 if ( n EQ CGAUTO_N_OMITTED )
2541 n = CGAUTO_N_MCM_GPRS_CSC;
2542
2543 /*
2544 *-------------------------------------------------------------------
2545 * process parameter
2546 *-------------------------------------------------------------------
2547 */
2548 automatic_response_mode = (SHORT) n;
2549
2550 /* the MT shall attempt to perform a GPRS attach if it is not already attached */
2551 if ( n EQ 1 )
2552 {
2553 return sAT_PlusCGATT ( srcId, CGATT_STATE_ATTACHED );
2554 }
2555 return AT_CMPL;
2556 }
2557
2558 /*
2559 +--------------------------------------------------------------------+
2560 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
2561 | STATE : finnished ROUTINE : sAT_PlusCGANS |
2562 +--------------------------------------------------------------------+
2563
2564 PURPOSE : This is the functional counterpart to the +CGANS= AT
2565 command to respond manual to a network request for
2566 PDP context activation.
2567 */
2568 GLOBAL T_ACI_RETURN sAT_PlusCGANS ( T_ACI_CMD_SRC srcId, USHORT response, char *l2p, U8 cid )
2569 {
2570 char L2P[MAX_L2P_LENGTH];
2571 T_PDP_CONTEXT pdp_context;
2572 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
2573 U8 i = 0;
2574 U8 cid_to_activate = PDP_CONTEXT_CID_INVALID;
2575
2576 TRACE_FUNCTION ("sAT_PlusCGANS()");
2577
2578 memcpy( &pdp_context, &pdp_context_default, sizeof( pdp_context ) );
2579
2580 /*
2581 *-------------------------------------------------------------------
2582 * check entity status
2583 *-------------------------------------------------------------------
2584 */
2585 if( smEntStat.curCmd NEQ AT_CMD_NONE )
2586
2587 return( AT_BUSY );
2588
2589 /*
2590 *-------------------------------------------------------------------
2591 * check command source
2592 *-------------------------------------------------------------------
2593 */
2594 if(!cmh_IsVldCmdSrc (srcId))
2595 {
2596 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2597 return( AT_FAIL );
2598 }
2599
2600 /*
2601 *-------------------------------------------------------------------
2602 * check parameter
2603 *-------------------------------------------------------------------
2604 */
2605 if (response >= CGANS_RESPONSE_INVALID)
2606 {
2607 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2608 return( AT_FAIL );
2609 }
2610
2611 /*
2612 *-------------------------------------------------------------------
2613 * check call table
2614 *-------------------------------------------------------------------
2615 */
2616 if( gprs_ct_index EQ current_gprs_ct_index )
2617 return ( AT_FAIL );
2618
2619 /*
2620 *-------------------------------------------------------------------
2621 * stop ringing
2622 *-------------------------------------------------------------------
2623 */
2624 for( i = 0; i < CMD_SRC_MAX; i++ )
2625 {
2626 R_AT( RAT_CRING_OFF, (T_ACI_CMD_SRC)i )( 0 );
2627 }
2628 #ifdef FF_ATI
2629 io_setRngInd ( IO_RING_OFF, CRING_SERV_TYP_NotPresent, CRING_SERV_TYP_NotPresent ); /* V.24 Ring Indicator Line */
2630 #endif
2631
2632 /*
2633 *-------------------------------------------------------------------
2634 * process parameter
2635 *-------------------------------------------------------------------
2636 */
2637 switch( response )
2638 {
2639 case CGANS_RESPONSE_REJECT:
2640 psaSM_PDP_No_activate(gprs_call_table[current_gprs_ct_index].sm_ind.ti, CAUSE_NWSM_ACTIVATE_REJECTED_UNSPECIFIED);
2641
2642 cmhSM_next_call_table_entry();
2643
2644 return AT_CMPL;
2645
2646 case CGANS_RESPONSE_ACCEPT:
2647 /*
2648 *-------------------------------------------------------------------
2649 * check number of context
2650 *-------------------------------------------------------------------
2651 */
2652 #if defined(FF_PKTIO) OR defined(FF_TCP_IP)
2653 if( srcc_reserve_sources( SRCC_PKTIO_SNDCP_LINK, 1 ) EQ FALSE )
2654 return ( AT_FAIL );
2655 #endif
2656 /*
2657 *-------------------------------------------------------------------
2658 * check the last two command arguments
2659 *-------------------------------------------------------------------
2660 */
2661 if( !gprs_call_table[current_gprs_ct_index].L2P[0] )
2662 {
2663 if ( l2p NEQ NULL )
2664 {
2665 if( !(*l2p) )
2666 strcpy(L2P, "PPP");
2667 else
2668 {
2669 strncpy(L2P, l2p, MAX_L2P_LENGTH - 1);
2670 L2P[MAX_L2P_LENGTH - 1] = 0;
2671 }
2672 }
2673 else
2674 strcpy(L2P, "PPP");
2675
2676 if ( strcmp(L2P, "PPP") )
2677 {
2678 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2679 return( AT_FAIL );
2680 }
2681
2682 cid_to_activate = cid;
2683 }
2684 else
2685 {
2686 cid_to_activate = (U8) gprs_call_table[current_gprs_ct_index].cid;
2687 }
2688
2689 /* find first free position in work_cids array */
2690 i = 0;
2691 while( i < PDP_CONTEXT_CID_MAX AND work_cids[i] NEQ PDP_CONTEXT_CID_INVALID )
2692 {
2693 i++;
2694 }
2695
2696 if( i >= PDP_CONTEXT_CID_MAX )
2697 {
2698 return AT_FAIL;
2699 }
2700
2701 cid_pointer = i;
2702
2703 switch( cid_to_activate )
2704 {
2705 case PDP_CONTEXT_CID_OMITTED:
2706 p_pdp_context_node = pdp_context_find_matching_node(
2707 (T_SMREG_VAL_pdp_type) gprs_call_table[current_gprs_ct_index].sm_ind.pdp_type,
2708 gprs_call_table[current_gprs_ct_index].sm_ind.ctrl_ip_address,
2709 &gprs_call_table[current_gprs_ct_index].sm_ind.ip_address );
2710
2711 if( p_pdp_context_node AND p_pdp_context_node->type EQ PDP_CONTEXT_TYPE_PRIMARY )
2712 {
2713 cid_to_activate = p_pdp_context_node->cid;
2714 work_cids[cid_pointer] = cid_to_activate;
2715 }
2716 else
2717 {
2718 // No defined context found, with matching parameters.
2719
2720 cid_to_activate = pdp_context_get_free_cid();
2721
2722 // Define PDP context with default parameters.
2723
2724 if( sAT_PlusCGDCONT( srcId, cid_to_activate, &pdp_context_default.attributes ) EQ AT_FAIL )
2725 {
2726 return AT_FAIL;
2727 }
2728 else
2729 {
2730 work_cids[cid_pointer] = cid_to_activate;
2731 }
2732
2733 }
2734
2735 break;
2736
2737 case PDP_CONTEXT_CID_INVALID:
2738 break;
2739
2740 default:
2741 switch( pdp_context_get_state_for_cid( cid_to_activate ) )
2742 {
2743 case PDP_CONTEXT_STATE_INVALID:
2744 /* define pdp context and */
2745 /* add pdp context cid to the work_cids array */
2746
2747 if( sAT_PlusCGDCONT( srcId, cid_to_activate, &pdp_context_default.attributes ) EQ AT_FAIL )
2748 {
2749 return AT_FAIL;
2750 }
2751 else
2752 {
2753 work_cids[cid_pointer] = cid_to_activate;
2754 }
2755 break;
2756
2757 case PDP_CONTEXT_STATE_DEFINED:
2758 /* add pdp context cid to the activation list */
2759
2760 work_cids[cid_pointer] = cid_to_activate;
2761 break;
2762 }
2763 }
2764
2765 /*
2766 *-------------------------------------------------------------------
2767 * set the actually context data
2768 *-------------------------------------------------------------------
2769 */
2770 /*
2771 ctx.qos.preced = gprs_call_table[current_gprs_ct_index].sm_ind.smreg_qos.preced;
2772 ctx.qos.delay = gprs_call_table[current_gprs_ct_index].sm_ind.smreg_qos.delay;
2773 ctx.qos.relclass = gprs_call_table[current_gprs_ct_index].sm_ind.smreg_qos.relclass;
2774 ctx.qos.peak = gprs_call_table[current_gprs_ct_index].sm_ind.smreg_qos.peak;
2775 ctx.qos.mean = gprs_call_table[current_gprs_ct_index].sm_ind.smreg_qos.mean;
2776 */
2777 strncpy(pdp_context.pdp_apn, (const char *) gprs_call_table[current_gprs_ct_index].sm_ind.apn.apn_buf,
2778 gprs_call_table[current_gprs_ct_index].sm_ind.apn.c_apn_buf);
2779
2780 /* IP v4 address */
2781 pdp_context.pdp_addr.ctrl_ip_address = gprs_call_table[current_gprs_ct_index].sm_ind.ctrl_ip_address;
2782 switch( gprs_call_table[current_gprs_ct_index].sm_ind.ctrl_ip_address)
2783 {
2784 case NAS_is_ipv4: /* IPv4 address */
2785 memcpy( &pdp_context.pdp_addr.ip_address.ipv4_addr.a4, &gprs_call_table[current_gprs_ct_index].sm_ind.ip_address.ipv4_addr.a4, NAS_SIZE_IPv4_ADDR );
2786 /*
2787 sprintf( ctx.pdp_addr, "%hd.%hd.%hd.%hd",
2788 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[0],
2789 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[1],
2790 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[2],
2791 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[3]);
2792 */
2793 break;
2794 case NAS_is_ipv6: /* IPv6 address */
2795 memcpy( &pdp_context.pdp_addr.ip_address.ipv6_addr.a6, &gprs_call_table[current_gprs_ct_index].sm_ind.ip_address.ipv6_addr.a6, NAS_SIZE_IPv6_ADDR );
2796 /*
2797 sprintf( ctx.pdp_addr, "%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd.%hd",
2798 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 0],
2799 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 1],
2800 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 2],
2801 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 3],
2802 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 4],
2803 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 5],
2804 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 6],
2805 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 7],
2806 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 8],
2807 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[ 9],
2808 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[10],
2809 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[11],
2810 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[12],
2811 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[13],
2812 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[14],
2813 gprs_call_table[current_gprs_ct_index].sm_ind.pdp_address.pdp_buf[15]);
2814 */
2815 break;
2816 default:
2817 return( AT_FAIL );
2818 }
2819
2820 switch( (T_SMREG_VAL_pdp_type) gprs_call_table[current_gprs_ct_index].sm_ind.pdp_type )
2821 {
2822 case SMREG_PDP_PPP:
2823 strcpy( pdp_context.pdp_type, "PPP" );
2824 break;
2825 case SMREG_PDP_IPV4:
2826 strcpy( pdp_context.pdp_type, "IP" );
2827 break;
2828 case SMREG_PDP_IPV6:
2829 strcpy( pdp_context.pdp_type, "IPV6" );
2830 break;
2831 default:
2832 return( AT_FAIL );
2833 }
2834
2835 /*
2836 *-------------------------------------------------------------------
2837 * set some parameter of the call table
2838 *-------------------------------------------------------------------
2839 */
2840 if ( !gprs_call_table[current_gprs_ct_index].L2P[0])
2841 {
2842 /*lint -e{645} */ /* L2P is initialized within the same if-construct some lines above */
2843 strcpy (gprs_call_table[current_gprs_ct_index].L2P, L2P);
2844 gprs_call_table[current_gprs_ct_index].cid = cid_to_activate;
2845 }
2846
2847 sAT_PlusCGDCONT_exec( cid_to_activate, &pdp_context );
2848
2849 p_pdp_context_node = pdp_context_find_node_from_cid( cid_to_activate );
2850 if( p_pdp_context_node )
2851 {
2852 p_pdp_context_node->internal_data.smreg_ti = gprs_call_table[current_gprs_ct_index].sm_ind.ti;
2853 }
2854 else
2855 {
2856 TRACE_ERROR( "ERROR: PDP context not found, in function sAT_PlusCGANS" );
2857 }
2858
2859 /*
2860 *-------------------------------------------------------------------
2861 * process function
2862 *-------------------------------------------------------------------
2863 */
2864 gpppEntStat.curCmd = AT_CMD_CGDATA;
2865 gpppEntStat.entOwn = srcId;
2866 gpppShrdPrm.owner = (UBYTE) srcId;
2867
2868 smShrdPrm.direc = CGEREP_EVENT_NW_ACT;
2869
2870 set_conn_param_on_working_cid( (UBYTE)srcId, DTI_ENTITY_PPPS );
2871
2872 cmhSM_data_link_context();
2873 return AT_EXCT;
2874 }
2875
2876 return AT_FAIL;
2877 }
2878
2879 GLOBAL T_ACI_RETURN sAT_PlusCGEREP ( T_ACI_CMD_SRC srcId, T_CGEREP_MODE mode, T_CGEREP_BFR bfr )
2880 {
2881
2882 TRACE_FUNCTION ("sAT_PlusCGEREP()");
2883
2884 /*
2885 *-------------------------------------------------------------------
2886 * check entity status
2887 *-------------------------------------------------------------------
2888 */
2889 if( smEntStat.curCmd NEQ AT_CMD_NONE )
2890
2891 return( AT_BUSY );
2892
2893 /*
2894 *-------------------------------------------------------------------
2895 * check first command argument
2896 *-------------------------------------------------------------------
2897 */
2898 if ( mode < CGEREP_MODE_OMITTED OR mode >= CGEREP_MODE_INVALID )
2899 {
2900 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2901 return( AT_FAIL );
2902 }
2903
2904 if ( bfr < CGEREP_BFR_OMITTED OR bfr >= CGEREP_BFR_INVALID )
2905 {
2906 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2907 return( AT_FAIL );
2908 }
2909
2910 /*
2911 *-------------------------------------------------------------------
2912 * process parameter
2913 *-------------------------------------------------------------------
2914 */
2915
2916 /* only the last source which used CGEREP will receive those indications */
2917 sm_cgerep_srcId = srcId;
2918
2919 if ( mode NEQ CGEREP_MODE_OMITTED )
2920 sm_cgerep_mode = mode;
2921
2922 if ( bfr NEQ CGEREP_BFR_OMITTED )
2923 sm_cgerep_bfr = bfr;
2924
2925 switch ( mode )
2926 {
2927 case CGEREP_MODE_BUFFER:
2928 case CGEREP_MODE_DICARD_RESERVED:
2929 cmhSM_cgerep_buffer ( );
2930 break;
2931 case CGEREP_MODE_BUFFER_RESERVED:
2932 break;
2933 case CGEREP_MODE_INVALID:
2934 case CGEREP_MODE_OMITTED:
2935 default:
2936 break;
2937 }
2938
2939 return AT_CMPL;
2940 }
2941
2942 #ifdef DTI
2943 GLOBAL T_ACI_RETURN sAT_PlusCGSMS ( T_ACI_CMD_SRC srcId, T_CGSMS_SERVICE service )
2944 {
2945 T_ACI_RETURN retCd = AT_CMPL; /* holds return code */
2946
2947 TRACE_FUNCTION ("sAT_PlusCGSMS()");
2948
2949 /*
2950 *-------------------------------------------------------------------
2951 * check entity status
2952 *-------------------------------------------------------------------
2953 */
2954 if( smEntStat.curCmd NEQ AT_CMD_NONE )
2955
2956 return( AT_BUSY );
2957
2958 /*
2959 *-------------------------------------------------------------------
2960 * check first command argument
2961 *-------------------------------------------------------------------
2962 */
2963 if ( service < CGSMS_SERVICE_OMITTED OR service >= CGSMS_SERVICE_INVALID )
2964 {
2965 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
2966 return( AT_FAIL );
2967 }
2968
2969 /*
2970 *-------------------------------------------------------------------
2971 * process parameter
2972 *-------------------------------------------------------------------
2973 */
2974 if ( service EQ CGSMS_SERVICE_OMITTED )
2975 service = sm_cgsms_service;
2976
2977 if ( service NEQ sm_cgsms_service )
2978 {
2979 smEntStat.curCmd = AT_CMD_CGSMS;
2980 smEntStat.entOwn = srcId;
2981 smShrdPrm.owner = (UBYTE) srcId;
2982
2983 cmhSM_set_sms_service ( service );
2984
2985 retCd = AT_EXCT;
2986 }
2987
2988 return retCd;
2989 }
2990 #endif
2991 /*
2992 +--------------------------------------------------------------------+
2993 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
2994 | STATE : finished ROUTINE : string_to_dns |
2995 +--------------------------------------------------------------------+
2996
2997 PURPOSE :
2998 */
2999 LOCAL void string_to_dns(CHAR* dns, ULONG *dns_long)
3000 {
3001 UBYTE dns_len = 4;
3002 CHAR dns_adrtest[3];
3003 UBYTE dns_adr [4];
3004 UBYTE i = 0;
3005
3006 memset(&dns_adrtest,0,dns_len-1);
3007 memset(&dns_adr,0,dns_len);
3008
3009 if(strlen(dns) NEQ 0)
3010 {
3011 for(i=0;i<dns_len;i++)
3012 {
3013 strncpy(dns_adrtest,dns,dns_len-1);
3014 dns_adr[i] = (UBYTE)atoi(dns_adrtest);
3015 dns = dns+dns_len;
3016 }
3017 for(i=0;i<dns_len;i++)
3018 {
3019 *dns_long= *dns_long + dns_adr[i];
3020 if (i<(dns_len-1))
3021 *dns_long = *dns_long<<8;
3022 }
3023 }
3024 }
3025
3026 /*
3027 +--------------------------------------------------------------------+
3028 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
3029 | STATE : finished ROUTINE : sAT_PercentCGPCO_HEX |
3030 +--------------------------------------------------------------------+
3031
3032 PURPOSE : This is the functional counterpart to the ?CGPCO= AT
3033 command to set protocol configuration options for the
3034 PDP context activation.
3035 */
3036
3037 GLOBAL T_ACI_RETURN sAT_PercentCGPCO_HEX ( T_ACI_CMD_SRC srcId, UBYTE cid, UBYTE *pco_array, UBYTE pco_len)
3038 {
3039 T_ACI_RETURN ret;
3040
3041 TRACE_FUNCTION("sAT_PercentCGPCO_HEX");
3042 /*
3043 *-------------------------------------------------------------------
3044 * check command source
3045 *-------------------------------------------------------------------
3046 */
3047 if ( !cmh_IsVldCmdSrc (srcId) )
3048 {
3049 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
3050 return( AT_FAIL );
3051 }
3052 ret = cmhSM_CGPCO_HEX (cid, pco_array, pco_len);
3053 return ret;
3054 }
3055
3056
3057 /*
3058 +--------------------------------------------------------------------+
3059 | PROJECT : GSM-PS (8441) MODULE : CMH_SMS |
3060 | STATE : finished ROUTINE : sAT_PercentCGPCO |
3061 +--------------------------------------------------------------------+
3062
3063 PURPOSE : This is the functional counterpart to the ?CGPCO= AT
3064 command to set protocol configuration options for the
3065 PDP context activation.
3066 */
3067
3068 GLOBAL T_ACI_RETURN sAT_PercentCGPCO( T_ACI_CMD_SRC srcId,
3069 U8 cid, USHORT protocol,
3070 CHAR *user, CHAR *pwd, CHAR *dns1, CHAR *dns2 )
3071 {
3072 U8 pco_len = ACI_PCO_MAX_LEN;
3073 UBYTE *pco_array;
3074 T_ACI_RETURN ret;
3075
3076
3077 /*
3078 * Due to introduction of dynamic data structures the functionality of the command is changed.
3079 * NOTE: User PCO is only applied to already defined PDP contexts.
3080 */
3081 ULONG dns_adr1 = 0x00000000;
3082 ULONG dns_adr2 = 0x00000000;
3083
3084
3085 TRACE_FUNCTION("sAT_PercentCGPCO");
3086 /*
3087 *-------------------------------------------------------------------
3088 * check command source
3089 *-------------------------------------------------------------------
3090 */
3091 if ( !cmh_IsVldCmdSrc (srcId) )
3092 {
3093 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
3094 return( AT_FAIL );
3095 }
3096
3097 ACI_MALLOC (pco_array, ACI_PCO_MAX_LEN);
3098
3099 string_to_dns( dns1, &dns_adr1 );
3100 string_to_dns( dns2, &dns_adr2 );
3101
3102 ret = (T_ACI_RETURN) utl_create_pco( pco_array, (USHORT*)&pco_len,
3103 ACI_PCO_CONTENTMASK_AUTH |
3104 ACI_PCO_CONTENTMASK_DNS1 |
3105 ACI_PCO_CONTENTMASK_DNS2,
3106 ACI_PCO_CONFIG_PROT_PPP,
3107 protocol, (UBYTE*)user, (UBYTE*)pwd, dns_adr1, dns_adr2);
3108 if (ret < 0)
3109 {
3110 TRACE_EVENT_P1 ("sAT_PercentCGPCO(): invalid protocol=%d", protocol);
3111
3112 ACI_MFREE (pco_array);
3113 return (AT_FAIL);
3114 }
3115 ret = cmhSM_CGPCO_HEX (cid, pco_array, pco_len);
3116 ACI_MFREE (pco_array);
3117 return ret;
3118 }
3119
3120 /*
3121 +--------------------------------------------------------------------+
3122 | PROJECT : GPRS MODULE : CMH_SMS |
3123 | STATE : finished ROUTINE : qAT_PercentCGPCO |
3124 +--------------------------------------------------------------------+
3125
3126 PURPOSE : %CGPCO command
3127 * analyze network PCO a cid
3128 */
3129
3130 GLOBAL T_ACI_RETURN qAT_PercentCGPCO ( T_ACI_CMD_SRC srcId, ULONG * gateway,
3131 ULONG * dns1,ULONG * dns2, USHORT cid)
3132 {
3133 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3134
3135
3136 TRACE_FUNCTION("qAT_PercentCGPCO()");
3137
3138 p_pdp_context_node = pdp_context_find_node_from_cid( (U8)cid);
3139 if( !p_pdp_context_node)
3140 {
3141 return (AT_FAIL);
3142 }
3143
3144 switch(p_pdp_context_node->internal_data.state)
3145 {
3146 case PDP_CONTEXT_STATE_ACTIVATED:
3147 case PDP_CONTEXT_STATE_ESTABLISH_3:
3148 case PDP_CONTEXT_STATE_DATA_LINK:
3149 utl_analyze_pco(p_pdp_context_node->internal_data.network_pco.pco, p_pdp_context_node->internal_data.network_pco.len, dns1, dns2, gateway);
3150 break;
3151 default:
3152 break;
3153 }
3154 return (AT_CMPL);
3155 }
3156
3157 #ifdef REL99
3158 /*
3159 +--------------------------------------------------------------------+
3160 | PROJECT : UMTS MODULE : CMH_SMS |
3161 | STATE : finished ROUTINE : sAT_PlusCGEQNEG |
3162 +--------------------------------------------------------------------+
3163
3164 PURPOSE : This is the functional counterpart to the +CGEQNEG= AT
3165 command and returns current settings for the specified
3166 PDP context. The function might be called multiple times
3167 if more cids are specified.
3168 The QoS returned is always in Release 99 format (3GPP).
3169 RETURNS: - AT_CMPL : Completed.
3170 - AT_FAIL : Command not valid for srcId.
3171 UPDATES: - qos: Quality of service for cid. Not updated if cid is undefined.
3172 - qos_valid: Indicates whether qos is updated not.
3173 */
3174 GLOBAL T_ACI_RETURN sAT_PlusCGEQNEG ( T_ACI_CMD_SRC srcId, U8 cid, BOOL *qos_valid, T_PS_qos *qos)
3175 {
3176 T_PDP_CONTEXT_INTERNAL *p_pdp_context_node = NULL;
3177 TRACE_FUNCTION ("sAT_PlusCGEQNEG()");
3178
3179 /*
3180 *-------------------------------------------------------------------
3181 * check command source - should be Serial link ?
3182 *-------------------------------------------------------------------
3183 */
3184 if ( !cmh_IsVldCmdSrc (srcId) )
3185 {
3186 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
3187 return( AT_FAIL );
3188 }
3189
3190 p_pdp_context_node = pdp_context_find_node_from_cid( cid );
3191 if( ! p_pdp_context_node )
3192 {
3193 *qos_valid = FALSE;
3194 return AT_CMPL;
3195 }
3196
3197 /*
3198 *-------------------------------------------------------------------
3199 * fill in parameters
3200 *-------------------------------------------------------------------
3201 */
3202 switch ( get_state_over_cid(cid) )
3203 {
3204 case PDP_CONTEXT_STATE_ACTIVATED:
3205 case PDP_CONTEXT_STATE_DATA_LINK:
3206 {
3207 if( p_pdp_context_node->ctrl_neg_qos EQ PS_is_R99 )
3208 {
3209 memcpy( qos, &p_pdp_context_node->neg_qos, sizeof(T_PS_qos) );
3210 }
3211 else
3212 {
3213 /* The QoS is in Release 97 format and must be converted first. */
3214 if( !cl_qos_convert_r97_to_r99( &p_pdp_context_node->neg_qos.qos_r97, &(qos->qos_r99)) )
3215 {
3216 /* Failed to convert to Release 99. Never end here !!!! */
3217 return( AT_FAIL );
3218 }
3219 }
3220 *qos_valid = TRUE;
3221 break;
3222 }
3223 default :
3224 *qos_valid = FALSE;
3225 }
3226
3227 return( AT_CMPL );
3228 }
3229
3230 /*
3231 +--------------------------------------------------------------------+
3232 | PROJECT : UMTS MODULE : CMH_SMS |
3233 | STATE : finished ROUTINE : sAT_PlusCGCMOD |
3234 +--------------------------------------------------------------------+
3235
3236 PURPOSE : This is the functional counterpart to the +CGCMOD= AT
3237 command.
3238 RETURNS: - AT_EXCT : Executing.
3239 - AT_FAIL : One of the cids is not valid or not active.
3240 */
3241 GLOBAL T_ACI_RETURN sAT_PlusCGCMOD ( T_ACI_CMD_SRC srcId, U8 *cid)
3242 {
3243
3244
3245 TRACE_FUNCTION ("sAT_PlusCGCMOD()");
3246
3247 /*
3248 *-------------------------------------------------------------------
3249 * check command source
3250 *-------------------------------------------------------------------
3251 */
3252 if ( !cmh_IsVldCmdSrc (srcId) )
3253 {
3254 ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_Parameter );
3255 return( AT_FAIL );
3256 }
3257
3258 /*
3259 *-------------------------------------------------------------------
3260 * check entity status
3261 *-------------------------------------------------------------------
3262 */
3263 if( smEntStat.curCmd NEQ AT_CMD_NONE )
3264 return( AT_BUSY );
3265
3266 if( gpppEntStat.curCmd NEQ AT_CMD_NONE )
3267 return( AT_BUSY );
3268
3269 /*
3270 *-------------------------------------------------------------------
3271 * check all context and fill work_cids list
3272 *-------------------------------------------------------------------
3273 */
3274 if (!cmhSM_make_active_cid_list ( srcId, cid ))
3275 return( AT_FAIL );
3276
3277 /*
3278 *-------------------------------------------------------------------
3279 * fill in parameters command parameters and send the modify request
3280 *-------------------------------------------------------------------
3281 */
3282 switch( get_state_over_cid(work_cids[cid_pointer]) )
3283 {
3284 case PDP_CONTEXT_STATE_ACTIVATED:
3285 set_state_over_cid(work_cids[cid_pointer], PDP_CONTEXT_STATE_ACTIVATED_MODIFYING);
3286 break;
3287
3288 case PDP_CONTEXT_STATE_DATA_LINK:
3289 set_state_over_cid(work_cids[cid_pointer], PDP_CONTEXT_STATE_DATA_LINK_MODIFYING);
3290 break;
3291
3292 default:
3293 return( AT_FAIL ); /* Obsolete: State already checked in cmhSM_make_active_cid_list */
3294 }
3295
3296 /* Send the modify request */
3297 psaSM_PDP_Modify();
3298 smEntStat.curCmd = AT_CMD_CGCMOD;
3299 smEntStat.entOwn = srcId;
3300 smShrdPrm.owner = (UBYTE) srcId;
3301 return( AT_EXCT );
3302 }
3303
3304 #endif /* REL99 */
3305
3306 #endif /* GPRS */
3307 /*==== EOF ========================================================*/