--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btmac/src/ATCodec/atccommand.cpp Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,590 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Parses/Encodes AT ccommands.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <s32strm.h>
+#include "atcodec.h"
+#include "ATCodecDefs.h"
+#include "debug.h"
+
+const TUint KDelimiterComma = (TUint) ',';
+
+_LIT8(KDesEqualQuestion, "=?");
+_LIT8(KDesEqual, "=");
+_LIT8(KDesQuestion, "?");
+_LIT8(KDesSemicolon, ";");
+_LIT8(KDesAT, "AT");
+_LIT8(KDesColon, ": ");
+_LIT8(KDesComma, ",");
+
+_LIT8(KCRLFFormat, "\r\n%S\r\n");
+const TInt KCRLFSize = 4;
+
+// ================= MEMBER FUNCTIONS =======================
+
+// Destructor
+EXPORT_C CATBase::~CATBase()
+ {
+ TRACE_FUNC
+ iText.Close();
+ iParamList.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CATBase::Id
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TATId CATBase::Id() const
+ {
+ return iId;
+ }
+
+// -----------------------------------------------------------------------------
+// CATBase::Type
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TATType CATBase::Type() const
+ {
+ return iType;
+ }
+
+// -----------------------------------------------------------------------------
+// CATBase::ParamNum
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CATBase::ParamNum() const
+ {
+ return iParamList.Count();
+ }
+
+// -----------------------------------------------------------------------------
+// CATBase::Parameter
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CATBase::Parameter(TInt aIndex, TATParam& aParam) const
+ {
+ if (aIndex < 0 || aIndex >= iParamList.Count())
+ {
+ return KErrArgument;
+ }
+ aParam = iParamList[aIndex];
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CATBase::GetParameters
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const RATParamArray& CATBase::Parameters() const
+ {
+ return iParamList;
+ }
+
+// -----------------------------------------------------------------------------
+// CATBase::Des
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CATBase::Des() const
+ {
+ return iText;
+ }
+
+EXPORT_C void CATBase::ExternalizeL(RWriteStream& aStream) const
+ {
+ aStream << iText;
+ aStream.WriteInt32L(KStreamVersion1);
+ aStream.WriteInt32L(iId);
+ aStream.WriteInt32L(iType);
+ TInt count = iParamList.Count();
+ aStream.WriteInt32L(count);
+ for (TInt i = 0; i < count; i++)
+ {
+ aStream << iParamList[i];
+ }
+ }
+
+EXPORT_C void CATBase::InternalizeL(RReadStream& aStream)
+ {
+ TInt32 version = aStream.ReadInt32L();
+
+ if (version == KStreamVersion1)
+ {
+ iText.CreateL(KMaxATSize);
+ aStream >> iText;
+ iId = static_cast<TATId>(aStream.ReadInt32L());
+ iType = static_cast<TATType>(aStream.ReadInt32L());
+ TInt count = aStream.ReadInt32L();
+ for (TInt i = 0; i < count; i++)
+ {
+ TATParam param;
+ aStream >> param;
+ iParamList.AppendL(param);
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CATBase::CATBase
+// ----------------------------------------------------------------------------
+//
+CATBase::CATBase()
+ {
+ TRACE_FUNC
+ }
+
+
+void CATBase::Reset()
+ {
+ iId = EUnknownAT;
+ iType = EATUnkownType;
+ iText.Close();
+ iParamList.Reset();
+ }
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CATCommand::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATCommand* CATCommand::NewL()
+ {
+ CATCommand* self = CATCommand::NewLC();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATCommand::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATCommand* CATCommand::NewLC()
+ {
+ CATCommand* self = new (ELeave) CATCommand;
+ CleanupStack::PushL(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATCommand::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATCommand* CATCommand::NewL(const TDesC8& aCmd)
+ {
+ CATCommand* self = CATCommand::NewLC(aCmd);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATCommand::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATCommand* CATCommand::NewLC(const TDesC8& aCmd)
+ {
+ CATCommand* self = new (ELeave) CATCommand;
+ CleanupStack::PushL(self);
+ TInt err = self->Set(aCmd);
+ LEAVE_IF_ERROR(err);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// CATCommand::Set
+// Only supports commands sent from BT audio accessory
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt CATCommand::Set(const TDesC8& aText)
+ {
+ TRACE_FUNC_ENTRY;
+ TRACE_INFO((_L8("'%S'"), &aText))
+ Reset();
+ TInt err = Parse(aText);
+ if (err)
+ {
+ TRACE_INFO((_L("ret %d"), err))
+ Reset();
+ }
+ TRACE_FUNC_EXIT;
+ return err;
+ }
+
+// ----------------------------------------------------------------------------
+// CATCommand::CATCommand
+// ----------------------------------------------------------------------------
+//
+CATCommand::CATCommand()
+ {
+ TRACE_FUNC;
+ Reset();
+ }
+
+// ----------------------------------------------------------------------------
+// CATCommand::Parse
+// ----------------------------------------------------------------------------
+//
+TInt CATCommand::Parse(const TDesC8& aText)
+ {
+ TRACE_FUNC;
+ TInt err = iText.Create(aText);
+ TRACE_INFO((_L("iText.Length(): %d"), iText.Length()));
+
+ if (err != KErrNone)
+ {
+ return err;
+ }
+
+ iText.Trim();
+ TPtrC8 at(KDesAT);
+ if (iText.FindF(at) == 0)
+ {
+ // Command AT
+ if (iText.CompareF(at) == 0)
+ {
+ iId = EAT;
+ iType = EATTestCmd;
+ return KErrNone;
+ }
+ TPtrC8 x;
+ x.Set(iText.Mid(at.Length()));
+ for (TInt i = 0; i < KATNameTableSize; i++)
+ {
+ TPtrC8 name(KATNameTable[i].KName);
+ if (x.FindF(name) == 0)
+ {
+ iId = KATNameTable[i].KId;
+ TRACE_INFO((_L("ATId %d"), iId))
+ x.Set(x.Mid(name.Length()));
+ ParseCommandType(x);
+ TRACE_INFO((_L("ATType %d"), iType))
+ if (iType == EATWriteCmd || iType == EATActionCmd)
+ {
+ for (TInt j = 0; j < KCommandParamTableSize; j++)
+ {
+ if (iId == KCommandParamTable[j].KId && iType == KCommandParamTable[j].KType)
+ {
+ return ParseParams(x, 0, j);
+ }
+ }
+ return x.Length();
+ }
+ else
+ {
+ return x.Length();
+ }
+ }
+ }
+ }
+ return KErrArgument;
+ }
+
+// -----------------------------------------------------------------------------
+// CATCommand::ParseCommandType
+// -----------------------------------------------------------------------------
+//
+void CATCommand::ParseCommandType(TPtrC8& aPtrC)
+ {
+ if (aPtrC.Find(KDesEqualQuestion) == 0)
+ {
+ aPtrC.Set(aPtrC.Mid(2));
+ iType = EATTestCmd;
+ }
+ else if (aPtrC.Find(KDesEqual) == 0)
+ {
+ aPtrC.Set(aPtrC.Mid(1));
+ iType = EATWriteCmd;
+ }
+ else if (aPtrC.Find(KDesQuestion) == 0)
+ {
+ aPtrC.Set(aPtrC.Mid(1));
+ iType = EATReadCmd;
+ }
+ else
+ {
+ iType = EATActionCmd;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CATCommand::ParseParamNum
+// -----------------------------------------------------------------------------
+//
+TInt CATCommand::ParseParams(TPtrC8& aDes, TUint aParamIndex, TUint aTableIndex)
+ {
+ TInt ret = KErrNone;
+ while( !(aParamIndex > KCommandParamTable[aTableIndex].KParamNum ||
+ aDes.Length() == 0 || aDes.Find(KDesSemicolon) == 0) )
+ {
+ TBuf8<KMaxATParamSize> paramDes(aDes);
+ TInt pos = aDes.Locate(KDelimiterComma);
+ if (pos < 0)
+ {
+ pos = aDes.Find(KDesSemicolon);
+ }
+ if (pos > 0)
+ {
+ paramDes = aDes.Left(pos);
+ }
+ paramDes.Trim();
+ if (paramDes.Length())
+ {
+ TATParamType type = EATNullParam;
+ type = (TATParamType) KCommandParamTable[aTableIndex].KParamTypes[aParamIndex];
+ TATParam param;
+ ret = param.SetValue(paramDes, type);
+ if (ret)
+ {
+ break;
+ }
+ ret = iParamList.Append(param);
+ if (ret)
+ {
+ break;
+ }
+ }
+ if (pos == KErrNotFound || pos == aDes.Length() - 1)
+ {
+ break;
+ }
+ else
+ {
+ aDes.Set(aDes.Mid(++pos));
+ aParamIndex++;
+ }
+ }
+ return ret;
+ }
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CATResult::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATResult* CATResult::NewL()
+ {
+ CATResult* self = CATResult::NewLC();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATResult::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATResult* CATResult::NewLC()
+ {
+ CATResult* self = new (ELeave) CATResult;
+ CleanupStack::PushL(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATResult::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATResult* CATResult::NewL(TATId aId, TATType aType, const RATParamArray* aParams)
+ {
+ CATResult* self = CATResult::NewLC(aId, aType, aParams);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATResult::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATResult* CATResult::NewLC(TATId aId, TATType aType, const RATParamArray* aParams)
+ {
+ CATResult* self = new (ELeave) CATResult;
+ CleanupStack::PushL(self);
+ TInt err = self->Set(aId, aType, aParams);
+ LEAVE_IF_ERROR(err);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATResult::NewL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATResult* CATResult::NewL(TATId aId, TATType aType, const TATParam aParam)
+ {
+ CATResult* self = CATResult::NewLC(aId, aType, aParam);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CATResult::NewLC
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CATResult* CATResult::NewLC(TATId aId, TATType aType, const TATParam aParam)
+ {
+ CATResult* self = new (ELeave) CATResult;
+ CleanupStack::PushL(self);
+ RATParamArray array;
+ TInt err = array.Append(aParam);
+ if (!err)
+ {
+ err = self->Set(aId, aType, &array);
+ }
+ array.Close();
+ LEAVE_IF_ERROR(err);
+ return self;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CATResult::Set
+// Only supports result code sent from BT audio gateway
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt CATResult::Set(TATId aId, TATType aType, const RATParamArray* aParams)
+ {
+ TRACE_FUNC_ENTRY;
+ Reset();
+ TInt err = Parse(aId, aType, aParams);
+ if (err)
+ {
+ TRACE_INFO((_L("ret %d"), err))
+ Reset();
+ }
+ else
+ {
+ AddCRLF(iText);
+ }
+ TRACE_FUNC_EXIT;
+ return err;
+ }
+
+// ----------------------------------------------------------------------------
+// CATResult::CATResult
+// ----------------------------------------------------------------------------
+//
+CATResult::CATResult()
+ {
+ TRACE_FUNC;
+ Reset();
+ }
+
+// ----------------------------------------------------------------------------
+// CATResult::Set
+// Only supports result code sent from BT audio gateway
+// ----------------------------------------------------------------------------
+//
+TInt CATResult::Parse(TATId aId, TATType aType, const RATParamArray* aParams)
+ {
+ TRACE_FUNC
+ TInt err = iText.Create(KMaxATSize);
+
+ if (err != KErrNone)
+ {
+ return err;
+ }
+
+ TRACE_INFO((_L("ATId %d, ATType %d"), aId, aType))
+ for (TInt i = 0; i < KATNameTableSize; i++)
+ {
+ if (aId == KATNameTable[i].KId)
+ {
+ // Validate parameters
+ for (TInt j = 0; j < KResultCodeParamTableSize; j++)
+ {
+ if (KResultCodeParamTable[j].KId == aId && KResultCodeParamTable[j].KType == aType)
+ {
+ if (!aParams || aParams->Count() < KResultCodeParamTable[j].KParamNum)
+ {
+ return KErrArgument;
+ }
+ else
+ {
+ for (TInt k = 0; k < KResultCodeParamTable[j].KParamNum; k++)
+ {
+ if ((*aParams)[k].Type() != KResultCodeParamTable[j].KParamTypes[k])
+ {
+ return KErrArgument;
+ }
+ }
+ }
+ }
+ }
+
+
+ iId = aId;
+ iType = aType;
+ iText.Copy(KATNameTable[i].KName);
+ if (aParams && aParams->Count())
+ {
+ TPtrC8 colon(KDesColon);
+ TPtrC8 comma(KDesComma);
+ iText.Append(colon);
+ for (TInt j = 0; j < aParams->Count(); j++)
+ {
+ TInt err = iParamList.Append((*aParams)[j]);
+ if (err)
+ {
+ return err;
+ }
+ if (iText.Length() + (*aParams)[j].Des().Length() > KMaxATSize)
+ {
+ return KErrArgument;
+ }
+ iText.Append((*aParams)[j].Des());
+ if (j != aParams->Count() - 1)
+ {
+ if (iText.Length() + comma.Length() > KMaxATSize)
+ {
+ return KErrArgument;
+ }
+ iText.Append(KDelimiterComma);
+ }
+ }
+ }
+ return KErrNone;
+ }
+ }
+ return KErrArgument;
+ }
+
+
+TInt CATResult::AddCRLF(TDes8& aText)
+ {
+ if (aText.Length() + KCRLFSize > KMaxATSize)
+ {
+ return KErrOverflow;
+ }
+ TBuf8<KMaxATSize> buf(aText);
+ aText.Format(KCRLFFormat, &buf);
+ return KErrNone;
+ }
+
+void ATCmdArrayResetAndDestroyAndClose(TAny* aPtr)
+ {
+ reinterpret_cast<RATResultPtrArray*>(aPtr)->ResetAndDestroy();
+ reinterpret_cast<RATResultPtrArray*>(aPtr)->Close();
+ }
+
+EXPORT_C void ATObjArrayCleanupResetAndDestroyPushL(RATResultPtrArray& aArray)
+ {
+ TCleanupItem item(ATCmdArrayResetAndDestroyAndClose, &aArray);
+ CleanupStack::PushL(item);
+ }
+
+
+// End of file