|
1 // Copyright (c) 1997-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 <commsdattypesv1_1.h> |
|
17 #include <cdblen.h> |
|
18 #include "ATDIAL.H" |
|
19 #include "mSLOGGER.H" |
|
20 #include "PHONE.H" |
|
21 #include "CALL.H" |
|
22 #include "ATNOCARR.H" |
|
23 #include "NOTIFY.H" |
|
24 #include "ATIO.H" |
|
25 |
|
26 #include <etelmm.h> |
|
27 #include "Matstd.h" |
|
28 |
|
29 const TInt KWaitForConnect=30000; |
|
30 |
|
31 CATDialVoice* CATDialVoice::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
32 { |
|
33 CATDialVoice* dial=new(ELeave) CATDialVoice(aIo, aTelObject, aInit,aPhoneGlobals); |
|
34 CleanupStack::PushL(dial); |
|
35 dial->ConstructL(); // This ConstructL call is required to allow our base classes to construct |
|
36 CleanupStack::Pop(); |
|
37 return dial; |
|
38 } |
|
39 |
|
40 CATDialVoice::CATDialVoice(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
41 : CATVoiceCallConnectCommands(aIo,aTelObject,aInit,aPhoneGlobals) |
|
42 {} |
|
43 |
|
44 |
|
45 void CATDialVoice::Start(TTsyReqHandle aTsyReqHandle, TAny* aParams) |
|
46 { |
|
47 LOGTEXT(_L8("Starting Voice Dial Command")); |
|
48 iState=EATInitialising; |
|
49 iTelnum=REINTERPRET_CAST(TDesC*,aParams); |
|
50 CATVoiceCallConnectCommands::Start(aTsyReqHandle,aParams); |
|
51 } |
|
52 |
|
53 void CATDialVoice::Stop(TTsyReqHandle aTsyReqHandle) |
|
54 // |
|
55 // Attempt to halt the dial process by sending a carriage return, expecting a NO CARRIER |
|
56 // message, or if the pre-dial commands are still being sent then simply wait for OK |
|
57 // |
|
58 { |
|
59 __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle)); |
|
60 __ASSERT_ALWAYS(iState!=EATNotInProgress,Panic(EATCommand_NotInProgress)); |
|
61 LOGTEXT(_L8("Cancelling Voice Dial Command")); |
|
62 iIo->WriteAndTimerCancel(this); |
|
63 if (iState!=EATInitialising) |
|
64 { |
|
65 Write(KCarriageReturn(),1); |
|
66 iState = EATCancellingWaitForWriteComplete; |
|
67 iPreConnectState=CATCallConnectCommands::ENotInProgress; |
|
68 } |
|
69 else |
|
70 { |
|
71 AddStdExpectStrings(); |
|
72 iPreConnectState=CATCallConnectCommands::ECancelling; |
|
73 iState = EATNotInProgress; |
|
74 } |
|
75 } |
|
76 |
|
77 TInt CATDialVoice::AddDialExpectStrings() |
|
78 { |
|
79 LOGTEXT2(_L8("Entered CATDialVoice::AddDialExpectStringsL with iNoDialToneExpectString of %x"),iNoDialToneExpectString); |
|
80 |
|
81 AddCommonExpectStrings(); |
|
82 |
|
83 TInt ret(KErrNone); |
|
84 |
|
85 if (!iCallMonitoringExpectString) |
|
86 { |
|
87 iCallMonitoringExpectString=iIo->AddExpectString(this,KCallMonitoringEventString); |
|
88 } |
|
89 |
|
90 if (!iBusyExpectString) |
|
91 { |
|
92 ret=iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameBusy),iBusyString); |
|
93 if(ret!=KErrNone) |
|
94 return ret; |
|
95 AppendWildCardChar(iBusyString); |
|
96 iBusyExpectString=iIo->AddExpectString(this,iBusyString); |
|
97 } |
|
98 |
|
99 if (!iNoDialToneExpectString) |
|
100 { |
|
101 ret=iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameNoDialTone),iNoDialToneString); |
|
102 if(ret!=KErrNone) |
|
103 return ret; |
|
104 iNoDialToneExpectString=iIo->AddExpectString(this,iNoDialToneString); |
|
105 } |
|
106 |
|
107 if (!iNoAnswerExpectString) |
|
108 { |
|
109 ret=iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameNoAnswer),iNoAnswerString); |
|
110 if(ret!=KErrNone) |
|
111 return ret; |
|
112 AppendWildCardChar(iNoAnswerString); |
|
113 iNoAnswerExpectString=iIo->AddExpectString(this,iNoAnswerString); |
|
114 } |
|
115 |
|
116 if (!iDelayedExpectString) |
|
117 iDelayedExpectString=iIo->AddExpectString(this,KDelayedString); |
|
118 |
|
119 LOGTEXT(_L8("Leaving CATDialVoice::AddDialExpectStringsL")); |
|
120 |
|
121 return KErrNone; |
|
122 } |
|
123 |
|
124 TInt CATDialVoice::ValidateDialExpectString() |
|
125 { |
|
126 CCommChatString* foundChatString = iIo->FoundChatString(); |
|
127 |
|
128 if (foundChatString == iOKExpectString) |
|
129 return KErrNone; |
|
130 |
|
131 if (foundChatString == iCallMonitoringExpectString) |
|
132 { |
|
133 LOGTEXT(_L8("Modem returned *ECAV Ericsson Call Monitoring (similar to NO CARRIER) in response to dial command")); |
|
134 return KErrEtelNoCarrier; |
|
135 } |
|
136 |
|
137 if (foundChatString == iNoCarrierExpectString) |
|
138 { |
|
139 LOGTEXT(_L8("Modem returned NO CARRIER in response to dial command")); |
|
140 return KErrEtelNoCarrier; |
|
141 } |
|
142 |
|
143 if (foundChatString == iNoDialToneExpectString) |
|
144 { |
|
145 LOGTEXT(_L8("Modem returned NO DIALTONE in response to dial command")); |
|
146 return KErrEtelNoDialTone; |
|
147 } |
|
148 |
|
149 if (foundChatString == iBusyExpectString) |
|
150 { |
|
151 LOGTEXT(_L8("Modem returned BUSY in response to dial command")); |
|
152 return KErrEtelBusyDetected; |
|
153 } |
|
154 |
|
155 if (foundChatString == iNoAnswerExpectString) |
|
156 { |
|
157 LOGTEXT(_L8("Modem returned NO ANSWER in response to dial command")); |
|
158 return KErrEtelNoAnswer; |
|
159 } |
|
160 |
|
161 if (foundChatString == iDelayedExpectString) |
|
162 { |
|
163 LOGTEXT(_L8("Modem returned DELAYED in response to dial command")); |
|
164 return KErrEtelBusyDetected; // No 'Delayed' error message |
|
165 } |
|
166 |
|
167 LOGTEXT(_L8("Voice dial command\tunexpected match!")); |
|
168 return KErrGeneral; |
|
169 } |
|
170 |
|
171 void CATDialVoice::RemoveDialExpectStrings() |
|
172 { |
|
173 RemoveCommonExpectStrings(); |
|
174 iIo->RemoveExpectString(iCallMonitoringExpectString); |
|
175 iCallMonitoringExpectString=NULL; // Set pointer to NULL to denote we have removed the expect string |
|
176 iIo->RemoveExpectString(iBusyExpectString); |
|
177 iBusyExpectString=NULL; // Set pointer to NULL to denote we have removed the expect string |
|
178 iIo->RemoveExpectString(iNoDialToneExpectString); |
|
179 iNoDialToneExpectString=NULL; // Set pointer to NULL to denote we have removed the expect string |
|
180 iIo->RemoveExpectString(iNoAnswerExpectString); |
|
181 iNoAnswerExpectString=NULL; // Set pointer to NULL to denote we have removed the expect string |
|
182 iIo->RemoveExpectString(iDelayedExpectString); |
|
183 iDelayedExpectString=NULL; // Set pointer to NULL to denote we have removed the expect string |
|
184 } |
|
185 |
|
186 void CATDialVoice::CompleteWithIOError(TEventSource aSource,TInt aStatus) |
|
187 { |
|
188 if (iState!=EATNotInProgress) |
|
189 { |
|
190 iState = EATNotInProgress; |
|
191 CATCallConnectCommands::CompleteWithIOError(aSource,aStatus); |
|
192 } |
|
193 } |
|
194 |
|
195 |
|
196 void CATDialVoice::EventSignal(TEventSource aSource) |
|
197 { |
|
198 LOGTEXT2(_L8("CATDialVoice::EventSignal with iState %d"),iState); |
|
199 if ((aSource==ETimeOutCompletion)&&(iState!=EATCancellingReadCompleted) |
|
200 &&(iState!=CATDialVoice::EATNotInProgress) |
|
201 &&(iState!=CATDialVoice::EDTRDropped) |
|
202 &&(iState!=CATDialVoice::EWaitForDTRRaiseSettle) |
|
203 &&(iState!=CATDialVoice::EATHangupReadCompleted)) |
|
204 { |
|
205 LOGTEXT(_L8("Timeout Error during voice Dial")); |
|
206 RemoveDialExpectStrings(); |
|
207 RemoveStdExpectStrings(); |
|
208 iState = EATNotInProgress; |
|
209 Complete(KErrTimedOut,aSource); |
|
210 return; |
|
211 } |
|
212 |
|
213 // |
|
214 // Read Completions can happen in unexpected places with the |
|
215 // Ericsson Call Monitoring (AT*ECAM=1) turned on, so need check |
|
216 // it outside of the state machine. |
|
217 // |
|
218 // The Ericsson call monitoring replaces the Ericsson SH888 hack also |
|
219 // |
|
220 if ((aSource==EReadCompletion)) |
|
221 { |
|
222 // Does it match a General Expect String? |
|
223 TInt ret=ValidateExpectString(); |
|
224 |
|
225 // Not General, so does it match a Dial Specific Expect String? |
|
226 if (ret != KErrNone) |
|
227 ret=ValidateDialExpectString(); |
|
228 |
|
229 // It doesn't match any Expect Strings at all, so complete with error |
|
230 // otherwise just continue with the state machine as normal |
|
231 if (ret != KErrNone) |
|
232 { |
|
233 LOGTEXT2(_L8("Completing call with Error %d"), ret); |
|
234 Complete(ret,aSource); |
|
235 return; |
|
236 } |
|
237 } |
|
238 |
|
239 if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted |
|
240 && iPreConnectState!=CATCallConnectCommands::ENotInProgress) |
|
241 { |
|
242 CATCallConnectCommands::PreConnectEventSignal(aSource); |
|
243 if (iPreConnectState==CATCallConnectCommands::ENotInProgress) // cancelled |
|
244 iState=EATNotInProgress; |
|
245 if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted) |
|
246 return; |
|
247 else |
|
248 iState=EATSendDialCommand; |
|
249 } |
|
250 |
|
251 switch(iState) |
|
252 { |
|
253 case EATSendDialCommand: |
|
254 { |
|
255 ChangeLineStatus(RCall::EStatusDialling); |
|
256 // Setting to EStatusDialling always returns KErrNone |
|
257 (void)ChangeCallStatus(RMobileCall::EStatusDialling); |
|
258 iPhoneGlobals->iNotificationStore->CheckNotification(REINTERPRET_CAST(CCallBase*,iTelObject),EBegunConnecting); |
|
259 TBuf8<KCommsDbSvrMaxFieldLength> dialModifier; |
|
260 TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameDialToneWaitModifier),dialModifier); |
|
261 if (ret) |
|
262 { |
|
263 Complete(ret,aSource); |
|
264 break; |
|
265 } |
|
266 TInt len = iTelnum->Length(); |
|
267 |
|
268 HBufC8* buf = NULL; |
|
269 TRAP(ret,buf = HBufC8::NewL(len)); |
|
270 if (ret) |
|
271 { |
|
272 Complete(ret,aSource); |
|
273 break; |
|
274 } |
|
275 TPtr8 newTelnum(buf->Des()); |
|
276 newTelnum.Copy(*iTelnum); |
|
277 |
|
278 TInt aPos=newTelnum.FindF(dialModifier); |
|
279 if (aPos!=KErrNotFound) |
|
280 newTelnum.Delete(aPos,1); |
|
281 iTxBuffer.Format(KDialVoiceCommandFormat,&newTelnum); |
|
282 delete buf; |
|
283 iIo->Write(this,iTxBuffer); |
|
284 iIo->SetTimeOut(this); |
|
285 iState=EATDialWaitForWriteComplete; |
|
286 } |
|
287 break; |
|
288 |
|
289 case EATDialWaitForWriteComplete: |
|
290 { |
|
291 __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); |
|
292 TInt ret=AddDialExpectStrings(); |
|
293 AddStdExpectStrings(); |
|
294 if (ret) |
|
295 { |
|
296 Complete(ret,aSource); |
|
297 break; |
|
298 } |
|
299 iIo->SetTimeOut(this,KWaitForConnect); // 30 seconds for the other end to pick up. |
|
300 iState=EATDialReadComplete; |
|
301 } |
|
302 break; |
|
303 |
|
304 case EATDialReadComplete: |
|
305 __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected)); |
|
306 { |
|
307 iIo->WriteAndTimerCancel(this); |
|
308 RemoveDialExpectStrings(); |
|
309 RemoveStdExpectStrings(); |
|
310 iState = EATNotInProgress; |
|
311 Complete(KErrNone,aSource); |
|
312 } |
|
313 break; |
|
314 |
|
315 case EATCancellingWaitForWriteComplete: |
|
316 { |
|
317 __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); |
|
318 TInt ret=AddDialExpectStrings(); |
|
319 if (ret) |
|
320 { |
|
321 Complete(ret,aSource); |
|
322 break; |
|
323 } |
|
324 if (!iOKExpectString) |
|
325 { |
|
326 iOKExpectString=iIo->AddExpectString(this,KOkString); |
|
327 } |
|
328 iIo->SetTimeOut(this); |
|
329 iState=EATCancellingReadCompleted; |
|
330 } |
|
331 break; |
|
332 |
|
333 case EATCancellingReadCompleted: |
|
334 { |
|
335 iState = EATNotInProgress; |
|
336 if (aSource==EReadCompletion) |
|
337 { |
|
338 TInt ret=ValidateDialExpectString(); |
|
339 RemoveDialExpectStrings(); |
|
340 iOKExpectString=NULL; |
|
341 if (ret==KErrNone) |
|
342 { |
|
343 iIo->DropDtr(); |
|
344 iIo->SetTimeOut(this,KDTRLowPeriod); |
|
345 iState=EDTRDropped; |
|
346 return; |
|
347 } |
|
348 } |
|
349 RemoveDialExpectStrings(); |
|
350 Complete(KErrCancel,aSource); |
|
351 } |
|
352 break; |
|
353 |
|
354 case EDTRDropped: |
|
355 __ASSERT_ALWAYS(aSource==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected)); |
|
356 iIo->Cancel(); |
|
357 iIo->RaiseDTR(); |
|
358 iIo->Read(); |
|
359 iIo->SetTimeOut(this,KDTRHighSettle); |
|
360 iState=EWaitForDTRRaiseSettle; |
|
361 break; |
|
362 |
|
363 case EWaitForDTRRaiseSettle: |
|
364 __ASSERT_ALWAYS(aSource==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected)); |
|
365 Write(KHangUpCommand(),1); |
|
366 iState=EATHangupWaitForWriteComplete; |
|
367 break; |
|
368 |
|
369 case EATHangupWaitForWriteComplete: |
|
370 __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); |
|
371 if (!iNoCarrierExpectString) |
|
372 iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString); |
|
373 StandardWriteCompletionHandler(aSource,2); |
|
374 iState=EATHangupReadCompleted; |
|
375 break; |
|
376 |
|
377 case EATHangupReadCompleted: |
|
378 __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected)); |
|
379 Complete(KErrCancel,aSource); |
|
380 break; |
|
381 |
|
382 default: |
|
383 ; |
|
384 } |
|
385 } |
|
386 |
|
387 // |
|
388 // Dial number for data call. Remove the dial modifier W if found and only add it again if the |
|
389 // call parameters indicate that we are to wait for dial tone. |
|
390 // |
|
391 CATDialData* CATDialData::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
392 { |
|
393 CATDialData* dial=new(ELeave) CATDialData(aIo, aTelObject, aInit,aPhoneGlobals); |
|
394 CleanupStack::PushL(dial); |
|
395 dial->ConstructL(); |
|
396 CleanupStack::Pop(); |
|
397 return dial; |
|
398 } |
|
399 |
|
400 CATDialData::CATDialData(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
401 : CATDataCallConnectCommands(aIo,aTelObject,aInit,aPhoneGlobals) |
|
402 {} |
|
403 |
|
404 |
|
405 void CATDialData::Start(TTsyReqHandle aTsyReqHandle, TAny* aParams) |
|
406 { |
|
407 LOGTEXT(_L8("Starting ATD Dial Command")); |
|
408 iState=EATInitialising; |
|
409 iTelnum=REINTERPRET_CAST(TDesC*,aParams); |
|
410 CATDataCallConnectCommands::Start(aTsyReqHandle,aParams); |
|
411 } |
|
412 |
|
413 void CATDialData::Stop(TTsyReqHandle aTsyReqHandle) |
|
414 // |
|
415 // Attempt to halt the dial process by sending a carriage return, expecting a NO CARRIER |
|
416 // message, or if the pre-dial commands are still being sent then simply wait for OK |
|
417 // |
|
418 { |
|
419 __ASSERT_ALWAYS(aTsyReqHandle == iReqHandle,Panic(EIllegalTsyReqHandle)); |
|
420 __ASSERT_ALWAYS(iState!=EATNotInProgress,Panic(EATCommand_NotInProgress)); |
|
421 LOGTEXT(_L8("Cancelling ATD Dial Command")); |
|
422 if (iState!=EATInitialising) |
|
423 { |
|
424 iIo->WriteAndTimerCancel(this); |
|
425 Write(KCarriageReturn(),1); |
|
426 iState = EATCancellingWaitForWriteComplete; |
|
427 iPreConnectState=CATCallConnectCommands::ENotInProgress; |
|
428 } |
|
429 else |
|
430 { |
|
431 AddStdExpectStrings(); |
|
432 iPreConnectState=CATCallConnectCommands::ECancelling; |
|
433 iState = EATNotInProgress; |
|
434 } |
|
435 } |
|
436 |
|
437 void CATDialData::AddDialExpectStringsL() |
|
438 { |
|
439 LOGTEXT2(_L8("Entered CATDialData::AddDialExpectStringsL with iNoDialToneExpectString of %x"),iNoDialToneExpectString); |
|
440 (void)User::LeaveIfError(AddCommonExpectStrings()); |
|
441 if (!iBusyExpectString) |
|
442 { |
|
443 (void)User::LeaveIfError(iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameBusy),iBusyString)); |
|
444 AppendWildCardChar(iBusyString); |
|
445 iBusyExpectString=iIo->AddExpectString(this,iBusyString); |
|
446 } |
|
447 if (!iNoDialToneExpectString) |
|
448 { |
|
449 (void)User::LeaveIfError(iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameNoDialTone),iNoDialToneString)); |
|
450 iNoDialToneExpectString=iIo->AddExpectString(this,iNoDialToneString); |
|
451 } |
|
452 if (!iNoAnswerExpectString) |
|
453 { |
|
454 (void)User::LeaveIfError(iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameNoAnswer),iNoAnswerString)); |
|
455 AppendWildCardChar(iNoAnswerString); |
|
456 iNoAnswerExpectString=iIo->AddExpectString(this,iNoAnswerString); |
|
457 } |
|
458 if (!iDelayedExpectString) |
|
459 iDelayedExpectString=iIo->AddExpectString(this,KDelayedString); |
|
460 LOGTEXT(_L8("Leaving CATDialData::AddDialExpectStringsL")); |
|
461 } |
|
462 |
|
463 void CATDialData::ValidateDialExpectStringL() |
|
464 { |
|
465 CCommChatString* foundChatString = iIo->FoundChatString(); |
|
466 if (foundChatString == iConnectExpectString) |
|
467 { |
|
468 return; |
|
469 } |
|
470 if (foundChatString == iNoCarrierExpectString) |
|
471 { |
|
472 LOGTEXT(_L8("Modem returned NO CARRIER in response to dial command")); |
|
473 User::Leave(KErrEtelNoCarrier); |
|
474 } |
|
475 if (foundChatString == iNoDialToneExpectString) |
|
476 { |
|
477 LOGTEXT(_L8("Modem returned NO DIALTONE in response to dial command")); |
|
478 User::Leave(KErrEtelNoDialTone); |
|
479 } |
|
480 if (foundChatString == iBusyExpectString) |
|
481 { |
|
482 LOGTEXT(_L8("Modem returned BUSY in response to dial command")); |
|
483 User::Leave(KErrEtelBusyDetected); |
|
484 } |
|
485 if (foundChatString == iNoAnswerExpectString) |
|
486 { |
|
487 LOGTEXT(_L8("Modem returned NO ANSWER in response to dial command")); |
|
488 User::Leave(KErrEtelNoAnswer); |
|
489 } |
|
490 if (foundChatString == iDelayedExpectString) |
|
491 { |
|
492 LOGTEXT(_L8("Modem returned DELAYED in response to dial command")); |
|
493 User::Leave(KErrEtelBusyDetected); // No 'Delayed' error message |
|
494 } |
|
495 LOGTEXT(_L8("Data dial command\tunexpected match!")); |
|
496 User::Leave(KErrGeneral); |
|
497 } |
|
498 |
|
499 void CATDialData::RemoveDialExpectStrings() |
|
500 { |
|
501 RemoveCommonExpectStrings(); |
|
502 iIo->RemoveExpectString(iBusyExpectString); |
|
503 iBusyExpectString=NULL; |
|
504 iIo->RemoveExpectString(iNoDialToneExpectString); |
|
505 iNoDialToneExpectString=NULL; |
|
506 iIo->RemoveExpectString(iNoAnswerExpectString); |
|
507 iNoAnswerExpectString=NULL; |
|
508 iIo->RemoveExpectString(iDelayedExpectString); |
|
509 iDelayedExpectString=NULL; |
|
510 } |
|
511 |
|
512 void CATDialData::CompleteWithIOError(TEventSource aSource,TInt aStatus) |
|
513 { |
|
514 if (iState!=EATNotInProgress) |
|
515 { |
|
516 iState = EATNotInProgress; |
|
517 CATCallConnectCommands::CompleteWithIOError(aSource,aStatus); |
|
518 } |
|
519 } |
|
520 |
|
521 void CATDialData::EventSignal(TEventSource aSource) |
|
522 { |
|
523 LOGTEXT3(_L8("CATDialData::EventSignal with iState:%d aSource:%d"),iState,aSource); |
|
524 |
|
525 if(aSource==ETimeOutCompletion) |
|
526 { |
|
527 if(iState!=EATSpeedReadComplete && iState!=EATCancellingReadCompleted && |
|
528 iState!=EATNotInProgress && |
|
529 iState!=EDTRDropped && iState!=EWaitForDTRRaiseSettle && iState!=EATHangupReadCompleted) |
|
530 { |
|
531 LOGTEXT(_L8("CATDialData::EventSignal Timeout Error during Dial")); |
|
532 RemoveDialExpectStrings(); |
|
533 iState = EATNotInProgress; |
|
534 Complete(KErrTimedOut,aSource); |
|
535 return; |
|
536 } |
|
537 } |
|
538 |
|
539 if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted |
|
540 && iPreConnectState!=CATCallConnectCommands::ENotInProgress) |
|
541 { |
|
542 CATCallConnectCommands::PreConnectEventSignal(aSource); |
|
543 if (iPreConnectState==CATCallConnectCommands::ENotInProgress) // cancelled |
|
544 { |
|
545 LOGTEXT2(_L8("CATDialData::EventSignal1 with iPreConnectState %d"),iPreConnectState); |
|
546 iState=EATNotInProgress; |
|
547 } |
|
548 if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted) |
|
549 { |
|
550 LOGTEXT2(_L8("CATDialData::EventSignal2 with iPreConnectState %d"),iPreConnectState); |
|
551 return; |
|
552 } |
|
553 else |
|
554 { |
|
555 // |
|
556 // Start the sending of the +CBST= command. |
|
557 // |
|
558 // If the SendBearerCapsCommand fails to start the sending |
|
559 // of the +CBST= command then we have to start the dial instead |
|
560 if(!SendBearerCapsCommand(aSource)) // Will set iState=EATBearerCapsWaitForWriteComplete |
|
561 StartDialCommand(aSource); // Will set iState=EATDialWaitForWriteComplete |
|
562 return; |
|
563 } |
|
564 } |
|
565 |
|
566 switch(iState) |
|
567 { |
|
568 case EATBearerCapsWaitForWriteComplete: |
|
569 __ASSERT_DEBUG(iCallType==EDataCall,Panic(ENotDataCallType)); |
|
570 __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); |
|
571 StandardWriteCompletionHandler(aSource,4); |
|
572 iState=EATBearerCapsReadComplete; |
|
573 break; |
|
574 |
|
575 case EATBearerCapsReadComplete: |
|
576 __ASSERT_DEBUG(iCallType==EDataCall,Panic(ENotDataCallType)); |
|
577 __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected)); |
|
578 // |
|
579 // Ignore any OK, ERROR or any other response from the modem. |
|
580 // This is because some modems, eg. those with out speakers, will ERROR these |
|
581 // configuration commands even though the call can go ahead. |
|
582 RemoveStdExpectStrings(); |
|
583 |
|
584 |
|
585 // |
|
586 // Start the dial command |
|
587 StartDialCommand(aSource); // This will set iState to EATDialWaitForWriteComplete |
|
588 break; |
|
589 |
|
590 case EATDialWaitForWriteComplete: |
|
591 { |
|
592 __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); |
|
593 TRAPD(ret,AddDialExpectStringsL()); |
|
594 if (ret) |
|
595 { |
|
596 Complete(ret,aSource); |
|
597 break; |
|
598 } |
|
599 iIo->SetTimeOut(this,(iPhoneGlobals->iPhoneStatus.iWaitForCarrierTime*1000)+KExtraWaitTime); |
|
600 iState=EATDialReadComplete; |
|
601 } |
|
602 break; |
|
603 |
|
604 case EATDialReadComplete: |
|
605 __ASSERT_ALWAYS(aSource==EReadCompletion,Panic(EATCommand_IllegalCompletionReadExpected)); |
|
606 { |
|
607 TRAPD(ret,ValidateDialExpectStringL()); |
|
608 RemoveDialExpectStrings(); |
|
609 if (ret!=KErrNone) |
|
610 { |
|
611 iState = EATNotInProgress; |
|
612 Complete(ret,aSource); |
|
613 break; |
|
614 } |
|
615 iIo->SetTimeOut(this,(KTimeForExtraRxData*5)); |
|
616 iState=EATSpeedReadComplete; |
|
617 } |
|
618 break; |
|
619 |
|
620 case EATSpeedReadComplete: |
|
621 { |
|
622 __ASSERT_ALWAYS(aSource==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected)); |
|
623 iIo->WriteAndTimerCancel(this); |
|
624 TInt ret=ParseForBearerCapsResponse(); |
|
625 iState = EATNotInProgress; |
|
626 if (ret!=KErrNone) |
|
627 { |
|
628 Complete(ret,aSource); |
|
629 break; |
|
630 } |
|
631 ret=ParseForBearerSpeedResponse(); |
|
632 Complete(ret,aSource); |
|
633 break; |
|
634 } |
|
635 |
|
636 case EATCancellingWaitForWriteComplete: |
|
637 { |
|
638 __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); |
|
639 TRAPD(ret,AddDialExpectStringsL()); |
|
640 if (ret) |
|
641 { |
|
642 Complete(ret,aSource); |
|
643 break; |
|
644 } |
|
645 if (!iOKExpectString) |
|
646 { |
|
647 iOKExpectString=iIo->AddExpectString(this,KOkString); |
|
648 } |
|
649 iIo->SetTimeOut(this); |
|
650 iState=EATCancellingReadCompleted; |
|
651 } |
|
652 break; |
|
653 |
|
654 case EATCancellingReadCompleted: |
|
655 { |
|
656 if (aSource==ETimeOutCompletion) |
|
657 { |
|
658 // The phone ignored the request to cancel the connection. |
|
659 // The modem will be forced to drop the connection when we |
|
660 // lower the DTR. |
|
661 LOGTEXT(_L8("Phone ignored dial cancel request")); |
|
662 } |
|
663 else if (aSource==EReadCompletion) |
|
664 { |
|
665 if (iIo->FoundChatString() != iOKExpectString) |
|
666 { |
|
667 // The modem did not respond with OK as expected. |
|
668 LOGTEXT(_L8("Phone returned an unexpected response to a dial cancel request")); |
|
669 } |
|
670 } |
|
671 RemoveDialExpectStrings(); |
|
672 iIo->RemoveExpectString(iOKExpectString); |
|
673 iOKExpectString=NULL; |
|
674 iIo->DropDtr(); |
|
675 iIo->SetTimeOut(this,KDTRLowPeriod); |
|
676 iState=EDTRDropped; |
|
677 } |
|
678 break; |
|
679 |
|
680 case EDTRDropped: |
|
681 __ASSERT_ALWAYS(aSource==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected)); |
|
682 iIo->Cancel(); |
|
683 iIo->RaiseDTR(); |
|
684 iIo->Read(); |
|
685 iIo->SetTimeOut(this,KDTRHighSettle); |
|
686 iState=EWaitForDTRRaiseSettle; |
|
687 break; |
|
688 |
|
689 case EWaitForDTRRaiseSettle: |
|
690 __ASSERT_ALWAYS(aSource==ETimeOutCompletion,Panic(EATCommand_IllegalCompletionWaitExpected)); |
|
691 Write(KHangUpCommand(),1); |
|
692 iState=EATHangupWaitForWriteComplete; |
|
693 break; |
|
694 |
|
695 case EATHangupWaitForWriteComplete: |
|
696 __ASSERT_ALWAYS(aSource==EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteExpected)); |
|
697 if (!iNoCarrierExpectString) |
|
698 iNoCarrierExpectString=iIo->AddExpectString(this,KNoCarrierString); |
|
699 StandardWriteCompletionHandler(aSource,2); |
|
700 iState=EATHangupReadCompleted; |
|
701 break; |
|
702 |
|
703 case EATHangupReadCompleted: |
|
704 __ASSERT_ALWAYS(aSource!=EWriteCompletion,Panic(EATCommand_IllegalCompletionWriteNotExpected)); |
|
705 Complete(KErrCancel,aSource); // if ret!=KErrNone, perhaps don't complete but carry on |
|
706 break; |
|
707 |
|
708 default: |
|
709 ; |
|
710 } |
|
711 } |
|
712 |
|
713 void CATDialData::StartDialCommand(TEventSource aSource) |
|
714 { |
|
715 // |
|
716 // Start the dial command |
|
717 ChangeLineStatus(RCall::EStatusDialling); |
|
718 // Setting to EStatusDialling always returns KErrNone |
|
719 (void)ChangeCallStatus(RMobileCall::EStatusDialling); |
|
720 iPhoneGlobals->iNotificationStore->CheckNotification(REINTERPRET_CAST(CCallBase*,iTelObject),EBegunConnecting); |
|
721 TBuf8<KCommsDbSvrMaxFieldLength> dialModifier; |
|
722 TInt ret = iPhoneGlobals->iConfiguration->ConfigModemString(TPtrC(KCDTypeNameDialToneWaitModifier),dialModifier); |
|
723 if (ret) |
|
724 { |
|
725 Complete(ret,aSource); |
|
726 return; |
|
727 } |
|
728 TInt len = iTelnum->Length(); |
|
729 |
|
730 HBufC8* buf = NULL; |
|
731 TRAP(ret,buf = HBufC8::NewL(len)); |
|
732 if (ret) |
|
733 { |
|
734 Complete(ret,aSource); |
|
735 return; |
|
736 } |
|
737 TPtr8 newTelnum(buf->Des()); |
|
738 newTelnum.Copy(*iTelnum); |
|
739 |
|
740 TInt aPos=newTelnum.FindF(dialModifier); |
|
741 if (aPos!=KErrNotFound) |
|
742 { |
|
743 newTelnum.Delete(aPos,1); |
|
744 } |
|
745 iTxBuffer.Format(KDialDataCommandFormat,&newTelnum); |
|
746 delete buf; |
|
747 iIo->Write(this,iTxBuffer); |
|
748 iIo->SetTimeOut(this); |
|
749 iState=EATDialWaitForWriteComplete; |
|
750 } |
|
751 |
|
752 TBool CATDialData::SendBearerCapsCommand(TEventSource /*aSource*/) |
|
753 /* |
|
754 * @return ETrue if +CBST= was sent |
|
755 * @return EFalse if +CBST= was not sent due to not having enough specified params |
|
756 */ |
|
757 { |
|
758 LOGTEXT(_L8("CATDataDial::SendBearerCapsCommand")); |
|
759 |
|
760 // |
|
761 // Assemble and send (if required) the +CBST=... string to the phone |
|
762 // to configure the settings for the next data call. |
|
763 // Use utility function provided by CCallMobileData |
|
764 CCallMobileData* parent=static_cast<CCallMobileData*>(iTelObject); |
|
765 if(parent->AssembleCBSTSetString(iTxBuffer)==KErrNone) |
|
766 { |
|
767 // |
|
768 // Send our AT command to the phone |
|
769 iIo->Write(this,iTxBuffer); |
|
770 iIo->SetTimeOut(this); |
|
771 iState=EATBearerCapsWaitForWriteComplete; |
|
772 return ETrue; |
|
773 } |
|
774 |
|
775 return EFalse; // We were unable to send a +CBST string |
|
776 } |
|
777 |
|
778 |
|
779 |
|
780 // |
|
781 // CATDialFax |
|
782 // |
|
783 |
|
784 CATDialFax* CATDialFax::NewL(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
785 { |
|
786 CATDialFax* dial=new(ELeave) CATDialFax(aIo, aTelObject, aInit,aPhoneGlobals); |
|
787 CleanupStack::PushL(dial); |
|
788 dial->ConstructL(); |
|
789 CleanupStack::Pop(); |
|
790 return dial; |
|
791 } |
|
792 |
|
793 CATDialFax::CATDialFax(CATIO* aIo, CTelObject* aTelObject,CATInit* aInit,CPhoneGlobals* aPhoneGlobals) |
|
794 : CATFaxCallConnectCommands(aIo,aTelObject,aInit,aPhoneGlobals) |
|
795 {} |
|
796 |
|
797 CATDialFax::~CATDialFax() |
|
798 { |
|
799 iIo->WriteAndTimerCancel(this); |
|
800 } |
|
801 |
|
802 void CATDialFax::Start(TTsyReqHandle aTsyReqHandle, TAny* aParams) |
|
803 { |
|
804 LOGTEXT(_L8("Starting dial fax call command")); |
|
805 iTelnum=REINTERPRET_CAST(TDesC*,aParams); |
|
806 CATFaxCallConnectCommands::Start(aTsyReqHandle,aParams); |
|
807 } |
|
808 |
|
809 void CATDialFax::Stop(TTsyReqHandle aTsyReqHandle) |
|
810 { |
|
811 LOGTEXT(_L8("Cancelling Dial Fax Call Command")); |
|
812 CATFaxCallConnectCommands::Stop(aTsyReqHandle); |
|
813 } |
|
814 |
|
815 void CATDialFax::EventSignal(TEventSource aSource) |
|
816 { |
|
817 if((aSource==ETimeOutCompletion) |
|
818 &&(iPreConnectState!=EATWaitForATCheckOK)) |
|
819 { |
|
820 LOGTEXT(_L8("Timeout Error during Dial")); |
|
821 Complete(KErrTimedOut,aSource); |
|
822 return; |
|
823 } |
|
824 |
|
825 if (iPreConnectState!=CATCallConnectCommands::EATInitCompleted |
|
826 && iPreConnectState!=CATCallConnectCommands::ENotInProgress) |
|
827 { |
|
828 CATCallConnectCommands::PreConnectEventSignal(aSource); |
|
829 } |
|
830 } |
|
831 |
|
832 void CATDialFax::CompleteSuccessfully() |
|
833 { |
|
834 REINTERPRET_CAST(CCallMobileFax*,iTelObject)->FaxDial(iReqHandle,iTelnum); |
|
835 } |
|
836 |