diff -r 000000000000 -r f63038272f30 bluetoothengine/btsap/src/BTSapMessage.cpp --- /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 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