bluetoothengine/btsap/src/BTSapMessage.cpp
changeset 0 f63038272f30
equal deleted inserted replaced
-1:000000000000 0:f63038272f30
       
     1 /*
       
     2 * Copyright (c) 2004 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: 
       
    15 *     This class handles SAP message encoding/decoding
       
    16 *
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "BTSapMessage.h"
       
    23 #include "debug.h"
       
    24 
       
    25 TBTSapMessage::TBTSapMessage()
       
    26     {
       
    27     }
       
    28 
       
    29 // ---------------------------------------------------------
       
    30 // SetMsgID
       
    31 // ---------------------------------------------------------
       
    32 void TBTSapMessage::SetMsgID(TMsgID aMsgID)
       
    33     {
       
    34     iData.Zero();
       
    35     // MsgID
       
    36     iData.Append(aMsgID);
       
    37     // para number
       
    38     iData.Append(0);
       
    39     // reserve
       
    40     iData.AppendFill(0, 2);
       
    41     }
       
    42 
       
    43 // ---------------------------------------------------------
       
    44 // MsgID
       
    45 // ---------------------------------------------------------
       
    46 TMsgID TBTSapMessage::MsgID()
       
    47     {
       
    48     return TMsgID(iData[KMsgIDOffset]);
       
    49     }
       
    50 
       
    51 void TBTSapMessage::AddParameter(TParaID aParaID, TInt aValue, TInt aLen)
       
    52     {
       
    53     if (aLen == 2)
       
    54         {
       
    55         TBuf8<KParaLenLen> value;
       
    56         value.Append(aValue >> 8);
       
    57         value.Append(aValue & 0xff);
       
    58         AddParameter(aParaID, value);
       
    59         }
       
    60     else
       
    61         {
       
    62         TUint8 value = (TUint8)aValue;
       
    63         AddParameter(aParaID, &value, 1);
       
    64         }
       
    65     }
       
    66 
       
    67 void TBTSapMessage::AddParameter(TParaID aParaID, const TDesC8& aValue)
       
    68     {
       
    69     AddParameter(aParaID, aValue.Ptr(), aValue.Length());
       
    70     }
       
    71 
       
    72 void TBTSapMessage::AddParameter(TParaID aParaID, const TUint8* aValue, TInt aLen)
       
    73     {
       
    74     // increase the number of parameters
       
    75     iData[KParaNumOffset] ++;
       
    76     //iData.Replace(1, 1, paraNum);
       
    77 
       
    78     // parameter ID
       
    79     iData.Append(aParaID);
       
    80     // reserve
       
    81     iData.AppendFill(0, KParaResvLen);
       
    82     // length
       
    83     //TUint16 paraLen = (TUint16)aLen;
       
    84     iData.Append(aLen >> 8); // high byte
       
    85     iData.Append(aLen & 0xff); // low byte
       
    86 
       
    87     // value
       
    88     iData.Append(aValue, aLen);
       
    89 
       
    90     //padding
       
    91     TInt reminder = aLen % KParaLenModulo;
       
    92     if (reminder > 0)
       
    93         {
       
    94         iData.AppendFill(0, KParaLenModulo - reminder);
       
    95         }
       
    96     }
       
    97 
       
    98 TInt TBTSapMessage::GetParameter(TParaID aParaID, TDes8& aValue)
       
    99     {
       
   100     TInt valuePos = 0;
       
   101     TInt valueLen = 0;
       
   102     TInt retVal = FindParameter(aParaID, valuePos, valueLen);
       
   103 
       
   104     if (retVal == KErrNone)
       
   105         {
       
   106         aValue.Copy(iData.Mid(valuePos, valueLen));
       
   107         }
       
   108 
       
   109     return retVal;
       
   110     }
       
   111 
       
   112 TInt TBTSapMessage::GetParameter(TParaID aParaID, TInt& aValue)
       
   113     {
       
   114     TInt valuePos = 0;
       
   115     TInt valueLen = 0;
       
   116     TInt retVal = FindParameter(aParaID, valuePos, valueLen);
       
   117 
       
   118     if (retVal == KErrNone)
       
   119         {
       
   120         if (valueLen == 1)
       
   121             {
       
   122             aValue = iData[valuePos];
       
   123             }
       
   124         else if (valueLen == 2)
       
   125             {
       
   126             aValue = (iData[valuePos] << 8) + iData[valuePos + 1];
       
   127             }
       
   128         else
       
   129             {
       
   130             retVal = KErrArgument;
       
   131             }
       
   132         }
       
   133 
       
   134     return retVal;
       
   135     }
       
   136 
       
   137 TInt TBTSapMessage::FindParameter(TParaID aParaID, TInt& aValuePos, TInt& aValueLen)
       
   138     {
       
   139     TInt retVal = KErrNotFound;
       
   140     TInt pos = KPayloadOffset;
       
   141     TInt valueLenPos = 0;
       
   142 
       
   143     while (pos < iData.Length())
       
   144         {
       
   145         valueLenPos = pos + KParaIDLen + KParaResvLen;
       
   146         aValueLen = iData[valueLenPos]  * 0xff + iData[valueLenPos + 1];
       
   147 
       
   148         if (iData[pos] == aParaID)
       
   149             {
       
   150             aValuePos = valueLenPos + KParaLenLen;
       
   151             retVal = KErrNone;
       
   152             break;
       
   153             }
       
   154 
       
   155         TInt paddingLen = (KParaLenModulo - (aValueLen % KParaLenModulo)) % KParaLenModulo;
       
   156         pos += KParaIDLen + KParaResvLen + KParaLenLen + aValueLen + paddingLen;
       
   157         }
       
   158 
       
   159     return retVal;
       
   160     }
       
   161 
       
   162 void TBTSapMessage::SetData(const TDes8& aData)
       
   163     {
       
   164     iData = aData;
       
   165     }
       
   166 
       
   167 TInt TBTSapMessage::AppendData(const TDes8& aData)
       
   168     {
       
   169     if ( iData.Length() + aData.Length() <= iData.MaxLength() )
       
   170         {
       
   171         iData.Append(aData);
       
   172         }
       
   173     else
       
   174         {
       
   175         return EInvalidSegmented;
       
   176         }
       
   177 
       
   178     return KErrNone;
       
   179     }
       
   180 
       
   181 void TBTSapMessage::Reset()
       
   182     {
       
   183     iData.Zero();
       
   184     }
       
   185 
       
   186 TBool TBTSapMessage::IsEmpty()
       
   187     {
       
   188     return (iData.Length() == 0);
       
   189     }
       
   190 
       
   191 TDes8& TBTSapMessage::Data()
       
   192     {
       
   193     return iData;
       
   194     }
       
   195 
       
   196 TValidationResult TBTSapMessage::Validate()
       
   197     {
       
   198     TValidationResult retVal = EInvalidUnknown;
       
   199     BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: IsValid: %d %d >>"), iData.Length(),  iData[KMsgIDOffset]));
       
   200 
       
   201     if (iData.Length() < KParaLenModulo || (iData.Length() % KParaLenModulo) > 0)
       
   202         {
       
   203         BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: short or /4 ***")));
       
   204         retVal = EInvalidSegmented;
       
   205         }
       
   206     else if (!IsValidRequestID(TMsgID(iData[KMsgIDOffset])))
       
   207         {
       
   208         BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: msgID wrong ***")));
       
   209         retVal = EInvalidMsgID;
       
   210         }
       
   211     else
       
   212         {
       
   213         TInt reserve = (iData[KParaNumOffset + 1] << 8) + iData[KParaNumOffset +2];
       
   214 
       
   215         if (reserve != KHeaderResvValue)
       
   216             {
       
   217             BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: header rsvd not 0 ***")));
       
   218             retVal = EInvalidReservedBytes;
       
   219             }
       
   220         else
       
   221             {
       
   222             TInt paraNum = GetParaNum();
       
   223             TInt pos = KPayloadOffset;
       
   224             TInt valueLenPos;
       
   225             TInt valueLen = 0;
       
   226             TInt i = 0;
       
   227 
       
   228             for (; i < paraNum; i ++)
       
   229                 {
       
   230                 if (pos >= iData.Length())
       
   231                     {
       
   232                     BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: paraNum big ***")));
       
   233                     retVal = EInvalidSegmented;
       
   234                     break;
       
   235                     }
       
   236                 else if (!IsValidParaID(TParaID(iData[pos]), TMsgID(iData[KMsgIDOffset])))
       
   237                     {
       
   238                     // parameter ID is out of range
       
   239                     BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: paraID wrong ***")));
       
   240                     retVal = EInvalidParameterID;
       
   241                     break;
       
   242                     }
       
   243                 else if (iData[pos + KParaResvLen] != KParaResvValue)
       
   244                     {
       
   245                     // reserved field is not equal to 0
       
   246                     BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: para rsvd not 0 ***")));
       
   247                     retVal = EInvalidReservedBytes;
       
   248                     break;
       
   249                     }
       
   250                 else
       
   251                     {
       
   252                     valueLenPos = pos + KParaIDLen + KParaResvLen;
       
   253                     valueLen = (iData[valueLenPos]  << 8) + iData[valueLenPos + 1];
       
   254                     pos = valueLenPos + KParaLenLen + valueLen;
       
   255 
       
   256                     if (pos > iData.Length())
       
   257                         {
       
   258                         BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: paraNum big ***")));
       
   259                         retVal = EInvalidSegmented;
       
   260                         break;
       
   261                         }
       
   262 
       
   263                     TInt paddingLen = (KParaLenModulo - (valueLen % KParaLenModulo)) % KParaLenModulo;
       
   264 
       
   265                     for (TInt k = 0; k < paddingLen; k ++)
       
   266                         {
       
   267                         if (iData[pos++] != KParaResvValue)
       
   268                             {
       
   269                             BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: padding not 0 ***")));
       
   270                             retVal = EInvalidPaddingBytes;
       
   271                             break;
       
   272                             }
       
   273                         }
       
   274                     }
       
   275                 }
       
   276 
       
   277             if (i == paraNum)
       
   278                 {
       
   279                 if (pos == iData.Length())
       
   280                     {
       
   281                     // no problem so far
       
   282                     retVal = EValidFormat;
       
   283                     }
       
   284                 else
       
   285                     {
       
   286                     BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap]  TBTSapMessage: paraNum small ***")));
       
   287                     retVal = EInvalidParaNumTooSmall;
       
   288                     }
       
   289                 }
       
   290 
       
   291             if(paraNum == 0)
       
   292                 {
       
   293                 // Check if the message needs a parameter
       
   294                 for(i = 0; i < sizeof(KMapParaID) / sizeof(KMapParaID[0]); i++)
       
   295                     {
       
   296                     if(KMapMsgID[i] == TMsgID(iData[KMsgIDOffset]))
       
   297                         {
       
   298                         retVal = EInvalidParaNumTooSmall;
       
   299                         break;
       
   300                         }
       
   301                     }
       
   302                 }
       
   303             }
       
   304         }
       
   305 
       
   306     return retVal;
       
   307     }
       
   308 
       
   309 TResultCode TBTSapMessage::ToResultCode(TInt aErrCode)
       
   310     {
       
   311     TUint size = sizeof(KMapErrCode) / sizeof(KMapErrCode[0]);
       
   312     TUint i = 0;
       
   313     for (; i < size; i++)
       
   314         {
       
   315         if (KMapErrCode[i] == aErrCode)
       
   316             {
       
   317             break;
       
   318             }
       
   319         }
       
   320 
       
   321     return (i < size ? KMapResultCode[i] : EResultCodeDataNotAvailable);
       
   322     }
       
   323 
       
   324 TBool TBTSapMessage::IsValidParaID(const TParaID aParaID, const TMsgID aMsgID) const
       
   325     {
       
   326     TUint size = sizeof(KMapParaID) / sizeof(KMapParaID[0]);
       
   327     TUint i = 0;
       
   328 
       
   329     for (; i < size; i++)
       
   330         {
       
   331         if (KMapParaID[i] == aParaID)
       
   332             {
       
   333             break;
       
   334             }
       
   335         }
       
   336 
       
   337     return (i < size ? KMapMsgID[i] == aMsgID : EFalse);
       
   338     }
       
   339 
       
   340 TBool TBTSapMessage::IsValidRequestID(const TMsgID aRequestID) const
       
   341     {
       
   342     TUint size = sizeof(KMapRequestID) / sizeof(KMapRequestID[0]);
       
   343     TUint i = 0;
       
   344 
       
   345     for (; i < size; i++)
       
   346         {
       
   347         if (KMapRequestID[i] == aRequestID)
       
   348             {
       
   349             break;
       
   350             }
       
   351         }
       
   352 
       
   353     return (i < size);
       
   354     }
       
   355 
       
   356 TUint8 TBTSapMessage::GetParaNum()
       
   357     {
       
   358     return iData[KParaNumOffset];
       
   359     }
       
   360 
       
   361 TInt TBTSapMessage::GetParaID(const TUint8 index, TParaID &aParaID)
       
   362     {
       
   363     TInt   retVal = KErrNotFound;
       
   364     TInt   pos = KPayloadOffset;
       
   365     TInt   valueLenPos = 0;
       
   366     TUint8 currentIndex = 0;
       
   367     TUint8 valueLen;
       
   368 
       
   369     while (pos < iData.Length())
       
   370         {
       
   371         valueLenPos = pos + KParaIDLen + KParaResvLen;
       
   372         valueLen = iData[valueLenPos]  * 0xff + iData[valueLenPos + 1];
       
   373 
       
   374         if (currentIndex == index)
       
   375             {
       
   376             aParaID = (TParaID) iData[pos];
       
   377             retVal = KErrNone;
       
   378             break;
       
   379             }
       
   380 
       
   381         TInt paddingLen = (KParaLenModulo - (valueLen % KParaLenModulo)) % KParaLenModulo;
       
   382         pos += KParaIDLen + KParaResvLen + KParaLenLen + valueLen + paddingLen;
       
   383         currentIndex++;
       
   384         }
       
   385 
       
   386     return retVal;
       
   387     }
       
   388 
       
   389 //  End of File