|
1 /* |
|
2 * Copyright (c) 2006 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: Parses/Encodes AT ccommands. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 #include <s32strm.h> |
|
22 #include "atcodec.h" |
|
23 #include "ATCodecDefs.h" |
|
24 #include "debug.h" |
|
25 |
|
26 const TUint KDelimiterComma = (TUint) ','; |
|
27 |
|
28 _LIT8(KDesEqualQuestion, "=?"); |
|
29 _LIT8(KDesEqual, "="); |
|
30 _LIT8(KDesQuestion, "?"); |
|
31 _LIT8(KDesSemicolon, ";"); |
|
32 _LIT8(KDesAT, "AT"); |
|
33 _LIT8(KDesColon, ": "); |
|
34 _LIT8(KDesComma, ","); |
|
35 |
|
36 _LIT8(KCRLFFormat, "\r\n%S\r\n"); |
|
37 const TInt KCRLFSize = 4; |
|
38 |
|
39 // ================= MEMBER FUNCTIONS ======================= |
|
40 |
|
41 // Destructor |
|
42 EXPORT_C CATBase::~CATBase() |
|
43 { |
|
44 TRACE_FUNC |
|
45 iText.Close(); |
|
46 iParamList.Close(); |
|
47 } |
|
48 |
|
49 // ----------------------------------------------------------------------------- |
|
50 // CATBase::Id |
|
51 // ----------------------------------------------------------------------------- |
|
52 // |
|
53 EXPORT_C TATId CATBase::Id() const |
|
54 { |
|
55 return iId; |
|
56 } |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // CATBase::Type |
|
60 // ----------------------------------------------------------------------------- |
|
61 // |
|
62 EXPORT_C TATType CATBase::Type() const |
|
63 { |
|
64 return iType; |
|
65 } |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // CATBase::ParamNum |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 EXPORT_C TInt CATBase::ParamNum() const |
|
72 { |
|
73 return iParamList.Count(); |
|
74 } |
|
75 |
|
76 // ----------------------------------------------------------------------------- |
|
77 // CATBase::Parameter |
|
78 // ----------------------------------------------------------------------------- |
|
79 // |
|
80 EXPORT_C TInt CATBase::Parameter(TInt aIndex, TATParam& aParam) const |
|
81 { |
|
82 if (aIndex < 0 || aIndex >= iParamList.Count()) |
|
83 { |
|
84 return KErrArgument; |
|
85 } |
|
86 aParam = iParamList[aIndex]; |
|
87 return KErrNone; |
|
88 } |
|
89 |
|
90 // ----------------------------------------------------------------------------- |
|
91 // CATBase::GetParameters |
|
92 // ----------------------------------------------------------------------------- |
|
93 // |
|
94 EXPORT_C const RATParamArray& CATBase::Parameters() const |
|
95 { |
|
96 return iParamList; |
|
97 } |
|
98 |
|
99 // ----------------------------------------------------------------------------- |
|
100 // CATBase::Des |
|
101 // ----------------------------------------------------------------------------- |
|
102 // |
|
103 EXPORT_C const TDesC8& CATBase::Des() const |
|
104 { |
|
105 return iText; |
|
106 } |
|
107 |
|
108 EXPORT_C void CATBase::ExternalizeL(RWriteStream& aStream) const |
|
109 { |
|
110 aStream << iText; |
|
111 aStream.WriteInt32L(KStreamVersion1); |
|
112 aStream.WriteInt32L(iId); |
|
113 aStream.WriteInt32L(iType); |
|
114 TInt count = iParamList.Count(); |
|
115 aStream.WriteInt32L(count); |
|
116 for (TInt i = 0; i < count; i++) |
|
117 { |
|
118 aStream << iParamList[i]; |
|
119 } |
|
120 } |
|
121 |
|
122 EXPORT_C void CATBase::InternalizeL(RReadStream& aStream) |
|
123 { |
|
124 TInt32 version = aStream.ReadInt32L(); |
|
125 |
|
126 if (version == KStreamVersion1) |
|
127 { |
|
128 iText.CreateL(KMaxATSize); |
|
129 aStream >> iText; |
|
130 iId = static_cast<TATId>(aStream.ReadInt32L()); |
|
131 iType = static_cast<TATType>(aStream.ReadInt32L()); |
|
132 TInt count = aStream.ReadInt32L(); |
|
133 for (TInt i = 0; i < count; i++) |
|
134 { |
|
135 TATParam param; |
|
136 aStream >> param; |
|
137 iParamList.AppendL(param); |
|
138 } |
|
139 } |
|
140 } |
|
141 |
|
142 // ---------------------------------------------------------------------------- |
|
143 // CATBase::CATBase |
|
144 // ---------------------------------------------------------------------------- |
|
145 // |
|
146 CATBase::CATBase() |
|
147 { |
|
148 TRACE_FUNC |
|
149 } |
|
150 |
|
151 |
|
152 void CATBase::Reset() |
|
153 { |
|
154 iId = EUnknownAT; |
|
155 iType = EATUnkownType; |
|
156 iText.Close(); |
|
157 iParamList.Reset(); |
|
158 } |
|
159 |
|
160 // ================= MEMBER FUNCTIONS ======================= |
|
161 |
|
162 // ----------------------------------------------------------------------------- |
|
163 // CATCommand::NewL |
|
164 // ----------------------------------------------------------------------------- |
|
165 // |
|
166 EXPORT_C CATCommand* CATCommand::NewL() |
|
167 { |
|
168 CATCommand* self = CATCommand::NewLC(); |
|
169 CleanupStack::Pop(self); |
|
170 return self; |
|
171 } |
|
172 |
|
173 // ----------------------------------------------------------------------------- |
|
174 // CATCommand::NewLC |
|
175 // ----------------------------------------------------------------------------- |
|
176 // |
|
177 EXPORT_C CATCommand* CATCommand::NewLC() |
|
178 { |
|
179 CATCommand* self = new (ELeave) CATCommand; |
|
180 CleanupStack::PushL(self); |
|
181 return self; |
|
182 } |
|
183 |
|
184 // ----------------------------------------------------------------------------- |
|
185 // CATCommand::NewL |
|
186 // ----------------------------------------------------------------------------- |
|
187 // |
|
188 EXPORT_C CATCommand* CATCommand::NewL(const TDesC8& aCmd) |
|
189 { |
|
190 CATCommand* self = CATCommand::NewLC(aCmd); |
|
191 CleanupStack::Pop(self); |
|
192 return self; |
|
193 } |
|
194 |
|
195 // ----------------------------------------------------------------------------- |
|
196 // CATCommand::NewLC |
|
197 // ----------------------------------------------------------------------------- |
|
198 // |
|
199 EXPORT_C CATCommand* CATCommand::NewLC(const TDesC8& aCmd) |
|
200 { |
|
201 CATCommand* self = new (ELeave) CATCommand; |
|
202 CleanupStack::PushL(self); |
|
203 TInt err = self->Set(aCmd); |
|
204 LEAVE_IF_ERROR(err); |
|
205 return self; |
|
206 } |
|
207 |
|
208 // ---------------------------------------------------------------------------- |
|
209 // CATCommand::Set |
|
210 // Only supports commands sent from BT audio accessory |
|
211 // ---------------------------------------------------------------------------- |
|
212 // |
|
213 EXPORT_C TInt CATCommand::Set(const TDesC8& aText) |
|
214 { |
|
215 TRACE_FUNC_ENTRY; |
|
216 TRACE_INFO((_L8("'%S'"), &aText)) |
|
217 Reset(); |
|
218 TInt err = Parse(aText); |
|
219 if (err) |
|
220 { |
|
221 TRACE_INFO((_L("ret %d"), err)) |
|
222 Reset(); |
|
223 } |
|
224 TRACE_FUNC_EXIT; |
|
225 return err; |
|
226 } |
|
227 |
|
228 // ---------------------------------------------------------------------------- |
|
229 // CATCommand::CATCommand |
|
230 // ---------------------------------------------------------------------------- |
|
231 // |
|
232 CATCommand::CATCommand() |
|
233 { |
|
234 TRACE_FUNC; |
|
235 Reset(); |
|
236 } |
|
237 |
|
238 // ---------------------------------------------------------------------------- |
|
239 // CATCommand::Parse |
|
240 // ---------------------------------------------------------------------------- |
|
241 // |
|
242 TInt CATCommand::Parse(const TDesC8& aText) |
|
243 { |
|
244 TRACE_FUNC; |
|
245 TInt err = iText.Create(aText); |
|
246 TRACE_INFO((_L("iText.Length(): %d"), iText.Length())); |
|
247 |
|
248 if (err != KErrNone) |
|
249 { |
|
250 return err; |
|
251 } |
|
252 |
|
253 iText.Trim(); |
|
254 TPtrC8 at(KDesAT); |
|
255 if (iText.FindF(at) == 0) |
|
256 { |
|
257 // Command AT |
|
258 if (iText.CompareF(at) == 0) |
|
259 { |
|
260 iId = EAT; |
|
261 iType = EATTestCmd; |
|
262 return KErrNone; |
|
263 } |
|
264 TPtrC8 x; |
|
265 x.Set(iText.Mid(at.Length())); |
|
266 for (TInt i = 0; i < KATNameTableSize; i++) |
|
267 { |
|
268 TPtrC8 name(KATNameTable[i].KName); |
|
269 if (x.FindF(name) == 0) |
|
270 { |
|
271 iId = KATNameTable[i].KId; |
|
272 TRACE_INFO((_L("ATId %d"), iId)) |
|
273 x.Set(x.Mid(name.Length())); |
|
274 ParseCommandType(x); |
|
275 TRACE_INFO((_L("ATType %d"), iType)) |
|
276 if (iType == EATWriteCmd || iType == EATActionCmd) |
|
277 { |
|
278 for (TInt j = 0; j < KCommandParamTableSize; j++) |
|
279 { |
|
280 if (iId == KCommandParamTable[j].KId && iType == KCommandParamTable[j].KType) |
|
281 { |
|
282 return ParseParams(x, 0, j); |
|
283 } |
|
284 } |
|
285 return x.Length(); |
|
286 } |
|
287 else |
|
288 { |
|
289 return x.Length(); |
|
290 } |
|
291 } |
|
292 } |
|
293 } |
|
294 return KErrArgument; |
|
295 } |
|
296 |
|
297 // ----------------------------------------------------------------------------- |
|
298 // CATCommand::ParseCommandType |
|
299 // ----------------------------------------------------------------------------- |
|
300 // |
|
301 void CATCommand::ParseCommandType(TPtrC8& aPtrC) |
|
302 { |
|
303 if (aPtrC.Find(KDesEqualQuestion) == 0) |
|
304 { |
|
305 aPtrC.Set(aPtrC.Mid(2)); |
|
306 iType = EATTestCmd; |
|
307 } |
|
308 else if (aPtrC.Find(KDesEqual) == 0) |
|
309 { |
|
310 aPtrC.Set(aPtrC.Mid(1)); |
|
311 iType = EATWriteCmd; |
|
312 } |
|
313 else if (aPtrC.Find(KDesQuestion) == 0) |
|
314 { |
|
315 aPtrC.Set(aPtrC.Mid(1)); |
|
316 iType = EATReadCmd; |
|
317 } |
|
318 else |
|
319 { |
|
320 iType = EATActionCmd; |
|
321 } |
|
322 } |
|
323 |
|
324 // ----------------------------------------------------------------------------- |
|
325 // CATCommand::ParseParamNum |
|
326 // ----------------------------------------------------------------------------- |
|
327 // |
|
328 TInt CATCommand::ParseParams(TPtrC8& aDes, TUint aParamIndex, TUint aTableIndex) |
|
329 { |
|
330 TInt ret = KErrNone; |
|
331 while( !(aParamIndex > KCommandParamTable[aTableIndex].KParamNum || |
|
332 aDes.Length() == 0 || aDes.Find(KDesSemicolon) == 0) ) |
|
333 { |
|
334 TBuf8<KMaxATParamSize> paramDes(aDes); |
|
335 TInt pos = aDes.Locate(KDelimiterComma); |
|
336 if (pos < 0) |
|
337 { |
|
338 pos = aDes.Find(KDesSemicolon); |
|
339 } |
|
340 if (pos > 0) |
|
341 { |
|
342 paramDes = aDes.Left(pos); |
|
343 } |
|
344 paramDes.Trim(); |
|
345 if (paramDes.Length()) |
|
346 { |
|
347 TATParamType type = EATNullParam; |
|
348 type = (TATParamType) KCommandParamTable[aTableIndex].KParamTypes[aParamIndex]; |
|
349 TATParam param; |
|
350 ret = param.SetValue(paramDes, type); |
|
351 if (ret) |
|
352 { |
|
353 break; |
|
354 } |
|
355 ret = iParamList.Append(param); |
|
356 if (ret) |
|
357 { |
|
358 break; |
|
359 } |
|
360 } |
|
361 if (pos == KErrNotFound || pos == aDes.Length() - 1) |
|
362 { |
|
363 break; |
|
364 } |
|
365 else |
|
366 { |
|
367 aDes.Set(aDes.Mid(++pos)); |
|
368 aParamIndex++; |
|
369 } |
|
370 } |
|
371 return ret; |
|
372 } |
|
373 |
|
374 // ================= MEMBER FUNCTIONS ======================= |
|
375 |
|
376 // ----------------------------------------------------------------------------- |
|
377 // CATResult::NewL |
|
378 // ----------------------------------------------------------------------------- |
|
379 // |
|
380 EXPORT_C CATResult* CATResult::NewL() |
|
381 { |
|
382 CATResult* self = CATResult::NewLC(); |
|
383 CleanupStack::Pop(self); |
|
384 return self; |
|
385 } |
|
386 |
|
387 // ----------------------------------------------------------------------------- |
|
388 // CATResult::NewLC |
|
389 // ----------------------------------------------------------------------------- |
|
390 // |
|
391 EXPORT_C CATResult* CATResult::NewLC() |
|
392 { |
|
393 CATResult* self = new (ELeave) CATResult; |
|
394 CleanupStack::PushL(self); |
|
395 return self; |
|
396 } |
|
397 |
|
398 // ----------------------------------------------------------------------------- |
|
399 // CATResult::NewL |
|
400 // ----------------------------------------------------------------------------- |
|
401 // |
|
402 EXPORT_C CATResult* CATResult::NewL(TATId aId, TATType aType, const RATParamArray* aParams) |
|
403 { |
|
404 CATResult* self = CATResult::NewLC(aId, aType, aParams); |
|
405 CleanupStack::Pop(self); |
|
406 return self; |
|
407 } |
|
408 |
|
409 // ----------------------------------------------------------------------------- |
|
410 // CATResult::NewLC |
|
411 // ----------------------------------------------------------------------------- |
|
412 // |
|
413 EXPORT_C CATResult* CATResult::NewLC(TATId aId, TATType aType, const RATParamArray* aParams) |
|
414 { |
|
415 CATResult* self = new (ELeave) CATResult; |
|
416 CleanupStack::PushL(self); |
|
417 TInt err = self->Set(aId, aType, aParams); |
|
418 LEAVE_IF_ERROR(err); |
|
419 return self; |
|
420 } |
|
421 |
|
422 // ----------------------------------------------------------------------------- |
|
423 // CATResult::NewL |
|
424 // ----------------------------------------------------------------------------- |
|
425 // |
|
426 EXPORT_C CATResult* CATResult::NewL(TATId aId, TATType aType, const TATParam aParam) |
|
427 { |
|
428 CATResult* self = CATResult::NewLC(aId, aType, aParam); |
|
429 CleanupStack::Pop(self); |
|
430 return self; |
|
431 } |
|
432 |
|
433 // ----------------------------------------------------------------------------- |
|
434 // CATResult::NewLC |
|
435 // ----------------------------------------------------------------------------- |
|
436 // |
|
437 EXPORT_C CATResult* CATResult::NewLC(TATId aId, TATType aType, const TATParam aParam) |
|
438 { |
|
439 CATResult* self = new (ELeave) CATResult; |
|
440 CleanupStack::PushL(self); |
|
441 RATParamArray array; |
|
442 TInt err = array.Append(aParam); |
|
443 if (!err) |
|
444 { |
|
445 err = self->Set(aId, aType, &array); |
|
446 } |
|
447 array.Close(); |
|
448 LEAVE_IF_ERROR(err); |
|
449 return self; |
|
450 } |
|
451 |
|
452 |
|
453 // ---------------------------------------------------------------------------- |
|
454 // CATResult::Set |
|
455 // Only supports result code sent from BT audio gateway |
|
456 // ---------------------------------------------------------------------------- |
|
457 // |
|
458 EXPORT_C TInt CATResult::Set(TATId aId, TATType aType, const RATParamArray* aParams) |
|
459 { |
|
460 TRACE_FUNC_ENTRY; |
|
461 Reset(); |
|
462 TInt err = Parse(aId, aType, aParams); |
|
463 if (err) |
|
464 { |
|
465 TRACE_INFO((_L("ret %d"), err)) |
|
466 Reset(); |
|
467 } |
|
468 else |
|
469 { |
|
470 AddCRLF(iText); |
|
471 } |
|
472 TRACE_FUNC_EXIT; |
|
473 return err; |
|
474 } |
|
475 |
|
476 // ---------------------------------------------------------------------------- |
|
477 // CATResult::CATResult |
|
478 // ---------------------------------------------------------------------------- |
|
479 // |
|
480 CATResult::CATResult() |
|
481 { |
|
482 TRACE_FUNC; |
|
483 Reset(); |
|
484 } |
|
485 |
|
486 // ---------------------------------------------------------------------------- |
|
487 // CATResult::Set |
|
488 // Only supports result code sent from BT audio gateway |
|
489 // ---------------------------------------------------------------------------- |
|
490 // |
|
491 TInt CATResult::Parse(TATId aId, TATType aType, const RATParamArray* aParams) |
|
492 { |
|
493 TRACE_FUNC |
|
494 TInt err = iText.Create(KMaxATSize); |
|
495 |
|
496 if (err != KErrNone) |
|
497 { |
|
498 return err; |
|
499 } |
|
500 |
|
501 TRACE_INFO((_L("ATId %d, ATType %d"), aId, aType)) |
|
502 for (TInt i = 0; i < KATNameTableSize; i++) |
|
503 { |
|
504 if (aId == KATNameTable[i].KId) |
|
505 { |
|
506 // Validate parameters |
|
507 for (TInt j = 0; j < KResultCodeParamTableSize; j++) |
|
508 { |
|
509 if (KResultCodeParamTable[j].KId == aId && KResultCodeParamTable[j].KType == aType) |
|
510 { |
|
511 if (!aParams || aParams->Count() < KResultCodeParamTable[j].KParamNum) |
|
512 { |
|
513 return KErrArgument; |
|
514 } |
|
515 else |
|
516 { |
|
517 for (TInt k = 0; k < KResultCodeParamTable[j].KParamNum; k++) |
|
518 { |
|
519 if ((*aParams)[k].Type() != KResultCodeParamTable[j].KParamTypes[k]) |
|
520 { |
|
521 return KErrArgument; |
|
522 } |
|
523 } |
|
524 } |
|
525 } |
|
526 } |
|
527 |
|
528 |
|
529 iId = aId; |
|
530 iType = aType; |
|
531 iText.Copy(KATNameTable[i].KName); |
|
532 if (aParams && aParams->Count()) |
|
533 { |
|
534 TPtrC8 colon(KDesColon); |
|
535 TPtrC8 comma(KDesComma); |
|
536 iText.Append(colon); |
|
537 for (TInt j = 0; j < aParams->Count(); j++) |
|
538 { |
|
539 TInt err = iParamList.Append((*aParams)[j]); |
|
540 if (err) |
|
541 { |
|
542 return err; |
|
543 } |
|
544 if (iText.Length() + (*aParams)[j].Des().Length() > KMaxATSize) |
|
545 { |
|
546 return KErrArgument; |
|
547 } |
|
548 iText.Append((*aParams)[j].Des()); |
|
549 if (j != aParams->Count() - 1) |
|
550 { |
|
551 if (iText.Length() + comma.Length() > KMaxATSize) |
|
552 { |
|
553 return KErrArgument; |
|
554 } |
|
555 iText.Append(KDelimiterComma); |
|
556 } |
|
557 } |
|
558 } |
|
559 return KErrNone; |
|
560 } |
|
561 } |
|
562 return KErrArgument; |
|
563 } |
|
564 |
|
565 |
|
566 TInt CATResult::AddCRLF(TDes8& aText) |
|
567 { |
|
568 if (aText.Length() + KCRLFSize > KMaxATSize) |
|
569 { |
|
570 return KErrOverflow; |
|
571 } |
|
572 TBuf8<KMaxATSize> buf(aText); |
|
573 aText.Format(KCRLFFormat, &buf); |
|
574 return KErrNone; |
|
575 } |
|
576 |
|
577 void ATCmdArrayResetAndDestroyAndClose(TAny* aPtr) |
|
578 { |
|
579 reinterpret_cast<RATResultPtrArray*>(aPtr)->ResetAndDestroy(); |
|
580 reinterpret_cast<RATResultPtrArray*>(aPtr)->Close(); |
|
581 } |
|
582 |
|
583 EXPORT_C void ATObjArrayCleanupResetAndDestroyPushL(RATResultPtrArray& aArray) |
|
584 { |
|
585 TCleanupItem item(ATCmdArrayResetAndDestroyAndClose, &aArray); |
|
586 CleanupStack::PushL(item); |
|
587 } |
|
588 |
|
589 |
|
590 // End of file |