|
1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "gprs.h" |
|
17 #include "Gprscontext.h" |
|
18 #include "mSLOGGER.H" |
|
19 #include <pcktcs.h> |
|
20 #include "ATGprsConfig.h" |
|
21 #include "ATIO.H" |
|
22 #include <etelpckt.h> |
|
23 #include "NOTIFY.H" |
|
24 #include "Matstd.h" |
|
25 |
|
26 _LIT8(KGetCGDCONTCommand,"AT+CGDCONT?\r"); |
|
27 _LIT8(KIPType4 , "IP"); |
|
28 _LIT8(KIPType6 , "IP"); |
|
29 _LIT8(KX25 , "X25"); |
|
30 |
|
31 |
|
32 /** |
|
33 * @file |
|
34 * This file implements the CATGPRSSetConfig class and the CATGPRSGetConfig. These two classes are used by the |
|
35 * GPRS AT TSY library. |
|
36 * This state machine uses "AT+CGQREQ" "AT+CGDCONT" "AT+CGQMIN" commands. |
|
37 */ |
|
38 CATGPRSSetConfig* CATGPRSSetConfig::NewL(TInt aCid, CATIO* aIo, CTelObject* aTelObject, CATInit* aInit, CPhoneGlobals* aPhoneGlobals) |
|
39 /** |
|
40 * Standard 2 phase constructor. |
|
41 * @param aIo pointer to communication object. |
|
42 * @param aTelObject pointer to parent. |
|
43 * @param aInit pointer to AT phone init object. |
|
44 * @param aPhoneGlobals pointer to phone global wide states. |
|
45 */ |
|
46 { |
|
47 CATGPRSSetConfig* p=new(ELeave) CATGPRSSetConfig(aCid, aIo, aTelObject, aInit, aPhoneGlobals); |
|
48 CleanupStack::PushL(p); |
|
49 p->ConstructL(); |
|
50 CleanupStack::Pop(); |
|
51 return p; |
|
52 } |
|
53 |
|
54 void CATGPRSSetConfig::ConstructL() |
|
55 /** |
|
56 * Construct all objects that can leave. |
|
57 */ |
|
58 { |
|
59 CATCommands::ConstructL(); |
|
60 } |
|
61 |
|
62 |
|
63 CATGPRSSetConfig::CATGPRSSetConfig(TInt aCid, CATIO* aIo, CTelObject *aTelObject, CATInit* aInit, CPhoneGlobals* aPhoneGlobals) |
|
64 : CATCommands(aIo, aTelObject, aInit, aPhoneGlobals), iCid(aCid) |
|
65 /** |
|
66 * Constructor. |
|
67 * |
|
68 * @param aIo pointer to communication object. |
|
69 * @param aTelObject pointer to parent. |
|
70 * @param aPhoneGlobals pointer to phone global wide states. |
|
71 */ |
|
72 { |
|
73 LOGTEXT(_L8("CATGprsClass::CATGprsClass called")); |
|
74 } |
|
75 |
|
76 |
|
77 CATGPRSSetConfig::~CATGPRSSetConfig() |
|
78 /** |
|
79 * Destructor. |
|
80 */ |
|
81 { |
|
82 LOGTEXT(_L8("CATGPRSSetConfig::~CATGPRSSetConfig called")); |
|
83 } |
|
84 |
|
85 |
|
86 void CATGPRSSetConfig::Start(TTsyReqHandle aTsyReqHandle, TAny* aConfig) |
|
87 /** |
|
88 * This starts the sending of the set commands. |
|
89 * |
|
90 * @param aConfig config package. |
|
91 * @param aTsyReqHandle handle to the client. |
|
92 */ |
|
93 { |
|
94 iReqHandle = aTsyReqHandle; |
|
95 TPckg<RPacketContext::TContextConfigGPRS>* contextConfigV1Pckg = (TPckg<RPacketContext::TContextConfigGPRS>*)aConfig; |
|
96 iContextConfigGPRS= &(*contextConfigV1Pckg)(); |
|
97 TInt ret=MakeupCGDCONT(); |
|
98 if(ret) |
|
99 { |
|
100 Complete(KErrNotSupported,ETimeOutCompletion); |
|
101 return; |
|
102 } |
|
103 |
|
104 LOGTEXT(_L8("CATGPRSSetConfig:\tCATConfigGPRS::Start function called in TSY")); |
|
105 |
|
106 __ASSERT_ALWAYS(iIo->AddExpectString(this,KNotifyMeIfErrorString) != NULL, Panic(EGeneral)); |
|
107 iState=EWaitForSetCGDCONTComplete; |
|
108 Write(KGprsCommandTimeOut); |
|
109 } |
|
110 |
|
111 void CATGPRSSetConfig::Stop(TTsyReqHandle aTsyReqHandle) |
|
112 /** |
|
113 * This function cancels the outstanding read and sets the state to EWaitForDSR. |
|
114 * |
|
115 * @param aTsyReqHandle handle to the client. |
|
116 */ |
|
117 { |
|
118 LOGTEXT(_L8("CATGPRSSetConfig::Stop called")); |
|
119 if(iState!=EATNotInProgress && aTsyReqHandle==iReqHandle) |
|
120 { |
|
121 LOGTEXT(_L8("CATGPRSSetConfig::Stop Completing client request with KErrCancel")); |
|
122 Complete(KErrCancel,ETimeOutCompletion); |
|
123 } |
|
124 } |
|
125 |
|
126 |
|
127 void CATGPRSSetConfig::CompleteWithIOError(TEventSource aSource,TInt aStatus) |
|
128 /** |
|
129 * This Function completes the command from the client whith an error. |
|
130 * |
|
131 * @param aSource source of event from communication class. |
|
132 * @param aStatus status of event. |
|
133 */ |
|
134 { |
|
135 Complete(aStatus, aSource); |
|
136 } |
|
137 |
|
138 |
|
139 void CATGPRSSetConfig::Complete(TInt aErr, TEventSource aSource) |
|
140 /** |
|
141 * This Function completes the get or set command from the client. |
|
142 * @param aErr an error code to relay to client. |
|
143 */ |
|
144 { |
|
145 LOGTEXT(_L8("CATGPRSSetConfig::Complete")); |
|
146 RemoveStdExpectStrings(); |
|
147 iIo->WriteAndTimerCancel(this); |
|
148 iIo->RemoveExpectStrings(this); |
|
149 if (aErr == KErrNone) |
|
150 { |
|
151 ((CGprsContext*)iTelObject)->SetConfig(iContextConfigGPRS); |
|
152 iPhoneGlobals->iNotificationStore->CheckNotification(iTelObject, EPacketContextConfigChanged); |
|
153 } |
|
154 |
|
155 // Allow our base class to do its thing and then complete the client request |
|
156 CATCommands::Complete(aErr,aSource); |
|
157 iTelObject->ReqCompleted(iReqHandle, aErr); |
|
158 |
|
159 iState = EATNotInProgress; |
|
160 } |
|
161 |
|
162 |
|
163 void CATGPRSSetConfig::EventSignal(TEventSource aSource) |
|
164 /** |
|
165 * This function contains the state machine for the command. The states flow consecutively in |
|
166 * get and set states and are described below. |
|
167 * |
|
168 * @par aSource Source of function call. |
|
169 * |
|
170 * @par EWaitForDSR |
|
171 * Wait for the DSR command to complete. Also sends AT+CGDCONT set or get command to the phone. |
|
172 * |
|
173 * @par EWaitForSetCGDCONTComplete, |
|
174 * Wait for response from the phone on the set command. |
|
175 * |
|
176 * @par EWaitForSetCGDCONTOK, |
|
177 * Validate phone response and send set AT+CGQMIN command. |
|
178 * |
|
179 * |
|
180 */ |
|
181 { |
|
182 LOGTEXT2(_L8("CATGPRSSetConfig::EventSignal with iState %d"),iState); |
|
183 if ((aSource==ETimeOutCompletion)) |
|
184 { |
|
185 LOGTEXT(_L8("CATGPRSSetConfig:\tTimeout Error during Config")); |
|
186 Complete(KErrTimedOut,aSource); |
|
187 return; |
|
188 } |
|
189 switch(iState) |
|
190 { |
|
191 case EWaitForSetCGDCONTComplete: |
|
192 LOGTEXT(_L8("CATGPRSSetConfig::EventSignal, EWaitForSetCGDCONTComplete")); |
|
193 StandardWriteCompletionHandler(aSource, KGprsCommandTimeOut); |
|
194 iState = EWaitForSetCGDCONTOK; |
|
195 break; |
|
196 |
|
197 case EWaitForSetCGDCONTOK: |
|
198 { |
|
199 // Called when OK is received |
|
200 LOGTEXT(_L8("CATGPRSSetConfig::EventSignal, EWaitForSetCGDCONTOK")); |
|
201 __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected)); |
|
202 TInt ret = ValidateExpectString(); |
|
203 Complete(ret, aSource); |
|
204 } |
|
205 break; |
|
206 |
|
207 case EATNotInProgress: |
|
208 break; |
|
209 default: |
|
210 LOGTEXT(_L8("CATGPRSSetConfig::EventSignal, default. Panic")); |
|
211 Panic(EIllegalEvent); |
|
212 break; |
|
213 } |
|
214 } |
|
215 |
|
216 |
|
217 TInt CATGPRSSetConfig::MakeupCGDCONT() |
|
218 /** |
|
219 * This Function creates the at set string for the AT+CGDCONT command. |
|
220 */ |
|
221 { |
|
222 const TInt KPDPTypeIdent=5; |
|
223 TBuf8<KPDPTypeIdent> pdpType; // PDP Type identifier |
|
224 TBuf8<RPacketContext::KGSNNameLength> gsnName; // Access point Name |
|
225 TBuf8<RPacketContext::KMaxPDPAddressLength> pdpAddress; // PDP pre-assigned address |
|
226 switch(iContextConfigGPRS->iPdpType) |
|
227 { |
|
228 |
|
229 case RPacketContext::EPdpTypeIPv4: |
|
230 pdpType.Format(KIPType4); |
|
231 break; |
|
232 |
|
233 case RPacketContext::EPdpTypeIPv6: |
|
234 pdpType.Format(KIPType6); |
|
235 break; |
|
236 |
|
237 case RPacketContext::EPdpTypeX25: |
|
238 pdpType.Format(KX25); |
|
239 break; |
|
240 |
|
241 default: |
|
242 return KErrUnknown; |
|
243 } |
|
244 |
|
245 gsnName.Copy(iContextConfigGPRS->iAccessPointName); |
|
246 pdpAddress.Copy(iContextConfigGPRS->iPdpAddress); |
|
247 const TBool dataCompression=iContextConfigGPRS->iPdpCompression & RPacketContext::KPdpDataCompression; |
|
248 const TBool headerCompression=iContextConfigGPRS->iPdpCompression & RPacketContext::KPdpHeaderCompression; |
|
249 |
|
250 iTxBuffer.Format(_L8("AT+CGDCONT=%d,\"%S\",\"%S\",\"%S\",%d,%d\r"), iCid, &pdpType, |
|
251 &gsnName, &pdpAddress,dataCompression,headerCompression); |
|
252 |
|
253 return KErrNone; |
|
254 } |
|
255 |
|
256 |
|
257 |
|
258 CATGPRSGetConfig* CATGPRSGetConfig::NewL(TInt aCid, CATIO* aIo, CTelObject* aTelObject, CATInit* aInit, CPhoneGlobals* aPhoneGlobals) |
|
259 /** |
|
260 * Standard 2 phase constructor. |
|
261 * |
|
262 * @param aIo pointer to communication object. |
|
263 * @param aTelObject pointer to parent. |
|
264 * @param aPhoneGlobals pointer to phone global wide states. |
|
265 */ |
|
266 { |
|
267 CATGPRSGetConfig* p=new(ELeave) CATGPRSGetConfig(aCid, aIo, aTelObject, aInit, aPhoneGlobals); |
|
268 CleanupStack::PushL(p); |
|
269 p->ConstructL(); |
|
270 CleanupStack::Pop(); |
|
271 return p; |
|
272 } |
|
273 |
|
274 void CATGPRSGetConfig::ConstructL() |
|
275 /** |
|
276 * Construct all objects that can leave. |
|
277 */ |
|
278 { |
|
279 CATCommands::ConstructL(); |
|
280 } |
|
281 |
|
282 CATGPRSGetConfig::CATGPRSGetConfig(TInt aCid, CATIO* aIo, CTelObject *aTelObject, CATInit* aInit, CPhoneGlobals* aPhoneGlobals) |
|
283 : CATCommands(aIo, aTelObject, aInit, aPhoneGlobals), iCid(aCid) |
|
284 /** |
|
285 * Constructor. |
|
286 * |
|
287 * @param aIo pointer to communication object. |
|
288 * @param aTelObject pointer to parent. |
|
289 * @param aPhoneGlobals pointer to phone global wide states. |
|
290 */ |
|
291 {} |
|
292 |
|
293 |
|
294 CATGPRSGetConfig::~CATGPRSGetConfig() |
|
295 /** |
|
296 * Destructor. |
|
297 */ |
|
298 {} |
|
299 |
|
300 |
|
301 void CATGPRSGetConfig::Start(TTsyReqHandle aTsyReqHandle, TAny* aConfig) |
|
302 /** |
|
303 * This starts the sending of the get commands. |
|
304 * |
|
305 * @param aTsyReqHandle handle to the client. |
|
306 * @param aConfig Pointer to a RPacketContext::TContextConfigGPRS. |
|
307 */ |
|
308 |
|
309 { |
|
310 LOGTEXT(_L8("CATGPRSGetConfig::Start called")); |
|
311 |
|
312 TPckg<RPacketContext::TContextConfigGPRS>* contextConfigV1Pckg = (TPckg<RPacketContext::TContextConfigGPRS>*)aConfig; |
|
313 iContextConfigV1 = &(*contextConfigV1Pckg)(); |
|
314 |
|
315 __ASSERT_ALWAYS(iIo->AddExpectString(this,KNotifyMeIfErrorString) != NULL, Panic(EGeneral)); |
|
316 iReqHandle = aTsyReqHandle; |
|
317 iState=EWaitForGetCGDCONTComplete; |
|
318 Write(KGetCGDCONTCommand, KGprsCommandTimeOut); |
|
319 } |
|
320 |
|
321 |
|
322 |
|
323 void CATGPRSGetConfig::Stop(TTsyReqHandle aTsyReqHandle) |
|
324 /** |
|
325 * This function cancels the outstanding read and sets the state to EWaitForDSR. |
|
326 * @param aTsyReqHandle handle to the client. |
|
327 */ |
|
328 { |
|
329 LOGTEXT(_L8("CATGPRSGetConfig::Stop called")); |
|
330 if(iState!=EATNotInProgress && aTsyReqHandle==iReqHandle) |
|
331 { |
|
332 LOGTEXT(_L8("CATGPRSGetConfig::Stop Completing client request with KErrCancel")); |
|
333 Complete(KErrCancel,ETimeOutCompletion); |
|
334 } |
|
335 } |
|
336 |
|
337 void CATGPRSGetConfig::Complete(TInt aErr, TEventSource aSource) |
|
338 /** |
|
339 * This Function completes the get or set command from the client. |
|
340 * @param aErr and error to relay to the client. |
|
341 */ |
|
342 { |
|
343 LOGTEXT(_L8("CATGPRSGetConfig::Complete")); |
|
344 RemoveStdExpectStrings(); |
|
345 iIo->WriteAndTimerCancel(this); |
|
346 iIo->RemoveExpectStrings(this); |
|
347 if(aErr == KErrNone) |
|
348 { |
|
349 ((CGprsContext*)iTelObject)->SetConfig(iContextConfigV1); |
|
350 } |
|
351 |
|
352 // Allow our base class to do its thing and then complete the client request |
|
353 CATCommands::Complete(aErr,aSource); |
|
354 iTelObject->ReqCompleted(iReqHandle, aErr); |
|
355 |
|
356 iState = EATNotInProgress; |
|
357 } |
|
358 |
|
359 void CATGPRSGetConfig::CompleteWithIOError(TEventSource aSource,TInt aStatus) |
|
360 /** |
|
361 * This Function completes the command from the client whith an error. |
|
362 * @param aSource source of event from communication class. |
|
363 * @param aStatus status of event. |
|
364 */ |
|
365 { |
|
366 Complete(aStatus, aSource); |
|
367 } |
|
368 |
|
369 void CATGPRSGetConfig::EventSignal(TEventSource aSource) |
|
370 /** |
|
371 * This function contains the state machine for the command. The states flow consecutively in |
|
372 * get and set states and are described below. |
|
373 * |
|
374 * @par aSource Source of function call. |
|
375 * |
|
376 * |
|
377 * @par EWaitForGetCGDCONTComplete, |
|
378 * Wait for response from the phone on the set command. |
|
379 * |
|
380 * @par EWaitForGetCGDCONTOK, |
|
381 * Validate phone response and send set AT+CGQMIN command. |
|
382 * |
|
383 */ |
|
384 { |
|
385 LOGTEXT2(_L8("CATGPRSGetConfig::EventSignal with iState %d"),iState); |
|
386 if ((aSource==ETimeOutCompletion)) |
|
387 { |
|
388 LOGTEXT(_L8("CATGPRSGetConfig:\tTimeout Error during Config")); |
|
389 Complete(KErrTimedOut,aSource); |
|
390 return; |
|
391 } |
|
392 switch(iState) |
|
393 { |
|
394 case EWaitForGetCGDCONTComplete: |
|
395 { |
|
396 iIo->WriteAndTimerCancel(this); |
|
397 StandardWriteCompletionHandler(aSource, KGprsCommandTimeOut); |
|
398 iState = EWaitForGetCGDCONTOK; |
|
399 } |
|
400 break; |
|
401 case EWaitForGetCGDCONTOK: |
|
402 { |
|
403 // Called when OK is received |
|
404 __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected)); |
|
405 TInt ret = ValidateExpectString(); |
|
406 if(ret) |
|
407 { |
|
408 Complete(ret, aSource); |
|
409 return; |
|
410 } |
|
411 TRAP_IGNORE(ParseCGDCONTResponseL()); |
|
412 Complete(ret, aSource); |
|
413 } |
|
414 break; |
|
415 |
|
416 |
|
417 case EATNotInProgress: |
|
418 break; |
|
419 |
|
420 default: |
|
421 { |
|
422 LOGTEXT(_L8("CATGPRSGetConfig::EventSignal, Default, panic")); |
|
423 Panic(EIllegalEvent); |
|
424 } |
|
425 break; |
|
426 } |
|
427 } |
|
428 |
|
429 |
|
430 void CATGPRSGetConfig::ParseCGDCONTResponseL() |
|
431 /** |
|
432 * This Function parses the response from the get AT+CGDCONT? command to the phone |
|
433 */ |
|
434 { |
|
435 ParseBufferLC(); |
|
436 CATParamListEntry* entry; |
|
437 TDblQueIter<CATParamListEntry> iter(iRxResults); |
|
438 while(entry = iter++,entry!=NULL) |
|
439 { |
|
440 if (entry->iResultPtr.MatchF(KCGDCONTResponseString)!=0) |
|
441 continue; |
|
442 entry = iter++; |
|
443 if(entry == NULL) |
|
444 User::Leave(KErrNotFound); |
|
445 TLex8 lex(entry->iResultPtr); |
|
446 TInt val; |
|
447 (void)User::LeaveIfError(lex.Val(val)); |
|
448 if(iCid == val) |
|
449 { |
|
450 entry = iter++; |
|
451 break; |
|
452 } |
|
453 } |
|
454 if(entry == NULL) |
|
455 User::Leave(KErrNotFound); |
|
456 // we are now pointing to the correct context, just parse the values |
|
457 // Get the pdp type |
|
458 TPtrC8 result(entry->iResultPtr); |
|
459 if(result == KIPType4) |
|
460 iContextConfigV1->iPdpType = RPacketContext::EPdpTypeIPv4; |
|
461 else if(result == KIPType6)//EPdpTypeIPv6, |
|
462 iContextConfigV1->iPdpType = RPacketContext::EPdpTypeIPv6; |
|
463 else if(result == KX25) |
|
464 iContextConfigV1->iPdpType = RPacketContext::EPdpTypeX25; |
|
465 else |
|
466 User::Leave(KErrNotSupported); |
|
467 //Get the gsnName |
|
468 entry = iter++; |
|
469 if(entry == NULL) |
|
470 User::Leave(KErrNotFound); |
|
471 result.Set(entry->iResultPtr); |
|
472 iContextConfigV1->iAccessPointName.Copy(result); |
|
473 // Get pdp address |
|
474 entry = iter++; |
|
475 if(entry == NULL) |
|
476 User::Leave(KErrNotFound); |
|
477 result.Set(entry->iResultPtr); |
|
478 iContextConfigV1->iPdpAddress.Copy(result); |
|
479 // get compression |
|
480 entry = iter++; |
|
481 if(entry == NULL) |
|
482 User::Leave(KErrGeneral); |
|
483 iContextConfigV1->iPdpCompression = CATParamListEntry::EntryValL(entry); |
|
484 CleanupStack::PopAndDestroy(); |
|
485 } |
|
486 |
|
487 |