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     Header Name: dm_ua_handlecommand.cc
     20 
     21     General Description: Implementation of SyncML toolkit callback functions.
     22 
     23 ==================================================================================================*/
     24 
     25 #include "dmstring.h"
     26 #include "dmStringUtil.h"
     27 #include "dm_tree_util.h"
     28 #include "xpl_dm_Manager.h"
     29 #include "dm_ua_handlecommand.h"
     30 #include "dmProcessScriptSession.h"
     31 #include "dmServerSession.h"
     32 #include "dm_security.h"
     33 #include "dmLockingHelper.h"
     34 #include "SYNCML_DM_DisplayAlert.H"
     35 #include "SYNCML_DM_ConfirmAlert.H"
     36 #include "SYNCML_DM_TextInputAlert.H"
     37 #include "SYNCML_DM_SingleChoiceAlert.H"
     38 #include "SYNCML_DM_MultipleChoiceAlert.H"
     39 #include "xpl_Logger.h"
     40 
     41 #include "xlttags.h"
     42 
     43 extern "C" {
     44 #include "smlerr.h"
     45 #include "xpt-b64.h"
     46 }
     47 
     48 /*==================================================================================================
     49                                  TYPEDEFS
     50 ==================================================================================================*/
     51 /* Note that the order of this table MUST match the order of the SYNCML_DM_COMMAND_T enum in
     52  * syncml_dm_data_types.h
     53  */
     54 static const CPCHAR dm_command_name_table[] = {
     55   "", //SYNCML_DM_NO_COMMAND
     56   "Add",  //SYNCML_DM_ADD
     57   "Delete", //SYNCML_DM_DELETE
     58   "Replace",  //SYNCML_DM_REPLACE
     59   "Get",  //SYNCML_DM_GET
     60   "Rename", //SYNCML_DM_RENAME
     61   "Exec", //SYNCML_DM_EXEC
     62   "Copy", //SYNCML_DM_COPY
     63   "Alert",  //SYNCML_DM_ALERT
     64   "SyncHdr",  //SYNCML_DM_HEADER
     65   "Status", //SYNCML_DM_STATUS
     66   "Atomic", //SYNCML_DM_ATOMIC
     67   "Sequence" //SYNCML_DM_SEQUENCE
     68 };
     69 
     70 static SYNCML_DM_BuildPackage *pDmBuildPackage;
     71 static DMProcessScriptSession *pDmMgmtSessionObj;
     72 
     73 /* Since SyncHdr STATUS doesn't get constructed until the receiving package's STATUS command is
     74  * handled, we need to save synchdr_dm_stat when the starting message is handled. Keep it until
     75  * SyncHdr STATUS is constructed. */
     76 static SYNCML_DM_RET_STATUS_T synchdr_dm_stat = SYNCML_DM_SUCCESS;
     77 
     78 static SYNCML_DM_CHAL_TYPE_T s_nSrvSecLevel = SYNCML_DM_CHAL_UNDEFINED;
     79 
     80 /*==================================================================================================
     81                                  LOCAL FUNCTION PROTOTYPES
     82 ==================================================================================================*/
     83 
     84 
     85 /*==================================================================================================
     86                                      LOCAL FUNCTIONS
     87 ==================================================================================================*/
     88 static inline SYNCML_DM_RET_STATUS_T SyncML2DMCode( const char* szSyncMLCode )
     89 {
     90   SYNCML_DM_RET_STATUS_T  nRet = DmAtoi( szSyncMLCode );
     91 
     92   if ( nRet == 200 )
     93     return SYNCML_DM_SUCCESS;
     94 
     95   return nRet;
     96 }
     97 
     98 
     99 
    100 /*==================================================================================================
    101                                  FUNCTIONS
    102 ==================================================================================================*/
    103 
    104 /*==================================================================================================
    105 FUNCTION        : SetMetaData
    106 
    107 DESCRIPTION     : The utility function to set up the meta data.
    108 
    109 ARGUMENT PASSED : p_meta_info
    110 OUTPUT PARAMETER: pp_type
    111                   p_format
    112 RETURN VALUE    : SML_ERR_OK or ERR code
    113 IMPORTANT NOTES :
    114 
    115 
    116 ==================================================================================================*/
    117 SYNCML_DM_RET_STATUS_T SetMetaData(SmlPcdataPtr_t p_meta_data,
    118                                     DMBuffer& pp_type,
    119                                     SYNCML_DM_FORMAT_T *p_format)
    120 {
    121     SmlMetInfMetInfPtr_t p_meta_info;
    122     CPCHAR p_temp_content;
    123 
    124     /* Setup OUTPUT parameter type and format. If p_meta_data is not set, assign default value
    125        to OUTPUT parameters, type as "text/plain", format as "chr". */
    126     if (p_meta_data != NULL)
    127     {
    128         if (p_meta_data->content != NULL)
    129         {
    130             if ( SML_PCDATA_EXTENSION != p_meta_data->contentType &&
    131                  SML_EXT_METINF != p_meta_data->extension )
    132             {
    133                 *p_format = SYNCML_DM_FORMAT_CHR;
    134                 pp_type.assign("text/plain");
    135             }
    136             else
    137             {
    138                 p_meta_info = (SmlMetInfMetInfPtr_t)p_meta_data->content;
    139                 if ((p_meta_info->format != NULL) &&
    140                    (p_meta_info->format->length != 0))
    141                 {
    142                     p_temp_content = (CPCHAR)p_meta_info->format->content;
    143                     *p_format = DMTree::ConvertFormatStr(p_temp_content);
    144                 }
    145                 else
    146                 {
    147                     /* If there is no format information, set p_format as default format "chr" */
    148                     *p_format = SYNCML_DM_FORMAT_CHR;
    149                 }
    150                 /* Set p_temp_type to the passed in type */
    151                 if((p_meta_info->type != NULL) && (p_meta_info->type->length != 0))
    152                 {
    153                     pp_type.assign((UINT8*)p_meta_info->type->content,p_meta_info->type->length);
    154                 }
    155                 else
    156                 {
    157                     /* If there is no type information, set the type as 'text/plain' */
    158                     pp_type.assign("text/plain");
    159                 }
    160             }
    161         }
    162     }
    163     else
    164     {
    165         *p_format = SYNCML_DM_FORMAT_CHR;
    166         pp_type.assign("text/plain");
    167     }
    168 
    169     if ( pp_type.getBuffer() == NULL )
    170         return SYNCML_DM_DEVICE_FULL;
    171 
    172     return SYNCML_DM_SUCCESS;
    173 }
    174 
    175 
    176 /*==================================================================================================
    177 FUNCTION        : SetExecResultsData
    178 
    179 DESCRIPTION     : The utility function to set up the results data for Exec command.
    180 
    181 ARGUMENT PASSED : p_passedin_result_item. p_target_uri
    182                   p_exec_ret_data
    183 OUTPUT PARAMETER: p_passedin_result_item
    184 
    185 RETURN VALUE    : SML_ERR_OK or ERR code
    186 IMPORTANT NOTES :
    187 
    188 
    189 ==================================================================================================*/
    190 Ret_t
    191 SetExecResultsData(SmlItemPtr_t  p_passedin_result_item,
    192                CPCHAR pURI,
    193                const DMString & execResults)
    194 {
    195     Ret_t sml_ret_stat = SML_ERR_OK;
    196     char data_size_str[UINT32_TYPE_STR_SIZE_10];
    197 
    198 
    199     p_passedin_result_item->source = smlAllocSource();
    200     if ( p_passedin_result_item->source == NULL )
    201         return SYNCML_DM_FAIL;
    202 
    203     pDmBuildPackage->BuildPcData(p_passedin_result_item->source->locURI, SML_PCDATA_STRING,
    204                                        SML_EXT_UNDEFINED,DmStrlen(pURI),(UINT8*)pURI);
    205 
    206     /* Convert the dwRetDataSize to a string */
    207     DmSprintf(data_size_str, "%d", execResults.length());
    208     p_passedin_result_item->meta = smlAllocPcdata();
    209     if ( p_passedin_result_item->meta == NULL )
    210     {
    211         return SYNCML_DM_FAIL;
    212     }
    213 
    214 
    215         pDmBuildPackage->BuildMetaInfo(
    216             p_passedin_result_item->meta,
    217             NULL, NULL, NULL,
    218             (UINT8*)data_size_str,
    219             NULL, NULL, NULL, NULL);
    220 
    221     /* Set the p_passedin_result_item->data */
    222         /* Client construct <Data> element no matter there are data from GET command or not. */
    223         p_passedin_result_item->data = smlAllocPcdata();
    224         if ( p_passedin_result_item->data == NULL )
    225         {
    226             return SYNCML_DM_FAIL;
    227         }
    228 
    229         pDmBuildPackage->BuildPcData(p_passedin_result_item->data, SML_PCDATA_STRING,
    230                                            SML_EXT_UNDEFINED,execResults.length(),(UINT8*)execResults.c_str());
    231     return sml_ret_stat;
    232 }
    233 
    234 
    235 static SYNCML_DM_RET_STATUS_T SaveStatus(UINT8          *p_CmdRefData,
    236                                     UINT8          *p_CmdName,
    237                                     UINT8          *p_SourceRefData,
    238                                     UINT8          *p_TargetRefData,
    239                                     UINT16          status_Code,
    240                                     const DMStringVector*           responses,
    241                                     SYNCML_DM_USER_DATA_T   *pUserData )
    242 {
    243   SmlStatusPtr_t pStatus = pDmBuildPackage->AllocateStatus(
    244         p_CmdRefData, p_CmdName, p_SourceRefData, p_TargetRefData, NULL,
    245         status_Code, responses );
    246 
    247   if ( !pStatus )
    248     return SYNCML_DM_FAIL;
    249 
    250   pUserData->aStatuses.push_back((UINT32)pStatus);
    251   return SYNCML_DM_SUCCESS;
    252 }
    253 
    254 
    255 static SYNCML_DM_RET_STATUS_T
    256 SaveCommandRefStatus(UINT8  *p_CmdRefData,
    257                                     UINT8          *p_CmdName,
    258                                     SmlItemPtr_t  pCommandItem,
    259                                     SYNCML_DM_RET_STATUS_T   status_Code,
    260                                     SYNCML_DM_USER_DATA_T   *pUserData )
    261 {
    262 
    263   UINT8  *p_SourceRefData = NULL;
    264   UINT8  *p_TargetRefData = NULL;
    265   SmlStatusPtr_t pStatus = NULL;
    266 
    267   if(pCommandItem->target != NULL && pCommandItem->target->locURI != NULL)
    268         p_TargetRefData = (UINT8 *)pCommandItem->target->locURI->content;
    269   else
    270   {
    271        if ( status_Code == SYNCML_DM_SUCCESS )
    272                   status_Code = SYNCML_DM_BAD_REQUEST;
    273   }
    274 
    275   if (pCommandItem->source != NULL &&  pCommandItem->source->locURI != NULL)
    276        p_SourceRefData = (UINT8*)pCommandItem->source->locURI->content;
    277 
    278   return SaveStatus(p_CmdRefData,
    279                                  p_CmdName,
    280                                  p_SourceRefData,
    281                                  p_TargetRefData,
    282                                  status_Code,
    283                                  NULL,
    284                                  pUserData);
    285 
    286   if ( !pStatus )
    287     return SYNCML_DM_FAIL;
    288 
    289   pUserData->aStatuses.push_back((UINT32)pStatus);
    290   return SYNCML_DM_SUCCESS;
    291 }
    292 
    293 static SYNCML_DM_RET_STATUS_T SaveResult(CPCHAR pStrTargetUri,
    294                                           CPCHAR p_CmdIdRef,
    295                                           DMGetData *p_get_ret_data,
    296                                           BOOLEAN is_ThisGetStructResult,
    297                                           BOOLEAN isFirstGetStruct,
    298                                           BOOLEAN isThisGetPropResult,
    299                                           SYNCML_DM_USER_DATA_T   *pUserData,
    300                                           UINT8 type, // exec/get/getstruct
    301                                           const SYNCML_DM_GET_ON_LIST_RET_DATA_T& oGetStructData )
    302 {
    303   SmlResultsPtr_t  p_results = NULL;
    304   SmlPcdataPtr_t  p_data = NULL;
    305   SYNCML_DM_RET_STATUS_T nRes = SYNCML_DM_SUCCESS;
    306   CPCHAR p_target_uri = pStrTargetUri;
    307 
    308 #ifdef TNDS_SUPPORT
    309   SmlPcdata_t  pcData;
    310   if ( type == SYNCML_DM_RESULT_VALUE::Enum_Result_GetTnds )
    311   {
    312      p_target_uri = oGetStructData._pbURI;
    313      nRes = pDmBuildPackage->AllocateTndsResult(pStrTargetUri, p_get_ret_data, oGetStructData, &pcData);
    314      if ( nRes == SYNCML_DM_SUCCESS )
    315      {
    316         p_data = &pcData;
    317      }
    318   }
    319 #endif
    320 
    321   nRes = pDmBuildPackage->AllocateResult( p_results, p_target_uri,
    322                                           p_CmdIdRef, p_get_ret_data,
    323                                           is_ThisGetStructResult, isFirstGetStruct,
    324                                           isThisGetPropResult, NULL, p_data);
    325 
    326   if ( nRes != SYNCML_DM_SUCCESS )
    327   {
    328     if ( NULL != p_results )
    329     {
    330        smlFreeResults(p_results);
    331        p_results = NULL;
    332     }
    333     return nRes;
    334   }
    335 
    336   pUserData->aResults.push_back( SYNCML_DM_RESULT_VALUE( type, p_results,
    337                                                          oGetStructData, p_CmdIdRef,
    338                                                          (CPCHAR)pDmBuildPackage->GetMsgRef()) );
    339   return nRes;
    340 }
    341 
    342 static SYNCML_DM_RET_STATUS_T AtomicRollback (VoidPtr_t    userData)
    343 {
    344     SYNCML_DM_USER_DATA_T   *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
    345     SYNCML_DM_RET_STATUS_T retStatus=SYNCML_DM_FAIL;
    346 
    347     if( !pUserData->rollback )
    348     {
    349        retStatus = dmTreeObj.GetLockContextManager().ReleaseIDInternal( SYNCML_DM_LOCKID_CURRENT, SYNCML_DM_ROLLBACK);
    350 
    351         pUserData->pAtomicStatus.status = SYNCML_DM_ATOMIC_FAILED;
    352 
    353         if (retStatus != SYNCML_DM_SUCCESS)
    354           retStatus = SYNCML_DM_ATOMIC_ROLLBACK_FAILED;
    355         else
    356           retStatus = SYNCML_DM_ATOMIC_ROLLBACK_OK;
    357 
    358         for ( int i = 0; i <pUserData->oStatus.size(); i++ )
    359           pUserData->oStatus[i].status = retStatus;
    360 
    361         pUserData->rollback = TRUE;
    362     }
    363     return retStatus;
    364 }
    365 
    366 
    367 static void SequenceStatus(VoidPtr_t userData, SYNCML_DM_RET_STATUS_T status)
    368 {
    369     SYNCML_DM_USER_DATA_T  *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
    370 
    371     if ( pUserData->IsSequence() )
    372     {
    373         if ( status != SYNCML_DM_SUCCESS )
    374             pUserData->sequenceFailed = TRUE;
    375     }
    376 }
    377 
    378 static void  CheckAuthorization( SmlCredPtr_t pCred )
    379 {
    380   DMClientServerCreds *pClientServerCreds = pDmMgmtSessionObj->GetClientServerCreds();
    381   SmlMetInfMetInfPtr_t pMeta = NULL;
    382 
    383   // check default required level
    384   if ( s_nSrvSecLevel == SYNCML_DM_CHAL_UNDEFINED )
    385   {
    386     CPCHAR szStr = XPL_DM_GetEnv(SYNCML_DM_SECURITY_LEVEL);
    387     if ( !szStr )
    388       s_nSrvSecLevel = SYNCML_DM_CHAL_BASIC;
    389     else {
    390       s_nSrvSecLevel = DmAtoi(szStr);
    391 
    392       if ( s_nSrvSecLevel < SYNCML_DM_CHAL_NONE ||
    393         s_nSrvSecLevel > SYNCML_DM_CHAL_HMAC )
    394         s_nSrvSecLevel = SYNCML_DM_CHAL_BASIC;
    395     }
    396   }
    397 
    398   if ( pClientServerCreds->ServerChalType <= SYNCML_DM_CHAL_NONE )
    399     pClientServerCreds->SetPrefServerAuth(s_nSrvSecLevel);  // use default only  if it's not set yet
    400 
    401   if ( pClientServerCreds->ServerChalType == SYNCML_DM_CHAL_HMAC )
    402     return; // authorization performed in onStatus handler
    403 
    404   // if none - just authorize at once, but if server provides credentials - verify it
    405   if ( pClientServerCreds->ServerChalType == SYNCML_DM_CHAL_NONE )
    406     pDmMgmtSessionObj->SetSecStateSrv( TRUE );
    407 
    408   if ( !pCred || !pCred->data || !pCred->meta)
    409       return; // no credentials
    410 
    411   const char* szType = NULL;
    412   const char* szData = NULL;
    413 
    414   szData = (const char*)pCred->data->content;
    415 
    416   if ( pCred->meta->contentType == SML_PCDATA_EXTENSION &&
    417     pCred->meta->extension == SML_EXT_METINF ){
    418     pMeta = (SmlMetInfMetInfPtr_t)pCred->meta->content;
    419 
    420     if ( pMeta && pMeta->type && pMeta->type->contentType == SML_PCDATA_STRING )
    421       szType =  (const char*)pMeta->type->content;
    422   }
    423 
    424   if ( !szType || !szData )
    425     return;
    426 
    427   SYNCMLDM_SEC_CREDENTIALS_T  *pGenCred = NULL;
    428 
    429   if ( DmStrcmp(szType, SYNCML_AUTH_BASIC) == 0 )
    430   {
    431         if ( pClientServerCreds->ServerChalType > SYNCML_DM_CHAL_BASIC)
    432           return; // basic is not allowed
    433 
    434         pClientServerCreds->SetPrefServerAuth(SYNCML_DM_CHAL_BASIC);  // use basic after that for this session
    435 
    436         SYNCMLDM_BASIC_SEC_INFO_T   basicSecInfo;
    437 
    438         basicSecInfo.pb_password = (UINT8*)pClientServerCreds->pServerPW.c_str();
    439         basicSecInfo.pb_user_name_or_server_id = (UINT8*)pClientServerCreds->pServerId.c_str();
    440 
    441         pGenCred = syncmldm_sec_build_basic_cred(&basicSecInfo);
    442   }
    443   else
    444       if ( DmStrcmp(szType, SYNCML_AUTH_MD5) == 0 )
    445       {
    446             if ( pClientServerCreds->ServerChalType > SYNCML_DM_CHAL_MD5)
    447               return; // MD5 digest is not allowed
    448 
    449             pClientServerCreds->SetPrefServerAuth( SYNCML_DM_CHAL_MD5 );  // use MD5 after that for this session
    450 
    451             SYNCMLDM_MD5_SEC_INFO_T     md5SecInfo;
    452             UINT8                       decodedNonce[MAX_BIN_NONCE_LEN];
    453             UINT32                      encodedNonceLen;
    454             UINT32                      decodedNonceLen;
    455 
    456             /* The ClientNonce string is b64 encoded and must be decoded now.*/
    457             encodedNonceLen = DmStrlen((const char *)pClientServerCreds->pServerNonce);
    458             decodedNonceLen = base64Decode((unsigned char *)decodedNonce,
    459                                     MAX_BIN_NONCE_LEN,
    460                                     (unsigned char*)pClientServerCreds->pServerNonce.c_str(),
    461                                     (unsigned long*)&encodedNonceLen);
    462             md5SecInfo.pb_user_name_or_server_id = (UINT8*)pClientServerCreds->pServerId.c_str();
    463             md5SecInfo.pb_password = (UINT8*)pClientServerCreds->pServerPW.c_str();
    464             md5SecInfo.pb_nonce = decodedNonce;
    465             md5SecInfo.o_encode_base64 = FALSE;
    466             if ( pMeta->format )
    467                 md5SecInfo.o_encode_base64 = TRUE;
    468             md5SecInfo.w_nonce_length = decodedNonceLen;
    469 
    470             pGenCred = syncmldm_sec_build_md5_cred(&md5SecInfo);
    471       }
    472 
    473   if ( !pGenCred )
    474     return;
    475 
    476   if ( memcmp(szData, (const char*)pGenCred->ab_credential_string, pGenCred->w_credential_string_length) == 0 )
    477     pDmMgmtSessionObj->SetSecStateSrv( TRUE );
    478   else
    479     pDmMgmtSessionObj->SetSecStateSrv( FALSE );
    480 
    481   DmFreeMem(pGenCred);
    482 }
    483 
    484 /*==================================================================================================
    485 FUNCTION        : HandleEndMessage
    486 
    487 DESCRIPTION     : This method calls SyncML Toolkit smlEndMessage to add the Final element in the
    488                   SyncBody for the sending message.
    489 ARGUMENT PASSED : id
    490                   userData
    491                   final
    492 OUTPUT PARAMETER:
    493 RETURN VALUE    : SML_ERR_OK or ERR code
    494 IMPORTANT NOTES :
    495 
    496 
    497 ==================================================================================================*/
    498 
    499 Ret_t
    500 HandleEndMessage (InstanceID_t id,
    501                   VoidPtr_t    userData,
    502                   Boolean_t    final)
    503 {
    504   SYNCML_DM_USER_DATA_T   *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
    505   SYNCML_DM_RET_STATUS_T  ret_stat = SYNCML_DM_SUCCESS;
    506   BOOLEAN isLastChunk = FALSE;
    507 
    508  // Is session aborted?
    509  if( pDmMgmtSessionObj->IsSessionAborted())
    510          return SYNCML_DM_SUCCESS;
    511 
    512   // put cahced statuses (if any)
    513   while ( ret_stat == SYNCML_DM_SUCCESS && pUserData->aStatuses.size() > 0 ) {
    514     ret_stat = pDmBuildPackage->BuildStatus( (SmlStatusPtr_t)pUserData->aStatuses[0] );
    515     if ( ret_stat == SYNCML_DM_SUCCESS ){
    516       smlFreeStatus((SmlStatusPtr_t)pUserData->aStatuses[0]);
    517       pUserData->aStatuses.remove(0);
    518     }
    519   }
    520  // Large Object delivery
    521 #ifdef LOB_SUPPORT
    522 if( !pDmBuildPackage->LargeObjectSendNextChunk(ret_stat, isLastChunk))
    523 #endif
    524  {
    525 #ifdef LOB_SUPPORT
    526   if(ret_stat != SYNCML_DM_SUCCESS)
    527   {        pUserData->aResults.remove(0);
    528         isLastChunk = FALSE;
    529   }
    530 #endif
    531 
    532   // pur cached results
    533   while ( ret_stat == SYNCML_DM_SUCCESS && pUserData->aResults.size() > 0 ) {
    534         // Large Object delivery
    535 #ifdef LOB_SUPPORT
    536         if(!isLastChunk)
    537                 ret_stat =  pDmBuildPackage->LargeObjectSendFirstChunk(pUserData->aResults[0]);
    538         isLastChunk = FALSE;
    539 #else
    540     // try to insert result first
    541     ret_stat = pDmBuildPackage->BuildResultsCommand(pUserData->aResults[0]._pGetExecResult);
    542 #endif
    543     if ( ret_stat == SYNCML_DM_RESULTS_TOO_LARGE )
    544       break;
    545 #ifndef LOB_SUPPORT
    546     smlFreeResults( pUserData->aResults[0]._pGetExecResult ); pUserData->aResults[0]._pGetExecResult= NULL;
    547 #endif
    548 
    549     if ( pUserData->aResults[0]._type == SYNCML_DM_RESULT_VALUE::Enum_Result_GetStruct ||
    550         pUserData->aResults[0]._type == SYNCML_DM_RESULT_VALUE::Enum_Result_GetStructData )
    551     {
    552             ret_stat = dmTreeObj.GetListNextItem(pUserData->aResults[0]._oGetStructPos);
    553 
    554         if (ret_stat == SYNCML_DM_SUCCESS && pUserData->aResults[0]._oGetStructPos.psRetData ) {
    555             ret_stat = pDmBuildPackage->AllocateResult(
    556               pUserData->aResults[0]._pGetExecResult,
    557               pUserData->aResults[0]._oGetStructPos._pbURI,
    558               pUserData->aResults[0]._cmdRef,
    559               pUserData->aResults[0]._oGetStructPos.psRetData,
    560               pUserData->aResults[0]._type == SYNCML_DM_RESULT_VALUE::Enum_Result_GetStruct,
    561               FALSE, FALSE,
    562               pUserData->aResults[0]._msgID, NULL );
    563 
    564 
    565           delete pUserData->aResults[0]._oGetStructPos.psRetData;
    566           pUserData->aResults[0]._oGetStructPos.psRetData = NULL;
    567               if(ret_stat != SYNCML_DM_SUCCESS)
    568                       pUserData->aResults.remove(0);
    569 
    570           continue; // write more data
    571         }
    572     }
    573     pUserData->aResults.remove(0);
    574   }
    575 }
    576  pDmBuildPackage->EndSyncmlDoc( ret_stat != SYNCML_DM_RESULTS_TOO_LARGE );
    577  pDmBuildPackage->Cleanup();
    578 
    579   return SML_ERR_OK;
    580 }
    581 
    582 
    583 /*==================================================================================================
    584 FUNCTION        : VerifyProtocolVersion
    585 
    586 DESCRIPTION     :
    587 ARGUMENT PASSED : pContent
    588 OUTPUT PARAMETER:
    589 RETURN VALUE    : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL code
    590 IMPORTANT NOTES :
    591 
    592 
    593 ==================================================================================================*/
    594 SYNCML_DM_RET_STATUS_T
    595 VerifyProtocolVersion( SmlSyncHdrPtr_t pContent)
    596 {
    597         if ( dmTreeObj.IsVersion_12()  )
    598            {
    599            /* Verify that the presentation protocol is what we support. */
    600                 if (DmStrcmp((const char *)pContent->version->content, SYNCML_REP_PROTOCOL_VERSION_1_2) != 0)
    601                         return SYNCML_DM_FAIL;
    602                     /* Verify that the DM protocol is what we support. */
    603                   if (DmStrcmp((const char *)pContent->proto->content, SYNCML_DM_PROTOCOL_VERSION_1_2) != 0)
    604                          return SYNCML_DM_FAIL;
    605             }
    606             else
    607             {
    608                       /* Verify that the presentation protocol is what we support. */
    609                     if (DmStrcmp((const char *)pContent->version->content, SYNCML_REP_PROTOCOL_VERSION_1_1) != 0)
    610                         return SYNCML_DM_FAIL;
    611                 /* Verify that the DM protocol is what we support. */
    612                   if (DmStrcmp((const char *)pContent->proto->content, SYNCML_DM_PROTOCOL_VERSION_1_1) != 0)
    613                         return SYNCML_DM_FAIL;
    614        }
    615        return SYNCML_DM_SUCCESS;
    616 
    617 
    618 }
    619 
    620 /*==================================================================================================
    621 FUNCTION        : HandleStartMessage
    622 
    623 DESCRIPTION     : This function should analyze SyncHeader data from received DM document, and build
    624                   responding SyncML header.
    625 ARGUMENT PASSED : id
    626                   userData
    627                   pContent
    628 OUTPUT PARAMETER:
    629 RETURN VALUE    : SML_ERR_OK or ERR code
    630 IMPORTANT NOTES :
    631 
    632 
    633 ==================================================================================================*/
    634 Ret_t
    635 HandleStartMessage (InstanceID_t    id,
    636                     VoidPtr_t       userData,
    637                     SmlSyncHdrPtr_t pContent)
    638 {
    639 
    640     SYNCML_DM_RET_STATUS_T ret_stat;
    641     UINT32             temp_max_msg_size;
    642     SmlMetInfMetInfPtr_t p_temp_meta_info;
    643     DMString           strRespUri;
    644     UINT16             server_session_id;
    645     SYNCML_DM_USER_DATA_T *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
    646 
    647     /* Reset the synchdr_dm_stat for this message.*/
    648     synchdr_dm_stat = SYNCML_DM_SUCCESS;
    649 
    650     /* Get the Session Object.*/
    651     pDmMgmtSessionObj = pUserData->pSessionMng;
    652     pDmBuildPackage = pUserData->pPkgBuilder;
    653     // ignore session ID when processing XML script
    654     if(pDmMgmtSessionObj->IsProcessScript() == FALSE)
    655     {
    656         // Verify that this is the same session, hex string
    657        if(pDmBuildPackage->IsSessionId() == TRUE)
    658        {
    659          // Verify that this is the same session, hex string
    660          server_session_id = DmStrtol((const char *)pContent->sessionID->content, NULL, 16 );
    661        }
    662        else
    663        {
    664          // Verify that this is the same session, dec string
    665          server_session_id = DmStrtol((const char *)pContent->sessionID->content, NULL, 10 );
    666        }
    667 
    668         if (server_session_id != pDmMgmtSessionObj->GetServerSessionId())
    669         {
    670             smlFreeSyncHdr(pContent);
    671             return SML_ERR_XLT_INVAL_SYNCML_DOC;
    672         }
    673     }
    674 
    675     ret_stat = VerifyProtocolVersion(pContent);
    676     if ( ret_stat != SYNCML_DM_SUCCESS )
    677     {
    678             smlFreeSyncHdr(pContent);
    679              return SML_ERR_XLT_INVAL_SYNCML_DOC;
    680     }
    681 
    682     /* Create the BuildPackage object instance. */
    683     pDmBuildPackage->Init(pUserData->pSessionMng);
    684 
    685     /* If respURI exists, call transport API to set the URI. */
    686     if ((pContent->respURI != NULL) && (pContent->respURI->length != 0))
    687     {
    688         /* Copy over the response URI */
    689        strRespUri.assign((const char *)pContent->respURI->content,  pContent->respURI->length);
    690        if(strRespUri.Encode() == FALSE)
    691             synchdr_dm_stat = SYNCML_DM_PROCESSING_ERROR;
    692 
    693         /* Call the MgmtSessionObj to set the response URI */
    694        ret_stat = pDmMgmtSessionObj->SetURI(strRespUri.c_str() );
    695        if (ret_stat != SYNCML_DM_SUCCESS)
    696        {
    697             synchdr_dm_stat = SYNCML_DM_PROCESSING_ERROR;
    698        }
    699     }
    700 
    701     /* If the MaxMsgSize is sent by the server, when it's greater than our MaxMsgSize, don't need
    702        to do anything; if it's smaller than our MaxMsgSize, set our MaxMsgSize to the new value. */
    703     if ((pContent->meta != NULL) && (pContent->meta->content != NULL))
    704     {
    705         p_temp_meta_info = (SmlMetInfMetInfPtr_t)pContent->meta->content;
    706         if ((p_temp_meta_info->maxmsgsize != NULL) &&
    707             (p_temp_meta_info->maxmsgsize->length != 0))
    708         {
    709             temp_max_msg_size = DmAtoi((const char *)p_temp_meta_info->maxmsgsize->content);
    710             /* If the Server MaxMsgSize is smaller than what we have, reset our MaxMessageSize */
    711             if (temp_max_msg_size < pDmBuildPackage->GetMaxMessageSize())
    712             {
    713                 pDmBuildPackage->SetMaxMessageSize(temp_max_msg_size);
    714             }
    715         }
    716 #ifdef LOB_SUPPORT
    717         if ((p_temp_meta_info->maxobjsize != NULL) &&
    718                 (p_temp_meta_info->maxobjsize->length != 0))
    719         {
    720                 temp_max_msg_size = DmAtoi((const char *)p_temp_meta_info->maxobjsize->content);
    721                 /* If the Server MaxObjSize is smaller than what we have, reset our MaxObjectSize */
    722                 if (pDmBuildPackage->GetMaxObjectSize()==0 || temp_max_msg_size < pDmBuildPackage->GetMaxObjectSize())
    723                 {
    724                         pDmBuildPackage->SetMaxObjectSize(temp_max_msg_size);
    725                 }
    726         }
    727 #endif
    728     }
    729 
    730     /* Build up the SyncML document header */
    731     ret_stat = pDmBuildPackage->BuildStartSyncHdr(pContent,FALSE);
    732     if (ret_stat != SYNCML_DM_SUCCESS)
    733     {
    734         synchdr_dm_stat = SYNCML_DM_BAD_REQUEST;
    735         smlFreeSyncHdr(pContent);
    736         return SML_ERR_UNSPECIFIC;
    737     }
    738 
    739     CheckAuthorization( pContent->cred );
    740 
    741 
    742     if ( pDmMgmtSessionObj->IsServerAuthorized())
    743         pDmMgmtSessionObj->ResetServerRetryCount();
    744 
    745     if( pDmMgmtSessionObj->IsProcessScript() )
    746     {
    747        ret_stat = pDmBuildPackage->BuildFinishSyncHdr(SYNCML_DM_CHAL_NONE);
    748        if (ret_stat != SYNCML_DM_SUCCESS)
    749        {
    750          synchdr_dm_stat = SYNCML_DM_BAD_REQUEST;
    751          smlFreeSyncHdr(pContent);
    752          return SML_ERR_UNSPECIFIC;
    753        }
    754     }
    755     /* We need to check the source and target URI and set the dm_stat to the correct status before
    756        we free the pContent.*/
    757     if ((pContent->target->locURI == NULL) || (pContent->source->locURI == NULL) ||
    758         (pContent->target->locURI->length == 0) || (pContent->source->locURI->length == 0))
    759     {
    760         synchdr_dm_stat = SYNCML_DM_PERMISSION_FAILED;
    761     }
    762 
    763     /* Free the memory */
    764     smlFreeSyncHdr(pContent);
    765 
    766     return SML_ERR_OK;
    767 }
    768 
    769 
    770 
    771 /*==================================================================================================
    772 FUNCTION        : PrepareCommandItem
    773 
    774 DESCRIPTION     : Check if command should be skipped and decode item URI
    775 
    776 ARGUMENT PASSED :
    777                   userData
    778                   pContent
    779                   command
    780 OUTPUT PARAMETER:
    781 RETURN VALUE    : SML_ERR_OK or ERR code
    782 IMPORTANT NOTES :
    783 
    784 
    785 ==================================================================================================*/
    786 static SYNCML_DM_RET_STATUS_T
    787 PrepareCommandItem (SmlItemPtr_t  pCommandItem,
    788                                               SYNCML_DM_USER_DATA_T   *pUserData,
    789                                               DMString & strCommandUri )
    790 {
    791 
    792         BOOLEAN res;
    793 
    794          if ( pUserData->IsCommandSkipped() )
    795              return SYNCML_DM_NOT_EXECUTED;
    796 
    797        if ((pCommandItem->target == NULL) || (pCommandItem->target->locURI == NULL))
    798               return SYNCML_DM_BAD_REQUEST;
    799 
    800         res = strCommandUri.assign((CPCHAR)pCommandItem->target->locURI->content,
    801                                                     pCommandItem->target->locURI->length);
    802         if ( res == FALSE )
    803                 return SYNCML_DM_DEVICE_FULL;
    804 
    805        if(strCommandUri.Decode() == FALSE)
    806               return SYNCML_DM_BAD_REQUEST;
    807 
    808         return SYNCML_DM_SUCCESS;
    809 
    810 }
    811 
    812 /*==================================================================================================
    813 FUNCTION        : ProcessStatus
    814 
    815 DESCRIPTION     : Process status of operationd
    816 
    817 ARGUMENT PASSED :
    818                   userData
    819                   pContent
    820                   command
    821 OUTPUT PARAMETER:
    822 RETURN VALUE    : SML_ERR_OK or ERR code
    823 IMPORTANT NOTES :
    824 
    825 
    826 ==================================================================================================*/
    827 
    828 static SYNCML_DM_RET_STATUS_T
    829 ProcessStatus (SYNCML_DM_RET_STATUS_T dm_stat,
    830                               VoidPtr_t  userData,
    831                               UINT8  * p_CmdRefData,
    832                               SmlItemPtr_t  pCommandItem,
    833                               SYNCML_DM_COMMAND_T command)
    834 {
    835 
    836        SYNCML_DM_USER_DATA_T *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
    837         SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
    838 
    839        if ( pCommandItem == NULL )
    840                    return SYNCML_DM_FAIL;
    841 
    842 
    843         UINT8 *pTargetURL = NULL;
    844     //Fix for Upmerge CR# LIBoo12975
    845      if((pCommandItem->target != NULL) && (pCommandItem->target->locURI != NULL))
    846      {
    847       if(command == SYNCML_DM_GET)
    848       {
    849         DMString strTargetEncode;
    850         strTargetEncode = DMString((const char *)pCommandItem->target->locURI->content, (int)pCommandItem->target->locURI->length);
    851            if(strTargetEncode.Encode() == FALSE)
    852            {
    853             return SYNCML_DM_FAIL;
    854            }
    855          pTargetURL  = (UINT8 *)strTargetEncode.c_str();
    856       }
    857       else
    858       {
    859           pTargetURL = (UINT8 *)pCommandItem->target->locURI->content;
    860       }
    861      }
    862 
    863         UINT8* pSourceURL = NULL;
    864         pSourceURL = (UINT8*)(pCommandItem->source != NULL ? pCommandItem->source->locURI->content : NULL);
    865 
    866        if( pDmMgmtSessionObj->GetInAtomicCommand() )
    867        {
    868 #ifdef DM_ATOMIC_SUPPORTED
    869              // Save the data for the status and results
    870              if(dm_stat != SYNCML_DM_SUCCESS &&  !pUserData->rollback)
    871                   AtomicRollback(userData);
    872 #endif
    873               pUserData->oStatus.push_back( SYNCML_DM_STATUS_DATA_T(
    874                                                                      (CPCHAR)p_CmdRefData,
    875                                                                      dm_command_name_table[command],
    876                                                                      (CPCHAR)pSourceURL,
    877                                                                      (CPCHAR)pTargetURL,
    878                                                                       dm_stat) );
    879 
    880        }
    881        else
    882        {
    883               ret_stat = SaveCommandRefStatus((UINT8 *)p_CmdRefData,
    884                                                    (UINT8 *)dm_command_name_table[command],
    885                                                     pCommandItem,
    886                                                     dm_stat,
    887                                                     pUserData );
    888 
    889        }
    890 
    891         return ret_stat;
    892 
    893 }
    894 
    895 #ifdef TNDS_SUPPORT
    896 SYNCML_DM_RET_STATUS_T ProcessTndsNode( SYNCML_DM_COMMAND_T command,
    897                                         SmlDmTndNodeListPtr_t p_nodelist,
    898                                         const DMString &parentURI,
    899                                         const DMString &targetURI)
    900 {
    901    SYNCML_DM_RET_STATUS_T ret = SYNCML_DM_SUCCESS;
    902    DMAddData oCommandData;
    903    while ( NULL != p_nodelist && ret == SYNCML_DM_SUCCESS)
    904    {
    905       SmlDmTndNodePtr_t p_tnd_node = p_nodelist->node;
    906       if ( p_tnd_node != NULL )
    907       {
    908          // node name
    909          DMString nodeName;
    910          nodeName = (CPCHAR)p_tnd_node->nodename->content;
    911          KCDBG("ProcessTndsNode: node name = %s", nodeName.c_str());
    912 
    913          // node format and type
    914          SYNCML_DM_FORMAT_T nodeFormat = SYNCML_DM_FORMAT_NODE;
    915          DMString nodeType = "text/plain", nodeValue = "";
    916          if ( p_tnd_node->rtprops != NULL )
    917          {
    918              if ( p_tnd_node->rtprops->format != NULL )
    919              {
    920                  nodeFormat = DMTree::ConvertFormatStr((CPCHAR)p_tnd_node->rtprops->format->value->content);
    921                  if ( (nodeFormat == SYNCML_DM_FORMAT_BIN) && (nodeName == DM_AAUTHDATA) )
    922                  {
    923                      nodeFormat = SYNCML_DM_FORMAT_CHR;
    924                  }
    925              }
    926              if ( p_tnd_node->rtprops->type != NULL )
    927              {
    928                  if ( p_tnd_node->rtprops->type->mime != NULL )
    929                  {
    930                      nodeType = (CPCHAR)p_tnd_node->rtprops->type->mime->content;
    931                  }
    932                  else if ( p_tnd_node->rtprops->type->ddfname != NULL )
    933                  {
    934                      nodeType = (CPCHAR)p_tnd_node->rtprops->type->ddfname->content;
    935                  }
    936              }
    937          }
    938          KCDBG("ProcessTndsNode: nodeType = %s", nodeType.c_str());
    939 
    940          DMString nodeTargetURI;
    941          if ( ( nodeType == MNG_OBJID_DMACC1 ) || (nodeType == MNG_OBJID_DMACC2) )
    942          {
    943              KCDBG("ProcessTndsNode: modified Target URI");
    944              nodeTargetURI = DM_DMACC_1_2_URI;   // TNDS is defined for 1.2 only
    945          }
    946 
    947          // calculate node path
    948          DMString nodePath;
    949          if (!nodeTargetURI.empty())
    950          {
    951             nodePath = nodeTargetURI + "/";
    952          }
    953          else
    954          {
    955             nodePath = parentURI + "/";
    956          }
    957 
    958          if ( p_tnd_node->path != NULL )
    959          {
    960             DMString path = (CPCHAR)p_tnd_node->path->content;
    961             nodePath = nodeTargetURI + "/" + path + "/";
    962          }
    963          nodePath += nodeName;
    964          KCDBG("ProcessTndsNode: node path = %s", nodePath.c_str());
    965 
    966          // node value
    967          if ( p_tnd_node->value != NULL )
    968          {
    969             if ( DmStrncmp((CPCHAR)p_tnd_node->value->content, DM_INBOX, strlen(DM_INBOX)) == 0 )
    970             {
    971                nodeValue = (CPCHAR)p_tnd_node->value->content + strlen(DM_INBOX) + 1;
    972             }
    973             else
    974             {
    975                nodeValue = (CPCHAR)p_tnd_node->value->content;
    976             }
    977          }
    978 
    979          // Construct Add/Replace Data
    980          oCommandData.clear();
    981          oCommandData.m_oURI.assign(nodePath.c_str());
    982          oCommandData.m_nFormat = nodeFormat;
    983          oCommandData.m_oMimeType.assign(nodeType.c_str());
    984          oCommandData.m_oData.assign(nodeValue.c_str());
    985 
    986          // Add/Replace node in DMT
    987          if ( command == SYNCML_DM_ADD )
    988          {
    989             KCDBG("ProcessTndsNode: command == ADD");
    990             ret = dmTreeObj.Add(oCommandData,SYNCML_DM_REQUEST_TYPE_SERVER);
    991             // Interior node exist
    992             if ( nodeFormat == SYNCML_DM_FORMAT_NODE  && ret == SYNCML_DM_TARGET_ALREADY_EXISTS )
    993             {
    994                ret = SYNCML_DM_SUCCESS;
    995             }
    996          }
    997              else
    998          {
    999             KCDBG("ProcessTndsNode: command == REPLACE");
   1000             ret = dmTreeObj.Replace(oCommandData,SYNCML_DM_REQUEST_TYPE_SERVER);
   1001          }
   1002 
   1003          // Process children node
   1004          if ( ret == SYNCML_DM_SUCCESS )
   1005          {
   1006             if (nodeTargetURI.empty())
   1007             {
   1008                 ret = ProcessTndsNode(command, p_tnd_node->nodelist, nodePath, targetURI);
   1009             }
   1010             else
   1011             {
   1012                 ret = ProcessTndsNode(command, p_tnd_node->nodelist, nodePath, nodeTargetURI);
   1013             }
   1014          }
   1015          else
   1016          {
   1017             KCDBG("Failed to handle TNDS node: %s, format: %d, value: %s, status:%d\n", nodePath.c_str(), nodeFormat, nodeValue.c_str(), ret);
   1018          }
   1019       }
   1020 
   1021       // Process sibling node
   1022       p_nodelist = p_nodelist->next;
   1023    }
   1024 
   1025    return ret;
   1026 }
   1027 
   1028 SYNCML_DM_RET_STATUS_T ProcessTndsCommand(
   1029                                         SYNCML_DM_COMMAND_T command,
   1030                                         VoidPtr_t    userData,
   1031                                         DMAddData & oCommand,
   1032                                         DMCommandType cmdType,
   1033                                         SmlItemPtr_t p_command_item)
   1034 {
   1035    DMString dataStr;
   1036    if ( NULL == p_command_item->data || NULL == p_command_item->data->content )
   1037    {
   1038       return SML_ERR_UNSPECIFIC;
   1039    }
   1040    if ( SML_PCDATA_EXTENSION !=  p_command_item->data->contentType &&
   1041         SML_EXT_DMTND !=  p_command_item->data->extension )
   1042    {
   1043       return SML_ERR_UNSPECIFIC;
   1044    }
   1045 
   1046    SmlDmTndPtr_t p_tnd_info = NULL;
   1047    p_tnd_info = (SmlDmTndPtr_t)p_command_item->data->content;
   1048    if ( oCommand.m_oURI.compare(DM_INBOX) )
   1049    {
   1050        oCommand.m_oURI.assign(".");
   1051    }
   1052 
   1053    SYNCML_DM_RET_STATUS_T dm_stat=dmTreeObj.GetLockContextManager().ReleaseIDInternal(SYNCML_DM_LOCKID_CURRENT, SYNCML_DM_ATOMIC);
   1054 
   1055    if ( dm_stat != SYNCML_DM_SUCCESS && dm_stat != SYNCML_DM_FEATURE_NOT_SUPPORTED )
   1056    {
   1057      return SML_ERR_UNSPECIFIC;
   1058    }
   1059 
   1060    /* Remember that we are in an Atomic command.*/
   1061    bool bIsInAtomic = pDmMgmtSessionObj->GetInAtomicCommand();
   1062 
   1063    pDmMgmtSessionObj->SetInAtomicCommand(TRUE);
   1064 
   1065    SmlDmTndNodeListPtr_t p_nodelist = p_tnd_info->nodelist;
   1066    DMString path = (CPCHAR)oCommand.m_oURI.getBuffer();
   1067    if ( oCommand.m_oURI.getBuffer()[0] == '/' )
   1068    {
   1069       DMString tmpPath = ".";
   1070       path = tmpPath + path;
   1071    }
   1072    dm_stat = ProcessTndsNode(command, p_nodelist, path.c_str(), path.c_str());
   1073    if ( dm_stat != SYNCML_DM_SUCCESS && dm_stat != SYNCML_DM_FEATURE_NOT_SUPPORTED )
   1074    {
   1075       // Roll back TNDS objects
   1076       AtomicRollback(userData);
   1077    }
   1078 
   1079    pDmMgmtSessionObj->SetInAtomicCommand(bIsInAtomic);
   1080    return dm_stat;
   1081 }
   1082 #endif // TNDS_SUPPORT
   1083 
   1084 /*==================================================================================================
   1085 FUNCTION        : ProcessCommand
   1086 
   1087 DESCRIPTION     : Process ADD?REPLACE command
   1088 
   1089                   This function will perform the following operations:
   1090                   1) Call DMTree::Add() or DMTree::Replace() function to perform ADD command on the DM tree.
   1091                   2) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   1092                      return status for each ADD command performed.
   1093 ARGUMENT PASSED : id
   1094                   userData
   1095                   pContent
   1096                   command
   1097 OUTPUT PARAMETER:
   1098 RETURN VALUE    : SML_ERR_OK or ERR code
   1099 IMPORTANT NOTES :
   1100 
   1101 
   1102 ==================================================================================================*/
   1103 Ret_t ProcessCommand (InstanceID_t id,
   1104                                               VoidPtr_t    userData,
   1105                                               SmlAddPtr_t  pContent,
   1106                                               SYNCML_DM_COMMAND_T command)
   1107 {
   1108     Ret_t       sml_ret_stat = SML_ERR_OK;
   1109     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1110     SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
   1111     SmlItemListPtr_t    p_command_list_item;
   1112     SmlItemPtr_t        p_command_item;
   1113     DMBuffer            oCommandType;
   1114     SYNCML_DM_FORMAT_T  commandFormat;
   1115 
   1116     DMAddData oCommandData;
   1117     SYNCML_DM_USER_DATA_T *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   1118 
   1119     /* Get the data we need to work on */
   1120     p_command_list_item = pContent->itemList;
   1121     p_command_item      = p_command_list_item->item;
   1122 
   1123     XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::ProcessCommand command=%d", command));
   1124 
   1125    if ( command == SYNCML_DM_ADD )
   1126            dm_stat = pDmBuildPackage->GenerateAlertForLOB(DM_COMMAND_ADD);
   1127    else
   1128            dm_stat = pDmBuildPackage->GenerateAlertForLOB(DM_COMMAND_REPLACE);
   1129 
   1130     if (dm_stat != SYNCML_DM_SUCCESS)
   1131     {
   1132             ret_stat = ProcessStatus (dm_stat,
   1133                                                    userData,
   1134                                                    (UINT8*)pContent->cmdID->content,
   1135                                                    p_command_item,
   1136                                                    command);
   1137     /* Free the memeory we allocated (p_plugin_add), and passed in (pContent). */
   1138                smlFreeGeneric((SmlGenericCmdPtr_t)pContent);
   1139            return SML_ERR_OK;
   1140     }
   1141 
   1142     pDmMgmtSessionObj->IncCommandCount(); /* This variable is used to check if syncml document has
   1143                                            * any management commands */
   1144 
   1145     /* Fill in meta data when meta data info is defined outside of the ITEM in the receiving
   1146        package.
   1147        if meta data is not set, default format "chr" and type "text/plain" will be filled. */
   1148     dm_stat = SetMetaData(pContent->meta, oCommandType, &commandFormat);
   1149     if ( dm_stat != SYNCML_DM_SUCCESS )
   1150     {
   1151         smlFreeGeneric((SmlGenericCmdPtr_t)pContent);
   1152         return SML_ERR_UNSPECIFIC;
   1153     }
   1154 
   1155     /* Make sure we are not in an atomic and the Server is authenticated before performing any
   1156      * DM commands.*/
   1157     if (pDmMgmtSessionObj->IsAuthorized())
   1158     {
   1159         /* Loop on every ADD ITEM */
   1160         while (p_command_item != NULL)
   1161         {
   1162             oCommandData.clear();
   1163 
   1164             // perform operation
   1165 
   1166             while ( TRUE )
   1167             {
   1168                     DMString tempURI;
   1169                 dm_stat = PrepareCommandItem (p_command_item,
   1170                                                                     pUserData,
   1171                                                                     tempURI);
   1172                 if ( dm_stat != SYNCML_DM_SUCCESS )
   1173                           break;
   1174 
   1175               oCommandData.m_oURI.assign(tempURI);
   1176 
   1177               if(oCommandData.m_oURI.getBuffer() == NULL)
   1178               {
   1179                     dm_stat = SYNCML_DM_DEVICE_FULL;
   1180                     break;
   1181               }
   1182 
   1183               /* Set the meta data for ADD/REPLACE command if it's defined for each ITEM */
   1184 
   1185               if (p_command_item->meta != NULL)
   1186               {
   1187                  dm_stat = SetMetaData(p_command_item->meta, oCommandData.m_oMimeType, &oCommandData.m_nFormat);
   1188                  if ( dm_stat != SYNCML_DM_SUCCESS )
   1189                       break;
   1190               }
   1191               else
   1192               {
   1193                 /* This particular item does not have meta data, so we need to use the meta data
   1194                  * from outside the command.
   1195                  */
   1196                 oCommandData.m_oMimeType = oCommandType;
   1197                 if ( oCommandData.getType() == NULL )
   1198                 {
   1199                      dm_stat = SYNCML_DM_DEVICE_FULL;
   1200                      break;
   1201                 }
   1202                 oCommandData.m_nFormat = commandFormat;
   1203               }
   1204 
   1205 #ifdef TNDS_SUPPORT
   1206               /* Handle TNDS object */
   1207               if ( oCommandData.m_oMimeType.compare(SYNCML_CONTENT_TYPE_DM_TNDS_XML, strlen(SYNCML_CONTENT_TYPE_DM_TNDS_XML)) ||
   1208                    oCommandData.m_oMimeType.compare(SYNCML_CONTENT_TYPE_DM_TNDS_WBXML, strlen(SYNCML_CONTENT_TYPE_DM_TNDS_WBXML)) )
   1209               {
   1210                   dm_stat = ProcessTndsCommand( command,
   1211                                                 userData,
   1212                                                 oCommandData,
   1213                                                 command == SYNCML_DM_ADD ?
   1214                                                            DM_COMMAND_ADD :
   1215                                                            DM_COMMAND_REPLACE,
   1216                                                 p_command_item);
   1217               }
   1218               else
   1219               {
   1220 #endif // TNDS_SUPPORT
   1221 
   1222 #ifdef LOB_SUPPORT
   1223 
   1224                 if(pDmBuildPackage->IsProcessingLargeObject())
   1225                         {
   1226                        XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::ProcessCommand processing lob\n"));
   1227                    if ( command == SYNCML_DM_ADD )
   1228                                 dm_stat = pDmBuildPackage->LargeObjectRecvNextChunk(oCommandData,
   1229                                                                                                                    DM_COMMAND_ADD,
   1230                                                                                                                    p_command_item);
   1231                             else
   1232                                    dm_stat = pDmBuildPackage->LargeObjectRecvNextChunk(oCommandData,
   1233                                                                                                                    DM_COMMAND_REPLACE,
   1234                                                                                                                    p_command_item);
   1235 
   1236 
   1237                         }
   1238                 else
   1239                         {
   1240                      XPL_LOG_DM_TMN_Debug(("not processing large obj\n"));
   1241                        if ( command == SYNCML_DM_ADD )
   1242                                 dm_stat = pDmBuildPackage->LargeObjectRecvFirstChunk(oCommandData,
   1243                                                                                                                            DM_COMMAND_ADD,
   1244                                                                                                                            p_command_item);
   1245                                  else
   1246                                 dm_stat = pDmBuildPackage->LargeObjectRecvFirstChunk(oCommandData,
   1247                                                                                                                            DM_COMMAND_REPLACE,
   1248                                                                                                                            p_command_item);
   1249 
   1250                         }
   1251 #else // LOB_SUPPORT
   1252 
   1253                /* Call TNM module to perform ADD command */
   1254 #ifdef DM_ATOMIC_SUPPORTED
   1255                if ( command == SYNCML_DM_ADD ) {
   1256                 XPL_LOG_DM_TMN_Debug(("about to add atomic supported\n"));
   1257                        dm_stat = dmTreeObj.Add(oCommandData,SYNCML_DM_REQUEST_TYPE_SERVER);
   1258                 XPL_LOG_DM_TMN_Debug(("add atomic supported dm_stat=%d\n", dm_stat));
   1259                 }
   1260                 else
   1261                         dm_stat = dmTreeObj.Replace(oCommandData,SYNCML_DM_REQUEST_TYPE_SERVER);
   1262 #else // DM_ATOMIC_SUPPORTED
   1263                if ( pDmMgmtSessionObj->GetInAtomicCommand() )
   1264                     dm_stat =  SYNCML_DM_COMMAND_FAILED;
   1265                else
   1266                {
   1267                      if ( command == SYNCML_DM_ADD ) {
   1268                      XPL_LOG_DM_TMN_Debug(("about to add atomic not supported\n"));
   1269                                 dm_stat = dmTreeObj.Add(oCommandData,SYNCML_DM_REQUEST_TYPE_SERVER);
   1270                          XPL_LOG_DM_TMN_Debug(("add atomic not supported dm_stat=%d\n", dm_stat));
   1271                                }
   1272                         else
   1273                                 dm_stat = dmTreeObj.Replace(oCommandData,SYNCML_DM_REQUEST_TYPE_SERVER);
   1274                }
   1275 #endif // DM_ATOMIC_SUPPORTED
   1276 #endif // LOB_SUPPORT
   1277 
   1278 #ifdef TNDS_SUPPORT
   1279               }
   1280 #endif // TNDS_SUPPORT
   1281 
   1282                SequenceStatus(userData, dm_stat);
   1283 
   1284                break;
   1285             }
   1286 
   1287             XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::ProcessCommand dm_stat=%d, command=%d\n",dm_stat, command));
   1288 
   1289             ret_stat = ProcessStatus (dm_stat,
   1290                                                    userData,
   1291                                                    (UINT8*)pContent->cmdID->content,
   1292                                                    p_command_item,
   1293                                                    command);
   1294            if (ret_stat != SYNCML_DM_SUCCESS)
   1295            {
   1296                   sml_ret_stat = SML_ERR_UNSPECIFIC;
   1297                   break;
   1298            }
   1299 
   1300            if (p_command_list_item->next != NULL)
   1301            {
   1302                        p_command_list_item = p_command_list_item->next;
   1303                   p_command_item = p_command_list_item->item;
   1304            }
   1305            else
   1306                  p_command_item = NULL;
   1307         } /* End of while */
   1308     } /* !inAtomicCommand && dmSecState */
   1309     else /*  dmSecState not authenticated */
   1310     {
   1311         /* Call the toolkit to construct the STATUS for ADD command */
   1312         ret_stat = SaveCommandRefStatus((UINT8 *)pContent->cmdID->content,
   1313                                  (UINT8 *)dm_command_name_table[command],
   1314                                  p_command_item,
   1315                                  pDmMgmtSessionObj->GetNotAuthorizedStatus(),
   1316                                  pUserData );
   1317          if (ret_stat != SYNCML_DM_SUCCESS)
   1318                sml_ret_stat = SML_ERR_UNSPECIFIC;
   1319     }
   1320     /* Free the memeory we allocated (p_plugin_add), and passed in (pContent). */
   1321     smlFreeGeneric((SmlGenericCmdPtr_t)pContent);
   1322 
   1323     return sml_ret_stat;
   1324 }
   1325 
   1326 
   1327 
   1328 /*==================================================================================================
   1329 FUNCTION        : HandleAddCommand
   1330 
   1331 DESCRIPTION     : When the ADD element is processed from the received message, this callback
   1332                   function will be called.
   1333 
   1334                   This function will perform the following operations:
   1335                   1) Call DMTree::Add() function to perform ADD command on the DM tree.
   1336                   2) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   1337                      return status for each ADD command performed.
   1338 ARGUMENT PASSED : id
   1339                   userData
   1340                   pContent
   1341 OUTPUT PARAMETER:
   1342 RETURN VALUE    : SML_ERR_OK or ERR code
   1343 IMPORTANT NOTES :
   1344 
   1345 
   1346 ==================================================================================================*/
   1347 Ret_t HandleAddCommand (InstanceID_t id, VoidPtr_t    userData, SmlAddPtr_t  pContent)
   1348 {
   1349     XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::HandleAdd enter"));
   1350     return ProcessCommand(id, userData, pContent,SYNCML_DM_ADD);
   1351 }
   1352 
   1353 /*==================================================================================================
   1354 FUNCTION        : HandleCopyCommand
   1355 
   1356 DESCRIPTION     : When the COPY element is processed from the received message, this callback
   1357                   function will be called.
   1358 
   1359                   This function will perform the following operations:
   1360                   1) Set DM status as SYNCML_DM_FEATURE_NOT_SUPPORTED.
   1361                   2) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   1362                      return status for each COPY command performed.
   1363 ARGUMENT PASSED : id
   1364                   userData
   1365                   pContent
   1366 OUTPUT PARAMETER:
   1367 RETURN VALUE    : SML_ERR_OK or ERR code
   1368 IMPORTANT NOTES :
   1369 
   1370 
   1371 ==================================================================================================*/
   1372 Ret_t
   1373 HandleCopyCommand (InstanceID_t  id,
   1374                    VoidPtr_t     userData,
   1375                    SmlCopyPtr_t  pContent)
   1376 {
   1377     Ret_t                  sml_ret_stat = SML_ERR_OK;
   1378     SYNCML_DM_RET_STATUS_T ret_stat;
   1379     SYNCML_DM_USER_DATA_T *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   1380 
   1381     pDmMgmtSessionObj->IncCommandCount(); /* This variable is used to check if syncml document has
   1382                                            * any management commands */
   1383 
   1384     /* Call the toolkit to construct the STATUS for COPY command */
   1385     ret_stat = SaveStatus(
   1386         (UINT8 *)pContent->cmdID->content,
   1387         (UINT8 *)dm_command_name_table[SYNCML_DM_COPY],
   1388         NULL,
   1389         NULL,
   1390         SYNCML_DM_FEATURE_NOT_SUPPORTED,
   1391         NULL,
   1392         pUserData);
   1393 
   1394     if (ret_stat != SYNCML_DM_SUCCESS)
   1395     {
   1396         sml_ret_stat = SML_ERR_UNSPECIFIC;
   1397     }
   1398 
   1399     /* Free the memory of pContent. */
   1400     smlFreeGeneric((SmlGenericCmdPtr_t)pContent);
   1401 
   1402     return sml_ret_stat;
   1403 }
   1404 
   1405 
   1406 /*==================================================================================================
   1407 FUNCTION        : HandleDeleteCommand
   1408 
   1409 DESCRIPTION     : When the DELETE element is processed from the received message, this callback
   1410                   function will be called.
   1411 
   1412                   This function will perform the following operations:
   1413                   1) Call DMTree::Delete() function to perform DELETE command on the DM tree.
   1414                   2) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   1415                      return status for each DELETE command performed.
   1416 ARGUMENT PASSED : id
   1417                   userData
   1418                   pContent
   1419 OUTPUT PARAMETER:
   1420 RETURN VALUE    : SML_ERR_OK or ERR code
   1421 IMPORTANT NOTES :
   1422 
   1423 
   1424 ==================================================================================================*/
   1425 Ret_t
   1426 HandleDeleteCommand (InstanceID_t   id,
   1427                      VoidPtr_t      userData,
   1428                      SmlDeletePtr_t pContent)
   1429 {
   1430     Ret_t   sml_ret_stat = SML_ERR_OK;
   1431     SYNCML_DM_RET_STATUS_T     dm_stat = 0;
   1432     SYNCML_DM_RET_STATUS_T ret_stat = 0;
   1433     SYNCML_DM_USER_DATA_T   *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   1434 
   1435     SmlItemListPtr_t p_delete_list_item;
   1436     SmlItemPtr_t     p_delete_item;
   1437 
   1438     p_delete_list_item = pContent->itemList;
   1439     p_delete_item      = p_delete_list_item->item;
   1440 
   1441     XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::HandleDelete enter"));
   1442 
   1443            ret_stat = pDmBuildPackage->GenerateAlertForLOB(DM_COMMAND_REPLACE);
   1444 
   1445     if (ret_stat != SYNCML_DM_SUCCESS)
   1446     {
   1447           ret_stat = ProcessStatus (dm_stat,
   1448                                                    userData,
   1449                                                    (UINT8*)pContent->cmdID->content,
   1450                                                    p_delete_item,
   1451                                                    SYNCML_DM_DELETE);
   1452     /* Free the memory of pContent and p_target_uri. */
   1453             smlFreeGeneric((SmlGenericCmdPtr_t)pContent);
   1454                 return SML_ERR_OK;
   1455     }
   1456 
   1457     pDmMgmtSessionObj->IncCommandCount(); /* This variable is used to check if syncml document has
   1458                                            * any management commands */
   1459 
   1460     /* Make sure we are not in an atomic and the Server is authenticated before performing any
   1461      * DM commands.*/
   1462     if (pDmMgmtSessionObj->IsAuthorized())
   1463     {
   1464         /* Loop on each DELETE item */
   1465         while (p_delete_item != NULL) {
   1466 
   1467 
   1468           // perform operation
   1469           while ( true )
   1470           {
   1471               DMString strDeleteUri;
   1472                 dm_stat = PrepareCommandItem (p_delete_item,
   1473                                                                     pUserData,
   1474                                                                     strDeleteUri);
   1475                 if ( dm_stat != SYNCML_DM_SUCCESS )
   1476                           break;
   1477 
   1478                 XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::HandleDelete uri=%s\n", strDeleteUri.c_str()));
   1479 
   1480 #ifdef DM_ATOMIC_SUPPORTED
   1481                dm_stat = dmTreeObj.Delete (strDeleteUri.c_str(),SYNCML_DM_REQUEST_TYPE_SERVER );
   1482 #else
   1483                if ( pDmMgmtSessionObj->GetInAtomicCommand() )
   1484                     dm_stat =  SYNCML_DM_COMMAND_FAILED;
   1485                else
   1486                     dm_stat = dmTreeObj.Delete (strDeleteUri.c_str(),SYNCML_DM_REQUEST_TYPE_SERVER );
   1487 #endif
   1488                SequenceStatus(userData, dm_stat);
   1489                break;
   1490           }
   1491 
   1492           ret_stat = ProcessStatus (dm_stat,
   1493                                                    userData,
   1494                                                    (UINT8*)pContent->cmdID->content,
   1495                                                    p_delete_item,
   1496                                                    SYNCML_DM_DELETE);
   1497           if (ret_stat != SYNCML_DM_SUCCESS)
   1498            {
   1499                   sml_ret_stat = SML_ERR_UNSPECIFIC;
   1500                   break;
   1501            }
   1502 
   1503             /* Move to the next item on the list */
   1504             if (p_delete_list_item->next != NULL) {
   1505                   p_delete_list_item = p_delete_list_item->next;
   1506                   p_delete_item = p_delete_list_item->item;
   1507             }
   1508             else
   1509                   p_delete_item = NULL;
   1510         } /* End of while */
   1511     } /* !inAtomicCommand && dmSecState */
   1512     else /* dmSecState not authenticated */
   1513     {
   1514             ret_stat =  SaveCommandRefStatus(
   1515                                       (UINT8 *)pContent->cmdID->content,
   1516                                       (UINT8 *)dm_command_name_table[SYNCML_DM_DELETE],
   1517                                       p_delete_item,
   1518                                       pDmMgmtSessionObj->GetNotAuthorizedStatus(),
   1519                                       pUserData );
   1520             if (ret_stat != SYNCML_DM_SUCCESS)
   1521             {
   1522                 sml_ret_stat = SML_ERR_UNSPECIFIC;
   1523             }
   1524     }
   1525 
   1526     /* Free the memory of pContent and p_target_uri. */
   1527     smlFreeGeneric((SmlGenericCmdPtr_t)pContent);
   1528 
   1529     return sml_ret_stat;
   1530 }
   1531 
   1532 
   1533 /*==================================================================================================
   1534 FUNCTION        : ProcessAlertCommand
   1535 
   1536 DESCRIPTION     : When the ALERT element is processed from the received message, this callback
   1537                   function will be called.
   1538 
   1539                   This function will perform the following operations:
   1540                   1) Process alert via XPL.
   1541                      return status for each ALERT command performed.
   1542 ARGUMENT PASSED : id
   1543                   userData
   1544                   pContent
   1545 OUTPUT PARAMETER:
   1546 RETURN VALUE    : SML_ERR_OK or ERR code
   1547 IMPORTANT NOTES :
   1548 
   1549 
   1550 ==================================================================================================*/
   1551 static SYNCML_DM_RET_STATUS_T
   1552 ProcessAlertCommand (VoidPtr_t   userData,
   1553                     SmlAlertPtr_t  pContent,
   1554                     SYNCML_DM_Alert * pAlert,
   1555                     DMStringVector   &  responses)
   1556 {
   1557     SYNCML_DM_USER_DATA_T  *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   1558     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1559 
   1560     if ( pAlert == NULL )
   1561         return SYNCML_DM_FAIL;
   1562 
   1563     if ( pUserData->IsCommandSkipped() || pDmMgmtSessionObj->IsSessionAborted() )
   1564          return SYNCML_DM_NOT_EXECUTED;
   1565 
   1566     pAlert->parse(pContent);
   1567     dm_stat = pAlert->show();
   1568     switch ( dm_stat )
   1569     {
   1570         case SYNCML_DM_SESSION_CANCELED:
   1571             pDmMgmtSessionObj->SetSessionAborted();
   1572             return SYNCML_DM_SUCCESS;
   1573 
   1574         case SYNCML_DM_SUCCESS:
   1575              dm_stat = pAlert->processResponse(responses,&pUserData->alertState);
   1576              break;
   1577 
   1578         default:
   1579             pUserData->alertState =  SYNCML_DM_ALERT_CANCEL;
   1580             break;
   1581      }
   1582 
   1583     return dm_stat;
   1584 
   1585 }
   1586 
   1587 
   1588 /*==================================================================================================
   1589 FUNCTION        : HandleAlertCommand
   1590 
   1591 DESCRIPTION     : When the ALERT element is processed from the received message, this callback
   1592                   function will be called.
   1593 
   1594                   This function will perform the following operations:
   1595                   1) Check the ALERT value, set the DM status accordingly.
   1596                   2) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   1597                      return status for each ALERT command performed.
   1598 ARGUMENT PASSED : id
   1599                   userData
   1600                   pContent
   1601 OUTPUT PARAMETER:
   1602 RETURN VALUE    : SML_ERR_OK or ERR code
   1603 IMPORTANT NOTES :
   1604 
   1605 
   1606 ==================================================================================================*/
   1607 Ret_t
   1608 HandleAlertCommand (InstanceID_t   id,
   1609                     VoidPtr_t      userData,
   1610                     SmlAlertPtr_t  pContent)
   1611 {
   1612   Ret_t              sml_ret_stat = SML_ERR_OK;
   1613   SYNCML_DM_RET_STATUS_T  ret_stat = 0;
   1614   SYNCML_DM_RET_STATUS_T dm_stat = 0;
   1615   SYNCML_DM_USER_DATA_T   *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   1616   DMStringVector    responses;         // holds all the user responses
   1617 
   1618   pDmMgmtSessionObj->IncCommandCount(); /* This variable is used to check if syncml document has
   1619                                          * any management commands */
   1620 
   1621   if (pDmMgmtSessionObj->IsAuthorized())
   1622   {
   1623 
   1624     UINT32  alert_code_value;
   1625 
   1626     /* Get the data we need to work on */
   1627 
   1628     alert_code_value = DmAtoi((const char *)pContent->data->content);
   1629 
   1630     /* Please refer syncml_dm_represent_v111_20021002.pdf section 8 */
   1631     switch (alert_code_value)
   1632     {
   1633         case DM_ALERT_SERVER_INITIATED_MGMT:
   1634         case DM_ALERT_CLIENT_INITIATED_MGMT:
   1635         case DM_ALERT_NEXT_MESSAGE:
   1636             dm_stat = SYNCML_DM_SUCCESS;
   1637             break;
   1638 
   1639         case DM_ALERT_SESSION_ABORT:
   1640             pDmMgmtSessionObj->SetSessionAborted();
   1641             dm_stat = SYNCML_DM_SUCCESS;
   1642             break;
   1643 
   1644         // handle user interaction alerts
   1645         case DM_ALERT_DISPLAY:
   1646         {
   1647             if ( !VerifyAlertItems(pContent) )
   1648             {
   1649                XPL_LOG_DM_TMN_Debug(("HandleAlertCommand, alert command items incorrect."));
   1650                dm_stat = SYNCML_DM_INCOMPLETE_COMMAND;
   1651             }
   1652             else  {
   1653                SYNCML_DM_DisplayAlert displayAlert;
   1654                dm_stat = ProcessAlertCommand(userData,pContent,&displayAlert,responses);
   1655             }
   1656         }
   1657         break;
   1658 
   1659         case DM_ALERT_CONTINUE_OR_ABORT:
   1660         {
   1661             if ( !VerifyAlertItems(pContent) )
   1662             {
   1663                XPL_LOG_DM_TMN_Debug(("HandleAlertCommand, alert command items incorrect."));
   1664                dm_stat = SYNCML_DM_INCOMPLETE_COMMAND;
   1665             }
   1666             else  {
   1667                SYNCML_DM_ConfirmAlert confirmAlert;
   1668                dm_stat = ProcessAlertCommand(userData,pContent,&confirmAlert,responses);
   1669             }
   1670         }
   1671         break;
   1672 
   1673         case DM_ALERT_TEXT_INPUT:
   1674         {
   1675             if ( !VerifyAlertItems(pContent) )
   1676             {
   1677                XPL_LOG_DM_TMN_Debug(("HandleAlertCommand, alert command items incorrect."));
   1678                dm_stat = SYNCML_DM_INCOMPLETE_COMMAND;
   1679             }
   1680             else  {
   1681                SYNCML_DM_TextInputAlert textInputAlert;
   1682                dm_stat = ProcessAlertCommand(userData,pContent,&textInputAlert,responses);
   1683             }
   1684         }
   1685         break;
   1686 
   1687         case DM_ALERT_SINGLE_CHOICE:
   1688         {
   1689             SYNCML_DM_SingleChoiceAlert singleChoiceAlert;
   1690             dm_stat = ProcessAlertCommand(userData,pContent,&singleChoiceAlert,responses);
   1691         }
   1692         break;
   1693 
   1694         case DM_ALERT_MULTIPLE_CHOICE:
   1695         {
   1696             SYNCML_DM_MultipleChoiceAlert multipleChoiceAlert;
   1697             dm_stat = ProcessAlertCommand(userData,pContent,&multipleChoiceAlert,responses);
   1698         }
   1699         break;
   1700 
   1701         default:
   1702             dm_stat = SYNCML_DM_FEATURE_NOT_SUPPORTED; /* Optional feature not supported */
   1703             break;
   1704     }
   1705 
   1706     if(pDmMgmtSessionObj->GetInAtomicCommand())
   1707     {
   1708 #ifdef DM_ATOMIC_SUPPORTED
   1709         // Save the data for the status and results
   1710       if ( dm_stat != SYNCML_DM_SUCCESS && dm_stat != SYNCML_DM_FEATURE_NOT_SUPPORTED )
   1711           AtomicRollback(userData);
   1712 #endif
   1713       pUserData->oStatus.push_back(
   1714                       SYNCML_DM_STATUS_DATA_T((const char*)pContent->cmdID->content,
   1715                                                          dm_command_name_table[SYNCML_DM_ALERT],
   1716                                                          NULL,
   1717                                                          NULL,
   1718                                                          dm_stat,
   1719                                                          &responses) );
   1720     }
   1721     else
   1722     {
   1723       ret_stat = SaveStatus((UINT8 *)pContent->cmdID->content,
   1724                                (UINT8 *)dm_command_name_table[SYNCML_DM_ALERT],
   1725                                 NULL,
   1726                                 NULL,
   1727                                 dm_stat,
   1728                                 &responses,
   1729                                 pUserData );
   1730       if (ret_stat != SYNCML_DM_SUCCESS)
   1731       {
   1732         sml_ret_stat = SML_ERR_UNSPECIFIC;
   1733       }
   1734     }
   1735   }
   1736   else
   1737   {
   1738 
   1739     ret_stat = SaveStatus(
   1740               (UINT8 *)pContent->cmdID->content,
   1741               (UINT8 *)dm_command_name_table[SYNCML_DM_ALERT],
   1742               NULL,
   1743               NULL,
   1744               pDmMgmtSessionObj->GetNotAuthorizedStatus(),
   1745               &responses,
   1746               pUserData );
   1747     if (ret_stat != SYNCML_DM_SUCCESS)
   1748       sml_ret_stat = SML_ERR_UNSPECIFIC;
   1749   }
   1750 
   1751   /* Free the memory of the pContent */
   1752   smlFreeAlert(pContent);
   1753 
   1754   return sml_ret_stat;
   1755 }
   1756 
   1757 
   1758 /*==================================================================================================
   1759 FUNCTION        : HandleExecCommand
   1760 
   1761 DESCRIPTION     : When the EXEC element is processed from the received message, this callback
   1762                   function will be called.
   1763 
   1764                   This function will perform the following operations:
   1765                   1) Call DMTree::Exec() function to perform EXEC command on the DM tree.
   1766                   2) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   1767                      return status for each EXEC command performed.
   1768 ARGUMENT PASSED : id
   1769                   userData
   1770                   pContent
   1771 OUTPUT PARAMETER:
   1772 RETURN VALUE    : SML_ERR_OK or ERR code
   1773 IMPORTANT NOTES :
   1774 
   1775 
   1776 ==================================================================================================*/
   1777 Ret_t
   1778 HandleExecCommand (InstanceID_t  id,
   1779                    VoidPtr_t     userData,
   1780                    SmlExecPtr_t  pContent)
   1781 {
   1782     SYNCML_DM_RET_STATUS_T dm_stat=SYNCML_DM_SUCCESS;
   1783     SYNCML_DM_USER_DATA_T  *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   1784 
   1785     SYNCML_DM_RET_STATUS_T ret_stat = 0;
   1786     SYNCML_DM_URI_RESULT_T dm_uri_result = 0;
   1787     SmlItemPtr_t p_exec_item;
   1788     DMString strExecUri;
   1789     DMString strOriExecUri;
   1790 
   1791     DMString execResults;
   1792     DMString execData;
   1793 
   1794     p_exec_item = pContent->item;
   1795 
   1796            ret_stat = pDmBuildPackage->GenerateAlertForLOB(DM_COMMAND_EXEC);
   1797 
   1798     if (ret_stat != SYNCML_DM_SUCCESS)
   1799     {
   1800        smlFreeExec((SmlExecPtr_t)pContent);
   1801         return SML_ERR_OK;
   1802     }
   1803 
   1804     pDmMgmtSessionObj->IncCommandCount(); /* This variable is used to check if syncml document has
   1805                                            * any management commands */
   1806 
   1807     /* Make sure we are not in an atomic and the Server is authenticated before performing any
   1808      * DM commands.*/
   1809     if (pDmMgmtSessionObj->GetInAtomicCommand() == FALSE &&
   1810           pDmMgmtSessionObj->IsAuthorized())
   1811     {
   1812 
   1813        if ((p_exec_item->target == NULL) || (p_exec_item->target->locURI == NULL))
   1814        {
   1815            smlFreeExec((SmlExecPtr_t)pContent);
   1816             return SML_ERR_UNSPECIFIC;
   1817        }
   1818 
   1819        strExecUri.assign((CPCHAR)p_exec_item->target->locURI->content,p_exec_item->target->locURI->length);
   1820 
   1821        strOriExecUri = strExecUri;
   1822        if(strExecUri.Decode() == FALSE)
   1823        {
   1824          smlFreeExec((SmlExecPtr_t)pContent);
   1825           return SML_ERR_UNSPECIFIC;
   1826        }
   1827         /* Fill the data for p_exec_data */
   1828        if (p_exec_item->data != NULL && p_exec_item->data->length > 0)
   1829        {
   1830             execData.assign((CPCHAR)p_exec_item->data->content,p_exec_item->data->length);
   1831             if ( execData == NULL )
   1832             {
   1833                smlFreeExec((SmlExecPtr_t)pContent);
   1834                return SML_ERR_UNSPECIFIC;
   1835             }
   1836        }
   1837 
   1838        const char* szCorrelator = NULL;
   1839 
   1840         if ( pContent->correlator && pContent->correlator->contentType == SML_PCDATA_STRING )
   1841             szCorrelator = (const char*)pContent->correlator->content;
   1842 
   1843 
   1844        /* Validate the URI */
   1845        dm_uri_result = dmTreeObj.URIValidateAndParse(strExecUri);
   1846        switch (dm_uri_result)
   1847        {
   1848            case SYNCML_DM_COMMAND_ON_UNKNOWN_PROPERTY:
   1849            case SYNCML_DM_COMMAND_INVALID_URI:
   1850            case SYNCML_DM_COMMAND_URI_TOO_LONG:
   1851              dm_stat = SYNCML_DM_BAD_REQUEST;
   1852              break;
   1853 
   1854            default:
   1855 
   1856              // schen link error, code is not there
   1857              // dm_stat = SYNCML_DM_FEATURE_NOT_SUPPORTED;
   1858              dm_stat = dmTreeObj.Exec(strExecUri.c_str(), execData, execResults, szCorrelator);
   1859              SequenceStatus(userData, dm_stat);
   1860              break;
   1861        }
   1862 
   1863     }
   1864     else
   1865            if (pDmMgmtSessionObj->GetInAtomicCommand())
   1866           {
   1867                 AtomicRollback(userData);
   1868                 /* We don't apply commands within the Atomic.*/
   1869                 dm_stat = SYNCML_DM_COMMAND_FAILED;
   1870           }
   1871           else
   1872                 dm_stat = pDmMgmtSessionObj->GetNotAuthorizedStatus();
   1873 
   1874     UINT8  *p_TargetRefData = NULL;
   1875     if(p_exec_item->target != NULL && p_exec_item->target->locURI != NULL){
   1876        p_TargetRefData = (UINT8 *)p_exec_item->target->locURI->content;
   1877     }
   1878 
   1879     if (0 == DmStrcmp((char *)p_TargetRefData, FDR_URI))
   1880     {
   1881        /* Build tha status with item tag for the EXEC command for FDR*/
   1882        ret_stat = SaveStatus((UINT8 *)pContent->cmdID->content,
   1883                                       (UINT8 *)dm_command_name_table[SYNCML_DM_EXEC],
   1884                                       NULL,
   1885                                       p_TargetRefData,
   1886                                       dm_stat,
   1887                                       NULL,
   1888                                       pUserData );
   1889     }
   1890     else
   1891     {
   1892        /* Build tha status for the EXEC command */
   1893        ret_stat = SaveStatus((UINT8 *)pContent->cmdID->content,
   1894                                       (UINT8 *)dm_command_name_table[SYNCML_DM_EXEC],
   1895                                       NULL,
   1896                                       NULL,
   1897                                       dm_stat,
   1898                                       NULL,
   1899                                       pUserData );
   1900 
   1901     }
   1902 
   1903     if (dm_stat == SYNCML_DM_SUCCESS && execResults.length() )
   1904     {
   1905          XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::HandleExecCommand, inside success chk\n"));
   1906          SmlResultsPtr_t  p_results=NULL;      /* To hold RESULTS structure */
   1907          SmlItemPtr_t     p_results_item;      /* To hold GET results item */
   1908          SmlItemListPtr_t p_results_list_item; /* To hold GET results list */
   1909 
   1910          // Allocate the memory for p_results
   1911          p_results = smlAllocResults();
   1912 
   1913          if ( !p_results )
   1914          {
   1915             smlFreeExec((SmlExecPtr_t)pContent);
   1916             return SML_ERR_UNSPECIFIC;
   1917          }
   1918 
   1919          XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::HandleExecCommand, before buildpcdata\n"));
   1920          pDmBuildPackage->BuildPcData(p_results->cmdRef,
   1921                                             SML_PCDATA_STRING,
   1922                                             SML_EXT_UNDEFINED,
   1923                                             DmStrlen((char *)pContent->cmdID->content),
   1924                                             (UINT8*)pContent->cmdID->content);
   1925 
   1926 
   1927          /* Fill in item fileds */
   1928          p_results_list_item = p_results->itemList;
   1929 
   1930          p_results_item = p_results_list_item->item;
   1931          ret_stat = SetExecResultsData(  p_results_item, strOriExecUri, execResults);
   1932          pUserData->aResults.push_back(
   1933             SYNCML_DM_RESULT_VALUE( SYNCML_DM_RESULT_VALUE::Enum_Result_Exec, p_results,
   1934             SYNCML_DM_GET_ON_LIST_RET_DATA_T(), (CPCHAR)pContent->cmdID->content,
   1935             (const char*)pDmBuildPackage->GetMsgRef()) );
   1936     }
   1937 
   1938 
   1939     if (ret_stat != SYNCML_DM_SUCCESS)
   1940     {
   1941         smlFreeExec((SmlExecPtr_t)pContent);
   1942         return SML_ERR_UNSPECIFIC;
   1943     }
   1944 
   1945     smlFreeExec((SmlExecPtr_t)pContent);
   1946 
   1947     XPL_LOG_DM_TMN_Debug(("dm_ua_handlecommand::HandleExecCommand leaving\n"));
   1948     return SML_ERR_OK;
   1949 }
   1950 
   1951 
   1952 /*==================================================================================================
   1953 FUNCTION        : HandleGetCommand
   1954 
   1955 DESCRIPTION     : When the GET element is processed from the received message, this callback
   1956                   function will be called.
   1957 
   1958                   This function will perform the following operations:
   1959                   1) Call DMTree::Get() function to perform GET command on the DM tree.
   1960                   2) Call BuildResultsCommand() to build the results from GET command.
   1961                   3) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   1962                      return status for each GET command performed.
   1963 ARGUMENT PASSED : id
   1964                   userData
   1965                   pContent
   1966 OUTPUT PARAMETER:
   1967 RETURN VALUE    : SML_ERR_OK or ERR code
   1968 IMPORTANT NOTES :
   1969 
   1970 
   1971 ==================================================================================================*/
   1972 Ret_t
   1973 HandleGetCommand (InstanceID_t id,
   1974                   VoidPtr_t    userData,
   1975                   SmlGetPtr_t  pContent)
   1976 {
   1977     DMString strTargetUri;
   1978     Ret_t sml_ret_stat = SML_ERR_OK;
   1979     SYNCML_DM_RET_STATUS_T dm_stat = 0;
   1980     SYNCML_DM_RET_STATUS_T ret_stat = 0;
   1981     DMGetData getData;
   1982 
   1983     /* p_get_struct_data is OUTPUT parameter of dmTreeObj.InitListAndGetListFirstItem call. We
   1984        need to initialize it as NULL before we pass it to the call, p_get_struct_data could not
   1985        be set if the return is not SUCCESS. */
   1986 
   1987     SYNCML_DM_GET_ON_LIST_RET_DATA_T p_get_struct_data;
   1988     SYNCML_DM_URI_RESULT_T dm_uri_result = 0;
   1989     SYNCML_DM_USER_DATA_T *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   1990 
   1991     SmlItemPtr_t     p_get_item;
   1992     SmlItemListPtr_t p_get_list_item;
   1993 
   1994     pDmMgmtSessionObj->IncCommandCount();
   1995 
   1996     /* Point the GET item to the correct spot */
   1997     p_get_list_item = pContent->itemList;
   1998     p_get_item      = p_get_list_item->item;
   1999 
   2000    dm_stat = pDmBuildPackage->GenerateAlertForLOB(DM_COMMAND_GET);
   2001     if (dm_stat != SYNCML_DM_SUCCESS)
   2002     {
   2003             ret_stat = ProcessStatus (dm_stat,
   2004                                                    userData,
   2005                                                    (UINT8*)pContent->cmdID->content,
   2006                                                    p_get_item,
   2007                                                    SYNCML_DM_GET);
   2008     /* Free the memory */
   2009           smlFreeGetPut(pContent);
   2010         return SML_ERR_OK;
   2011     }
   2012 
   2013     /* Make sure we are not in an atomic and the Server is authenticated before performing any
   2014      * DM commands.*/
   2015     if (pDmMgmtSessionObj->GetInAtomicCommand() == FALSE &&
   2016          pDmMgmtSessionObj->IsAuthorized())
   2017     {
   2018 
   2019       while (p_get_item != NULL)
   2020       {                              /* Loop through each GET ITEM */
   2021 
   2022           getData.clear();
   2023           while ( true )
   2024           {
   2025               DMString strTargetUri;
   2026               XPL_LOG_DM_TMN_Debug(("\ninside dm_ua_handlecommand::HandleGet, uri=%s\n", strTargetUri.c_str()));
   2027                 dm_stat = PrepareCommandItem (p_get_item,
   2028                                                                        pUserData,
   2029                                                                        strTargetUri);
   2030                 if ( dm_stat != SYNCML_DM_SUCCESS )
   2031                           break;
   2032 
   2033                   /* Validete the URI */
   2034               dm_uri_result = dmTreeObj.URIValidateAndParse((char*)strTargetUri.c_str());
   2035               switch (dm_uri_result) {
   2036                     case SYNCML_DM_COMMAND_INVALID_URI:
   2037                     case SYNCML_DM_COMMAND_ON_UNKNOWN_PROPERTY:
   2038                     case SYNCML_DM_COMMAND_URI_TOO_LONG:
   2039                        dm_stat = SYNCML_DM_BAD_REQUEST;
   2040                        break;
   2041 
   2042                     case SYNCML_DM_COMMAND_ON_NODE:
   2043                     case SYNCML_DM_COMMAND_ON_ACL_PROPERTY:
   2044                     case SYNCML_DM_COMMAND_ON_FORMAT_PROPERTY:
   2045                     case SYNCML_DM_COMMAND_ON_NAME_PROPERTY:
   2046                     case SYNCML_DM_COMMAND_ON_SIZE_PROPERTY:
   2047                     case SYNCML_DM_COMMAND_ON_TYPE_PROPERTY:
   2048                     case SYNCML_DM_COMMAND_ON_TITLE_PROPERTY:
   2049                     case SYNCML_DM_COMMAND_ON_TSTAMP_PROPERTY:
   2050                     case SYNCML_DM_COMMAND_ON_VERNO_PROPERTY:
   2051                        dm_stat = dmTreeObj.Get(strTargetUri.c_str(), getData,SYNCML_DM_REQUEST_TYPE_SERVER);
   2052                        XPL_LOG_DM_TMN_Debug(("\ninside dm_ua_handlecommand::HandleGet, dmTreeObj.Get=%d", dm_stat));
   2053                     if (dm_stat == SYNCML_DM_SUCCESS)
   2054                        {
   2055                          dm_stat = SaveResult( strTargetUri, (const char *)pContent->cmdID->content,
   2056                                                &getData, FALSE, FALSE,
   2057                                                (dm_uri_result == SYNCML_DM_COMMAND_ON_NODE ? FALSE : TRUE),
   2058                                                pUserData, SYNCML_DM_RESULT_VALUE::Enum_Result_Get,
   2059                                                p_get_struct_data );
   2060                        }
   2061                        break;
   2062 
   2063                     case SYNCML_DM_COMMAND_LIST_STRUCT:
   2064                     case SYNCML_DM_COMMAND_LIST_STRUCTDATA:
   2065                     case SYNCML_DM_COMMAND_LIST_TNDS:
   2066                        /* Call TNM to get the first item on the Get Struct results list */
   2067                       {
   2068                        DMGetData * pGetData = NULL;
   2069                        DMString strTargetUriNoQuery(strTargetUri);
   2070 
   2071                        // remove query from URI
   2072                        char *psQPos = DmStrstr(strTargetUri, SYNCML_DM_LIST);
   2073                        if (psQPos != NULL)
   2074                        {
   2075                            strTargetUriNoQuery.assign(strTargetUri.c_str(), psQPos - strTargetUri.c_str());
   2076                        }
   2077 
   2078                        dm_stat = dmTreeObj.InitListAndGetListFirstItem(strTargetUriNoQuery,
   2079                                                                 SYNCML_DM_GET_ON_LIST_STRUCT,
   2080                                                                 p_get_struct_data);
   2081 
   2082                        if (dm_stat == SYNCML_DM_SUCCESS)
   2083                        {
   2084                            UINT8 type = 0;
   2085                            if ( dm_uri_result == SYNCML_DM_COMMAND_LIST_STRUCT )
   2086                            {
   2087                                type = SYNCML_DM_RESULT_VALUE::Enum_Result_GetStruct;
   2088                            }
   2089                            else if ( dm_uri_result == SYNCML_DM_COMMAND_LIST_STRUCTDATA )
   2090                            {
   2091                                type = SYNCML_DM_RESULT_VALUE::Enum_Result_GetStructData;
   2092                            }
   2093                            else if ( dm_uri_result == SYNCML_DM_COMMAND_LIST_TNDS )
   2094                            {
   2095                                type = SYNCML_DM_RESULT_VALUE::Enum_Result_GetTnds;
   2096                            }
   2097                            else
   2098                            {
   2099                                dm_stat = SYNCML_DM_BAD_REQUEST;
   2100                                break;
   2101                            }
   2102                            pGetData = p_get_struct_data.psRetData; p_get_struct_data.psRetData = NULL;
   2103                            dm_stat = SaveResult( strTargetUriNoQuery.c_str(), (CPCHAR)pContent->cmdID->content,
   2104                                                  pGetData,
   2105                                                  dm_uri_result == SYNCML_DM_COMMAND_LIST_STRUCT,
   2106                                                  type != SYNCML_DM_RESULT_VALUE::Enum_Result_GetTnds,
   2107                                                  FALSE,
   2108                                                  pUserData,
   2109                                                  type,
   2110                                                  p_get_struct_data);
   2111                            if ( pGetData )
   2112                               delete pGetData;
   2113                        }
   2114                        else
   2115                            /* Free the memory of p_passedin_get_struct_data */
   2116                            pDmBuildPackage->FreeGetStructData(p_get_struct_data);
   2117                        }
   2118                        break;
   2119                     default:
   2120                        dm_stat = SYNCML_DM_FEATURE_NOT_SUPPORTED;
   2121                        break;
   2122 
   2123               }  // end switch
   2124               break;
   2125 
   2126            }
   2127            ret_stat = ProcessStatus (dm_stat,
   2128                                                    userData,
   2129                                                    (UINT8*)pContent->cmdID->content,
   2130                                                    p_get_item,
   2131                                                    SYNCML_DM_GET);
   2132            if (ret_stat != SYNCML_DM_SUCCESS)
   2133            {
   2134                   sml_ret_stat = SML_ERR_UNSPECIFIC;
   2135                   break;
   2136            }
   2137 
   2138           /* Move to the next item */
   2139           if (p_get_list_item->next != NULL)
   2140            {
   2141                       p_get_list_item = p_get_list_item->next;
   2142                 p_get_item = p_get_list_item->item;
   2143           }
   2144           else
   2145                 p_get_item = NULL;
   2146       } /* End of while */
   2147 
   2148    }
   2149    else
   2150    { /* !inAtomicCommand && dmSecState */  /* inAtomicCommand == TRUE || dmSecState not authenticated */
   2151 
   2152       if (pDmMgmtSessionObj->GetInAtomicCommand() == TRUE)
   2153       {
   2154          AtomicRollback(userData);
   2155          dm_stat = SYNCML_DM_COMMAND_FAILED; /* We don't apply commands within the Atomic.*/
   2156       }
   2157       else
   2158           dm_stat = pDmMgmtSessionObj->GetNotAuthorizedStatus();
   2159 
   2160       ret_stat = SaveCommandRefStatus(
   2161                                                (UINT8 *)pContent->cmdID->content,
   2162                                            (UINT8 *)dm_command_name_table[SYNCML_DM_GET],
   2163                                             p_get_item,
   2164                                             dm_stat,
   2165                                             pUserData);
   2166        if (ret_stat != SYNCML_DM_SUCCESS)
   2167              sml_ret_stat = SML_ERR_UNSPECIFIC;
   2168   }
   2169 
   2170     /* Free the memory */
   2171   smlFreeGetPut(pContent);
   2172   pContent = NULL;
   2173 
   2174   return (sml_ret_stat);
   2175 }
   2176 
   2177 
   2178 /*==================================================================================================
   2179 FUNCTION        : HandleReplaceCommand
   2180 
   2181 DESCRIPTION     : When the REPLACE element is processed from the received message, this callback
   2182                   function will be called.
   2183 
   2184                   This function will perform the following operations:
   2185                   1) Call DMTree::Replace() function to perform REPLACE command on the DM
   2186                      tree.
   2187                   2) Call SYNCML_DM_BuildPackage::BuildStatus() to build up the staus command with
   2188                      return status for each REPLACE command performed.
   2189 ARGUMENT PASSED : id
   2190                   userData
   2191                   pContent
   2192 OUTPUT PARAMETER:
   2193 RETURN VALUE    : SML_ERR_OK or ERR code
   2194 IMPORTANT NOTES :
   2195 
   2196 
   2197 ==================================================================================================*/
   2198 Ret_t
   2199 HandleReplaceCommand (InstanceID_t    id,
   2200                       VoidPtr_t       userData,
   2201                       SmlReplacePtr_t pContent)
   2202 {
   2203       return ProcessCommand(id, userData, pContent,SYNCML_DM_REPLACE);
   2204 }
   2205 
   2206 
   2207 /*==================================================================================================
   2208 FUNCTION        : HandleStartSequenceCommand
   2209 
   2210 DESCRIPTION     : When the SEQUENCE element is processed from the received message, this callback
   2211                   function will be called.
   2212 
   2213                   This function will perform the following operations:
   2214 
   2215 ARGUMENT PASSED : id
   2216                   userData
   2217                   pContent
   2218 OUTPUT PARAMETER:
   2219 RETURN VALUE    : SML_ERR_OK or ERR code
   2220 IMPORTANT NOTES :
   2221 
   2222 
   2223 ==================================================================================================*/
   2224 Ret_t
   2225 HandleStartSequenceCommand(InstanceID_t id,
   2226                            VoidPtr_t    userData,
   2227                            SmlSequencePtr_t  pContent)
   2228 {
   2229     Ret_t                  sml_ret_stat = SML_ERR_OK;
   2230     SYNCML_DM_RET_STATUS_T ret_stat;
   2231     SYNCML_DM_USER_DATA_T   *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   2232     SYNCML_DM_RET_STATUS_T     dm_stat = SYNCML_DM_SUCCESS;
   2233 
   2234           ret_stat = pDmBuildPackage->GenerateAlertForLOB(DM_COMMAND_SEQUENCE_START);
   2235 
   2236     if (ret_stat != SYNCML_DM_SUCCESS)
   2237     {
   2238     /* Free the memory of pContent. Toolkit use same API to free the memory for atomic and
   2239        sequence */
   2240     smlFreeAtomic((SmlAtomicPtr_t)pContent);
   2241         return SML_ERR_OK;
   2242     }
   2243   pUserData->StartSequence();
   2244 
   2245   if (pDmMgmtSessionObj->IsAuthorized())
   2246         dm_stat = SYNCML_DM_SUCCESS;
   2247   else
   2248         dm_stat = pDmMgmtSessionObj->GetNotAuthorizedStatus();
   2249 
   2250     pDmMgmtSessionObj->IncCommandCount(); /* This variable is used to check if syncml document has
   2251                                            * any management commands */
   2252 
   2253     /* Call the toolkit to construct the STATUS for SEQUENCE command */
   2254     ret_stat = SaveStatus(
   2255                           (UINT8 *)pContent->cmdID->content,
   2256                           (UINT8 *)dm_command_name_table[SYNCML_DM_SEQUENCE],
   2257                            NULL,
   2258                            NULL,
   2259                            dm_stat,
   2260                            NULL,
   2261                            pUserData );
   2262 
   2263     if (ret_stat != SYNCML_DM_SUCCESS)
   2264     {
   2265         sml_ret_stat = SML_ERR_UNSPECIFIC;
   2266     }
   2267 
   2268     /* Free the memory of pContent. Toolkit use same API to free the memory for atomic and
   2269        sequence */
   2270     smlFreeAtomic((SmlAtomicPtr_t)pContent);
   2271 
   2272     return sml_ret_stat;
   2273 }
   2274 
   2275 /*==================================================================================================
   2276 FUNCTION        : HandleEndSequenceCommand
   2277 
   2278 DESCRIPTION     : When the SEQUENCE element is processed from the received message, this callback
   2279                   function will be called.
   2280 
   2281                   This function will perform the following operations:
   2282 
   2283 ARGUMENT PASSED : id
   2284                   userData
   2285 OUTPUT PARAMETER:
   2286 RETURN VALUE    : SML_ERR_OK or ERR code
   2287 IMPORTANT NOTES :
   2288 
   2289 
   2290 ==================================================================================================*/
   2291 Ret_t
   2292 HandleEndSequenceCommand(InstanceID_t id,
   2293                          VoidPtr_t    userData)
   2294 {
   2295     /* We don't need to do anything special for the End Sequence.*/
   2296     SYNCML_DM_USER_DATA_T *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   2297 
   2298     if(pUserData)
   2299         pUserData->EndSequence();
   2300     return SML_ERR_OK;
   2301 }
   2302 
   2303 
   2304 
   2305 /*==================================================================================================
   2306 FUNCTION        : HandleStartAtomicCommand
   2307 
   2308 DESCRIPTION     : When the ATOMIC element is processed from the received message, this callback
   2309                   function will be called.
   2310 
   2311                   This function will perform the following operations:
   2312 
   2313 ARGUMENT PASSED : id
   2314                   userData
   2315                   pContent
   2316 OUTPUT PARAMETER:
   2317 RETURN VALUE    : SML_ERR_OK or ERR code
   2318 IMPORTANT NOTES :
   2319 
   2320 
   2321 ==================================================================================================*/
   2322 Ret_t
   2323 HandleStartAtomicCommand(InstanceID_t id,
   2324                          VoidPtr_t    userData,
   2325                          SmlAtomicPtr_t  pContent)
   2326 {
   2327   Ret_t                  sml_ret_stat = SML_ERR_OK;
   2328   SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   2329   SYNCML_DM_USER_DATA_T   *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   2330 
   2331   dm_stat = pDmBuildPackage->GenerateAlertForLOB(DM_COMMAND_ATOMIC_START);
   2332 
   2333     if (dm_stat != SYNCML_DM_SUCCESS)
   2334     {
   2335          smlFreeAtomic(pContent  );
   2336         return SML_ERR_OK;
   2337     }
   2338 
   2339   if (pDmMgmtSessionObj->IsAuthorized())
   2340   {
   2341     if(pDmMgmtSessionObj->GetInAtomicCommand())
   2342     { // nested atomics are not allowed
   2343       SaveStatus((UINT8 *)pContent->cmdID->content,
   2344                           (UINT8 *)dm_command_name_table[SYNCML_DM_ATOMIC],
   2345                            NULL,
   2346                            NULL,
   2347                            SYNCML_DM_COMMAND_FAILED,
   2348                            NULL,
   2349                            pUserData);
   2350       smlFreeAtomic(pContent  );
   2351       return sml_ret_stat;
   2352     }
   2353 
   2354     dm_stat=dmTreeObj.GetLockContextManager().ReleaseIDInternal(SYNCML_DM_LOCKID_CURRENT, SYNCML_DM_ATOMIC);
   2355 
   2356     if ( dm_stat != SYNCML_DM_SUCCESS && dm_stat != SYNCML_DM_FEATURE_NOT_SUPPORTED )
   2357     {
   2358       smlFreeAtomic(pContent  );
   2359       return SML_ERR_UNSPECIFIC;
   2360     }
   2361 
   2362     /* Remember that we are in an Atomic command.*/
   2363     pDmMgmtSessionObj->SetInAtomicCommand(TRUE);
   2364 
   2365     // Save the data for the status
   2366     pUserData->pAtomicStatus.bValueSet = TRUE;
   2367     pUserData->pAtomicStatus.pCmdId = (CPCHAR)pContent->cmdID->content;
   2368     pUserData->pAtomicStatus.pCmdName = dm_command_name_table[SYNCML_DM_ATOMIC];
   2369     pUserData->pAtomicStatus.status = dm_stat;
   2370   }
   2371   else
   2372   {
   2373     dm_stat = SaveStatus((UINT8 *)pContent->cmdID->content,
   2374                                       (UINT8 *)dm_command_name_table[SYNCML_DM_ATOMIC],
   2375                                        NULL,
   2376                                        NULL,
   2377                                        pDmMgmtSessionObj->GetNotAuthorizedStatus(),
   2378                                        NULL,
   2379                                        pUserData);
   2380     if (dm_stat != SYNCML_DM_SUCCESS)
   2381       sml_ret_stat = SML_ERR_UNSPECIFIC;
   2382   }
   2383   smlFreeAtomic(pContent  );
   2384   return sml_ret_stat;
   2385 }
   2386 
   2387 
   2388 /*==================================================================================================
   2389 FUNCTION        : HandleEndAtomicCommand
   2390 
   2391 DESCRIPTION     : When the End ATOMIC element is processed from the received message, this callback
   2392                   function will be called.
   2393 
   2394                   This function will perform the following operations:
   2395 
   2396 ARGUMENT PASSED : id
   2397                   userData
   2398 OUTPUT PARAMETER:
   2399 RETURN VALUE    : SML_ERR_OK or ERR code
   2400 IMPORTANT NOTES :
   2401 
   2402 
   2403 ==================================================================================================*/
   2404 Ret_t
   2405 HandleEndAtomicCommand(InstanceID_t id,
   2406                        VoidPtr_t    userData)
   2407 {
   2408   Ret_t                  sml_ret_stat = SML_ERR_OK;
   2409   SYNCML_DM_USER_DATA_T   *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   2410   SYNCML_DM_RET_STATUS_T retStatus=SYNCML_DM_SUCCESS;
   2411 
   2412   if (pDmMgmtSessionObj->IsAuthorized())
   2413   {
   2414      pDmMgmtSessionObj->SetInAtomicCommand(FALSE);
   2415 
   2416     if ( !pUserData->rollback )
   2417     {
   2418       retStatus=dmTreeObj.GetLockContextManager().ReleaseIDInternal(SYNCML_DM_LOCKID_CURRENT, SYNCML_DM_COMMIT);
   2419 
   2420       if ( retStatus != SYNCML_DM_SUCCESS && retStatus != SYNCML_DM_FEATURE_NOT_SUPPORTED)
   2421         return SML_ERR_UNSPECIFIC;
   2422      }
   2423 
   2424     /* We are now out of the Atomic command.*/
   2425     UINT8 *p_SourceRefData = !pUserData->pAtomicStatus.pSource.empty() ?
   2426                                                      (UINT8 *)(pUserData->pAtomicStatus.pSource.c_str()) : NULL;
   2427     UINT8 *p_TargetRefData = !pUserData->pAtomicStatus.pTarget.empty() ?
   2428                                                      (UINT8 *)pUserData->pAtomicStatus.pTarget.c_str() : NULL;
   2429 
   2430     retStatus = SaveStatus((UINT8 *)pUserData->pAtomicStatus.pCmdId.c_str(),
   2431                                          (UINT8 *)pUserData->pAtomicStatus.pCmdName.c_str(),
   2432                                          p_SourceRefData,
   2433                                          p_TargetRefData,
   2434                                          pUserData->pAtomicStatus.status,
   2435                                          NULL,
   2436                                          pUserData);
   2437 
   2438     if (retStatus != SYNCML_DM_SUCCESS)
   2439        sml_ret_stat = SML_ERR_UNSPECIFIC;
   2440 
   2441     for ( int i = 0; i <pUserData->oStatus.size(); i++ )
   2442     {
   2443        const SYNCML_DM_STATUS_DATA_T& ptrStatus = pUserData->oStatus[i];
   2444 
   2445          UINT8 *p_SourceRefData = !ptrStatus.pSource.empty() ?
   2446                                                      (UINT8 *)(ptrStatus.pSource.c_str()) : NULL;
   2447        retStatus = SaveStatus((UINT8 *)ptrStatus.pCmdId.c_str(),
   2448                               (UINT8 *)ptrStatus.pCmdName.c_str(),
   2449                               p_SourceRefData,
   2450                               (UINT8 *)ptrStatus.pTarget.c_str(),
   2451                               ptrStatus.status,
   2452                               &ptrStatus.responses,
   2453                               pUserData);
   2454 
   2455        if (retStatus != SYNCML_DM_SUCCESS)
   2456           sml_ret_stat = SML_ERR_UNSPECIFIC;
   2457     }
   2458 
   2459     pUserData->EndAtomic();
   2460   }
   2461 
   2462   return sml_ret_stat;
   2463 }
   2464 
   2465 
   2466 /*==================================================================================================
   2467 FUNCTION        : HandleStatusCommand
   2468 
   2469 DESCRIPTION     : When the STATUS element is processed from the received message, this callback
   2470                   function will be called.
   2471 
   2472                   This function will perform the following operations:
   2473                   1) Check the status code.
   2474                   2) Call TNMTree::Replace() to replace the nonce value.
   2475                   3) Update the UserAgent's Security state based on the client authentication
   2476                      status received from the server.
   2477                   4) Call SYNCML_DM_BuildPackage::BuildFinishSyncHdr() to finish our SyncHdr
   2478                   5) Determine if we need to Challenge the server
   2479                   6) Call SYNCML_DM_BuildPackage::BuildStatus() to build up our first status
   2480                      which contains our server authentication disposition.
   2481 
   2482 ARGUMENT PASSED : id
   2483                   userData
   2484                   pContent
   2485 OUTPUT PARAMETER:
   2486 RETURN VALUE    : SML_ERR_OK or ERR code
   2487 IMPORTANT NOTES :
   2488 
   2489 
   2490 ==================================================================================================*/
   2491 Ret_t
   2492 HandleStatusCommand (InstanceID_t   id,
   2493                      VoidPtr_t      userData,
   2494                      SmlStatusPtr_t pContent)
   2495 {
   2496     SYNCML_DM_USER_DATA_T  *pUserData = (SYNCML_DM_USER_DATA_T *)userData;
   2497     Ret_t                   sml_ret_stat = SML_ERR_OK;
   2498     SYNCML_DM_RET_STATUS_T  ret_stat;
   2499     SYNCML_DM_RET_STATUS_T      local_dm_stat = SYNCML_DM_SUCCESS;
   2500     UINT8                   *pClientNonce = NULL;
   2501     UINT8                   *pServerNonce = NULL;
   2502     UINT8                   *p_auth = NULL;
   2503     SYNCML_DM_RET_STATUS_T      clientAuthStatus;
   2504     SYNCML_DM_RET_STATUS_T      serverStatus;
   2505     SYNCML_DM_CHAL_TYPE_T   serverChalType = SYNCML_DM_CHAL_NONE;
   2506     UINT8                   command_id_str[UINT16_TYPE_STR_SIZE_5] = "0";
   2507     /* command_id_str reference should be "0" for header */
   2508     DM_CHALLENGE_T                  *pClientChal = NULL;
   2509     DMClientServerCreds     *pClientServerCreds;
   2510     SYNCML_DM_SEC_STATE_FLAG_T   currSecState;
   2511     SYNCMLDM_NONCE_STRING_INFO_T    *pNonceStruct = NULL;
   2512     SYNCMLDM_NONCE_GENERATE_PARAMETER_INFO_T    nonceInfo;
   2513     SmlMetInfMetInfPtr_t p_meta_info = NULL;
   2514 
   2515     /* First check if this status is for the "SyncHdr".*/
   2516     if (DmStrncmp((char *)pContent->cmd->content, SYNCML_SYNCHDR, pContent->cmd->length) == 0)
   2517     {
   2518         XPL_LOG_DM_TMN_Debug(("\ninside dm_ua_handlecommand::handleStatusCommand, synchdr command ref:%s\n\n", (char*)pContent->cmdRef->content));
   2519         /* Get the Client and Server Cred info and current Security state.*/
   2520         pClientServerCreds = pDmMgmtSessionObj->GetClientServerCreds();
   2521         currSecState = pDmMgmtSessionObj->GetSecState();
   2522 
   2523         // DP: if we have postponed nonce - save it
   2524         if ( pUserData->bNonceGenerated )
   2525         {
   2526           pUserData->bNonceGenerated = FALSE;
   2527           if ( pClientServerCreds && pClientServerCreds->pServerNonce )
   2528           {
   2529                 if ( dmTreeObj.IsVersion_12()  )
   2530                             pClientServerCreds->SaveServerAttribute(DM_AAUTHDATA, pClientServerCreds->pServerNonce);
   2531                   else
   2532                           pClientServerCreds->SaveServerAttribute(DM_SERVERNONCE, pClientServerCreds->pServerNonce);
   2533           }
   2534         }
   2535 
   2536         /* We must check the new Status value from the Server in case our Security State changed.*/
   2537         p_auth = (UINT8 *)DmAllocMem(pContent->data->length+1);
   2538         if ( p_auth == NULL )
   2539            return SYNCML_DM_DEVICE_FULL;
   2540         DmStrncpy((char *)p_auth,
   2541                 (const char *)pContent->data->content,
   2542                 pContent->data->length);
   2543         p_auth[pContent->data->length] = '\0';
   2544 
   2545         /* We always need to check the clientAuthStatus since we send creds on every message.*/
   2546         clientAuthStatus = SyncML2DMCode((char *)p_auth);
   2547         DmFreeMem(p_auth);
   2548 
   2549         XPL_LOG_DM_TMN_Debug(("\ninside dm_ua_handlecommand::handleStatusCommand, synchdr command clientAuthStatus: %d\n\n", clientAuthStatus));
   2550 
   2551         if (clientAuthStatus == SYNCML_DM_AUTHENTICATION_REQUIRED)
   2552         {
   2553             return clientAuthStatus;
   2554         }
   2555 
   2556         /* Update the client retry count */
   2557         if (clientAuthStatus  == SYNCML_DM_AUTHENTICATION_ACCEPTED ||
   2558             clientAuthStatus == SYNCML_DM_SUCCESS)
   2559         {
   2560             /* Reset client retry count when client is authenticated */
   2561             pDmMgmtSessionObj->SetClientRetryCount(0);
   2562 
   2563             // Save authPref value if needed
   2564             pClientServerCreds->SaveAuthPref();
   2565         }
   2566         else
   2567         {
   2568             /* Increment the retry count when client is not authenticated.*/
   2569             pDmMgmtSessionObj->IncClientRetryCount();
   2570         }
   2571 
   2572         /* Update the security state with the client authentication status. Note that we only
   2573          * check for cases that cause a change in the SecurityState.
   2574          */
   2575         switch (currSecState)
   2576         {
   2577             case DM_CLIENT_NO_SERVER_NO_AUTH:
   2578                 if (clientAuthStatus == SYNCML_DM_AUTHENTICATION_ACCEPTED ||
   2579                     clientAuthStatus == SYNCML_DM_SUCCESS)
   2580                 {
   2581                     currSecState = DM_CLIENT_Y_SERVER_NO_AUTH;
   2582                 }
   2583                 break;
   2584 
   2585             case DM_CLIENT_NO_SERVER_Y_AUTH:
   2586                 if (clientAuthStatus == SYNCML_DM_AUTHENTICATION_ACCEPTED ||
   2587                     clientAuthStatus == SYNCML_DM_SUCCESS)
   2588                 {
   2589                     currSecState = DM_BOTH_CLIENT_SERVER_AUTH;
   2590                 }
   2591                 break;
   2592 
   2593             case DM_CLIENT_Y_SERVER_NO_AUTH:
   2594                 if (clientAuthStatus != SYNCML_DM_AUTHENTICATION_ACCEPTED &&
   2595                     clientAuthStatus != SYNCML_DM_SUCCESS)
   2596                 {
   2597                     currSecState = DM_CLIENT_NO_SERVER_NO_AUTH;
   2598                 }
   2599                 break;
   2600 
   2601             case DM_BOTH_CLIENT_SERVER_AUTH:
   2602                 if (clientAuthStatus != SYNCML_DM_AUTHENTICATION_ACCEPTED &&
   2603                     clientAuthStatus != SYNCML_DM_SUCCESS)
   2604                 {
   2605                     currSecState = DM_CLIENT_NO_SERVER_Y_AUTH;
   2606                 }
   2607                 break;
   2608         }
   2609 
   2610         /* Update the UserAgent Security state in case it changed.*/
   2611         pDmMgmtSessionObj->SetSecState(currSecState);
   2612 
   2613         if ((pContent->chal != NULL) && (pContent->chal->meta != NULL))
   2614         {
   2615             /* We were challenged in the SyncHdr, so we need to build our creditials in the package.*/
   2616             if (currSecState == DM_CLIENT_NO_SERVER_NO_AUTH ||
   2617                 currSecState == DM_CLIENT_NO_SERVER_Y_AUTH)
   2618             {
   2619                 /* If the client has not been authenticated yet, increment the commandCount so
   2620                  * we'll still respond even if there are no other operational commmands.
   2621                  * But if the client has already been authenticated, then we won't increment since
   2622                  * this may be the end of the session.  In that case, the nonce will be used
   2623                  * in the next session.
   2624                  */
   2625                 pDmMgmtSessionObj->IncCommandCount();
   2626             }
   2627 
   2628             p_meta_info = (sml_metinf_metinf_s *)pContent->chal->meta->content;
   2629 
   2630             /* Check the Type.*/
   2631             if (p_meta_info->type != NULL)
   2632             {
   2633                 /* Check which type of challenge was sent.*/
   2634                 if (smlLibStrncmp((char *)p_meta_info->type->content, SYNCML_AUTH_MAC,
   2635                                   p_meta_info->type->length) == 0)
   2636                 {
   2637                     /* We received a challenge for HMAC-MD5.*/
   2638                     serverChalType = SYNCML_DM_CHAL_HMAC;
   2639                 }
   2640                 else if (smlLibStrncmp((char *)p_meta_info->type->content, SYNCML_AUTH_MD5,
   2641                                        p_meta_info->type->length) == 0)
   2642                 {
   2643                     /* We received a challenge for MD5.*/
   2644                     serverChalType = SYNCML_DM_CHAL_MD5;
   2645                 }
   2646                 else
   2647                 {
   2648                     /* We received a challenge for Basic security.*/
   2649                     serverChalType = SYNCML_DM_CHAL_BASIC;
   2650                 }
   2651             }
   2652 
   2653             // DP switch to new auth type if needed
   2654             if ( dmTreeObj.IsVersion_12()  )
   2655             {
   2656                 local_dm_stat = pClientServerCreds->SetPrefClientAuth(serverChalType);
   2657                 if ( local_dm_stat != SYNCML_DM_SUCCESS )
   2658                 {
   2659                         pDmMgmtSessionObj->SetClientRetryCount(MAX_AUTH_RETRY+1);
   2660                 }
   2661             }
   2662             /* Get the nextnonce sent to us from the server.*/
   2663             if (p_meta_info->nextnonce != NULL)
   2664             {
   2665                 pClientNonce = (UINT8 *)DmAllocMem(p_meta_info->nextnonce->length + 1);
   2666                 if ( pClientNonce == NULL )
   2667                    return SYNCML_DM_DEVICE_FULL;
   2668                 memcpy(pClientNonce,
   2669                        p_meta_info->nextnonce->content,
   2670                        p_meta_info->nextnonce->length);
   2671                 pClientNonce[p_meta_info->nextnonce->length] = '\0';
   2672 
   2673                 /* Save the new ClientNonce in the Tree.*/
   2674                   if ( dmTreeObj.IsVersion_12()  )
   2675                         local_dm_stat = pClientServerCreds->SaveClientAttribute(DM_AAUTHDATA, (CPCHAR)pClientNonce);
   2676                   else
   2677                           local_dm_stat = pClientServerCreds->SaveClientAttribute(DM_CLIENTNONCE, (CPCHAR)pClientNonce);
   2678                 /* Note that we continue even if we failed to store the clientNonce.*/
   2679                 pClientServerCreds->pClientNonce = (const char*)pClientNonce;
   2680                 DmFreeMem(pClientNonce);
   2681 
   2682                 /* Note that we continue even if we failed to store the clientNonce.*/
   2683             }
   2684         } /* If chal != NULL */
   2685 
   2686         /* Call the method to finish our SyncHdr and start the toolkit message.*/
   2687         ret_stat = pDmBuildPackage->BuildFinishSyncHdr(serverChalType);
   2688         if (ret_stat != SYNCML_DM_SUCCESS)
   2689         {
   2690             sml_ret_stat = SML_ERR_UNSPECIFIC;
   2691             synchdr_dm_stat = SYNCML_DM_BAD_REQUEST;
   2692         }
   2693 
   2694         /* Determine if we need to challenge the server. Note that we will challange
   2695          * the Server even if it has already been authenticated (hmac/md5 only).*/
   2696         if ( (currSecState == DM_CLIENT_NO_SERVER_NO_AUTH ||
   2697             currSecState == DM_CLIENT_Y_SERVER_NO_AUTH) &&
   2698             pClientServerCreds->ServerChalType > SYNCML_DM_CHAL_BASIC )
   2699         { // generate new nonce if required
   2700             DMGetData devID;
   2701             /* First we need to generate a new nextNonce for the server.*/
   2702             nonceInfo.pb_user_name = (UINT8*)pClientServerCreds->pClientUserName.c_str();
   2703             nonceInfo.pb_password = (UINT8*)pClientServerCreds->pServerPW.c_str();
   2704             nonceInfo.pb_server_id = (UINT8*)pClientServerCreds->pServerId.c_str();
   2705 
   2706             dmTreeObj.Get(DM_DEV_INFO_DEVID_URI, devID,SYNCML_DM_REQUEST_TYPE_INTERNAL);
   2707 
   2708             pNonceStruct = syncmldm_sec_generate_nonce(&nonceInfo,devID.getCharData());
   2709             if ( pNonceStruct == NULL )
   2710             {
   2711                 return SYNCML_DM_COMMAND_FAILED;
   2712             }
   2713 
   2714             /* Copy the new Server Nonce.*/
   2715             pServerNonce = (UINT8 *)DmAllocMem(pNonceStruct->w_nonce_string_length + 1);
   2716             if ( pServerNonce == NULL )
   2717             {
   2718                 DmFreeMem(pNonceStruct);
   2719                 return SYNCML_DM_DEVICE_FULL;
   2720             }
   2721             memcpy(pServerNonce, pNonceStruct->ab_nonce_string,
   2722                    pNonceStruct->w_nonce_string_length);
   2723             pServerNonce[pNonceStruct->w_nonce_string_length] = '\0';
   2724 
   2725             /* Store the new ServerNonce in the Tree.*/
   2726             // DP: don't save nonce in the tree yet, since server answer can be empty packet and
   2727             // we can end session without sending it to the server
   2728             pUserData->bNonceGenerated = TRUE;
   2729             DmFreeMem(pNonceStruct);
   2730 
   2731             /* Note we continue even if we failed to store the serverNonce.*/
   2732             pClientServerCreds->pServerNonce = (const char*)pServerNonce;
   2733             DmFreeMem(pServerNonce);
   2734         }
   2735 
   2736         if (currSecState == DM_CLIENT_NO_SERVER_NO_AUTH ||
   2737             currSecState == DM_CLIENT_Y_SERVER_NO_AUTH ||
   2738             pClientServerCreds->ServerChalType >= SYNCML_DM_CHAL_MD5 ) { // no authenticated or needs chal
   2739           /* Setup the Client Challenge information.*/
   2740           pClientChal = (DM_CHALLENGE_T *)DmAllocMem(sizeof(DM_CHALLENGE_T));
   2741           if ( pClientChal == NULL )
   2742           {
   2743              return SYNCML_DM_DEVICE_FULL;
   2744           }
   2745 
   2746           if ( pClientServerCreds->ServerChalType == SYNCML_DM_CHAL_HMAC )
   2747                 pClientChal->pChalType = (UINT8 *) SYNCML_AUTH_MAC;
   2748           else if ( pClientServerCreds->ServerChalType == SYNCML_DM_CHAL_MD5 )
   2749                 pClientChal->pChalType = (UINT8 *) SYNCML_AUTH_MD5;
   2750           else
   2751                 pClientChal->pChalType = (UINT8 *) SYNCML_AUTH_BASIC;
   2752 
   2753           pClientChal->pChalFormat = (UINT8 *)SYNCML_B64;
   2754           pClientChal->pChalNonce = pClientServerCreds->ServerChalType >= SYNCML_DM_CHAL_MD5 ?
   2755             (UINT8*)pClientServerCreds->pServerNonce.c_str() : NULL;
   2756         }
   2757 
   2758         /* Set the Server's authentication status.*/
   2759         if (currSecState == DM_CLIENT_NO_SERVER_NO_AUTH ||
   2760             currSecState == DM_CLIENT_Y_SERVER_NO_AUTH)
   2761           synchdr_dm_stat = pDmMgmtSessionObj->GetNotAuthorizedStatus();
   2762 
   2763         /* Now that our SyncHdr is header is closed, we need to create our first status.
   2764          * Call the toolkit to construct STATUS for SyncHdr */
   2765         SmlStatusPtr_t pStatus = pDmBuildPackage->AllocateStatus(
   2766             command_id_str,
   2767             (UINT8 *)dm_command_name_table[SYNCML_DM_HEADER],
   2768             NULL,   /* Source URI, it's not needed for SyncHdr STATUS */
   2769             NULL,   /* Target URI, it's not needed for SyncHdr STATUS */
   2770             pClientChal,
   2771             synchdr_dm_stat, NULL );
   2772         if ( pStatus ) {
   2773             ret_stat = pDmBuildPackage->BuildStatus( pStatus );
   2774             smlFreeStatus(pStatus);
   2775         }
   2776         else
   2777           ret_stat = SYNCML_DM_FAIL;
   2778 
   2779         DmFreeMem(pClientChal);
   2780 
   2781         if (ret_stat != SYNCML_DM_SUCCESS)
   2782         {
   2783             sml_ret_stat = SML_ERR_UNSPECIFIC;
   2784         }
   2785     } /* SyncHdr check */
   2786 
   2787     /* Check if this Status is for our "Replace" command (Our DevInfo) */
   2788     else if (DmStrncmp((char *)pContent->cmd->content, SYNCML_REPLACE, pContent->cmd->length) == 0)
   2789     {
   2790           XPL_LOG_DM_TMN_Debug(("\ninside dm_ua_handlecommand::handleStatusCommand, replace command ref:%s\n\n", (char*)pContent->cmdRef->content));
   2791           /* Determine the serverStatus for our DevInfo.*/
   2792           p_auth = (UINT8 *)DmAllocMem(pContent->data->length+1);
   2793           if ( p_auth == NULL )
   2794           {
   2795              return SYNCML_DM_DEVICE_FULL;
   2796           }
   2797           DmStrncpy((char *)p_auth,
   2798                     (const char *)pContent->data->content,
   2799                     pContent->data->length);
   2800           p_auth[pContent->data->length] = '\0';
   2801           serverStatus = SyncML2DMCode((char *)p_auth);
   2802           DmFreeMem(p_auth);
   2803 
   2804           /* We only resend the DevInfo in the case of Authentication failure.*/
   2805           if (serverStatus == SYNCML_DM_UNAUTHORIZED)
   2806           {
   2807               /* Call the method to build our DevInfo into the REPLACE command for this package. */
   2808               ret_stat = pDmBuildPackage->BuildReplaceCommand();
   2809               if (ret_stat != SYNCML_DM_SUCCESS)
   2810               {
   2811                   sml_ret_stat = SML_ERR_UNSPECIFIC;
   2812               }
   2813           }
   2814           else if (serverStatus == SYNCML_DM_AUTHENTICATION_REQUIRED)
   2815           {
   2816               return serverStatus;
   2817           }
   2818     } /* Replace check */
   2819 
   2820     /* Check if this Status is for our "Alert" command (Our SessionDirection) */
   2821     else if (DmStrncmp((char *)pContent->cmd->content, SYNCML_ALERT, pContent->cmd->length) == 0 &&
   2822              DmStrncmp((char *)pContent->cmdRef->content, "1", pContent->cmdRef->length) == 0)
   2823     {
   2824           XPL_LOG_DM_TMN_Debug(("\ninside dm_ua_handlecommand::handleStatusCommand, alert command ref:%s\n\n", (char*)pContent->cmdRef->content));
   2825           /* Determine the serverStatus for our Alert (Session Direction).*/
   2826           p_auth = (UINT8 *)DmAllocMem(pContent->data->length+1);
   2827           if ( p_auth == NULL )
   2828           {
   2829               return SYNCML_DM_DEVICE_FULL;
   2830           }
   2831           DmStrncpy((char *)p_auth,
   2832                     (const char *)pContent->data->content,
   2833                     pContent->data->length);
   2834           p_auth[pContent->data->length] = '\0';
   2835           serverStatus = SyncML2DMCode((char *)p_auth);
   2836           DmFreeMem(p_auth);
   2837 
   2838           /* We only resend the DevInfo in the case of Authentication failure.*/
   2839           if (serverStatus == SYNCML_DM_UNAUTHORIZED)
   2840           {
   2841               /* Call the method to build our DevInfo into the REPLACE command for this package. */
   2842               ret_stat = pDmBuildPackage->BuildAlertCommand(pDmBuildPackage->getDirection(), NULL, NULL);
   2843               if (ret_stat != SYNCML_DM_SUCCESS)
   2844               {
   2845                   sml_ret_stat = SML_ERR_UNSPECIFIC;
   2846               }
   2847               /* Call the method to build 1226 command for this package. */
   2848               ret_stat = pDmBuildPackage->BuildAlert1226Command();
   2849               if (ret_stat != SYNCML_DM_SUCCESS)
   2850               {
   2851                   sml_ret_stat = SML_ERR_UNSPECIFIC;
   2852               }
   2853           }
   2854           else if (serverStatus == SYNCML_DM_AUTHENTICATION_REQUIRED)
   2855           {
   2856               return serverStatus;
   2857           }
   2858     } /* Replace check */
   2859 
   2860     /* Free the memory we allocated. */
   2861     smlFreeStatus(pContent);
   2862 
   2863     return sml_ret_stat;
   2864 }
   2865 
   2866 bool VerifyAlertItems(SmlAlertPtr_t  pContent)
   2867 {
   2868    if ( pContent == NULL )
   2869    {
   2870      return false;
   2871    }
   2872 
   2873    // Verify first alert item is not NULL.
   2874    SmlItemListPtr_t  p_alert_list_item;
   2875    p_alert_list_item = pContent->itemList;
   2876    if (p_alert_list_item == NULL)
   2877    {
   2878       return false;
   2879    }
   2880 
   2881    SmlItemPtr_t         p_alert_item;
   2882    p_alert_item = p_alert_list_item->item;
   2883    if (p_alert_item == NULL)
   2884    {
   2885       return false;
   2886    }
   2887 
   2888    // Verify second alert item is not NULL.
   2889    p_alert_list_item = p_alert_list_item->next;
   2890    if (p_alert_list_item == NULL)
   2891    {
   2892       return false;
   2893    }
   2894 
   2895    p_alert_item = p_alert_list_item->item;
   2896    if (p_alert_item == NULL)
   2897    {
   2898       return false;
   2899    }
   2900 
   2901    // Verify no more than 2 items are specified in alert.
   2902    p_alert_list_item = p_alert_list_item->next;
   2903    if (p_alert_list_item != NULL)
   2904    {
   2905       return false;
   2906    }
   2907 
   2908    return true;
   2909 }
   2910