--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/btsap/src/BTSapMessage.cpp Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,389 @@
+/*
+* Copyright (c) 2004 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:
+* This class handles SAP message encoding/decoding
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include "BTSapMessage.h"
+#include "debug.h"
+
+TBTSapMessage::TBTSapMessage()
+ {
+ }
+
+// ---------------------------------------------------------
+// SetMsgID
+// ---------------------------------------------------------
+void TBTSapMessage::SetMsgID(TMsgID aMsgID)
+ {
+ iData.Zero();
+ // MsgID
+ iData.Append(aMsgID);
+ // para number
+ iData.Append(0);
+ // reserve
+ iData.AppendFill(0, 2);
+ }
+
+// ---------------------------------------------------------
+// MsgID
+// ---------------------------------------------------------
+TMsgID TBTSapMessage::MsgID()
+ {
+ return TMsgID(iData[KMsgIDOffset]);
+ }
+
+void TBTSapMessage::AddParameter(TParaID aParaID, TInt aValue, TInt aLen)
+ {
+ if (aLen == 2)
+ {
+ TBuf8<KParaLenLen> value;
+ value.Append(aValue >> 8);
+ value.Append(aValue & 0xff);
+ AddParameter(aParaID, value);
+ }
+ else
+ {
+ TUint8 value = (TUint8)aValue;
+ AddParameter(aParaID, &value, 1);
+ }
+ }
+
+void TBTSapMessage::AddParameter(TParaID aParaID, const TDesC8& aValue)
+ {
+ AddParameter(aParaID, aValue.Ptr(), aValue.Length());
+ }
+
+void TBTSapMessage::AddParameter(TParaID aParaID, const TUint8* aValue, TInt aLen)
+ {
+ // increase the number of parameters
+ iData[KParaNumOffset] ++;
+ //iData.Replace(1, 1, paraNum);
+
+ // parameter ID
+ iData.Append(aParaID);
+ // reserve
+ iData.AppendFill(0, KParaResvLen);
+ // length
+ //TUint16 paraLen = (TUint16)aLen;
+ iData.Append(aLen >> 8); // high byte
+ iData.Append(aLen & 0xff); // low byte
+
+ // value
+ iData.Append(aValue, aLen);
+
+ //padding
+ TInt reminder = aLen % KParaLenModulo;
+ if (reminder > 0)
+ {
+ iData.AppendFill(0, KParaLenModulo - reminder);
+ }
+ }
+
+TInt TBTSapMessage::GetParameter(TParaID aParaID, TDes8& aValue)
+ {
+ TInt valuePos = 0;
+ TInt valueLen = 0;
+ TInt retVal = FindParameter(aParaID, valuePos, valueLen);
+
+ if (retVal == KErrNone)
+ {
+ aValue.Copy(iData.Mid(valuePos, valueLen));
+ }
+
+ return retVal;
+ }
+
+TInt TBTSapMessage::GetParameter(TParaID aParaID, TInt& aValue)
+ {
+ TInt valuePos = 0;
+ TInt valueLen = 0;
+ TInt retVal = FindParameter(aParaID, valuePos, valueLen);
+
+ if (retVal == KErrNone)
+ {
+ if (valueLen == 1)
+ {
+ aValue = iData[valuePos];
+ }
+ else if (valueLen == 2)
+ {
+ aValue = (iData[valuePos] << 8) + iData[valuePos + 1];
+ }
+ else
+ {
+ retVal = KErrArgument;
+ }
+ }
+
+ return retVal;
+ }
+
+TInt TBTSapMessage::FindParameter(TParaID aParaID, TInt& aValuePos, TInt& aValueLen)
+ {
+ TInt retVal = KErrNotFound;
+ TInt pos = KPayloadOffset;
+ TInt valueLenPos = 0;
+
+ while (pos < iData.Length())
+ {
+ valueLenPos = pos + KParaIDLen + KParaResvLen;
+ aValueLen = iData[valueLenPos] * 0xff + iData[valueLenPos + 1];
+
+ if (iData[pos] == aParaID)
+ {
+ aValuePos = valueLenPos + KParaLenLen;
+ retVal = KErrNone;
+ break;
+ }
+
+ TInt paddingLen = (KParaLenModulo - (aValueLen % KParaLenModulo)) % KParaLenModulo;
+ pos += KParaIDLen + KParaResvLen + KParaLenLen + aValueLen + paddingLen;
+ }
+
+ return retVal;
+ }
+
+void TBTSapMessage::SetData(const TDes8& aData)
+ {
+ iData = aData;
+ }
+
+TInt TBTSapMessage::AppendData(const TDes8& aData)
+ {
+ if ( iData.Length() + aData.Length() <= iData.MaxLength() )
+ {
+ iData.Append(aData);
+ }
+ else
+ {
+ return EInvalidSegmented;
+ }
+
+ return KErrNone;
+ }
+
+void TBTSapMessage::Reset()
+ {
+ iData.Zero();
+ }
+
+TBool TBTSapMessage::IsEmpty()
+ {
+ return (iData.Length() == 0);
+ }
+
+TDes8& TBTSapMessage::Data()
+ {
+ return iData;
+ }
+
+TValidationResult TBTSapMessage::Validate()
+ {
+ TValidationResult retVal = EInvalidUnknown;
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: IsValid: %d %d >>"), iData.Length(), iData[KMsgIDOffset]));
+
+ if (iData.Length() < KParaLenModulo || (iData.Length() % KParaLenModulo) > 0)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: short or /4 ***")));
+ retVal = EInvalidSegmented;
+ }
+ else if (!IsValidRequestID(TMsgID(iData[KMsgIDOffset])))
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: msgID wrong ***")));
+ retVal = EInvalidMsgID;
+ }
+ else
+ {
+ TInt reserve = (iData[KParaNumOffset + 1] << 8) + iData[KParaNumOffset +2];
+
+ if (reserve != KHeaderResvValue)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: header rsvd not 0 ***")));
+ retVal = EInvalidReservedBytes;
+ }
+ else
+ {
+ TInt paraNum = GetParaNum();
+ TInt pos = KPayloadOffset;
+ TInt valueLenPos;
+ TInt valueLen = 0;
+ TInt i = 0;
+
+ for (; i < paraNum; i ++)
+ {
+ if (pos >= iData.Length())
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: paraNum big ***")));
+ retVal = EInvalidSegmented;
+ break;
+ }
+ else if (!IsValidParaID(TParaID(iData[pos]), TMsgID(iData[KMsgIDOffset])))
+ {
+ // parameter ID is out of range
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: paraID wrong ***")));
+ retVal = EInvalidParameterID;
+ break;
+ }
+ else if (iData[pos + KParaResvLen] != KParaResvValue)
+ {
+ // reserved field is not equal to 0
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: para rsvd not 0 ***")));
+ retVal = EInvalidReservedBytes;
+ break;
+ }
+ else
+ {
+ valueLenPos = pos + KParaIDLen + KParaResvLen;
+ valueLen = (iData[valueLenPos] << 8) + iData[valueLenPos + 1];
+ pos = valueLenPos + KParaLenLen + valueLen;
+
+ if (pos > iData.Length())
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: paraNum big ***")));
+ retVal = EInvalidSegmented;
+ break;
+ }
+
+ TInt paddingLen = (KParaLenModulo - (valueLen % KParaLenModulo)) % KParaLenModulo;
+
+ for (TInt k = 0; k < paddingLen; k ++)
+ {
+ if (iData[pos++] != KParaResvValue)
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: padding not 0 ***")));
+ retVal = EInvalidPaddingBytes;
+ break;
+ }
+ }
+ }
+ }
+
+ if (i == paraNum)
+ {
+ if (pos == iData.Length())
+ {
+ // no problem so far
+ retVal = EValidFormat;
+ }
+ else
+ {
+ BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] TBTSapMessage: paraNum small ***")));
+ retVal = EInvalidParaNumTooSmall;
+ }
+ }
+
+ if(paraNum == 0)
+ {
+ // Check if the message needs a parameter
+ for(i = 0; i < sizeof(KMapParaID) / sizeof(KMapParaID[0]); i++)
+ {
+ if(KMapMsgID[i] == TMsgID(iData[KMsgIDOffset]))
+ {
+ retVal = EInvalidParaNumTooSmall;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return retVal;
+ }
+
+TResultCode TBTSapMessage::ToResultCode(TInt aErrCode)
+ {
+ TUint size = sizeof(KMapErrCode) / sizeof(KMapErrCode[0]);
+ TUint i = 0;
+ for (; i < size; i++)
+ {
+ if (KMapErrCode[i] == aErrCode)
+ {
+ break;
+ }
+ }
+
+ return (i < size ? KMapResultCode[i] : EResultCodeDataNotAvailable);
+ }
+
+TBool TBTSapMessage::IsValidParaID(const TParaID aParaID, const TMsgID aMsgID) const
+ {
+ TUint size = sizeof(KMapParaID) / sizeof(KMapParaID[0]);
+ TUint i = 0;
+
+ for (; i < size; i++)
+ {
+ if (KMapParaID[i] == aParaID)
+ {
+ break;
+ }
+ }
+
+ return (i < size ? KMapMsgID[i] == aMsgID : EFalse);
+ }
+
+TBool TBTSapMessage::IsValidRequestID(const TMsgID aRequestID) const
+ {
+ TUint size = sizeof(KMapRequestID) / sizeof(KMapRequestID[0]);
+ TUint i = 0;
+
+ for (; i < size; i++)
+ {
+ if (KMapRequestID[i] == aRequestID)
+ {
+ break;
+ }
+ }
+
+ return (i < size);
+ }
+
+TUint8 TBTSapMessage::GetParaNum()
+ {
+ return iData[KParaNumOffset];
+ }
+
+TInt TBTSapMessage::GetParaID(const TUint8 index, TParaID &aParaID)
+ {
+ TInt retVal = KErrNotFound;
+ TInt pos = KPayloadOffset;
+ TInt valueLenPos = 0;
+ TUint8 currentIndex = 0;
+ TUint8 valueLen;
+
+ while (pos < iData.Length())
+ {
+ valueLenPos = pos + KParaIDLen + KParaResvLen;
+ valueLen = iData[valueLenPos] * 0xff + iData[valueLenPos + 1];
+
+ if (currentIndex == index)
+ {
+ aParaID = (TParaID) iData[pos];
+ retVal = KErrNone;
+ break;
+ }
+
+ TInt paddingLen = (KParaLenModulo - (valueLen % KParaLenModulo)) % KParaLenModulo;
+ pos += KParaIDLen + KParaResvLen + KParaLenLen + valueLen + paddingLen;
+ currentIndex++;
+ }
+
+ return retVal;
+ }
+
+// End of File