1 /* |
|
2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: AT command handler and notifier |
|
15 * |
|
16 */ |
|
17 |
|
18 /* |
|
19 * Points to consider: |
|
20 * - Each of the AT commands sent to ATEXT are converted to upper case form. |
|
21 * Thus the ATEXT plugins don't need to check for case. The conversion to |
|
22 * upper case form stops when carriage return or '=' character is found. |
|
23 */ |
|
24 |
|
25 /* |
|
26 * The AT command handling is splitted to two parts on high level: |
|
27 * 1) Splitter: splitting the sub-commands in a command line to multiple ones |
|
28 * for ATEXT to process. |
|
29 * 2) Combiner: combining the replies coming from ATEXT using a filter |
|
30 * (the filter categories are explained in DunAtCmdPusher.cpp) |
|
31 */ |
|
32 |
|
33 #include "DunAtCmdHandler.h" |
|
34 #include "DunAtUrcHandler.h" |
|
35 #include "DunDownstream.h" |
|
36 #include "DunDebug.h" |
|
37 |
|
38 const TInt8 KDunCancel = 24; // Used for line editing, cancel character |
|
39 const TInt8 KDunEscape = 27; // Used for editor ending, escape character |
|
40 |
|
41 // --------------------------------------------------------------------------- |
|
42 // Two-phased constructor. |
|
43 // --------------------------------------------------------------------------- |
|
44 // |
|
45 EXPORT_C CDunAtCmdHandler* CDunAtCmdHandler::NewL( |
|
46 MDunAtCmdStatusReporter* aUpstream, |
|
47 MDunStreamManipulator* aDownstream, |
|
48 const TDesC8* aConnectionName ) |
|
49 { |
|
50 CDunAtCmdHandler* self = new (ELeave) CDunAtCmdHandler( |
|
51 aUpstream, |
|
52 aDownstream, |
|
53 aConnectionName ); |
|
54 CleanupStack::PushL( self ); |
|
55 self->ConstructL(); |
|
56 CleanupStack::Pop( self ); |
|
57 return self; |
|
58 } |
|
59 |
|
60 // --------------------------------------------------------------------------- |
|
61 // Destructor. |
|
62 // --------------------------------------------------------------------------- |
|
63 // |
|
64 CDunAtCmdHandler::~CDunAtCmdHandler() |
|
65 { |
|
66 FTRACE(FPrint( _L("CDunAtCmdHandler::~CDunAtCmdHandler()") )); |
|
67 ResetData(); |
|
68 FTRACE(FPrint( _L("CDunAtCmdHandler::~CDunAtCmdHandler() complete") )); |
|
69 } |
|
70 |
|
71 // --------------------------------------------------------------------------- |
|
72 // Resets data to initial values |
|
73 // --------------------------------------------------------------------------- |
|
74 // |
|
75 EXPORT_C void CDunAtCmdHandler::ResetData() |
|
76 { |
|
77 FTRACE(FPrint( _L("CDunAtCmdHandler::ResetData()") )); |
|
78 // APIs affecting this: |
|
79 // IssueRequest() |
|
80 Stop(); |
|
81 // NewL() |
|
82 DeletePluginHandlers(); |
|
83 delete iCmdEchoer; |
|
84 iCmdEchoer = NULL; |
|
85 delete iNvramListen; |
|
86 iNvramListen = NULL; |
|
87 delete iModeListen; |
|
88 iModeListen = NULL; |
|
89 delete iEcomListen; |
|
90 iEcomListen = NULL; |
|
91 delete iAtSpecialCmdHandler; |
|
92 iAtSpecialCmdHandler = NULL; |
|
93 if ( iAtCmdExtCommon.Handle() ) |
|
94 { |
|
95 iAtCmdExtCommon.SynchronousClose(); |
|
96 iAtCmdExtCommon.Close(); |
|
97 } |
|
98 if ( iAtCmdExt.Handle() ) |
|
99 { |
|
100 iAtCmdExt.SynchronousClose(); |
|
101 iAtCmdExt.Close(); |
|
102 } |
|
103 iSpecials.ResetAndDestroy(); |
|
104 iSpecials.Close(); |
|
105 // AddCmdModeCallback() |
|
106 iCmdCallbacks.Close(); |
|
107 // Internal |
|
108 Initialize(); |
|
109 FTRACE(FPrint( _L("CDunAtCmdHandler::ResetData() complete") )); |
|
110 } |
|
111 |
|
112 // --------------------------------------------------------------------------- |
|
113 // Adds callback for command mode notification |
|
114 // The callback will be called when command mode starts or ends |
|
115 // --------------------------------------------------------------------------- |
|
116 // |
|
117 EXPORT_C TInt CDunAtCmdHandler::AddCmdModeCallback( MDunCmdModeMonitor* aCallback ) |
|
118 { |
|
119 FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback()" ) )); |
|
120 if ( !aCallback ) |
|
121 { |
|
122 FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (aCallback) not initialized!" ) )); |
|
123 return KErrGeneral; |
|
124 } |
|
125 TInt retTemp = iCmdCallbacks.Find( aCallback ); |
|
126 if ( retTemp != KErrNotFound ) |
|
127 { |
|
128 FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (already exists) complete" ) )); |
|
129 return KErrAlreadyExists; |
|
130 } |
|
131 retTemp = iCmdCallbacks.Append( aCallback ); |
|
132 if ( retTemp != KErrNone ) |
|
133 { |
|
134 FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() (append failed!) complete" ) )); |
|
135 return retTemp; |
|
136 } |
|
137 FTRACE(FPrint( _L("CDunAtCmdHandler::AddCmdModeCallback() complete" ) )); |
|
138 return KErrNone; |
|
139 } |
|
140 |
|
141 // --------------------------------------------------------------------------- |
|
142 // Parses an AT command |
|
143 // --------------------------------------------------------------------------- |
|
144 // |
|
145 EXPORT_C TInt CDunAtCmdHandler::ParseCommand( TDesC8& aCommand, |
|
146 TBool& aPartialInput ) |
|
147 { |
|
148 FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand()") )); |
|
149 FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received:") )); |
|
150 FTRACE(FPrintRaw(aCommand) ); |
|
151 TBool editorMode = iCmdPusher->EditorMode(); |
|
152 if ( editorMode ) |
|
153 { |
|
154 // Note: return here with "no partial input" and some error to fool |
|
155 // CDunUpstream into not reissuing the read request. |
|
156 iCmdPusher->IssueRequest( aCommand, EFalse ); |
|
157 aPartialInput = EFalse; |
|
158 return KErrGeneral; |
|
159 } |
|
160 iCommand = &aCommand; // iCommand only for normal mode |
|
161 // Manage partial AT command |
|
162 TBool needsCarriage = ETrue; |
|
163 TBool okToExit = ManagePartialCommand( aCommand, needsCarriage ); |
|
164 if ( okToExit ) |
|
165 { |
|
166 FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (ok to exit) complete") )); |
|
167 aPartialInput = ETrue; |
|
168 return KErrNone; |
|
169 } |
|
170 if ( iHandleState != EDunStateIdle ) |
|
171 { |
|
172 aPartialInput = EFalse; |
|
173 ResetParseBuffers(); |
|
174 FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (not ready) complete") )); |
|
175 return KErrNotReady; |
|
176 } |
|
177 TBool pushStarted = HandleASlashCommand(); |
|
178 if ( pushStarted ) |
|
179 { |
|
180 // Note: return here with "partial input" status to fool CDunUpstream |
|
181 // into reissuing the read request. The AT command has not really |
|
182 // started yet so this is necessary. |
|
183 aPartialInput = ETrue; |
|
184 ResetParseBuffers(); |
|
185 FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() (A/) complete") )); |
|
186 return KErrNone; |
|
187 } |
|
188 FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() received total:") )); |
|
189 FTRACE(FPrintRaw(iInputBuffer) ); |
|
190 iHandleState = EDunStateAtCmdHandling; |
|
191 iUpstream->NotifyAtCmdHandlingStart(); |
|
192 iDecodeInfo.iFirstDecode = ETrue; |
|
193 iDecodeInfo.iDecodeIndex = 0; |
|
194 HandleNextDecodedCommand(); |
|
195 FTRACE(FPrint( _L("CDunAtCmdHandler::ParseCommand() complete") )); |
|
196 aPartialInput = EFalse; |
|
197 return KErrNone; |
|
198 } |
|
199 |
|
200 // --------------------------------------------------------------------------- |
|
201 // Manages request to abort command handling |
|
202 // --------------------------------------------------------------------------- |
|
203 // |
|
204 EXPORT_C TInt CDunAtCmdHandler::ManageAbortRequest() |
|
205 { |
|
206 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest()") )); |
|
207 // Just forward the request, do no other own processing |
|
208 TInt retVal = iCmdPusher->ManageAbortRequest(); |
|
209 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageAbortRequest() complete") )); |
|
210 return retVal; |
|
211 } |
|
212 |
|
213 // --------------------------------------------------------------------------- |
|
214 // Sets end of command line marker on for the possible series of AT commands. |
|
215 // --------------------------------------------------------------------------- |
|
216 // |
|
217 EXPORT_C void CDunAtCmdHandler::SetEndOfCmdLine( TBool aClearInput ) |
|
218 { |
|
219 FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine()") )); |
|
220 ManageEndOfCmdHandling( EFalse, ETrue, aClearInput ); |
|
221 FTRACE(FPrint( _L("CDunAtCmdHandler::SetEndOfCmdLine() complete") )); |
|
222 } |
|
223 |
|
224 // --------------------------------------------------------------------------- |
|
225 // Sends a character to be echoed |
|
226 // --------------------------------------------------------------------------- |
|
227 // |
|
228 EXPORT_C TInt CDunAtCmdHandler::SendEchoCharacter( const TDesC8* aInput, |
|
229 MDunAtCmdEchoer* aCallback ) |
|
230 { |
|
231 FTRACE(FPrint( _L("CDunAtCmdHandler::SendEchoCharacter()") )); |
|
232 TInt retVal = iCmdEchoer->SendEchoCharacter( aInput, aCallback ); |
|
233 FTRACE(FPrint( _L("CDunAtCmdHandler::SendEchoCharacter() complete") )); |
|
234 return retVal; |
|
235 } |
|
236 |
|
237 // --------------------------------------------------------------------------- |
|
238 // Stops sending of AT command from parse buffer |
|
239 // --------------------------------------------------------------------------- |
|
240 // |
|
241 EXPORT_C TInt CDunAtCmdHandler::Stop() |
|
242 { |
|
243 FTRACE(FPrint( _L("CDunAtCmdHandler::Stop()") )); |
|
244 // Only stop iCmdPusher here, not iUrcHandlers! |
|
245 if ( iHandleState != EDunStateAtCmdHandling ) |
|
246 { |
|
247 FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() (not ready) complete" ))); |
|
248 return KErrNotReady; |
|
249 } |
|
250 iCmdPusher->Stop(); |
|
251 // The line below is used in the case when this function is called by |
|
252 // CDunUpstream as a result of "data mode ON" change notification. |
|
253 // In this case it is possible that HandleNextDecodedCommand() returns |
|
254 // without resetting the iInputBuffer because of the way it checks the |
|
255 // iHandleState. |
|
256 ManageEndOfCmdHandling( EFalse, ETrue, ETrue ); |
|
257 FTRACE(FPrint( _L("CDunAtCmdHandler::Stop() complete") )); |
|
258 return KErrNone; |
|
259 } |
|
260 |
|
261 // --------------------------------------------------------------------------- |
|
262 // Starts URC message handling |
|
263 // --------------------------------------------------------------------------- |
|
264 // |
|
265 EXPORT_C TInt CDunAtCmdHandler::StartUrc() |
|
266 { |
|
267 FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc()") )); |
|
268 TInt i; |
|
269 TInt count = iUrcHandlers.Count(); |
|
270 for ( i=0; i<count; i++ ) |
|
271 { |
|
272 TInt retTemp = iUrcHandlers[i]->IssueRequest(); |
|
273 if ( retTemp!=KErrNone && retTemp!=KErrNotReady ) |
|
274 { |
|
275 FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc() (ERROR) complete") )); |
|
276 return retTemp; |
|
277 } |
|
278 } |
|
279 FTRACE(FPrint( _L("CDunAtCmdHandler::StartUrc() complete") )); |
|
280 return KErrNone; |
|
281 } |
|
282 |
|
283 // --------------------------------------------------------------------------- |
|
284 // Stops URC message handling |
|
285 // --------------------------------------------------------------------------- |
|
286 // |
|
287 EXPORT_C TInt CDunAtCmdHandler::StopUrc() |
|
288 { |
|
289 FTRACE(FPrint( _L("CDunAtCmdHandler::StopUrc()") )); |
|
290 TInt i; |
|
291 TInt retVal = KErrNone; |
|
292 TInt count = iUrcHandlers.Count(); |
|
293 for ( i=0; i<count; i++ ) |
|
294 { |
|
295 retVal = iUrcHandlers[i]->Stop(); |
|
296 } |
|
297 FTRACE(FPrint( _L("CDunAtCmdHandler::StopUrc() complete") )); |
|
298 return retVal; |
|
299 } |
|
300 |
|
301 // --------------------------------------------------------------------------- |
|
302 // CDunAtCmdHandler::CDunAtCmdHandler |
|
303 // --------------------------------------------------------------------------- |
|
304 // |
|
305 CDunAtCmdHandler::CDunAtCmdHandler( MDunAtCmdStatusReporter* aUpstream, |
|
306 MDunStreamManipulator* aDownstream, |
|
307 const TDesC8* aConnectionName ) : |
|
308 iUpstream( aUpstream ), |
|
309 iDownstream( aDownstream ), |
|
310 iConnectionName( aConnectionName ) |
|
311 { |
|
312 Initialize(); |
|
313 } |
|
314 |
|
315 // --------------------------------------------------------------------------- |
|
316 // CDunAtCmdHandler::ConstructL |
|
317 // --------------------------------------------------------------------------- |
|
318 // |
|
319 void CDunAtCmdHandler::ConstructL() |
|
320 { |
|
321 FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL()") )); |
|
322 if ( !iUpstream || !iDownstream || !iConnectionName ) |
|
323 { |
|
324 User::Leave( KErrGeneral ); |
|
325 } |
|
326 // Connect to AT command extension (must succeed) |
|
327 TInt retTemp = KErrNone; |
|
328 CleanupClosePushL( iAtCmdExt ); |
|
329 retTemp = iAtCmdExt.Connect( EDunATExtension, *iConnectionName ); |
|
330 if ( retTemp != KErrNone ) |
|
331 { |
|
332 FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() connect (%d)"), retTemp)); |
|
333 User::Leave( retTemp ); |
|
334 } |
|
335 CleanupClosePushL( iAtCmdExtCommon ); |
|
336 retTemp = iAtCmdExtCommon.Connect( *iConnectionName ); |
|
337 if ( retTemp != KErrNone ) |
|
338 { |
|
339 FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() common connect (%d)"), retTemp)); |
|
340 User::Leave( retTemp ); |
|
341 } |
|
342 // Create the array of special commands |
|
343 CreateSpecialCommandsL(); |
|
344 // Create the plugin handlers |
|
345 CreatePluginHandlersL(); |
|
346 // Create the echo handler |
|
347 iCmdEchoer = CDunAtCmdEchoer::NewL( iDownstream ); |
|
348 // Create the listeners |
|
349 iEcomListen = CDunAtEcomListen::NewL( &iAtCmdExt, this ); |
|
350 iModeListen = CDunAtModeListen::NewL( &iAtCmdExtCommon, this ); |
|
351 iNvramListen = CDunAtNvramListen::NewL( &iAtCmdExt, &iAtCmdExtCommon ); |
|
352 iAtSpecialCmdHandler = CDunAtSpecialCmdHandler::NewL(); |
|
353 // Set the default modes (+report) and characters |
|
354 GetAndSetDefaultSettingsL(); |
|
355 // Start listening |
|
356 iEcomListen->IssueRequest(); |
|
357 iModeListen->IssueRequest(); |
|
358 iNvramListen->IssueRequest(); |
|
359 CleanupStack::Pop( &iAtCmdExtCommon ); |
|
360 CleanupStack::Pop( &iAtCmdExt ); |
|
361 FTRACE(FPrint( _L("CDunAtCmdHandler::ConstructL() complete") )); |
|
362 } |
|
363 |
|
364 // --------------------------------------------------------------------------- |
|
365 // Initializes this class |
|
366 // --------------------------------------------------------------------------- |
|
367 // |
|
368 void CDunAtCmdHandler::Initialize() |
|
369 { |
|
370 // Don't initialize iUpstream here (it is set through NewL) |
|
371 // Don't initialize iDownstream here (it is set through NewL) |
|
372 // Don't initialize iConnectionName here (it is set through NewL) |
|
373 iHandleState = EDunStateIdle; |
|
374 iCarriageReturn = 0; |
|
375 iLineFeed = 0; |
|
376 iBackspace = 0; |
|
377 iCommand = NULL; |
|
378 iDecodeInfo.iFirstDecode = ETrue; |
|
379 iDecodeInfo.iDecodeIndex = KErrNotFound; |
|
380 iDecodeInfo.iExtendedIndex = KErrNotFound; |
|
381 iDecodeInfo.iPrevChar = 0; |
|
382 iDecodeInfo.iPrevExists = EFalse; |
|
383 iDecodeInfo.iAssignFound = EFalse; |
|
384 iDecodeInfo.iInQuotes = EFalse; |
|
385 iDecodeInfo.iSpecialFound = EFalse; |
|
386 iEditorModeInfo.iContentFound = EFalse; |
|
387 iCmdPusher = NULL; |
|
388 iEcomListen = NULL; |
|
389 iModeListen = NULL; |
|
390 iNvramListen = NULL; |
|
391 iDataMode = EFalse; |
|
392 iEchoOn = EFalse; |
|
393 iQuietOn = EFalse; |
|
394 iVerboseOn = EFalse; |
|
395 iEndIndex = KErrNotFound; |
|
396 } |
|
397 |
|
398 // --------------------------------------------------------------------------- |
|
399 // Creates plugin handlers for this class |
|
400 // --------------------------------------------------------------------------- |
|
401 // |
|
402 void CDunAtCmdHandler::CreatePluginHandlersL() |
|
403 { |
|
404 FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL()") )); |
|
405 if ( !iAtCmdExt.Handle() ) |
|
406 { |
|
407 FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL() complete") )); |
|
408 User::Leave( KErrGeneral ); |
|
409 } |
|
410 // First create the command reply pusher |
|
411 CDunAtCmdPusher* cmdPusher = CDunAtCmdPusher::NewLC( &iAtCmdExt, |
|
412 this, |
|
413 iDownstream, |
|
414 &iOkBuffer ); |
|
415 // Next create the URC handlers |
|
416 TInt i; |
|
417 TInt numOfPlugins = iAtCmdExt.NumberOfPlugins(); |
|
418 for ( i=0; i<numOfPlugins; i++ ) |
|
419 { |
|
420 AddOneUrcHandlerL(); |
|
421 } |
|
422 CleanupStack::Pop( cmdPusher ); |
|
423 iCmdPusher = cmdPusher; |
|
424 FTRACE(FPrint( _L("CDunAtCmdHandler::CreatePluginHandlersL() complete") )); |
|
425 } |
|
426 |
|
427 // --------------------------------------------------------------------------- |
|
428 // Creates an array of special commands |
|
429 // --------------------------------------------------------------------------- |
|
430 // |
|
431 void CDunAtCmdHandler::CreateSpecialCommandsL() |
|
432 { |
|
433 FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL()") )); |
|
434 TInt retTemp = KErrNone; |
|
435 TBool firstSearch = ETrue; |
|
436 for ( ;; ) |
|
437 { |
|
438 retTemp = iAtCmdExt.GetNextSpecialCommand( iInputBuffer, firstSearch ); |
|
439 if ( retTemp != KErrNone ) |
|
440 { |
|
441 break; |
|
442 } |
|
443 HBufC8* specialCmd = HBufC8::NewMaxLC( iInputBuffer.Length() ); |
|
444 TPtr8 specialCmdPtr = specialCmd->Des(); |
|
445 specialCmdPtr.Copy( iInputBuffer ); |
|
446 specialCmdPtr.UpperCase(); |
|
447 iSpecials.AppendL( specialCmd ); |
|
448 CleanupStack::Pop( specialCmd ); |
|
449 } |
|
450 iInputBuffer.Zero(); |
|
451 FTRACE(FPrint( _L("CDunAtCmdHandler::CreateSpecialCommandsL() complete") )); |
|
452 } |
|
453 |
|
454 // --------------------------------------------------------------------------- |
|
455 // Recreates special command data. |
|
456 // This is done when a plugin is installed or uninstalled. |
|
457 // --------------------------------------------------------------------------- |
|
458 // |
|
459 TInt CDunAtCmdHandler::RecreateSpecialCommands() |
|
460 { |
|
461 FTRACE(FPrint( _L("CDunAtCmdHandler::RecreateSpecialCommands()") )); |
|
462 iSpecials.ResetAndDestroy(); |
|
463 TRAPD( retTrap, CreateSpecialCommandsL() ); |
|
464 FTRACE(FPrint( _L("CDunAtCmdHandler::RecreateSpecialCommands() complete") )); |
|
465 return retTrap; |
|
466 } |
|
467 |
|
468 // --------------------------------------------------------------------------- |
|
469 // Gets default settings from RATExtCommon and sets them to RATExt |
|
470 // --------------------------------------------------------------------------- |
|
471 // |
|
472 void CDunAtCmdHandler::GetAndSetDefaultSettingsL() |
|
473 { |
|
474 FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL()") )); |
|
475 // Note: Let's assume command mode is off by default |
|
476 TUint modeSet = GetCurrentModeL( KModeEcho | KModeQuiet | KModeVerbose ); |
|
477 iEchoOn = ( modeSet & KEchoModeBase ) ? ETrue : EFalse; |
|
478 iQuietOn = ( modeSet & KQuietModeBase ) ? ETrue : EFalse; |
|
479 iVerboseOn = ( modeSet & KVerboseModeBase ) ? ETrue : EFalse; |
|
480 iCarriageReturn = GetCurrentModeL( KModeCarriage ); |
|
481 iLineFeed = GetCurrentModeL( KModeLineFeed ); |
|
482 iBackspace = GetCurrentModeL( KModeBackspace ); |
|
483 iAtCmdExt.ReportQuietModeChange( iQuietOn ); |
|
484 iAtCmdExt.ReportVerboseModeChange( iVerboseOn ); |
|
485 iAtCmdExt.ReportCharacterChange( ECharTypeCarriage, iCarriageReturn ); |
|
486 iAtCmdExt.ReportCharacterChange( ECharTypeLineFeed, iLineFeed ); |
|
487 iAtCmdExt.ReportCharacterChange( ECharTypeBackspace, iBackspace ); |
|
488 RegenerateReplyStrings(); |
|
489 FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn )); |
|
490 FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() settings: CR=%u, LF=%u, BS=%u"), iCarriageReturn, iLineFeed, iBackspace )); |
|
491 FTRACE(FPrint( _L("CDunAtCmdHandler::GetAndSetDefaultSettingsL() complete") )); |
|
492 } |
|
493 |
|
494 // --------------------------------------------------------------------------- |
|
495 // Regenerates the reply strings based on settings |
|
496 // --------------------------------------------------------------------------- |
|
497 // |
|
498 TBool CDunAtCmdHandler::RegenerateReplyStrings() |
|
499 { |
|
500 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateReplyStrings()") )); |
|
501 TBool retVal = EFalse; |
|
502 retVal |= RegenerateOkReply(); |
|
503 retVal |= RegenerateErrorReply(); |
|
504 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateReplyStrings() complete") )); |
|
505 return retVal; |
|
506 } |
|
507 |
|
508 // --------------------------------------------------------------------------- |
|
509 // Regenerates the ok reply based on settings |
|
510 // --------------------------------------------------------------------------- |
|
511 // |
|
512 TBool CDunAtCmdHandler::RegenerateOkReply() |
|
513 { |
|
514 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply()") )); |
|
515 iOkBuffer.Zero(); |
|
516 if ( iQuietOn ) |
|
517 { |
|
518 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() (quiet) complete") )); |
|
519 return ETrue; |
|
520 } |
|
521 if ( iVerboseOn ) |
|
522 { |
|
523 _LIT8( KVerboseOk, "OK" ); |
|
524 iOkBuffer.Append( iCarriageReturn ); |
|
525 iOkBuffer.Append( iLineFeed ); |
|
526 iOkBuffer.Append( KVerboseOk ); |
|
527 iOkBuffer.Append( iCarriageReturn ); |
|
528 iOkBuffer.Append( iLineFeed ); |
|
529 } |
|
530 else |
|
531 { |
|
532 _LIT8( KNumericOk, "0" ); |
|
533 iOkBuffer.Append( KNumericOk ); |
|
534 iOkBuffer.Append( iCarriageReturn ); |
|
535 } |
|
536 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateOkReply() complete") )); |
|
537 return EFalse; |
|
538 } |
|
539 |
|
540 // --------------------------------------------------------------------------- |
|
541 // Regenerates the error reply based on settings |
|
542 // --------------------------------------------------------------------------- |
|
543 // |
|
544 TBool CDunAtCmdHandler::RegenerateErrorReply() |
|
545 { |
|
546 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply()") )); |
|
547 iErrorBuffer.Zero(); |
|
548 if ( iQuietOn ) |
|
549 { |
|
550 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() (quiet) complete") )); |
|
551 return ETrue; |
|
552 } |
|
553 if ( iVerboseOn ) |
|
554 { |
|
555 _LIT8( KVerboseError, "ERROR" ); |
|
556 iErrorBuffer.Append( iCarriageReturn ); |
|
557 iErrorBuffer.Append( iLineFeed ); |
|
558 iErrorBuffer.Append( KVerboseError ); |
|
559 iErrorBuffer.Append( iCarriageReturn ); |
|
560 iErrorBuffer.Append( iLineFeed ); |
|
561 } |
|
562 else |
|
563 { |
|
564 _LIT8( KNumericError, "4" ); |
|
565 iErrorBuffer.Append( KNumericError ); |
|
566 iErrorBuffer.Append( iCarriageReturn ); |
|
567 } |
|
568 FTRACE(FPrint( _L("CDunAtCmdHandler::RegenerateErrorReply() complete") )); |
|
569 return EFalse; |
|
570 } |
|
571 |
|
572 // --------------------------------------------------------------------------- |
|
573 // Gets current mode |
|
574 // --------------------------------------------------------------------------- |
|
575 // |
|
576 TUint CDunAtCmdHandler::GetCurrentModeL( TUint aMask ) |
|
577 { |
|
578 FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL()") )); |
|
579 TUint maskCheck = aMask & ( ~KSupportedModes ); |
|
580 if ( maskCheck != 0 ) |
|
581 { |
|
582 FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() (not supported) complete") )); |
|
583 User::Leave( KErrNotSupported ); |
|
584 } |
|
585 TUint newMode = 0; |
|
586 TInt retTemp = iAtCmdExtCommon.GetMode( aMask, newMode ); |
|
587 if ( retTemp != KErrNone ) |
|
588 { |
|
589 FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() (ERROR) complete") )); |
|
590 User::Leave( retTemp ); |
|
591 } |
|
592 FTRACE(FPrint( _L("CDunAtCmdHandler::GetCurrentModeL() complete") )); |
|
593 return newMode & (KModeChanged-1); |
|
594 } |
|
595 |
|
596 // --------------------------------------------------------------------------- |
|
597 // Instantiates one URC message handling class instance and adds it to the URC |
|
598 // message handler array |
|
599 // --------------------------------------------------------------------------- |
|
600 // |
|
601 CDunAtUrcHandler* CDunAtCmdHandler::AddOneUrcHandlerL() |
|
602 { |
|
603 FTRACE(FPrint( _L("CDunAtCmdHandler::AddOneUrcHandlerL()") )); |
|
604 CDunAtUrcHandler* urcHandler = CDunAtUrcHandler::NewLC( &iAtCmdExt, |
|
605 iDownstream ); |
|
606 iUrcHandlers.AppendL( urcHandler ); |
|
607 CleanupStack::Pop( urcHandler ); |
|
608 FTRACE(FPrint( _L("CDunAtCmdHandler::AddOneUrcHandlerL() complete") )); |
|
609 return urcHandler; |
|
610 } |
|
611 |
|
612 // --------------------------------------------------------------------------- |
|
613 // Deletes all instantiated URC message handlers |
|
614 // --------------------------------------------------------------------------- |
|
615 // |
|
616 void CDunAtCmdHandler::DeletePluginHandlers() |
|
617 { |
|
618 FTRACE(FPrint( _L("CDunAtCmdHandler::DeletePluginHandlers()") )); |
|
619 delete iCmdPusher; |
|
620 iCmdPusher = NULL; |
|
621 TInt i; |
|
622 TInt count = iUrcHandlers.Count(); |
|
623 for ( i=0; i<count; i++ ) |
|
624 { |
|
625 delete iUrcHandlers[i]; |
|
626 iUrcHandlers[i] = NULL; |
|
627 } |
|
628 iUrcHandlers.Reset(); |
|
629 iUrcHandlers.Close(); |
|
630 FTRACE(FPrint( _L("CDunAtCmdHandler::DeletePluginHandlers() complete") )); |
|
631 } |
|
632 |
|
633 // --------------------------------------------------------------------------- |
|
634 // Manages partial AT command |
|
635 // --------------------------------------------------------------------------- |
|
636 // |
|
637 TBool CDunAtCmdHandler::ManagePartialCommand( TDesC8& aCommand, |
|
638 TBool& aNeedsCarriage ) |
|
639 { |
|
640 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand()") )); |
|
641 aNeedsCarriage = ETrue; |
|
642 // Check length of command |
|
643 if ( aCommand.Length() == 0 ) |
|
644 { |
|
645 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length zero) complete") )); |
|
646 return ETrue; |
|
647 } |
|
648 // Check one character (or unit) based input data |
|
649 if ( aCommand.Length() == KDunChSetMaxCharLen ) |
|
650 { |
|
651 EchoCommand( aCommand ); |
|
652 // Handle backspace and cancel characters |
|
653 TBool found = HandleSpecialCharacters( aCommand ); |
|
654 if ( found ) |
|
655 { |
|
656 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (special) complete") )); |
|
657 return ETrue; |
|
658 } |
|
659 } |
|
660 TBool endFound = EFalse; |
|
661 TBool overflow = AppendCommandToInputBuffer( aCommand, endFound ); |
|
662 if ( overflow ) |
|
663 { |
|
664 // Overflow occurred so return ETrue (consumed) to skip all the rest |
|
665 // characters until carriage return is found |
|
666 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (overflow) complete") )); |
|
667 return ETrue; |
|
668 } |
|
669 // If something went wrong, do nothing (return consumed) |
|
670 if ( iInputBuffer.Length() <= 0 ) |
|
671 { |
|
672 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (length) complete") )); |
|
673 return ETrue; |
|
674 } |
|
675 // If "A/", no carriage return is needed, check that now |
|
676 if ( IsASlashCommand() ) |
|
677 { |
|
678 aNeedsCarriage = EFalse; |
|
679 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (A/) complete") )); |
|
680 return EFalse; |
|
681 } |
|
682 // For other commands and if no end, just return with consumed |
|
683 if ( !endFound ) |
|
684 { |
|
685 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() (void) complete") )); |
|
686 return ETrue; |
|
687 } |
|
688 FTRACE(FPrint( _L("CDunAtCmdHandler::ManagePartialCommand() complete") )); |
|
689 return EFalse; |
|
690 } |
|
691 |
|
692 // --------------------------------------------------------------------------- |
|
693 // Echoes a command if echo is on |
|
694 // --------------------------------------------------------------------------- |
|
695 // |
|
696 TBool CDunAtCmdHandler::EchoCommand( TDesC8& aDes ) |
|
697 { |
|
698 FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand()") )); |
|
699 if ( aDes.Length() > KDunChSetMaxCharLen ) |
|
700 { |
|
701 FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (wrong length) complete") )); |
|
702 return EFalse; |
|
703 } |
|
704 if ( iEchoOn ) |
|
705 { |
|
706 iEchoBuffer.Copy( aDes ); |
|
707 iDownstream->NotifyDataPushRequest( &iEchoBuffer, NULL ); |
|
708 FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() complete") )); |
|
709 return ETrue; |
|
710 } |
|
711 FTRACE(FPrint( _L("CDunAtCmdHandler::EchoCommand() (not started) complete") )); |
|
712 return EFalse; |
|
713 } |
|
714 |
|
715 // --------------------------------------------------------------------------- |
|
716 // Handles backspace and cancel characters |
|
717 // --------------------------------------------------------------------------- |
|
718 // |
|
719 TBool CDunAtCmdHandler::HandleSpecialCharacters( TDesC8& aCommand ) |
|
720 { |
|
721 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters()") )); |
|
722 if ( aCommand.Length() != KDunChSetMaxCharLen ) |
|
723 { |
|
724 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (wrong length) complete") )); |
|
725 return EFalse; |
|
726 } |
|
727 if ( aCommand[0] == iBackspace ) |
|
728 { |
|
729 TInt bufferLength = iInputBuffer.Length(); |
|
730 if ( bufferLength > 0 ) |
|
731 { |
|
732 iInputBuffer.SetLength( bufferLength-1 ); |
|
733 } |
|
734 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (backspace) complete") )); |
|
735 return ETrue; |
|
736 } |
|
737 if ( aCommand[0] == KDunCancel ) |
|
738 { |
|
739 ResetParseBuffers(); // More processing here? |
|
740 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() (cancel) complete") )); |
|
741 return ETrue; |
|
742 } |
|
743 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleSpecialCharacters() complete") )); |
|
744 return EFalse; |
|
745 } |
|
746 |
|
747 // --------------------------------------------------------------------------- |
|
748 // Appends command to parse buffer |
|
749 // --------------------------------------------------------------------------- |
|
750 // |
|
751 TBool CDunAtCmdHandler::AppendCommandToInputBuffer( TDesC8& aCommand, |
|
752 TBool& aEndFound ) |
|
753 { |
|
754 FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer()") )); |
|
755 aEndFound = EFalse; |
|
756 TInt cmdBufIndex = 0; |
|
757 TInt cmdBufLim = aCommand.Length(); |
|
758 while ( cmdBufIndex < cmdBufLim ) |
|
759 { |
|
760 if ( iInputBuffer.Length() == iInputBuffer.MaxLength() ) |
|
761 { |
|
762 // 1) If output is full and end found from input |
|
763 // -> reset buffers and overflow found |
|
764 // 2) If output is full and end not found from input |
|
765 // -> don't reset buffers and overflow found |
|
766 TInt foundIndex = FindEndOfCommand( aCommand ); |
|
767 if ( foundIndex >= 0 ) |
|
768 { |
|
769 aEndFound = ETrue; |
|
770 ResetParseBuffers(); |
|
771 FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (reset) complete") )); |
|
772 } |
|
773 FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() (overflow) complete") )); |
|
774 return ETrue; |
|
775 } |
|
776 TChar character = aCommand[cmdBufIndex]; |
|
777 if ( IsEndOfCommand(character) ) |
|
778 { |
|
779 aEndFound = ETrue; |
|
780 iEndIndex = cmdBufIndex; |
|
781 break; |
|
782 } |
|
783 iInputBuffer.Append( aCommand[cmdBufIndex] ); |
|
784 cmdBufIndex++; |
|
785 } |
|
786 FTRACE(FPrint( _L("CDunAtCmdHandler::AppendCommandToInputBuffer() complete") )); |
|
787 return EFalse; |
|
788 } |
|
789 |
|
790 // --------------------------------------------------------------------------- |
|
791 // Handles next decoded command from input buffer |
|
792 // --------------------------------------------------------------------------- |
|
793 // |
|
794 TBool CDunAtCmdHandler::HandleNextDecodedCommand() |
|
795 { |
|
796 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand()") )); |
|
797 if ( iHandleState != EDunStateAtCmdHandling ) |
|
798 { |
|
799 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (not ready) complete") )); |
|
800 return ETrue; |
|
801 } |
|
802 TBool extracted = ExtractNextDecodedCommand(); |
|
803 if ( !extracted ) |
|
804 { |
|
805 ManageEndOfCmdHandling( ETrue, ETrue, ETrue ); |
|
806 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() (last) complete") )); |
|
807 return ETrue; |
|
808 } |
|
809 // Next convert the decoded AT command to uppercase |
|
810 // Don't check for case status -> let mixed cases pass |
|
811 iParseInfo.iSendBuffer.Copy( iDecodeInfo.iDecodeBuffer ); |
|
812 TInt maxLength = iParseInfo.iSendBuffer.MaxLength(); |
|
813 TPtr8 upperDes( &iParseInfo.iSendBuffer[0], iParseInfo.iLimit, maxLength ); |
|
814 upperDes.UpperCase(); |
|
815 // Next always send the command to ATEXT |
|
816 iCmdPusher->IssueRequest( iParseInfo.iSendBuffer ); |
|
817 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleNextDecodedCommand() complete") )); |
|
818 return EFalse; |
|
819 } |
|
820 |
|
821 // --------------------------------------------------------------------------- |
|
822 // Finds the start of the next command |
|
823 // --------------------------------------------------------------------------- |
|
824 // |
|
825 TInt CDunAtCmdHandler::FindStartOfNextCommand() |
|
826 { |
|
827 FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand()") )); |
|
828 // Note: here we need to avoid internal recursion when parsing the |
|
829 // multiple IsEndOfCommand() and IsDelimiterCharacter() markers inside the |
|
830 // same upstream block. |
|
831 // Skip all the extra markers except the one we already know to exist. |
|
832 TInt i; |
|
833 TInt startVal = iEndIndex + 1; |
|
834 TInt foundIndex = KErrNotFound; |
|
835 TInt count = iCommand->Length(); |
|
836 for ( i=startVal; i<count; i++ ) |
|
837 { |
|
838 TChar character = (*iCommand)[i]; |
|
839 if ( !(IsEndOfCommand(character)||IsDelimiterCharacter(character)) ) |
|
840 { |
|
841 foundIndex = i; |
|
842 break; |
|
843 } |
|
844 } |
|
845 FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfNextCommand() complete") )); |
|
846 return foundIndex; |
|
847 } |
|
848 |
|
849 // --------------------------------------------------------------------------- |
|
850 // Manages end of AT command handling |
|
851 // --------------------------------------------------------------------------- |
|
852 // |
|
853 void CDunAtCmdHandler::ManageEndOfCmdHandling( TBool aNotifyExternal, |
|
854 TBool aNotifyLocal, |
|
855 TBool aClearInput ) |
|
856 { |
|
857 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling()") )); |
|
858 if ( iInputBuffer.Length() > 0 ) |
|
859 { |
|
860 iLastBuffer.Copy( iInputBuffer ); |
|
861 } |
|
862 ResetParseBuffers( aClearInput ); |
|
863 iHandleState = EDunStateIdle; |
|
864 if ( aNotifyLocal ) |
|
865 { |
|
866 iCmdPusher->SetEndOfCmdLine(); |
|
867 } |
|
868 if ( !aNotifyExternal ) |
|
869 { |
|
870 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() (no external) complete") )); |
|
871 return; |
|
872 } |
|
873 TInt foundIndex = FindStartOfNextCommand(); |
|
874 iUpstream->NotifyAtCmdHandlingEnd( foundIndex ); |
|
875 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEndOfCmdHandling() complete") )); |
|
876 } |
|
877 |
|
878 // --------------------------------------------------------------------------- |
|
879 // Extracts next decoded command from input buffer to decode buffer |
|
880 // --------------------------------------------------------------------------- |
|
881 // |
|
882 TBool CDunAtCmdHandler::ExtractNextDecodedCommand( TBool aPeek ) |
|
883 { |
|
884 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand()") )); |
|
885 iParseInfo.iLimit = KErrNotFound; |
|
886 TDunDecodeInfo oldInfo = iDecodeInfo; |
|
887 iDecodeInfo.iDecodeBuffer.Zero(); |
|
888 // Find start of decode command from input buffer |
|
889 TInt startIndex = iDecodeInfo.iDecodeIndex; |
|
890 startIndex = FindStartOfDecodedCommand( iInputBuffer, startIndex ); |
|
891 if ( startIndex < 0 ) |
|
892 { |
|
893 RestoreOldDecodeInfo( aPeek, oldInfo ); |
|
894 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no start) complete") )); |
|
895 return EFalse; |
|
896 } |
|
897 // Find end of decode command from input buffer |
|
898 TBool specialCmd = EFalse; |
|
899 TInt endIndex = KErrNotFound; |
|
900 specialCmd = CheckSpecialCommand( startIndex, endIndex ); |
|
901 if ( !specialCmd ) |
|
902 { |
|
903 FindSubCommand( startIndex, endIndex ); |
|
904 } |
|
905 if ( endIndex < startIndex ) |
|
906 { |
|
907 RestoreOldDecodeInfo( aPeek, oldInfo ); |
|
908 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() (no end) complete") )); |
|
909 return EFalse; |
|
910 } |
|
911 TInt cmdLength = endIndex - startIndex + 1; |
|
912 // If the limit was not already set then do it now |
|
913 if ( iParseInfo.iLimit < 0 ) |
|
914 { |
|
915 iParseInfo.iLimit = cmdLength; |
|
916 } |
|
917 // Next create a new command |
|
918 if ( !iDecodeInfo.iFirstDecode && !specialCmd ) |
|
919 { |
|
920 _LIT( KAtMsg, "AT" ); |
|
921 iDecodeInfo.iDecodeBuffer.Append( KAtMsg ); |
|
922 iParseInfo.iLimit += 2; // Length of "AT" |
|
923 // Note: The length of iDecodeBuffer is not exceeded here because "AT" |
|
924 // is added only for the second commands after that. |
|
925 } |
|
926 TPtrC8 decodedCmd = iInputBuffer.Mid( startIndex, cmdLength ); |
|
927 iDecodeInfo.iDecodeBuffer.Append( decodedCmd ); |
|
928 // Set index for next round |
|
929 iDecodeInfo.iFirstDecode = EFalse; |
|
930 iDecodeInfo.iDecodeIndex = endIndex + 1; |
|
931 RestoreOldDecodeInfo( aPeek, oldInfo ); |
|
932 FTRACE(FPrint( _L("CDunAtCmdHandler::ExtractNextDecodedCommand() complete") )); |
|
933 return ETrue; |
|
934 } |
|
935 |
|
936 // --------------------------------------------------------------------------- |
|
937 // Restores old decode info. For ExtractNextDecodedCommand() when aPeeks is |
|
938 // ETrue. |
|
939 // --------------------------------------------------------------------------- |
|
940 // |
|
941 void CDunAtCmdHandler::RestoreOldDecodeInfo( TBool aPeek, |
|
942 TDunDecodeInfo& aOldInfo ) |
|
943 { |
|
944 FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo()") )); |
|
945 if ( aPeek ) |
|
946 { |
|
947 iEditorModeInfo.iPeekInfo = iDecodeInfo; |
|
948 iDecodeInfo = aOldInfo; |
|
949 } |
|
950 FTRACE(FPrint( _L("CDunAtCmdHandler::RestoreOldDecodeInfo() complete") )); |
|
951 } |
|
952 |
|
953 // --------------------------------------------------------------------------- |
|
954 // Finds end of an AT command |
|
955 // --------------------------------------------------------------------------- |
|
956 // |
|
957 TInt CDunAtCmdHandler::FindEndOfCommand( TDesC8& aDes, TInt aStartIndex ) |
|
958 { |
|
959 FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand()") )); |
|
960 TInt i; |
|
961 TInt length = aDes.Length(); |
|
962 for ( i=aStartIndex; i<length; i++ ) |
|
963 { |
|
964 TChar character = aDes[i]; |
|
965 if ( IsEndOfCommand(character) ) |
|
966 { |
|
967 FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand() complete (%d)"), i )); |
|
968 return i; |
|
969 } |
|
970 } |
|
971 FTRACE(FPrint( _L("CDunAtCmdHandler::FindEndOfCommand() (not found) complete") )); |
|
972 return KErrNotFound; |
|
973 } |
|
974 |
|
975 // --------------------------------------------------------------------------- |
|
976 // Tests for end of AT command character |
|
977 // --------------------------------------------------------------------------- |
|
978 // |
|
979 TBool CDunAtCmdHandler::IsEndOfCommand( TChar& aCharacter ) |
|
980 { |
|
981 FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand()") )); |
|
982 if ( aCharacter==iCarriageReturn || aCharacter==iLineFeed ) |
|
983 { |
|
984 FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (found) complete") )); |
|
985 return ETrue; |
|
986 } |
|
987 FTRACE(FPrint( _L("CDunAtCmdHandler::IsEndOfCommand() (not found) complete") )); |
|
988 return EFalse; |
|
989 } |
|
990 |
|
991 // --------------------------------------------------------------------------- |
|
992 // Finds start of a decoded AT command |
|
993 // --------------------------------------------------------------------------- |
|
994 // |
|
995 TInt CDunAtCmdHandler::FindStartOfDecodedCommand( TDesC8& aDes, |
|
996 TInt aStartIndex ) |
|
997 { |
|
998 FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand()") )); |
|
999 TInt i; |
|
1000 TInt count = aDes.Length(); |
|
1001 for ( i=aStartIndex; i<count; i++ ) |
|
1002 { |
|
1003 TChar character = aDes[i]; |
|
1004 if ( !IsDelimiterCharacter(character) ) |
|
1005 { |
|
1006 FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand() complete (%d)"), i )); |
|
1007 return i; |
|
1008 } |
|
1009 } |
|
1010 FTRACE(FPrint( _L("CDunAtCmdHandler::FindStartOfDecodedCommand() (not found) complete") )); |
|
1011 return KErrNotFound; |
|
1012 } |
|
1013 |
|
1014 // --------------------------------------------------------------------------- |
|
1015 // Checks if character is delimiter character |
|
1016 // --------------------------------------------------------------------------- |
|
1017 // |
|
1018 TBool CDunAtCmdHandler::IsDelimiterCharacter( TChar aCharacter ) |
|
1019 { |
|
1020 FTRACE(FPrint( _L("CDunAtCmdHandler::IsDelimiterCharacter()") )); |
|
1021 if ( aCharacter.IsSpace() || aCharacter==';' || aCharacter==0x00 ) |
|
1022 { |
|
1023 FTRACE(FPrint( _L("CDunAtCmdHandler::IsDelimiterCharacter() complete") )); |
|
1024 return ETrue; |
|
1025 } |
|
1026 FTRACE(FPrint( _L("CDunAtCmdHandler::IsDelimiterCharacter() (not delimiter) complete") )); |
|
1027 return EFalse; |
|
1028 } |
|
1029 |
|
1030 // --------------------------------------------------------------------------- |
|
1031 // Checks if character is of extended group |
|
1032 // --------------------------------------------------------------------------- |
|
1033 // |
|
1034 TBool CDunAtCmdHandler::IsExtendedCharacter( TChar aCharacter ) |
|
1035 { |
|
1036 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedCharacter()") )); |
|
1037 if ( aCharacter=='+' || aCharacter=='&' || aCharacter=='%' || |
|
1038 aCharacter=='\\' || aCharacter=='*' || aCharacter=='#' || |
|
1039 aCharacter=='$' || aCharacter=='^' ) |
|
1040 { |
|
1041 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedCharacter() complete") )); |
|
1042 return ETrue; |
|
1043 } |
|
1044 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedCharacter() (not extended) complete") )); |
|
1045 return EFalse; |
|
1046 } |
|
1047 |
|
1048 // --------------------------------------------------------------------------- |
|
1049 // Checks special command |
|
1050 // --------------------------------------------------------------------------- |
|
1051 // |
|
1052 TBool CDunAtCmdHandler::CheckSpecialCommand( TInt aStartIndex, |
|
1053 TInt& aEndIndex ) |
|
1054 { |
|
1055 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand()") )); |
|
1056 TBuf8<KDunInputBufLength> upperBuf; |
|
1057 TInt newLength = iInputBuffer.Length() - aStartIndex; |
|
1058 upperBuf.Copy( &iInputBuffer[aStartIndex], newLength ); |
|
1059 upperBuf.UpperCase(); |
|
1060 TInt i; |
|
1061 TInt count = iSpecials.Count(); |
|
1062 for ( i=0; i<count; i++ ) |
|
1063 { |
|
1064 HBufC8* specialCmd = iSpecials[i]; |
|
1065 TInt specialLength = specialCmd->Length(); |
|
1066 if ( newLength < specialLength ) |
|
1067 { |
|
1068 continue; |
|
1069 } |
|
1070 TInt origLength = newLength; |
|
1071 if ( newLength > specialLength ) |
|
1072 { |
|
1073 upperBuf.SetLength( specialLength ); |
|
1074 } |
|
1075 TInt cmpResult = upperBuf.Compare( *specialCmd ); |
|
1076 upperBuf.SetLength( origLength ); |
|
1077 if ( cmpResult == 0 ) |
|
1078 { |
|
1079 iParseInfo.iLimit = specialLength; |
|
1080 aEndIndex = (origLength-1) + aStartIndex; |
|
1081 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() complete") )); |
|
1082 return ETrue; |
|
1083 } |
|
1084 } |
|
1085 FTRACE(FPrint( _L("CDunAtCmdHandler::CheckSpecialCommand() (not found) complete") )); |
|
1086 return EFalse; |
|
1087 } |
|
1088 |
|
1089 // --------------------------------------------------------------------------- |
|
1090 // Saves character decode state for a found character |
|
1091 // --------------------------------------------------------------------------- |
|
1092 // |
|
1093 void CDunAtCmdHandler::SaveFoundCharDecodeState( TChar aCharacter, |
|
1094 TBool aAddSpecial ) |
|
1095 { |
|
1096 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveFoundCharDecodeState()") )); |
|
1097 iDecodeInfo.iPrevExists = ETrue; |
|
1098 iDecodeInfo.iPrevChar = aCharacter; |
|
1099 if ( aAddSpecial ) |
|
1100 { |
|
1101 iDecodeInfo.iSpecialFound = |
|
1102 iAtSpecialCmdHandler->IsCompleteSubCommand( aCharacter ); |
|
1103 } |
|
1104 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveFoundCharDecodeState() complete") )); |
|
1105 } |
|
1106 |
|
1107 // --------------------------------------------------------------------------- |
|
1108 // Saves character decode state for a not found character |
|
1109 // --------------------------------------------------------------------------- |
|
1110 // |
|
1111 void CDunAtCmdHandler::SaveNotFoundCharDecodeState() |
|
1112 { |
|
1113 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveNotFoundCharDecodeState()") )); |
|
1114 iDecodeInfo.iPrevExists = EFalse; |
|
1115 // Note: don't set iAssignFound or iInQuotes here |
|
1116 iDecodeInfo.iSpecialFound = EFalse; |
|
1117 FTRACE(FPrint( _L("CDunAtCmdHandler::SaveNotFoundCharDecodeState() complete") )); |
|
1118 } |
|
1119 |
|
1120 // --------------------------------------------------------------------------- |
|
1121 // Find quotes within subcommands |
|
1122 // --------------------------------------------------------------------------- |
|
1123 // |
|
1124 TBool CDunAtCmdHandler::FindSubCommandQuotes( TChar aCharacter, |
|
1125 TInt aStartIndex, |
|
1126 TInt& aEndIndex ) |
|
1127 { |
|
1128 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes()") )); |
|
1129 if ( aCharacter == '"' ) |
|
1130 { |
|
1131 if ( iParseInfo.iLimit < 0 ) // Only first the first '"' |
|
1132 { |
|
1133 iParseInfo.iLimit = aEndIndex - aStartIndex; |
|
1134 } |
|
1135 iDecodeInfo.iInQuotes ^= ETrue; // EFalse to ETrue or ETrue to EFalse |
|
1136 SaveFoundCharDecodeState( aCharacter, EFalse ); |
|
1137 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (quote) complete") )); |
|
1138 return ETrue; |
|
1139 } |
|
1140 // The next ones are those that are not in quotes. |
|
1141 // We still need to save the iParseInfo.iLimit and skip non-delimiter characters. |
|
1142 if ( aCharacter == '=' ) |
|
1143 { |
|
1144 if ( iParseInfo.iLimit < 0 ) // Only first the first '"' |
|
1145 { |
|
1146 iParseInfo.iLimit = aEndIndex - aStartIndex; |
|
1147 } |
|
1148 iDecodeInfo.iAssignFound = ETrue; |
|
1149 SaveFoundCharDecodeState( aCharacter, EFalse ); |
|
1150 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (equals) complete") )); |
|
1151 return ETrue; |
|
1152 } |
|
1153 if ( iDecodeInfo.iInQuotes ) |
|
1154 { |
|
1155 SaveNotFoundCharDecodeState(); |
|
1156 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (in quotes) complete") )); |
|
1157 return ETrue; |
|
1158 } |
|
1159 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandQuotes() (not found) complete") )); |
|
1160 return EFalse; |
|
1161 } |
|
1162 |
|
1163 // --------------------------------------------------------------------------- |
|
1164 // Check if in next subcommand's extended border |
|
1165 // --------------------------------------------------------------------------- |
|
1166 // |
|
1167 TBool CDunAtCmdHandler::IsExtendedBorder( TChar aCharacter, |
|
1168 TInt aStartIndex, |
|
1169 TInt& aEndIndex ) |
|
1170 { |
|
1171 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder()") )); |
|
1172 TInt expectedIndex = 0; // "+CMD" when iDecodeInfo.iFirstDecode is EFalse |
|
1173 TInt extendedIndex = aEndIndex - aStartIndex; // absolute index to the extended character |
|
1174 if ( iDecodeInfo.iFirstDecode ) |
|
1175 { |
|
1176 expectedIndex = 2; // "AT+CMD" |
|
1177 } |
|
1178 if ( extendedIndex == expectedIndex ) |
|
1179 { |
|
1180 iDecodeInfo.iExtendedIndex = aEndIndex; |
|
1181 SaveFoundCharDecodeState( aCharacter ); |
|
1182 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (no border) complete") )); |
|
1183 return EFalse; |
|
1184 } |
|
1185 aEndIndex--; |
|
1186 FTRACE(FPrint( _L("CDunAtCmdHandler::IsExtendedBorder() (border) complete") )); |
|
1187 return ETrue; |
|
1188 } |
|
1189 |
|
1190 // --------------------------------------------------------------------------- |
|
1191 // Finds subcommand with alphanumeric borders |
|
1192 // --------------------------------------------------------------------------- |
|
1193 // |
|
1194 TBool CDunAtCmdHandler::FindSubCommandAlphaBorder( TChar aCharacter, |
|
1195 TInt& aEndIndex ) |
|
1196 { |
|
1197 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder()") )); |
|
1198 if ( iDecodeInfo.iAssignFound && !iDecodeInfo.iInQuotes ) |
|
1199 { |
|
1200 // Check the special case when assigning a number with "basic" command |
|
1201 // and there is no delimiter after it. In this case <Numeric>|<Alpha> |
|
1202 // border must be detected but only for a "basic" command, not for |
|
1203 // extended. |
|
1204 if ( iDecodeInfo.iExtendedIndex<0 && iDecodeInfo.iPrevExists && |
|
1205 iDecodeInfo.iPrevChar.IsDigit() && aCharacter.IsAlpha() ) |
|
1206 { |
|
1207 aEndIndex--; |
|
1208 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (N|A) complete") )); |
|
1209 return ETrue; |
|
1210 } |
|
1211 // The code below is for the following type of cases: |
|
1212 // (do not check alphanumeric borders if "=" set without quotes): |
|
1213 // AT+CMD=a |
|
1214 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (skip) complete") )); |
|
1215 return EFalse; |
|
1216 } |
|
1217 if ( !iDecodeInfo.iPrevExists || !aCharacter.IsAlpha() ) |
|
1218 { |
|
1219 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (not found) complete") )); |
|
1220 return EFalse; |
|
1221 } |
|
1222 if ( iDecodeInfo.iPrevChar.IsAlpha() ) |
|
1223 { |
|
1224 // The check below detects the following type of cases |
|
1225 // (note that special handling is needed to separate the Alpha|Alpha boundary): |
|
1226 // AT&FE0 |
|
1227 if ( iDecodeInfo.iSpecialFound ) |
|
1228 { |
|
1229 // Special command was found before and this is Alpha|Alpha boundary -> end |
|
1230 aEndIndex--; |
|
1231 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (special) complete") )); |
|
1232 return ETrue; |
|
1233 } |
|
1234 // The code below is for the following type of cases |
|
1235 // (note there is no border between C|M, for example -> continue): |
|
1236 // ATCMD |
|
1237 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (continue) complete") )); |
|
1238 return EFalse; |
|
1239 } |
|
1240 // The code below is for skipping the following type of cases: |
|
1241 // AT+CMD [the '+' must be skipped] |
|
1242 if ( aEndIndex-1 == iDecodeInfo.iExtendedIndex ) |
|
1243 { |
|
1244 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (extended) complete") )); |
|
1245 return EFalse; |
|
1246 } |
|
1247 // The code below is for the following type of cases: |
|
1248 // ATCMD?ATCMD |
|
1249 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommandAlphaBorder() (boundary) complete") )); |
|
1250 aEndIndex--; |
|
1251 return ETrue; |
|
1252 } |
|
1253 |
|
1254 // --------------------------------------------------------------------------- |
|
1255 // Finds subcommand |
|
1256 // --------------------------------------------------------------------------- |
|
1257 // |
|
1258 TInt CDunAtCmdHandler::FindSubCommand( TInt aStartIndex, TInt& aEndIndex ) |
|
1259 { |
|
1260 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand()") )); |
|
1261 aEndIndex = aStartIndex; |
|
1262 TBool found = EFalse; |
|
1263 TInt length = iInputBuffer.Length(); |
|
1264 iDecodeInfo.iAssignFound = EFalse; |
|
1265 iDecodeInfo.iInQuotes = EFalse; |
|
1266 iDecodeInfo.iExtendedIndex = KErrNotFound; |
|
1267 SaveNotFoundCharDecodeState(); |
|
1268 iAtSpecialCmdHandler->ResetComparisonBuffer(); // just to be sure |
|
1269 for ( ; aEndIndex<length; aEndIndex++ ) |
|
1270 { |
|
1271 TChar character = iInputBuffer[aEndIndex]; |
|
1272 found = FindSubCommandQuotes( character, aStartIndex, aEndIndex ); |
|
1273 if ( found ) |
|
1274 { |
|
1275 continue; |
|
1276 } |
|
1277 if ( character == '?' ) |
|
1278 { |
|
1279 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (?) complete") )); |
|
1280 return KErrNone; |
|
1281 } |
|
1282 // The check below detects the following type of cases: |
|
1283 // ATCMD<delimiter> |
|
1284 if ( IsDelimiterCharacter(character) ) |
|
1285 { |
|
1286 aEndIndex--; |
|
1287 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (delimiter) complete") )); |
|
1288 return KErrNone; |
|
1289 } |
|
1290 // The check below detects the following type of cases: |
|
1291 // ATCMD+CMD [first + as delimiter] |
|
1292 // AT+CMD+CMD [second + as delimiter] |
|
1293 if ( IsExtendedCharacter(character) ) |
|
1294 { |
|
1295 found = IsExtendedBorder( character, aStartIndex, aEndIndex ); |
|
1296 if ( !found ) |
|
1297 { |
|
1298 continue; |
|
1299 } |
|
1300 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (extended) complete") )); |
|
1301 return KErrNone; |
|
1302 } |
|
1303 found = FindSubCommandAlphaBorder( character, aEndIndex ); |
|
1304 if ( found ) |
|
1305 { |
|
1306 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (alpha sub) complete") )); |
|
1307 return KErrNone; |
|
1308 } |
|
1309 SaveFoundCharDecodeState( character ); |
|
1310 } |
|
1311 aEndIndex--; |
|
1312 FTRACE(FPrint( _L("CDunAtCmdHandler::FindSubCommand() (not found) complete") )); |
|
1313 return KErrNotFound; |
|
1314 } |
|
1315 |
|
1316 // --------------------------------------------------------------------------- |
|
1317 // Check if "A/" command |
|
1318 // --------------------------------------------------------------------------- |
|
1319 // |
|
1320 TBool CDunAtCmdHandler::IsASlashCommand() |
|
1321 { |
|
1322 FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand()") )); |
|
1323 if ( iInputBuffer.Length() == 2 ) |
|
1324 { |
|
1325 if ( iInputBuffer[1] == '/' && |
|
1326 (iInputBuffer[0] == 'A' || iInputBuffer[0] == 'a') ) |
|
1327 { |
|
1328 FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (found) complete") )); |
|
1329 return ETrue; |
|
1330 } |
|
1331 } |
|
1332 FTRACE(FPrint( _L("CDunAtCmdHandler::IsASlashCommand() (not found) complete") )); |
|
1333 return EFalse; |
|
1334 } |
|
1335 |
|
1336 // --------------------------------------------------------------------------- |
|
1337 // Handles "A/" command |
|
1338 // --------------------------------------------------------------------------- |
|
1339 // |
|
1340 TBool CDunAtCmdHandler::HandleASlashCommand() |
|
1341 { |
|
1342 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand()") )); |
|
1343 // If not "A/" command, return |
|
1344 if ( !IsASlashCommand() ) |
|
1345 { |
|
1346 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (no push) complete") )); |
|
1347 return EFalse; |
|
1348 } |
|
1349 // If "A/" command and last buffer exist, set the last buffer as the current buffer |
|
1350 if ( iLastBuffer.Length() > 0 ) |
|
1351 { |
|
1352 iInputBuffer.Copy( iLastBuffer ); |
|
1353 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (copy) complete") )); |
|
1354 return EFalse; |
|
1355 } |
|
1356 // Last buffer not set so return "ERROR" if quiet mode not on |
|
1357 if ( iQuietOn ) |
|
1358 { |
|
1359 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() (quiet) complete") )); |
|
1360 return EFalse; |
|
1361 } |
|
1362 iDownstream->NotifyDataPushRequest( &iErrorBuffer, NULL ); |
|
1363 FTRACE(FPrint( _L("CDunAtCmdHandler::HandleASlashCommand() complete") )); |
|
1364 return ETrue; |
|
1365 } |
|
1366 |
|
1367 // --------------------------------------------------------------------------- |
|
1368 // Resets parse buffers |
|
1369 // --------------------------------------------------------------------------- |
|
1370 // |
|
1371 void CDunAtCmdHandler::ResetParseBuffers( TBool aClearInput ) |
|
1372 { |
|
1373 FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers()") )); |
|
1374 if ( aClearInput ) |
|
1375 { |
|
1376 iInputBuffer.Zero(); |
|
1377 } |
|
1378 iDecodeInfo.iFirstDecode = ETrue; |
|
1379 iDecodeInfo.iDecodeIndex = 0; |
|
1380 iDecodeInfo.iPrevExists = EFalse; |
|
1381 iDecodeInfo.iDecodeBuffer.Zero(); |
|
1382 FTRACE(FPrint( _L("CDunAtCmdHandler::ResetParseBuffers() complete") )); |
|
1383 } |
|
1384 |
|
1385 // --------------------------------------------------------------------------- |
|
1386 // Manages command mode change |
|
1387 // --------------------------------------------------------------------------- |
|
1388 // |
|
1389 TBool CDunAtCmdHandler::ManageCommandModeChange( TUint aMode ) |
|
1390 { |
|
1391 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange()" ) )); |
|
1392 if ( aMode & KCommandModeChanged ) |
|
1393 { |
|
1394 if ( aMode & KModeCommand ) // command mode ON |
|
1395 { |
|
1396 ReportCommandModeChange( ETrue ); |
|
1397 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() command mode changed ON" ) )); |
|
1398 } |
|
1399 else // command mode OFF |
|
1400 { |
|
1401 ReportCommandModeChange( EFalse ); |
|
1402 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() command mode changed OFF" ) )); |
|
1403 } |
|
1404 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange() (change) complete" ) )); |
|
1405 return ETrue; |
|
1406 } |
|
1407 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCommandModeChange()" ) )); |
|
1408 return EFalse; |
|
1409 } |
|
1410 |
|
1411 // --------------------------------------------------------------------------- |
|
1412 // Reports command mode start/end change |
|
1413 // --------------------------------------------------------------------------- |
|
1414 // |
|
1415 void CDunAtCmdHandler::ReportCommandModeChange( TBool aStart ) |
|
1416 { |
|
1417 FTRACE(FPrint( _L("CDunAtCmdHandler::ReportCommandModeChange()" ) )); |
|
1418 TInt i; |
|
1419 TInt count = iCmdCallbacks.Count(); |
|
1420 if ( aStart ) |
|
1421 { |
|
1422 if ( iDataMode ) |
|
1423 { |
|
1424 for ( i=0; i<count; i++ ) |
|
1425 { |
|
1426 iCmdCallbacks[i]->NotifyCommandModeStart(); |
|
1427 } |
|
1428 iDataMode = EFalse; |
|
1429 } |
|
1430 } |
|
1431 else // end |
|
1432 { |
|
1433 if ( !iDataMode ) |
|
1434 { |
|
1435 for ( i=0; i<count; i++ ) |
|
1436 { |
|
1437 iCmdCallbacks[i]->NotifyCommandModeEnd(); |
|
1438 } |
|
1439 iDataMode = ETrue; |
|
1440 } |
|
1441 } |
|
1442 FTRACE(FPrint( _L("CDunAtCmdHandler::ReportCommandModeChange() complete" ) )); |
|
1443 } |
|
1444 |
|
1445 // --------------------------------------------------------------------------- |
|
1446 // Manages echo mode change |
|
1447 // --------------------------------------------------------------------------- |
|
1448 // |
|
1449 TBool CDunAtCmdHandler::ManageEchoModeChange( TUint aMode ) |
|
1450 { |
|
1451 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange()" ) )); |
|
1452 if ( aMode & KEchoModeChanged ) |
|
1453 { |
|
1454 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() checking echo mode..." ) )); |
|
1455 if ( aMode & KModeEcho ) // echo mode ON |
|
1456 { |
|
1457 iEchoOn = ETrue; |
|
1458 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() echo mode changed ON" ) )); |
|
1459 } |
|
1460 else // echo mode OFF |
|
1461 { |
|
1462 iEchoOn = EFalse; |
|
1463 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() echo mode changed OFF" ) )); |
|
1464 } |
|
1465 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() (change) complete" ) )); |
|
1466 return ETrue; |
|
1467 } |
|
1468 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() complete" ) )); |
|
1469 return EFalse; |
|
1470 } |
|
1471 |
|
1472 // --------------------------------------------------------------------------- |
|
1473 // Manages quiet mode change |
|
1474 // --------------------------------------------------------------------------- |
|
1475 // |
|
1476 TBool CDunAtCmdHandler::ManageQuietModeChange( TUint aMode ) |
|
1477 { |
|
1478 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange()" ) )); |
|
1479 if ( aMode & KQuietModeChanged ) |
|
1480 { |
|
1481 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEchoModeChange() checking quiet mode..." ) )); |
|
1482 if ( aMode & KModeQuiet ) // quiet mode ON |
|
1483 { |
|
1484 iAtCmdExt.ReportQuietModeChange( ETrue ); |
|
1485 iQuietOn = ETrue; |
|
1486 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() quiet mode changed ON" ) )); |
|
1487 } |
|
1488 else // quiet mode OFF |
|
1489 { |
|
1490 iAtCmdExt.ReportQuietModeChange( EFalse ); |
|
1491 iQuietOn = EFalse; |
|
1492 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() quiet mode changed OFF" ) )); |
|
1493 } |
|
1494 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() (change) complete" ) )); |
|
1495 return ETrue; |
|
1496 } |
|
1497 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageQuietModeChange() complete" ) )); |
|
1498 return EFalse; |
|
1499 } |
|
1500 |
|
1501 // --------------------------------------------------------------------------- |
|
1502 // Manages quiet mode change |
|
1503 // --------------------------------------------------------------------------- |
|
1504 // |
|
1505 TBool CDunAtCmdHandler::ManageVerboseModeChange( TUint aMode ) |
|
1506 { |
|
1507 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange()" ) )); |
|
1508 if ( aMode & KVerboseModeChanged ) |
|
1509 { |
|
1510 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() checking verbose mode..." ) )); |
|
1511 if ( aMode & KModeVerbose ) // verbose mode ON |
|
1512 { |
|
1513 iAtCmdExt.ReportVerboseModeChange( ETrue ); |
|
1514 iVerboseOn = ETrue; |
|
1515 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyVerboseStatusChange() verbose mode changed ON" ) )); |
|
1516 } |
|
1517 else // verbose mode OFF |
|
1518 { |
|
1519 iAtCmdExt.ReportVerboseModeChange( EFalse ); |
|
1520 iVerboseOn = EFalse; |
|
1521 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyVerboseStatusChange() verbose mode changed OFF" ) )); |
|
1522 } |
|
1523 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() (change) complete" ) )); |
|
1524 return ETrue; |
|
1525 } |
|
1526 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageVerboseModeChange() complete" ) )); |
|
1527 return EFalse; |
|
1528 } |
|
1529 |
|
1530 // --------------------------------------------------------------------------- |
|
1531 // Manages character change |
|
1532 // --------------------------------------------------------------------------- |
|
1533 // |
|
1534 void CDunAtCmdHandler::ManageCharacterChange( TUint aMode ) |
|
1535 { |
|
1536 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange()" ) )); |
|
1537 if ( aMode & KCarriageChanged ) |
|
1538 { |
|
1539 iCarriageReturn = aMode & (KModeChanged-1); |
|
1540 iAtCmdExt.ReportCharacterChange( ECharTypeCarriage, iCarriageReturn ); |
|
1541 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() carriage return changed" ) )); |
|
1542 } |
|
1543 else if ( aMode & KLineFeedChanged ) |
|
1544 { |
|
1545 iLineFeed = aMode & (KModeChanged-1); |
|
1546 iAtCmdExt.ReportCharacterChange( ECharTypeLineFeed, iLineFeed ); |
|
1547 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() line feed changed" ) )); |
|
1548 } |
|
1549 else if ( aMode & KBackspaceChanged ) |
|
1550 { |
|
1551 iBackspace = aMode & (KModeChanged-1); |
|
1552 iAtCmdExt.ReportCharacterChange( ECharTypeBackspace, iBackspace ); |
|
1553 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() backspace changed" ) )); |
|
1554 } |
|
1555 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageCharacterChange() complete" ) )); |
|
1556 } |
|
1557 |
|
1558 // --------------------------------------------------------------------------- |
|
1559 // Manages editor mode reply |
|
1560 // --------------------------------------------------------------------------- |
|
1561 // |
|
1562 TInt CDunAtCmdHandler::ManageEditorModeReply( TBool aStart ) |
|
1563 { |
|
1564 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply()" ) )); |
|
1565 // Two modes possible here: |
|
1566 // 1) Sending data directly from DTE to DCE, i.e. no subsequent data in |
|
1567 // the input buffer -> Reissue read request from DTE. |
|
1568 // 2) Sending data from input buffer to DCE -> Do not reissue read request |
|
1569 // from DTE: send the data in a loop |
|
1570 // In summary: send data byte-by-byte in editor mode until end of input. |
|
1571 // When end of input notify CDunUpstream to reissue the read request. |
|
1572 TBool nextContentFound = FindNextContent( aStart ); |
|
1573 if ( !nextContentFound ) |
|
1574 { |
|
1575 iUpstream->NotifyEditorModeReply( aStart ); |
|
1576 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") )); |
|
1577 return KErrNone; |
|
1578 } |
|
1579 // In block mode end the block mode by sending <ESC> and hope it works. |
|
1580 iEscapeBuffer.Zero(); |
|
1581 iEscapeBuffer.Append( KDunEscape ); |
|
1582 iCmdPusher->IssueRequest( iEscapeBuffer, EFalse ); |
|
1583 FTRACE(FPrint( _L("CDunAtCmdHandler::ManageEditorModeReply() complete" ) )); |
|
1584 return KErrNone; |
|
1585 } |
|
1586 |
|
1587 // --------------------------------------------------------------------------- |
|
1588 // Finds the next content from the input data |
|
1589 // --------------------------------------------------------------------------- |
|
1590 // |
|
1591 TBool CDunAtCmdHandler::FindNextContent( TBool aStart ) |
|
1592 { |
|
1593 FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent()" ) )); |
|
1594 if ( !aStart ) |
|
1595 { |
|
1596 FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (skip) complete" ) )); |
|
1597 return iEditorModeInfo.iContentFound; |
|
1598 } |
|
1599 iEditorModeInfo.iContentFound = EFalse; |
|
1600 TInt foundCmdIndex = KErrNotFound; |
|
1601 TBool nextContentFound = ExtractNextDecodedCommand( ETrue ); // peek |
|
1602 if ( !nextContentFound ) |
|
1603 { |
|
1604 // Check the next subblock |
|
1605 foundCmdIndex = FindStartOfNextCommand(); |
|
1606 } |
|
1607 if ( !nextContentFound && foundCmdIndex<0 ) |
|
1608 { |
|
1609 FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() (not found) complete") )); |
|
1610 return EFalse; |
|
1611 } |
|
1612 iEditorModeInfo.iContentFound = ETrue; |
|
1613 FTRACE(FPrint( _L("CDunAtCmdHandler::FindNextContent() complete" ) )); |
|
1614 return ETrue; |
|
1615 } |
|
1616 |
|
1617 // --------------------------------------------------------------------------- |
|
1618 // From class MDunAtCmdPusher. |
|
1619 // Notifies about end of AT command processing. This is after all reply data |
|
1620 // for an AT command is multiplexed to the downstream. |
|
1621 // --------------------------------------------------------------------------- |
|
1622 // |
|
1623 TInt CDunAtCmdHandler::NotifyEndOfProcessing( TInt /*aError*/ ) |
|
1624 { |
|
1625 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing()" ) )); |
|
1626 TBool editorMode = iCmdPusher->EditorMode(); |
|
1627 if ( editorMode ) |
|
1628 { |
|
1629 ManageEditorModeReply( ETrue ); |
|
1630 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() (editor) complete" ) )); |
|
1631 return KErrNone; |
|
1632 } |
|
1633 HandleNextDecodedCommand(); |
|
1634 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfProcessing() complete" ) )); |
|
1635 return KErrNone; |
|
1636 } |
|
1637 |
|
1638 // --------------------------------------------------------------------------- |
|
1639 // From class MDunAtCmdPusher. |
|
1640 // Notifies about request to stop AT command handling for the rest of the |
|
1641 // command line data |
|
1642 // --------------------------------------------------------------------------- |
|
1643 // |
|
1644 TInt CDunAtCmdHandler::NotifyEndOfCmdLineProcessing() |
|
1645 { |
|
1646 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing()" ) )); |
|
1647 TInt retVal = Stop(); |
|
1648 ManageEndOfCmdHandling( ETrue, EFalse, ETrue ); |
|
1649 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEndOfCmdLineProcessing() complete" ) )); |
|
1650 return retVal; |
|
1651 } |
|
1652 |
|
1653 // --------------------------------------------------------------------------- |
|
1654 // From class MDunAtCmdPusher. |
|
1655 // Notifies about request to peek for the next command |
|
1656 // --------------------------------------------------------------------------- |
|
1657 // |
|
1658 TBool CDunAtCmdHandler::NotifyNextCommandPeekRequest() |
|
1659 { |
|
1660 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest()") )); |
|
1661 TBool extracted = ExtractNextDecodedCommand( ETrue ); |
|
1662 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyNextCommandPeekRequest() complete") )); |
|
1663 return extracted; |
|
1664 } |
|
1665 |
|
1666 // --------------------------------------------------------------------------- |
|
1667 // From class MDunAtCmdPusher. |
|
1668 // Notifies about editor mode reply |
|
1669 // --------------------------------------------------------------------------- |
|
1670 // |
|
1671 TInt CDunAtCmdHandler::NotifyEditorModeReply() |
|
1672 { |
|
1673 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply()") )); |
|
1674 TInt retVal = ManageEditorModeReply( EFalse ); |
|
1675 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyEditorModeReply() complete") )); |
|
1676 return retVal; |
|
1677 } |
|
1678 |
|
1679 // --------------------------------------------------------------------------- |
|
1680 // From class MDunAtEcomListen. |
|
1681 // Notifies about new plugin installation |
|
1682 // --------------------------------------------------------------------------- |
|
1683 // |
|
1684 TInt CDunAtCmdHandler::NotifyPluginInstallation( TUid& /*aPluginUid*/ ) |
|
1685 { |
|
1686 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation()" ) )); |
|
1687 CDunAtUrcHandler* urcHandler = NULL; |
|
1688 TRAPD( retTrap, urcHandler=AddOneUrcHandlerL() ); |
|
1689 if ( retTrap != KErrNone ) |
|
1690 { |
|
1691 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (trapped!) complete" ) )); |
|
1692 return retTrap; |
|
1693 } |
|
1694 TInt retTemp = urcHandler->IssueRequest(); |
|
1695 if ( retTemp != KErrNone ) |
|
1696 { |
|
1697 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (issuerequest) complete" ) )); |
|
1698 return retTemp; |
|
1699 } |
|
1700 TUid ownerUid = urcHandler->OwnerUid(); |
|
1701 iAtCmdExt.ReportListenerUpdateReady( ownerUid, EEcomTypeInstall ); |
|
1702 // As a last step recreate the special command data |
|
1703 retTemp = RecreateSpecialCommands(); |
|
1704 if ( retTemp != KErrNone ) |
|
1705 { |
|
1706 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() (recreate) complete" ) )); |
|
1707 return retTemp; |
|
1708 } |
|
1709 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginInstallation() complete" ) )); |
|
1710 return KErrNone; |
|
1711 } |
|
1712 |
|
1713 // --------------------------------------------------------------------------- |
|
1714 // From class MDunAtEcomListen. |
|
1715 // Notifies about existing plugin uninstallation |
|
1716 // --------------------------------------------------------------------------- |
|
1717 // |
|
1718 TInt CDunAtCmdHandler::NotifyPluginUninstallation( TUid& aPluginUid ) |
|
1719 { |
|
1720 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation()" ) )); |
|
1721 TInt i; |
|
1722 TInt count = iUrcHandlers.Count(); |
|
1723 for ( i=count-1; i>=0; i-- ) |
|
1724 { |
|
1725 TUid ownerUid = iUrcHandlers[i]->OwnerUid(); |
|
1726 if ( ownerUid == aPluginUid ) |
|
1727 { |
|
1728 delete iUrcHandlers[i]; |
|
1729 iUrcHandlers.Remove( i ); |
|
1730 iAtCmdExt.ReportListenerUpdateReady( ownerUid, |
|
1731 EEcomTypeUninstall ); |
|
1732 } |
|
1733 } |
|
1734 // As a last step recreate the special command data |
|
1735 TInt retTemp = RecreateSpecialCommands(); |
|
1736 if ( retTemp != KErrNone ) |
|
1737 { |
|
1738 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation() (recreate) complete" ) )); |
|
1739 return retTemp; |
|
1740 } |
|
1741 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyPluginUninstallation() complete" ) )); |
|
1742 return KErrNone; |
|
1743 } |
|
1744 |
|
1745 // --------------------------------------------------------------------------- |
|
1746 // From class MDunAtModeListen. |
|
1747 // Gets called on mode status change |
|
1748 // --------------------------------------------------------------------------- |
|
1749 // |
|
1750 TInt CDunAtCmdHandler::NotifyModeStatusChange( TUint aMode ) |
|
1751 { |
|
1752 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange()") )); |
|
1753 TBool commandModeSet = ManageCommandModeChange( aMode ); |
|
1754 TBool echoModeSet = ManageEchoModeChange( aMode ); |
|
1755 TBool quietModeSet = ManageQuietModeChange( aMode ); |
|
1756 TBool verboseModeSet = ManageVerboseModeChange( aMode ); |
|
1757 if ( quietModeSet || verboseModeSet ) |
|
1758 { |
|
1759 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn )); |
|
1760 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() (regenerate) mode set" ) )); |
|
1761 RegenerateReplyStrings(); |
|
1762 return KErrNone; |
|
1763 } |
|
1764 // Keep the following after "quietModeSet || verboseModeSet" in order to |
|
1765 // regenerate the reply also if two modes change at the same time |
|
1766 if ( commandModeSet || echoModeSet ) |
|
1767 { |
|
1768 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: E=%d, Q=%d, V=%d"), iEchoOn, iQuietOn, iVerboseOn )); |
|
1769 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() mode set" ) )); |
|
1770 return KErrNone; |
|
1771 } |
|
1772 ManageCharacterChange( aMode ); |
|
1773 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() new settings: CR=%u, LF=%u, BS=%u"), iCarriageReturn, iLineFeed, iBackspace )); |
|
1774 RegenerateReplyStrings(); |
|
1775 FTRACE(FPrint( _L("CDunAtCmdHandler::NotifyModeStatusChange() complete") )); |
|
1776 return KErrNone; |
|
1777 } |
|