Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*==================================================================================================
     18 
     19     Source Name: DMServerSession.cc
     20 
     21     General Description: Implementation of DMServerSession class.
     22 
     23 ==================================================================================================*/
     24 
     25 #include "dmServerSession.h"
     26 #include "dm_ua_handlecommand.h"
     27 #include "dm_tree_util.h"
     28 #include "xpl_dm_Manager.h"
     29 #include "xpl_dm_Notifications.h"
     30 #include "dmLockingHelper.h"
     31 
     32 #ifndef DM_NO_LOCKING
     33 #include "dmThreadQueue.h"
     34 #endif
     35 
     36 extern "C" {
     37 #include "xpt-b64.h"
     38 #include "stdio.h"
     39 }
     40 
     41 #include "xpl_Logger.h"
     42 
     43 extern int g_cancelSession;
     44 
     45 /*==================================================================================================
     46                                  SOURCE FUNCTIONS
     47 ==================================================================================================*/
     48 
     49 
     50 /*==================================================================================================
     51 FUNCTION        : DMServerSession::DMServerSession
     52 
     53 DESCRIPTION     : The class constructor.
     54 ARGUMENT PASSED : sml_ContentType
     55                   sml_EncodingType
     56 OUTPUT PARAMETER:
     57 RETURN VALUE    :
     58 IMPORTANT NOTES :
     59 
     60 ==================================================================================================*/
     61 DMServerSession::DMServerSession()
     62 {
     63 
     64     m_nSecState = DM_CLIENT_NO_SERVER_NO_AUTH;
     65 }
     66 
     67 
     68 
     69 
     70 /*==================================================================================================
     71 FUNCTION        : DMServerSession::ConnectServer
     72 
     73 DESCRIPTION     : The SessionStart() function calls this function to connect to the server.
     74                   The function will perform the following operations:
     75                   1) Get the DM account URI from the DM tree.
     76                   2) Call SYNCML_DM_TransportController::Connect() function to establish the DM
     77                      session clent/server connection.
     78 ARGUMENT PASSED : server_Id
     79 OUTPUT PARAMETER:
     80 RETURN VALUE    :
     81 IMPORTANT NOTES :
     82 
     83 ==================================================================================================*/
     84 SYNCML_DM_RET_STATUS_T
     85 DMServerSession::ConnectServer(CPCHAR pServerId)
     86 {
     87     SYNCML_DM_RET_STATUS_T  ret_stat = SYNCML_DM_SUCCESS;
     88     XPL_ADDR_TYPE_T         addressType = XPL_ADDR_DEFAULT;
     89     CPCHAR                  szDMAccRootPath = ::XPL_DM_GetEnv( SYNCML_DM_DMACC_ROOT_PATH );
     90     CPCHAR                  szServerIdNodeName = ::XPL_DM_GetEnv( SYNCML_DM_NODENAME_SERVERID );
     91 
     92 
     93      XPL_LOG_DM_SESS_Debug(("Entered DMServerSession::ConnectServer\n"));
     94 
     95     /* Get the current server ID's DM account URI */
     96     if ( !dmTreeObj.GetParentOfKeyValue (pServerId,
     97                                          szServerIdNodeName,
     98                                          szDMAccRootPath,
     99                                          clientServerCreds.pDMAccNodeName) )
    100     {
    101       XPL_LOG_DM_SESS_Error(("Cannot Get Parent for %s\n",szServerIdNodeName ));
    102       return SYNCML_DM_FAIL;
    103     }
    104 
    105     DMGetData oDataAddr, oDataAddrType, oDataPort, oData;
    106 
    107     ret_stat = dmTreeObj.GetDefAccountAddrInfo((CPCHAR)clientServerCreds.pDMAccNodeName,
    108                                                oDataAddr,
    109                                                oDataAddrType,
    110                                                oDataPort );
    111 
    112     if ( ret_stat != SYNCML_DM_SUCCESS )
    113     {
    114       XPL_LOG_DM_SESS_Error(("Cannot Get Account Address Info for %s\n",(CPCHAR)clientServerCreds.pDMAccNodeName ));
    115       return ret_stat;
    116     }
    117 
    118     if ( dmTreeObj.IsVersion_12()  )
    119     {
    120 	    // Get the value of the pbDMAccUri/PrefConRef node
    121 	    addressType = XPL_ADDR_HTTP;
    122 	    ret_stat = dmTreeObj.GetAccNodeValue((CPCHAR)clientServerCreds.pDMAccNodeName,
    123 	                                          DM_PREFCONREF,
    124 	                                          oData);
    125     }
    126     else
    127     {
    128            if ( oDataAddrType.getCharData() )
    129    		addressType = DmAtoi(oDataAddrType.getCharData());
    130 	    else
    131 	       addressType = XPL_ADDR_HTTP;
    132 
    133 	    if (  addressType != XPL_ADDR_HTTP && addressType != XPL_ADDR_WSP )
    134 			return SYNCML_DM_FAIL;
    135 
    136    	    ret_stat = dmTreeObj.GetAccNodeValue((CPCHAR)clientServerCreds.pDMAccNodeName,
    137 	                                          DM_CONREF,
    138 	                                          oData);
    139     }
    140 
    141     if ( ret_stat == SYNCML_DM_SUCCESS )
    142      { dmTreeObj.SetConRef(oData.getCharData());
    143       	ret_stat = m_oConnObject.Init(g_iDMWorkspaceSize,addressType,oData.getCharData());
    144     }
    145     else
    146         if ( ret_stat == SYNCML_DM_NOT_FOUND )
    147          { 	dmTreeObj.SetConRef(NULL);
    148          	ret_stat = m_oConnObject.Init(g_iDMWorkspaceSize,addressType,NULL);
    149          }
    150 
    151     XPL_LOG_DM_SESS_Debug (("Leaving DMServerSession::ConnectServer ret_stat=%d\n",ret_stat));
    152     return (ret_stat);
    153 }
    154 
    155 
    156 /*==================================================================================================
    157 FUNCTION        : DMServerSession::BuildSendPackageOne
    158 
    159 DESCRIPTION     : SessionStart function calls this function to build the DM package one and send it
    160                   to the server.
    161                   The function will perform the following operations:
    162                   1) Create the SYNCML_DM_BuildPackage object.
    163                   2) Build the package one document.
    164                   3) Send the package one to the Transport Binding.
    165 ARGUMENT PASSED : session_Direction
    166                   p_ParsedPk0
    167 OUTPUT PARAMETER:
    168 RETURN VALUE    : STYNCML_DM_SUCCES for success or SYNCML_DM_FAIL for failure
    169 IMPORTANT NOTES :
    170 
    171 
    172 ==================================================================================================*/
    173 SYNCML_DM_RET_STATUS_T
    174 DMServerSession::BuildSendPackageOne(CPCHAR pServerID, DmtSessionProp * pSessionProp)
    175 {
    176     XPL_LOG_DM_SESS_Debug (("Entering DMServerSession::BuildSendPackageOne serverId = %s\n", pServerID));
    177     SYNCML_DM_RET_STATUS_T  ret_stat = SYNCML_DM_SUCCESS;
    178     m_oPkgBuilder.Init(this);
    179 
    180 #ifndef DM_NO_LOCKING
    181     INT32 nLockID = 0;
    182     {
    183         DMLockingHelper oLock( 0, ".", pServerID,SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE);
    184         nLockID = oLock.GetID();
    185 
    186         if ( !oLock.IsLockedSuccessfully() )
    187         {
    188             return SYNCML_DM_FAIL;
    189         }
    190 
    191         ret_stat = m_oPkgBuilder.BuildPackageOne(pServerID, pSessionProp);
    192     }
    193 
    194     dmTreeObj.ReleaseLock( nLockID );
    195 #else
    196     ret_stat = m_oPkgBuilder.BuildPackageOne(pServerID, pSessionProp);
    197 #endif
    198     if ( ret_stat == SYNCML_DM_SUCCESS )
    199     {
    200         ret_stat = SendPackage();
    201     }
    202 
    203     return (ret_stat);
    204 }
    205 
    206 
    207 /*==================================================================================================
    208 FUNCTION        : DMServerSession::SessionStart
    209 
    210 DESCRIPTION     : The UserAgen::SessionStart calls this function after it creates MgmtSession object.
    211                   The function will perform the following operations:
    212                   1) Call SessionStart() to setup the DM tree.
    213                   2) Register the DM engine with the SYNCML toolkit.
    214                   3) Connect the client with the server.
    215                   4) Build and send the package one.
    216 ARGUMENT PASSED : p_SessionStart
    217 OUTPUT PARAMETER:
    218 RETURN VALUE    :
    219 IMPORTANT NOTES :
    220 
    221 
    222 ==================================================================================================*/
    223 SYNCML_DM_RET_STATUS_T
    224 DMServerSession::Start(CPCHAR pServerID,
    225                        DmtSessionProp * pSessionProp)
    226 {
    227     SYNCML_DM_RET_STATUS_T ret_stat;
    228     BOOLEAN bMoreMessage = TRUE;
    229 
    230     ret_stat = Init(pSessionProp->isWBXML());
    231     if ( ret_stat != SYNCML_DM_SUCCESS )
    232         return ret_stat;
    233 
    234     /* Register the DM engine with the SYNCML toolkit. */
    235     userData.pSessionMng = this;
    236     userData.pPkgBuilder = &m_oPkgBuilder;
    237     ret_stat = RegisterDmEngineWithSyncmlToolkit(&userData);
    238     if ( ret_stat != SYNCML_DM_SUCCESS )
    239     {
    240         XPL_LOG_DM_SESS_Debug(("Exiting: RegisterDmEngineWithSyncmlToolkit failed\n"));
    241         return (ret_stat);
    242     }
    243 
    244     /* Create connection between server and client */
    245     ret_stat = ConnectServer(pServerID);
    246     if (ret_stat != SYNCML_DM_SUCCESS)
    247     {
    248         XPL_LOG_DM_SESS_Error(("Cannot connect server\n"));
    249         return (ret_stat);
    250     }
    251 
    252     /* Remember the sessionDirection in case we have to resend the Alert.*/
    253     pSessionProp->generateSessionID();
    254     serverSessionId = pSessionProp->getSessionID();
    255 
    256 
    257     /* Build and send the package one to the Server. */
    258     ret_stat = BuildSendPackageOne(pServerID, pSessionProp);
    259     if (ret_stat != SYNCML_DM_SUCCESS)
    260         return (ret_stat);
    261 
    262     XPL_DM_NotifySessionProgress(TRUE);
    263 
    264     while (bMoreMessage == TRUE && g_cancelSession == 0)
    265     {
    266         /* Call the method to receive the package from the transport.*/
    267         ret_stat = RecvPackage();
    268         if (ret_stat != SYNCML_DM_SUCCESS)
    269         {
    270              XPL_DM_NotifySessionProgress(FALSE);
    271             return ret_stat;
    272         }
    273 
    274         /* Call the method to parse and handle the commands in the package.*/
    275         commandCount = 0;
    276 
    277  #ifndef DM_NO_LOCKING
    278         int nLockID = 0;
    279 
    280         {
    281            DMLockingHelper oLock( 0, ".", pServerID, SYNCML_DM_LOCK_TYPE_EXCLUSIVE, FALSE );
    282            nLockID = oLock.GetID();
    283 
    284            if ( !oLock.IsLockedSuccessfully() )
    285            {
    286                XPL_DM_NotifySessionProgress(FALSE);
    287                return SYNCML_DM_FAIL;
    288            }
    289 
    290            ret_stat = ParseMessage();
    291         }
    292 
    293         dmTreeObj.ReleaseLock( nLockID );
    294 #else
    295         ret_stat = ParseMessage();
    296 #endif
    297 
    298         if (ret_stat != SYNCML_DM_SUCCESS)
    299         {
    300             XPL_DM_NotifySessionProgress(FALSE);
    301             return ret_stat;
    302         }
    303 
    304         /* Check to see if we are passed the max retries */
    305         if (serverRetryCount > MAX_AUTH_RETRY || clientRetryCount > MAX_AUTH_RETRY)
    306         {
    307              XPL_DM_NotifySessionProgress(FALSE);
    308              return SYNCML_DM_SESSION_AUTH_FAIL;
    309         }
    310 
    311         /* Check to see if any operational commands were parsed.*/
    312         if ( commandCount != 0 && m_bSessionAborted == FALSE && g_cancelSession == 0)
    313         {
    314             ret_stat = SendPackage();
    315             if (ret_stat != SYNCML_DM_SUCCESS)
    316             {
    317                 XPL_DM_NotifySessionProgress(FALSE);
    318                 return ret_stat;
    319             }
    320         }
    321         else
    322         {
    323             /* End the DM Session.*/
    324             bMoreMessage = FALSE;
    325 
    326         }
    327     }
    328 
    329     XPL_DM_NotifySessionProgress(FALSE);
    330     return SYNCML_DM_SUCCESS;
    331 }
    332 
    333 
    334 /*==================================================================================================
    335 FUNCTION        : DMServerSession::SetURI
    336 
    337 DESCRIPTION     : The UserAgent::SetURI will call this function if receiving package set the
    338                   response URI to a new value.
    339                   The function will call Connection object to set the URI of the SyncML server
    340                   for HTTP/WSP.
    341 ARGUMENT PASSED : p_RespURI
    342 OUTPUT PARAMETER:
    343 RETURN VALUE    : SYNCML_DM_SUCCESS if success,
    344                   SYNCML_DM_FAIL if failed.
    345 IMPORTANT NOTES :
    346 
    347 
    348 ==================================================================================================*/
    349 SYNCML_DM_RET_STATUS_T
    350 DMServerSession::SetURI (const char *p_RespURI)
    351 {
    352     return m_oConnObject.SetURI(p_RespURI);
    353 }
    354 
    355 
    356 
    357 /*==================================================================================================
    358 FUNCTION        : DMServerSession::RecvPackage
    359 
    360 DESCRIPTION     : The UserAgent::TransportMsg will call this function when data is received
    361                   This function calls SYNCML_DM_Connection::Recv() to get the DM docuemnt from the
    362                   Transport.
    363 ARGUMENT PASSED :
    364 OUTPUT PARAMETER:
    365 RETURN VALUE    :
    366 IMPORTANT NOTES :
    367 
    368 
    369 ==================================================================================================*/
    370 SYNCML_DM_RET_STATUS_T
    371 DMServerSession::RecvPackage()
    372 {
    373     SYNCML_DM_RET_STATUS_T      serverAuthStatus = SYNCML_DM_SUCCESS;
    374     SYNCMLDM_SEC_CREDENTIALS_T  *pGenHmac;
    375     UINT8                       decodedNonce[MAX_BIN_NONCE_LEN];
    376     UINT32                      encodedNonceLen =0;
    377     UINT32                      decodedNonceLen =0;
    378     SYNCML_DM_RET_STATUS_T      retStat = SYNCML_DM_SUCCESS;
    379 
    380 
    381     pWritePos = recvSmlDoc.pData;
    382 
    383     /* Unlock the workspace so the Toolkit controls it again. */
    384     smlUnlockReadBuffer(sendInstanceId, workspaceUsedSize);
    385 
    386     /* Check if the HMAC-MD5 headers were included.*/
    387     if( m_oRecvCredHeaders.empty() == FALSE )
    388     {
    389         //XPL_LOG_DM_SESS_Debug(("m_oRecvCredHeaders is not empty.\n"));
    390         //XPL_LOG_DM_SESS_Debug(("m_oRecvCredHeaders: username:%s\n", (CPCHAR)(m_oRecvCredHeaders.m_oUserName.getBuffer())));
    391         //XPL_LOG_DM_SESS_Debug(("m_oRecvCredHeaders: mac:%s\n", (CPCHAR)(m_oRecvCredHeaders.m_oMac.getBuffer())));
    392 
    393         SYNCMLDM_HMAC_SEC_INFO_T    hmacSecInfo;
    394         // since server sends hmac, use hmac after that
    395         clientServerCreds.SetPrefServerAuth(SYNCML_DM_CHAL_HMAC);
    396 
    397          /* Remember that the Cred Headers are here.*/
    398         SetServCredsMissing(FALSE);
    399 
    400         /* Copy the received DM document into the SyncML workspace */
    401         /* Create the Server Credentials.*/
    402         hmacSecInfo.pb_user_name_or_server_id = (UINT8*)clientServerCreds.pServerId.c_str();
    403         hmacSecInfo.pb_password = (UINT8*)clientServerCreds.pServerPW.c_str();
    404         hmacSecInfo.o_encode_base64 = TRUE;         /* Always true for HMAC */
    405         hmacSecInfo.pb_syncml_document = pWritePos; /* Pointer for SyncML Doc */
    406         hmacSecInfo.dw_syncml_document_length = recvSmlDoc.dataSize; /* Size of Doc*/
    407 
    408          /* Validate the HMAC-MD5 header from the HTTP header.
    409           * We will check every message regardless of the Security state.
    410           * The ServerNonce string is b64 encoded and must be decoded now.*/
    411         if(clientServerCreds.pServerNonce != NULL)
    412         {
    413             encodedNonceLen = DmStrlen((const char *)clientServerCreds.pServerNonce);
    414             decodedNonceLen = base64Decode((unsigned char *)decodedNonce,
    415                                             MAX_BIN_NONCE_LEN,
    416                                             (unsigned char*)clientServerCreds.pServerNonce.c_str(),
    417                                             (unsigned long*)&encodedNonceLen);
    418         }
    419 
    420          /* Generate the Server Credentials.*/
    421         hmacSecInfo.pb_nonce = decodedNonce;
    422         hmacSecInfo.w_nonce_length = decodedNonceLen;
    423 
    424         pGenHmac = syncmldm_sec_build_hmac_cred((const SYNCMLDM_HMAC_SEC_INFO_T *)&hmacSecInfo);
    425 
    426          /* Compare the created creds to the received creds.*/
    427         if ( pGenHmac == NULL || !m_oRecvCredHeaders.m_oMac.compare((CPCHAR)pGenHmac->ab_credential_string,
    428                                                                      pGenHmac->w_credential_string_length) )
    429 
    430         {
    431              serverAuthStatus = SYNCML_DM_UNAUTHORIZED;
    432              serverRetryCount++;
    433         }
    434         else
    435         {
    436              /* Reset count since server is now authenticated.*/
    437              serverRetryCount = 0;
    438         }
    439         DmFreeMem(pGenHmac);
    440 
    441          /* Update the security state with the server authentication status. Note that
    442           * we only check for cases that cause a change in the SecurityState.
    443           */
    444          switch (m_nSecState)
    445          {
    446             case DM_CLIENT_NO_SERVER_NO_AUTH:
    447                 if (serverAuthStatus == SYNCML_DM_SUCCESS)
    448                     m_nSecState = DM_CLIENT_NO_SERVER_Y_AUTH;
    449                 break;
    450 
    451             case DM_CLIENT_Y_SERVER_NO_AUTH:
    452                 if (serverAuthStatus == SYNCML_DM_SUCCESS)
    453                     m_nSecState = DM_BOTH_CLIENT_SERVER_AUTH;
    454                 break;
    455 
    456             case DM_CLIENT_NO_SERVER_Y_AUTH:
    457                 if (serverAuthStatus != SYNCML_DM_SUCCESS)
    458                      m_nSecState = DM_CLIENT_NO_SERVER_NO_AUTH;
    459                 break;
    460 
    461             case DM_BOTH_CLIENT_SERVER_AUTH:
    462                 if (serverAuthStatus != SYNCML_DM_SUCCESS)
    463                     m_nSecState = DM_CLIENT_Y_SERVER_NO_AUTH;
    464                 break;
    465 
    466             default:
    467                 /* The Security State is messed up, so reset it.*/
    468                 m_nSecState = DM_CLIENT_NO_SERVER_NO_AUTH;
    469                 break;
    470          }
    471          /* Update the User Agent's security state.*/
    472 
    473     } /* p_cred_headers != NULL */
    474     else
    475     {
    476         /* The HMAC-MD5 creditials are missing.*/
    477         if ( !IsServerAuthorized() )
    478         {
    479             SetServCredsMissing(TRUE);
    480             serverRetryCount++;
    481         }
    482         else
    483             serverRetryCount = 0;
    484 
    485     }
    486 
    487     return(retStat);
    488 
    489 }
    490 
    491 
    492 /*==================================================================================================
    493 FUNCTION        : DMServerSession::SendPackage
    494 
    495 DESCRIPTION     : This function will be called when a DM package is built up and ready to send.
    496                   The function will call SYNCML_DM_Connection::Send() to send the DM document to
    497                   the remote server.
    498 ARGUMENT PASSED :
    499 OUTPUT PARAMETER:
    500 RETURN VALUE    :
    501 IMPORTANT NOTES : Both sendSmlDoc and pRecvSmlDoc must pass to pConnObject->Send. pConnObject will
    502                   write receiving DM document to the pRecvSmlDoc after it sends sendSmlDoc.
    503 
    504 
    505 ==================================================================================================*/
    506 SYNCML_DM_RET_STATUS_T
    507 DMServerSession::SendPackage()
    508 {
    509     SYNCMLDM_HMAC_SEC_INFO_T       hmacSecInfo;
    510     SYNCMLDM_SEC_CREDENTIALS_T    *pHmacCreds = NULL;
    511     SYNCML_DM_RET_STATUS_T         ret_stat;
    512     UINT8                          decodedNonce[MAX_BIN_NONCE_LEN];
    513     UINT32                         encodedNonceLen = 0;
    514     UINT32                         decodedNonceLen = 0;
    515     Ret_t                          sml_ret_stat;
    516 
    517      /* Lock the workspace for reading and writing SyncML document.
    518      * These buffers will be unlocked after the UA receives SyncML document */
    519     smlLockReadBuffer(sendInstanceId, &pReadPos, &workspaceUsedSize);
    520 
    521     /* Set sendSmlDoc point to workspace */
    522     sendSmlDoc.dataSize = workspaceUsedSize;
    523     sendSmlDoc.pData = pReadPos;
    524 
    525     /* The ClientNonce string is b64 encoded and must be decoded now.*/
    526     if(clientServerCreds.pClientNonce != NULL)
    527     {
    528         const char *clientNonce = clientServerCreds.pClientNonce.c_str();
    529         encodedNonceLen = DmStrlen(clientNonce);
    530         if (encodedNonceLen == 0) {
    531             clientNonce = SERVER_RESYNC_NONCE;
    532             encodedNonceLen = DmStrlen(clientNonce);
    533         }
    534         decodedNonceLen = base64Decode((UINT8*)decodedNonce,
    535                                        MAX_BIN_NONCE_LEN,
    536                                        (unsigned char*)clientNonce,
    537                                        (unsigned long*)&encodedNonceLen);
    538     }
    539     /* Let's make up our credentials before we send the package. */
    540     hmacSecInfo.pb_user_name_or_server_id = (UINT8*)clientServerCreds.pClientUserName.c_str();
    541     hmacSecInfo.pb_password = (UINT8*)clientServerCreds.pClientPW.c_str();
    542     hmacSecInfo.pb_nonce = decodedNonce;
    543     hmacSecInfo.pb_syncml_document = pReadPos; /* Used as the pointer to the SyncML Doc */
    544     hmacSecInfo.o_encode_base64 = TRUE;        /* Always true for HMAC credentials */
    545     hmacSecInfo.w_nonce_length = decodedNonceLen;
    546     hmacSecInfo.dw_syncml_document_length = workspaceUsedSize; /* Size of the SyncML Doc */
    547 
    548     if( clientServerCreds.AuthPrefCredType == SYNCML_DM_CHAL_HMAC )
    549 	    pHmacCreds = syncmldm_sec_build_hmac_cred((const SYNCMLDM_HMAC_SEC_INFO_T *)&hmacSecInfo);
    550 
    551     m_oRecvCredHeaders.clear();
    552     if ( pHmacCreds != NULL )
    553     {
    554         if ( pHmacCreds->w_credential_string_length )
    555         {
    556             m_oRecvCredHeaders.m_oMac.assign(pHmacCreds->ab_credential_string,pHmacCreds->w_credential_string_length);
    557             if ( m_oRecvCredHeaders.m_oMac.getBuffer() == NULL )
    558             {
    559                 FreeAndSetNull(pHmacCreds);
    560                 return SYNCML_DM_DEVICE_FULL;
    561             }
    562         }
    563 
    564         m_oRecvCredHeaders.m_oAlgorithm.assign(SYNCML_MAC_ALG);
    565         if ( m_oRecvCredHeaders.m_oAlgorithm.getBuffer() == NULL )
    566         {
    567             FreeAndSetNull(pHmacCreds);
    568             return SYNCML_DM_DEVICE_FULL;
    569         }
    570 
    571         if ( clientServerCreds.pClientUserName )
    572         {
    573             m_oRecvCredHeaders.m_oUserName.assign((CPCHAR)clientServerCreds.pClientUserName);
    574             if ( m_oRecvCredHeaders.m_oUserName.getBuffer() == NULL )
    575             {
    576                 FreeAndSetNull(pHmacCreds);
    577                 return SYNCML_DM_DEVICE_FULL;
    578             }
    579         }
    580     }
    581 
    582     sml_ret_stat = smlLockWriteBuffer(recvInstanceId, &pWritePos, &workspaceFreeSize);
    583 
    584     if ( sml_ret_stat == SML_ERR_OK )
    585     {
    586         recvSmlDoc.pData = pWritePos;
    587         ret_stat = m_oConnObject.Send(&sendSmlDoc, &recvSmlDoc, smlContentType, &m_oRecvCredHeaders);
    588     }
    589     else
    590         ret_stat = SYNCML_DM_FAIL;
    591 
    592     FreeAndSetNull(pHmacCreds);
    593     return (ret_stat);
    594 }
    595 
    596 
    597 /*==================================================================================================
    598 FUNCTION        : DMProcessScriptSession::SetServCredsMissing
    599 
    600 DESCRIPTION     : This function reset class data members value to defaults after one DM session is
    601                   ended.
    602 ARGUMENT PASSED :
    603 OUTPUT PARAMETER:
    604 RETURN VALUE    :
    605 IMPORTANT NOTES :
    606 
    607 ==================================================================================================*/
    608 void
    609 DMServerSession::SetServCredsMissing( BOOLEAN newIsServCredsMissing )
    610 {
    611    isServCredsMissing = newIsServCredsMissing;
    612 }
    613