|
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 // Serial IO Functions |
|
15 // |
|
16 // |
|
17 |
|
18 #include "ATIO.H" |
|
19 #include "mSLOGGER.H" |
|
20 #include "ATERROR.H" |
|
21 |
|
22 // |
|
23 // CCompletionEntry |
|
24 // |
|
25 CCompletionEntry* CCompletionEntry::NewL(CCommChatString* aCs, CATBase* aAtCommand) |
|
26 { |
|
27 return new(ELeave) CCompletionEntry(aCs,aAtCommand); |
|
28 } |
|
29 |
|
30 CCompletionEntry::CCompletionEntry(CCommChatString* aCs, CATBase* aAtCommand) : iCs(aCs), iAtCommand(aAtCommand) |
|
31 {} |
|
32 |
|
33 CCompletionEntry::~CCompletionEntry() |
|
34 {} |
|
35 |
|
36 // |
|
37 // CATIo |
|
38 // |
|
39 CATIO* CATIO::NewL(TFileName& aCsy, TName& aPort,TPortAccess& aPortAccess) |
|
40 { |
|
41 CATIO* atIo=new(ELeave) CATIO(aPortAccess); |
|
42 CleanupStack::PushL(atIo); |
|
43 atIo->ConstructL(aCsy,aPort); |
|
44 CleanupStack::Pop(); |
|
45 LOGTEXT2(_L8("CATIO::NewL returns 0x%x"),atIo); |
|
46 return atIo; |
|
47 } |
|
48 |
|
49 CATIO::CATIO(TPortAccess& aPortAccess) |
|
50 : iPortAccess(aPortAccess) |
|
51 { |
|
52 iExpectList.SetOffset(_FOFF(CCompletionEntry,iLink)); |
|
53 } |
|
54 |
|
55 void CATIO::ConstructL(TFileName& aCsy, TName& aPort) |
|
56 { |
|
57 iCsy=aCsy; |
|
58 CommConstructL(KCommReadPriority,KCommWritePriority); |
|
59 iChat = new (ELeave) CCommChatter(this, KChatterPriority); |
|
60 iChat->CreateL(KChatBufferSize); |
|
61 |
|
62 { // Braces scope the lifetime of tmpCsy and tmpPort |
|
63 TBuf8<KMaxFileName> tmpCsy; |
|
64 TBuf8<KMaxName> tmpPort; |
|
65 tmpCsy.Copy(aCsy); // Convert parameter to 8 bit string |
|
66 tmpPort.Copy(aPort); // Convert parameter to 8 bit string |
|
67 LOGTEXTREL3(_L8("CATIO::ConstructL Attempting open csy:%S port:%S"),&tmpCsy,&tmpPort); |
|
68 } |
|
69 TInt ret = CommOpen(aCsy, aPort, ECommShared); |
|
70 if(ret == KErrAccessDenied || ret == KErrInUse) |
|
71 iPortAccess=EPortAccessDenied; |
|
72 else |
|
73 (void)User::LeaveIfError(ret); |
|
74 LOGTEXTREL(_L8("CATIO::ConstructL Open successful")); |
|
75 |
|
76 iChatStringFound= new(ELeave) CArrayFixFlat<CCommChatString*>(5); |
|
77 } |
|
78 |
|
79 CATIO::~CATIO() |
|
80 { |
|
81 delete iChatStringFound; |
|
82 delete iChat; |
|
83 } |
|
84 |
|
85 TInt CATIO::ConfigurePort(TCommConfig aConfiguration) |
|
86 { |
|
87 if (iPortAccess==EPortAccessAllowed) |
|
88 { |
|
89 TInt ret; |
|
90 TCommConfig cbuf; |
|
91 TCommConfigV01 &cfg=cbuf(); |
|
92 iCommPort.Config(cbuf); // Get the Configuration |
|
93 |
|
94 TCommConfigV01 &newCfg=aConfiguration(); |
|
95 cfg.iRate=newCfg.iRate; |
|
96 cfg.iDataBits=newCfg.iDataBits; |
|
97 cfg.iStopBits=newCfg.iStopBits; |
|
98 cfg.iParity=newCfg.iParity; |
|
99 cfg.iHandshake=newCfg.iHandshake; |
|
100 ret = iCommPort.SetConfig(cbuf); // Set the Configuration |
|
101 if(ret!=KErrNone) |
|
102 { |
|
103 LOGTEXT2(_L8("CATIO:\tError %d configuring port"),ret); |
|
104 return ret; |
|
105 } |
|
106 } |
|
107 return KErrNone; |
|
108 } |
|
109 |
|
110 TInt CATIO::GetPortShutdownTimeout() |
|
111 { |
|
112 if (iPortAccess==EPortAccessAllowed) |
|
113 { |
|
114 TCommConfig2 cbuf; |
|
115 TCommConfigV02& cfg=cbuf(); |
|
116 iCommPort.Config(cbuf); // Get the Configuration |
|
117 |
|
118 return (cfg.iTxShutdownTimeout); |
|
119 } |
|
120 else |
|
121 return (0); |
|
122 } |
|
123 |
|
124 TInt CATIO::SetPortShutdownTimeout(TInt aTimeout) |
|
125 { |
|
126 if (iPortAccess==EPortAccessAllowed) |
|
127 { |
|
128 TCommConfig2 cbuf; |
|
129 TCommConfigV02 &cfg=cbuf(); |
|
130 iCommPort.Config(cbuf); // Get the Configuration |
|
131 |
|
132 cfg.iTxShutdownTimeout = aTimeout; |
|
133 return (iCommPort.SetConfig(cbuf)); // Set the Configuration |
|
134 } |
|
135 else |
|
136 return KErrAccessDenied; |
|
137 } |
|
138 |
|
139 void CATIO::Start(CATBase* aCompletionClass) |
|
140 { |
|
141 CommReadReady(); |
|
142 StartWrite(aCompletionClass); |
|
143 } |
|
144 |
|
145 void CATIO::StartWrite(CATBase* aCompletionClass) |
|
146 { |
|
147 if (iPortAccess==EPortAccessAllowed) |
|
148 { |
|
149 iWriteCommand=aCompletionClass; |
|
150 CommWriteReady(); |
|
151 iWritePending=ETrue; |
|
152 } |
|
153 } |
|
154 |
|
155 TPtrC8 CATIO::Buffer() const |
|
156 { |
|
157 return iChat->Buffer(); |
|
158 } |
|
159 |
|
160 TInt CATIO::BufferFindF(const TDesC8& aDes) const |
|
161 { |
|
162 return iChat->Buffer().FindF(aDes); |
|
163 } |
|
164 |
|
165 TPtrC8 CATIO::CurrentLine() const |
|
166 { |
|
167 return iChat->CurrentLine(); |
|
168 } |
|
169 |
|
170 void CATIO::ClearBuffer() |
|
171 { |
|
172 if(!iPreserveBuffer) |
|
173 iChat->ClearBuffer(); |
|
174 } |
|
175 |
|
176 void CATIO::ClearCurrentLine() |
|
177 { |
|
178 iChat->ClearCurrentLine(); |
|
179 } |
|
180 |
|
181 void CATIO::CommReadComplete(TInt aStatus) |
|
182 { |
|
183 LOGTEXT(_L8("Read Completion")); |
|
184 __ASSERT_ALWAYS(iReadPending,Panic(EATCommand_IllegalCompletionReadNotExpected)); |
|
185 if (aStatus==KErrCommsLineFail) |
|
186 { |
|
187 if (iSecondChanceForCommsError++!=1) |
|
188 aStatus=KErrNone; // only signal error if get 2 KErrCommsLineFail's in succession |
|
189 else |
|
190 iSecondChanceForCommsError=0; |
|
191 } |
|
192 if (aStatus!=KErrNone) |
|
193 { |
|
194 SignalCommandsWithError(aStatus); |
|
195 return; |
|
196 } |
|
197 iReadPending = EFalse; |
|
198 TRAPD(ret,ProcessReadCharsL()); |
|
199 if(ret!=KErrNone) |
|
200 { |
|
201 Cancel(); // This error cannot be related to a command - so they'll all be cleaned up. |
|
202 iChat->DeleteAllAndStop(); |
|
203 } |
|
204 } |
|
205 |
|
206 void CATIO::SignalCommandsWithError(TInt aStatus) |
|
207 // |
|
208 // Complete all current AT commands with the error and call the error handler |
|
209 // |
|
210 { |
|
211 LOGTEXT2(_L8("Received an error of %d"),aStatus); |
|
212 Cancel(); |
|
213 CCompletionEntry* ce; |
|
214 TDblQueIter<CCompletionEntry> iter(iExpectList); |
|
215 while (ce = iter, ce!=NULL) |
|
216 { |
|
217 ce->iAtCommand->GenericEventSignal(EReadCompletion,aStatus); |
|
218 iter.SetToLast(); |
|
219 CCompletionEntry* removeSimilar; |
|
220 while (removeSimilar=iter--, removeSimilar!=ce) |
|
221 { |
|
222 if(removeSimilar && removeSimilar->iAtCommand==ce->iAtCommand) |
|
223 { |
|
224 iChat->RemoveString(removeSimilar->iCs); |
|
225 delete removeSimilar->iCs; |
|
226 removeSimilar->iLink.Deque(); |
|
227 delete removeSimilar; |
|
228 } |
|
229 } |
|
230 iChat->RemoveString(ce->iCs); |
|
231 delete ce->iCs; |
|
232 ce->iLink.Deque(); |
|
233 delete ce; |
|
234 iter.SetToFirst(); |
|
235 } |
|
236 // Reset TSY status, complete notifications and re-add some expect strings |
|
237 iErrorHandler->CleanUp(aStatus); |
|
238 } |
|
239 |
|
240 void CATIO::ProcessReadCharsL() |
|
241 { |
|
242 LOGTEXT2(_L8("Received %d"),iRxBuf.Length()); |
|
243 LOGTEXTREL2(_L8("Rx:\t%S"),&iRxBuf); |
|
244 |
|
245 TBool hitFlag=EFalse; |
|
246 TInt len; |
|
247 |
|
248 for (iRxBufOffset=0; iRxBufOffset<iRxBuf.Length(); iRxBufOffset++) |
|
249 { |
|
250 iChat->AddCharL(iRxBuf[iRxBufOffset]); |
|
251 // Check for hits and one up-call per hit NOW |
|
252 if((len=iChatStringFound->Count())>0) |
|
253 { |
|
254 for(TInt i=0;i<len;i++) |
|
255 { |
|
256 hitFlag=ETrue; |
|
257 // Find the AT Command to complete |
|
258 CCompletionEntry* ce; |
|
259 TDblQueIter<CCompletionEntry> iter(iExpectList); |
|
260 TBool aFoundFlag=EFalse; |
|
261 while (ce = iter++, ce!=NULL) |
|
262 { |
|
263 if(ce->iCs==iChatStringFound->At(i)) |
|
264 { |
|
265 iCurrentFoundChatString=ce->iCs; |
|
266 ce->iAtCommand->GenericEventSignal(EReadCompletion,KErrNone); |
|
267 aFoundFlag=ETrue; |
|
268 break; |
|
269 } |
|
270 } |
|
271 if(!aFoundFlag) |
|
272 { |
|
273 LOGTEXT(_L8("Internal Error - Chat String signalled, but not found")); |
|
274 User::Leave(KErrGeneral); |
|
275 } |
|
276 } |
|
277 iChatStringFound->Delete(0,iChatStringFound->Count()); |
|
278 } |
|
279 } |
|
280 if(hitFlag) |
|
281 { |
|
282 //iReadPending=EFalse; |
|
283 Read(); // Queue Another... |
|
284 } |
|
285 else |
|
286 { |
|
287 iReadPending = ETrue; |
|
288 CommReadOneOrMore(iRxBuf); |
|
289 } |
|
290 } |
|
291 |
|
292 void CATIO::SetPreserveBufferFlag(TBool aFlg) |
|
293 // |
|
294 // Set Preserve Buffer Flag |
|
295 // |
|
296 { |
|
297 iPreserveBuffer=aFlg; |
|
298 } |
|
299 |
|
300 CCommChatString* CATIO::FoundChatString() |
|
301 { |
|
302 return iCurrentFoundChatString; |
|
303 } |
|
304 |
|
305 CCommChatString* CATIO::AddExpectString(CATBase* aATBase, const TDesC8& aString, TBool aPartLine) |
|
306 { |
|
307 CCommChatString* cs=NULL; |
|
308 |
|
309 TRAPD(err,cs=DoAddExpectStringL(aATBase,aString,aPartLine)); |
|
310 if(err==KErrNone) |
|
311 LOGTEXT2(_L8("CATIO::AddExpectString added %S"),&aString); |
|
312 else |
|
313 { |
|
314 cs=NULL; |
|
315 LOGTEXT2(_L8("CATIO::AddExpectString FAILED TO ADD %S"),&aString); |
|
316 } |
|
317 return cs; |
|
318 } |
|
319 |
|
320 CCommChatString* CATIO::DoAddExpectStringL(CATBase* aATBase, const TDesC8& aString, TBool aPartLine) |
|
321 { |
|
322 CCommChatString* cs=iChat->AddStringL(aString, aPartLine); |
|
323 CCompletionEntry* completionEntry=CCompletionEntry::NewL(cs,aATBase); |
|
324 iExpectList.AddLast(*completionEntry); |
|
325 return cs; |
|
326 } |
|
327 |
|
328 |
|
329 void CATIO::RemoveExpectString(CCommChatString* aExpectString) |
|
330 { |
|
331 // Find the AT Command to complete |
|
332 CCompletionEntry* ce; |
|
333 TDblQueIter<CCompletionEntry> iter(iExpectList); |
|
334 while (ce = iter++, ce!=NULL) |
|
335 { |
|
336 if(ce->iCs==aExpectString) |
|
337 { |
|
338 iChat->RemoveString(ce->iCs); |
|
339 delete ce->iCs; |
|
340 ce->iLink.Deque(); |
|
341 delete ce; |
|
342 break; |
|
343 } |
|
344 } |
|
345 } |
|
346 |
|
347 void CATIO::RemoveExpectStrings(CATBase* aATBase) |
|
348 { |
|
349 // Find the AT Command to complete |
|
350 CCompletionEntry* ce; |
|
351 TDblQueIter<CCompletionEntry> iter(iExpectList); |
|
352 while (ce = iter++, ce!=NULL) |
|
353 { |
|
354 if(ce->iAtCommand==aATBase) |
|
355 { |
|
356 iChat->RemoveString(ce->iCs); |
|
357 delete ce->iCs; |
|
358 ce->iLink.Deque(); |
|
359 delete ce; |
|
360 } |
|
361 } |
|
362 } |
|
363 |
|
364 void CATIO::CommWriteComplete(TInt aStatus) |
|
365 { |
|
366 LOGTEXT(_L8("Comm Write Completion")); |
|
367 iChat->StopTimer(); |
|
368 __ASSERT_ALWAYS(iWritePending,Panic(EATCommand_IllegalCompletionWriteNotExpected)); |
|
369 // if(!iWritePending) |
|
370 // aStatus=KErrIllegalWriteComplete; // No Write Queued! |
|
371 iWritePending=EFalse; |
|
372 iWriteCommand->GenericEventSignal(EWriteCompletion,aStatus); |
|
373 } |
|
374 |
|
375 void CATIO::ChatStringMatchL(CCommChatString* aCs) |
|
376 { |
|
377 iStringFound=ETrue; |
|
378 iChatStringFound->AppendL(aCs); |
|
379 } |
|
380 |
|
381 void CATIO::ChatTimeout() |
|
382 { |
|
383 LOGTEXT(_L8("Chat Time-out Completion")); |
|
384 if(iWaitTimerPending) |
|
385 { |
|
386 iWaitTimerPending=EFalse; |
|
387 iTimeOutCommand->GenericEventSignal(ETimeOutCompletion,KErrNone); |
|
388 } |
|
389 else |
|
390 Panic(EATCommand_IllegalWaitCompletion); |
|
391 } |
|
392 |
|
393 void CATIO::SetTimeOut(CATBase* aCompletionClass, TUint aTimePeriodMillisec) |
|
394 { |
|
395 iTimeOutCommand=aCompletionClass; |
|
396 iChat->StartTimer(aTimePeriodMillisec*1000); |
|
397 iWaitTimerPending=ETrue; |
|
398 } |
|
399 |
|
400 void CATIO::Read() |
|
401 { |
|
402 if (iPortAccess==EPortAccessAllowed && iReadPending==FALSE) |
|
403 { |
|
404 iReadPending=ETrue; |
|
405 iStringFound=EFalse; |
|
406 CommReadOneOrMore(iRxBuf); |
|
407 iRxBufOffset = 0; |
|
408 LOGTEXT(_L8("Queued a Read")); |
|
409 } |
|
410 } |
|
411 |
|
412 void CATIO::Write(CATBase* aCompletionClass, const TDesC8& aString) |
|
413 { |
|
414 if (iPortAccess==EPortAccessAllowed) |
|
415 { |
|
416 ClearBuffer(); // assume previous responses fully processed |
|
417 iWriteCommand=aCompletionClass; |
|
418 iWritePending=ETrue; |
|
419 CommWrite(aString); |
|
420 if (aString.Length() > 350) |
|
421 { |
|
422 LOGTEXT2(_L8("CATIO:\taString too big! Length:%d"), aString.Length()); |
|
423 } |
|
424 else |
|
425 { |
|
426 LOGTEXTREL2(_L8("Tx:\t%S"),&aString); |
|
427 } |
|
428 LOGTEXT(_L8("Queued a Transmission")); |
|
429 } |
|
430 } |
|
431 |
|
432 TBool CATIO::ReadPending() |
|
433 { |
|
434 return iReadPending; |
|
435 } |
|
436 |
|
437 void CATIO::Disconnect() |
|
438 { |
|
439 if (iPortAccess == EPortAccessAllowed) |
|
440 { |
|
441 TCommConfig cbuf; |
|
442 TCommConfigV01 &cfg=cbuf(); |
|
443 iCommPort.Config(cbuf); |
|
444 cfg.iHandshake = KConfigFreeRTS | KConfigFreeDTR; |
|
445 TInt ret=iCommPort.SetConfig(cbuf); |
|
446 if (ret == KErrNone) |
|
447 iCommPort.SetSignalsToSpace(KSignalRTS | KSignalDTR); |
|
448 } |
|
449 |
|
450 CommClose(); |
|
451 |
|
452 iPortAccess = EPortAccessDenied; |
|
453 } |
|
454 |
|
455 void CATIO::Cancel() |
|
456 { |
|
457 LOGTEXT(_L8("CATIO:\tCancel called")); |
|
458 CommCancel(); |
|
459 iReadPending = EFalse; |
|
460 iWritePending = EFalse; |
|
461 iChat->StopTimer(); |
|
462 } |
|
463 |
|
464 void CATIO::ReadCancel() |
|
465 { |
|
466 LOGTEXT(_L8("CATIO:\tReadCancel called")); |
|
467 CommReadCancel(); |
|
468 iReadPending = EFalse; |
|
469 } |
|
470 |
|
471 void CATIO::WriteAndTimerCancel(CATBase* aATBase) |
|
472 { |
|
473 if (aATBase==iWriteCommand) |
|
474 { |
|
475 CommWriteCancel(); |
|
476 } |
|
477 if (aATBase==iTimeOutCommand) |
|
478 { |
|
479 iChat->StopTimer(); |
|
480 } |
|
481 } |
|
482 |
|
483 |
|
484 void CATIO::DropDtr() |
|
485 { |
|
486 if (iPortAccess==EPortAccessAllowed) |
|
487 { |
|
488 LOGTEXT(_L8("CATIO::DropDtr Dropping DTR")); |
|
489 iCommPort.SetSignals(0,KSignalDTR); |
|
490 } |
|
491 } |
|
492 |
|
493 |
|
494 void CATIO::RaiseDTR() |
|
495 { |
|
496 if (iPortAccess==EPortAccessAllowed) |
|
497 { |
|
498 LOGTEXT(_L8("CATIO::RaiseDTR Raising DTR")); |
|
499 iCommPort.SetSignals(KSignalDTR,0); |
|
500 } |
|
501 } |
|
502 |
|
503 void CATIO::ResetReadAndWriteBuffers() |
|
504 { |
|
505 iCommPort.ResetBuffers(); |
|
506 } |
|
507 |
|
508 TInt CATIO::GetSizeOfRxBuffer() |
|
509 { |
|
510 return iCommPort.QueryReceiveBuffer(); |
|
511 } |
|
512 |
|
513 TUint CATIO::Signals() |
|
514 { |
|
515 return iCommPort.Signals(); |
|
516 } |
|
517 |
|
518 void CATIO::DropRTS() |
|
519 { |
|
520 if (iPortAccess==EPortAccessAllowed) |
|
521 { |
|
522 LOGTEXT(_L8("Dropping RTS")); |
|
523 iCommPort.SetSignals(0,KSignalRTS); |
|
524 } |
|
525 } |
|
526 |
|
527 void CATIO::RaiseRTS() |
|
528 { |
|
529 if (iPortAccess==EPortAccessAllowed) |
|
530 { |
|
531 LOGTEXT(_L8("Raising RTS")); |
|
532 iCommPort.SetSignals(KSignalRTS,0); |
|
533 } |
|
534 } |