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: SYNCML_DM_BuildPackage.cc 20 21 General Description: Implementation of SYNCML_DM_BuildPackage class. 22 23 ==================================================================================================*/ 24 25 #include "SYNCML_DM_BuildPackage.H" 26 #include "dm_security.h" 27 #include "dmProcessScriptSession.h" 28 #include "GeneratePassword.H" 29 #include "dmt.hpp" 30 #include "dm_tree_util.h" 31 #include "xpl_File.h" 32 33 extern "C" { 34 #include "xpt-b64.h" 35 #include "md5.h" 36 #ifdef __SML_XML__ 37 #include <smldef.h> 38 #endif 39 #include <string.h> 40 41 #include "xlttags.h" 42 43 #ifdef __SML_XML__ 44 extern const ESCAPE_CHAR_TABLE_T escape_char_table[]; 45 #endif 46 } 47 48 /*================================================================================================== 49 FUNCTION : SYNCML_DM_BuildPackage::SYNCML_DM_BuildPackage 50 51 DESCRIPTION : The SYNCML_DM_BuildPackage class constructor. 52 ARGUMENT PASSED : 53 OUTPUT PARAMETER: 54 RETURN VALUE : 55 IMPORTANT NOTES : 56 ==================================================================================================*/ 57 SYNCML_DM_BuildPackage::SYNCML_DM_BuildPackage() 58 { 59 commandId = 1; 60 messageId = 1; 61 MaxMessageSize = g_iDMWorkspaceSize; //DM_MAX_MSG_SIZE; 62 MaxObjectSize = 0; 63 64 pSyncHdr = NULL; 65 66 /* We need the MgmtSessionObj pointer and current sendInstanceId.*/ 67 pDmMgmtSessionObj = NULL; 68 sendInstanceId = 0; 69 sessionDirection = SYNCML_DM_CLIENT_INITIATED_SESSION; 70 #ifdef LOB_SUPPORT 71 m_pChunkData = NULL; 72 LargeObjectClear(); 73 #endif 74 } 75 76 77 /*================================================================================================== 78 FUNCTION : SYNCML_DM_BuildPackage::~SYNCML_DM_BuildPackage 79 80 DESCRIPTION : The SYNCML_DM_BuildPackage class destructor. 81 ARGUMENT PASSED : 82 OUTPUT PARAMETER: 83 RETURN VALUE : 84 IMPORTANT NOTES : 85 ==================================================================================================*/ 86 SYNCML_DM_BuildPackage::~SYNCML_DM_BuildPackage() 87 { 88 Cleanup(); 89 #ifdef LOB_SUPPORT 90 LargeObjectClear(); 91 #endif 92 } 93 94 void SYNCML_DM_BuildPackage::Cleanup() 95 { 96 smlFreeSyncHdr(pSyncHdr); 97 98 pMessageIdOfServer = NULL; 99 pSyncHdr = NULL; 100 101 } 102 103 void SYNCML_DM_BuildPackage::Init(DMProcessScriptSession * pSession) 104 { 105 pMessageIdOfServer = NULL; 106 commandId = 1; 107 MaxMessageSize = g_iDMWorkspaceSize; //DM_MAX_MSG_SIZE; 108 pSyncHdr = NULL; 109 110 /* We need the MgmtSessionObj pointer and current sendInstanceId.*/ 111 pDmMgmtSessionObj = pSession; 112 sendInstanceId = pSession->GetSendInstanceId(); 113 114 } 115 116 /*================================================================================================== 117 FUNCTION : SYNCML_DM_BuildPackage::operator new 118 119 DESCRIPTION : Operators to allocate memory for operation. 120 ARGUMENT PASSED : sz 121 OUTPUT PARAMETER: 122 RETURN VALUE : 123 IMPORTANT NOTES : 124 ==================================================================================================*/ 125 void * SYNCML_DM_BuildPackage::operator new(size_t sz) 126 { 127 return (DmAllocMem(sz)); 128 } 129 130 /*================================================================================================== 131 FUNCTION : SYNCML_DM_BuildPackage::operator delete 132 133 DESCRIPTION : Operators to delete memory for operation. 134 ARGUMENT PASSED : buf 135 OUTPUT PARAMETER: 136 RETURN VALUE : 137 IMPORTANT NOTES : 138 ==================================================================================================*/ 139 void SYNCML_DM_BuildPackage::operator delete(void *buf) 140 { 141 DmFreeMem(buf); 142 } 143 144 /*================================================================================================== 145 FUNCTION : SYNCML_DM_BuildPackage::GetMaxMessageSize 146 147 DESCRIPTION : This function returns the value of MaxMessageSize. 148 ARGUMENT PASSED : 149 OUTPUT PARAMETER: 150 RETURN VALUE : MaxMessageSize 151 IMPORTANT NOTES : 152 ==================================================================================================*/ 153 UINT32 154 SYNCML_DM_BuildPackage::GetMaxMessageSize() const 155 { 156 return (MaxMessageSize); 157 } 158 159 /*================================================================================================== 160 FUNCTION : SYNCML_DM_BuildPackage::GetMaxObjectSize 161 162 DESCRIPTION : This function returns the value of MaxObjectSize. 163 ARGUMENT PASSED : 164 OUTPUT PARAMETER: 165 RETURN VALUE : MaxMessageSize 166 IMPORTANT NOTES : 167 ==================================================================================================*/ 168 UINT32 169 SYNCML_DM_BuildPackage::GetMaxObjectSize() const 170 { 171 return (MaxObjectSize); 172 } 173 174 /*================================================================================================== 175 FUNCTION : SYNCML_DM_BuildPackage::SetMaxMessageSize 176 177 DESCRIPTION : This function sets the value of MaxMessageSize. 178 ARGUMENT PASSED : passedin_MaxMsgSize 179 OUTPUT PARAMETER: 180 RETURN VALUE : 181 IMPORTANT NOTES : 182 ==================================================================================================*/ 183 void 184 SYNCML_DM_BuildPackage::SetMaxMessageSize(UINT32 passedin_MaxMsgSize) 185 { 186 MaxMessageSize = passedin_MaxMsgSize; 187 } 188 189 /*================================================================================================== 190 FUNCTION : SYNCML_DM_BuildPackage::SetMaxObjectSize 191 192 DESCRIPTION : This function sets the value of MaxObjectSize. 193 ARGUMENT PASSED : passedin_MaxObjSize 194 OUTPUT PARAMETER: 195 RETURN VALUE : 196 IMPORTANT NOTES : 197 ==================================================================================================*/ 198 void 199 SYNCML_DM_BuildPackage::SetMaxObjectSize(UINT32 passedin_MaxObjSize) 200 { 201 MaxObjectSize = passedin_MaxObjSize; 202 } 203 204 /*================================================================================================== 205 FUNCTION : SYNCML_DM_BuildPackage::FreeGetStructData 206 207 DESCRIPTION : This method will free the memeroy for the struct SYNCML_DM_GET_STRUCT_RET_DATA_T. 208 ARGUMENT PASSED : 209 OUTPUT PARAMETER: 210 RETURN VALUE : 211 IMPORTANT NOTES : 212 ==================================================================================================*/ 213 void 214 SYNCML_DM_BuildPackage:: FreeGetStructData(SYNCML_DM_GET_ON_LIST_RET_DATA_T& p_GetStructData) 215 { 216 if (p_GetStructData.psRetData != NULL) 217 { 218 delete p_GetStructData.psRetData; 219 p_GetStructData.psRetData = NULL; 220 } 221 } 222 223 /*================================================================================================== 224 FUNCTION : SYNCML_DM_BuildPackage::BuildPcData 225 226 DESCRIPTION : This method will build up the PC data structure. 227 ARGUMENT PASSED : content_type 228 extension 229 p_Content 230 OUTPUT PARAMETER: p_PcData 231 RETURN VALUE : 232 IMPORTANT NOTES : The calling function will not check the return value, since when memory allocation 233 fails, the phone will panic. 234 ==================================================================================================*/ 235 void 236 SYNCML_DM_BuildPackage::BuildPcData (SmlPcdataPtr_t p_PcData, 237 SmlPcdataType_t content_type, 238 SmlPcdataExtension_t extension, 239 UINT32 dataSize, 240 UINT8 *p_Content) 241 { 242 BOOLEAN bEscapeChar = FALSE; 243 #ifdef __SML_XML__ 244 CPCHAR dm_escape_env = XPL_DM_GetEnv(SYNCML_DM_ESCAPE_CHAR); 245 #endif 246 247 p_PcData->contentType = content_type; 248 p_PcData->extension = extension; 249 p_PcData->length = dataSize; 250 251 if (p_PcData->content != NULL) { 252 DmFreeMem(p_PcData->content); 253 } 254 255 #ifdef __SML_XML__ 256 if (dm_escape_env && content_type == SML_PCDATA_STRING ) 257 { 258 INT32 nLen = dataSize; 259 260 while ( nLen > 0 ) 261 { 262 nLen--; 263 264 if ( p_Content[nLen] == '&' || p_Content[nLen] == '<' || 265 p_Content[nLen] == '>' || p_Content[nLen] == '\\' || 266 p_Content[nLen] == '"' ) 267 { 268 269 UINT32 i=0; 270 for (i = 0; escape_char_table[i].escape_str != NULL; i++) 271 if ( escape_char_table[i].token == p_Content[nLen]) 272 { 273 dataSize += smlLibStrlen( escape_char_table[i].escape_str); 274 bEscapeChar = FALSE; 275 break; 276 } 277 } 278 } 279 } 280 #endif 281 282 283 p_PcData->content = (UINT8 *)DmAllocMem(dataSize+1); 284 if ( p_PcData->content == NULL ) 285 return; 286 287 memset(p_PcData->content, 0, dataSize+1); 288 289 if(bEscapeChar == FALSE) 290 { 291 memcpy(p_PcData->content, p_Content, dataSize); 292 293 if ( content_type == SML_PCDATA_STRING && !dm_escape_env) 294 { 295 BOOLEAN bSendAsPCDATA = FALSE; 296 INT32 nLen = dataSize; 297 298 while ( nLen > 0 ) 299 { 300 nLen--; 301 302 if ( p_Content[nLen] == '&' || p_Content[nLen] == '<' || 303 p_Content[nLen] == '>' || p_Content[nLen] == '\\' || 304 p_Content[nLen] == '"') 305 { 306 bSendAsPCDATA = TRUE; 307 break; 308 } 309 } 310 311 if ( bSendAsPCDATA ) 312 p_PcData->contentType = SML_PCDATA_CDATA; 313 } 314 } 315 #ifdef __SML_XML__ 316 else 317 { 318 MemPtr_t buffer =(MemPtr_t) p_PcData->content; 319 for(INT32 nLen = 0; nLen < p_PcData->length; nLen++) 320 { 321 if ( p_Content[nLen] == '&' || p_Content[nLen] == '<' || 322 p_Content[nLen] == '>' || p_Content[nLen] == '\\' || 323 p_Content[nLen] == '"' ) 324 { 325 326 *buffer++ = '&' ; 327 UINT32 i = 0; 328 for (i = 0; escape_char_table[i].escape_str != NULL; i++) 329 { 330 if ( escape_char_table[i].token == p_Content[nLen]) 331 { 332 INT32 str_len = smlLibStrlen( escape_char_table[i].escape_str); 333 memcpy(buffer, (MemPtr_t)escape_char_table[i].escape_str, str_len); 334 buffer += str_len; 335 break; 336 } 337 } 338 } 339 else 340 *buffer++=p_Content[nLen]; 341 } 342 p_PcData->length = dataSize; 343 } 344 #endif 345 346 347 } 348 349 /*================================================================================================== 350 FUNCTION : SYNCML_DM_BuildPackage::BuildPcDataWAllocMem 351 352 DESCRIPTION : This method will allocate the memory for PC data structure and call BuildPcData 353 to build up the PC data structure. 354 ARGUMENT PASSED : 355 p_Content 356 OUTPUT PARAMETER: p_PcData 357 RETURN VALUE : 358 IMPORTANT NOTES : The calling function will not check the return value, since when memory allocation 359 fails, the phone will panic. 360 ==================================================================================================*/ 361 void 362 SYNCML_DM_BuildPackage::BuildPcDataWAllocMem (SmlPcdataPtr_t *pp_PcData, 363 UINT32 dataSize, 364 UINT8 *p_Data) 365 { 366 SmlPcdataPtr_t p_temp_pc_data; 367 368 if (*pp_PcData != NULL) { 369 smlFreePcdata(*pp_PcData); 370 } 371 372 p_temp_pc_data = smlAllocPcdata(); 373 if ( p_temp_pc_data != NULL) 374 { 375 BuildPcData(p_temp_pc_data, SML_PCDATA_STRING, 376 SML_EXT_UNDEFINED, dataSize, p_Data); 377 378 } 379 *pp_PcData = p_temp_pc_data; 380 p_temp_pc_data = NULL; 381 } 382 383 384 /*================================================================================================== 385 FUNCTION : SYNCML_DM_BuildPackage::BuildMetaInfo 386 387 DESCRIPTION : This method will build up the meta data structure. 388 ARGUMENT PASSED : p_Format 389 p_Type 390 p_Size 391 p_NextNonce 392 p_Version 393 p_Maxmsgsize 394 p_Maxobjsize 395 OUTPUT PARAMETER: p_PcData 396 RETURN VALUE : 397 IMPORTANT NOTES : The calling function will not check the return value, since when memory allocation 398 fails, the phone will panic. 399 ==================================================================================================*/ 400 void 401 SYNCML_DM_BuildPackage::BuildMetaInfo (SmlPcdataPtr_t p_PcData, 402 UINT8 *p_Format, UINT8 *p_Type, 403 UINT8 *p_Mark, UINT8 *p_Size, 404 UINT8 *p_NextNonce, UINT8 *p_Version, 405 UINT8 *p_Maxmsgsize, UINT8 *p_Maxobjsize) 406 { 407 SmlMetInfMetInfPtr_t p_meta_info; 408 UINT32 data_length = 0; 409 UINT32 data_size; 410 411 p_meta_info = smlAllocMetInfMetInf(); 412 413 if ( p_meta_info != NULL) 414 { 415 if (p_Format != NULL) 416 { 417 data_size = DmStrlen((const char*)p_Format); 418 BuildPcDataWAllocMem (&p_meta_info->format, data_size, p_Format); 419 data_length += data_size; 420 } 421 422 if (p_Type != NULL) 423 { 424 data_size = DmStrlen((const char*)p_Type); 425 BuildPcDataWAllocMem (&p_meta_info->type, data_size, p_Type); 426 data_length += data_size; 427 } 428 429 if (p_Mark != NULL) 430 { 431 data_size = DmStrlen((const char*)p_Mark); 432 BuildPcDataWAllocMem (&p_meta_info->mark, data_size, p_Mark); 433 data_length += data_size; 434 } 435 436 if (p_Size != NULL) 437 { 438 data_size = DmStrlen((const char*)p_Size); 439 BuildPcDataWAllocMem(&p_meta_info->size, data_size, p_Size); 440 data_length += data_size; 441 } 442 443 if (p_NextNonce != NULL) 444 { 445 data_size = DmStrlen((const char*)p_NextNonce); 446 BuildPcDataWAllocMem(&p_meta_info->nextnonce, data_size, p_NextNonce); 447 data_length += data_size; 448 } 449 450 if (p_Version != NULL) 451 { 452 data_size = DmStrlen((const char*)p_Version); 453 BuildPcDataWAllocMem(&p_meta_info->version, data_size, p_Version); 454 data_length += data_size; 455 } 456 457 if (p_Maxmsgsize != NULL) 458 { 459 data_size = DmStrlen((const char*)p_Maxmsgsize); 460 BuildPcDataWAllocMem(&p_meta_info->maxmsgsize, data_size, p_Maxmsgsize); 461 data_length += data_size; 462 } 463 464 if (p_Maxobjsize != NULL) 465 { 466 data_size = DmStrlen((const char*)p_Maxobjsize); 467 BuildPcDataWAllocMem(&p_meta_info->maxobjsize, data_size, p_Maxobjsize); 468 data_length += data_size; 469 } 470 471 /* These elements are not used now. */ 472 p_meta_info->mem = NULL; 473 p_meta_info->emi = NULL; 474 p_meta_info->anchor = NULL; 475 } 476 477 p_PcData->contentType = SML_PCDATA_EXTENSION; 478 p_PcData->extension = SML_EXT_METINF; 479 p_PcData->length = sizeof(p_meta_info) + data_length; 480 481 p_PcData->content = p_meta_info; 482 } 483 484 485 /*================================================================================================== 486 FUNCTION : SYNCML_DM_BuildPackage::BuildMetaSizeInfo 487 488 DESCRIPTION : This method will build up the meta size data structure. 489 RETURN VALUE : 490 IMPORTANT NOTES : 491 ==================================================================================================*/ 492 SYNCML_DM_RET_STATUS_T 493 SYNCML_DM_BuildPackage::BuildMetaSizeInfo(SmlPcdataPtr_t p_PcData, int datasize) 494 { 495 SmlMetInfMetInfPtr_t p_meta_info; 496 UINT32 data_length = 0; 497 if(p_PcData->content != NULL) 498 { p_meta_info = (SmlMetInfMetInfPtr_t)p_PcData->content; 499 data_length = p_PcData->length; 500 } 501 else 502 { 503 p_meta_info = smlAllocMetInfMetInf(); 504 if(p_meta_info == NULL) 505 return SYNCML_DM_DEVICE_FULL; 506 data_length = sizeof(p_meta_info); 507 p_PcData->contentType = SML_PCDATA_EXTENSION; 508 p_PcData->extension = SML_EXT_METINF; 509 } 510 // <Size> information already built 511 if( p_meta_info->size!= NULL && p_meta_info->size->content != NULL) 512 return SYNCML_DM_SUCCESS; 513 514 UINT32 data_size; 515 UINT8 data_size_str[UINT32_TYPE_STR_SIZE_10]; 516 517 DmSprintf((char *)data_size_str, "%d", datasize); 518 519 data_size = DmStrlen((const char*)data_size_str); 520 BuildPcDataWAllocMem(&p_meta_info->size, data_size, data_size_str); 521 data_length += data_size; 522 523 p_PcData->length = data_length; 524 525 p_PcData->content = p_meta_info; 526 return SYNCML_DM_SUCCESS; 527 } 528 529 /*================================================================================================== 530 FUNCTION : SYNCML_DM_BuildPackage::BuildStartSyncHdr 531 532 DESCRIPTION : This function will be called by BuildPackageOne and HandleStartMessage to build up 533 the SyncML package header. 534 535 The function composes the SyncML header data. 536 ARGUMENT PASSED : p_Content 537 OUTPUT PARAMETER: 538 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL if memory allocation failed. 539 IMPORTANT NOTES : 540 ==================================================================================================*/ 541 SYNCML_DM_RET_STATUS_T 542 SYNCML_DM_BuildPackage::BuildStartSyncHdr (SmlSyncHdrPtr_t p_Content, BOOLEAN isPackageOne) 543 { 544 UINT8 message_id_str[UINT16_TYPE_STR_SIZE_5]; 545 546 pSyncHdr = smlAllocSyncHdr(); 547 548 if (pSyncHdr == NULL) 549 return SYNCML_DM_FAIL; 550 551 /* Convert message id of the server */ 552 if (p_Content->msgID->length == 0) 553 pMessageIdOfServer = DEFAULT_MESSAGE_ID; 554 else 555 { 556 /* Allocate the memory for pMessageIdOfServer, copy over the data. */ 557 pMessageIdOfServer.assign((const char *)p_Content->msgID->content, 558 p_Content->msgID->length); 559 } 560 561 562 if ( dmTreeObj.IsVersion_12() ) 563 { 564 /* Build the <VerDTD> element */ 565 BuildPcData(pSyncHdr->version, SML_PCDATA_STRING,SML_EXT_UNDEFINED, 566 DmStrlen((char *)SYNCML_REP_PROTOCOL_VERSION_1_2), 567 (UINT8 *)SYNCML_REP_PROTOCOL_VERSION_1_2); 568 569 /* Build the <VerProto> elelemnt */ 570 BuildPcData(pSyncHdr->proto, SML_PCDATA_STRING, SML_EXT_UNDEFINED, 571 DmStrlen((char *)SYNCML_DM_PROTOCOL_VERSION_1_2), 572 (UINT8 *)SYNCML_DM_PROTOCOL_VERSION_1_2); 573 } 574 else 575 { 576 /* Build the <VerDTD> element */ 577 BuildPcData(pSyncHdr->version, SML_PCDATA_STRING,SML_EXT_UNDEFINED, 578 DmStrlen((char *)SYNCML_REP_PROTOCOL_VERSION_1_1), 579 (UINT8 *)SYNCML_REP_PROTOCOL_VERSION_1_1); 580 581 /* Build the <VerProto> elelemnt */ 582 BuildPcData(pSyncHdr->proto, SML_PCDATA_STRING, SML_EXT_UNDEFINED, 583 DmStrlen((char *)SYNCML_DM_PROTOCOL_VERSION_1_1), 584 (UINT8 *)SYNCML_DM_PROTOCOL_VERSION_1_1); 585 586 } 587 588 /* Build the <SessionId> element */ 589 BuildPcData(pSyncHdr->sessionID, SML_PCDATA_STRING, SML_EXT_UNDEFINED, 590 p_Content->sessionID->length, 591 (UINT8 *)p_Content->sessionID->content); 592 593 /* Keep the sessionID information in the MgmtSessionObj's serverSessionId when building 594 package one */ 595 if ( isPackageOne ) 596 { 597 /* The message ID has to be set as "1" for the package one, this is required by the 598 * SyncML DM spec. */ 599 messageId = 1; 600 601 } 602 603 /* Build the <MsgId> element */ 604 DmSprintf((char *)message_id_str, "%d", messageId++); 605 BuildPcData(pSyncHdr->msgID, SML_PCDATA_STRING, 606 SML_EXT_UNDEFINED, 607 DmStrlen((char *)message_id_str), 608 message_id_str); 609 610 /* Need to swap the <target> and the <source> element when constructing the DM document. 611 The server SOURCE element from the receiving package will be client TARGET when sending back. 612 The server TARGET element from the receiving package will be client SOURCE. */ 613 /* build the <target> element */ 614 615 /* build the <target> element, Need to use the response URI if it exists */ 616 DMString strSourceUri; 617 if((p_Content->source != NULL) && (p_Content->source->locURI != NULL) &&(p_Content->source->locURI->content !=NULL)) 618 { strSourceUri = DMString((const char *)p_Content->source->locURI->content, (int)p_Content->source->locURI->length); 619 if(strSourceUri.Encode() == FALSE) 620 return SYNCML_DM_FAIL; 621 } 622 623 if (p_Content->respURI != NULL) 624 { 625 BuildPcData(pSyncHdr->target->locURI, SML_PCDATA_STRING, 626 SML_EXT_UNDEFINED, 627 p_Content->respURI->length, 628 (UINT8 *)p_Content->respURI->content); 629 } 630 else 631 { 632 BuildPcData(pSyncHdr->target->locURI, SML_PCDATA_STRING, 633 SML_EXT_UNDEFINED, 634 strSourceUri.length(), 635 (UINT8 *)strSourceUri.c_str()); 636 } 637 if ((p_Content->source !=NULL) && (p_Content->source->locName != NULL)) 638 { 639 if (p_Content->source->locName->content != NULL) 640 { 641 BuildPcDataWAllocMem(&pSyncHdr->target->locName, 642 p_Content->source->locName->length, 643 (UINT8 *)p_Content->source->locName->content); 644 } 645 else 646 { 647 pSyncHdr->target->locName = NULL; 648 } 649 } 650 651 /* Build the <source> element */ 652 DMString strTargetUri; 653 if((p_Content->target != NULL) && (p_Content->target->locURI != NULL) && (p_Content->target->locURI->content != NULL)) 654 { 655 strTargetUri = DMString((CPCHAR)p_Content->target->locURI->content, (INT32)p_Content->target->locURI->length); 656 if(strTargetUri.Encode() == FALSE) 657 return SYNCML_DM_FAIL; 658 } 659 BuildPcData(pSyncHdr->source->locURI, SML_PCDATA_STRING, 660 SML_EXT_UNDEFINED, 661 strTargetUri.length(), 662 (UINT8 *)strTargetUri.c_str()); 663 664 if((p_Content->target != NULL) && (p_Content->target->locName != NULL)) 665 { 666 if (p_Content->target->locName->content != NULL) 667 { 668 BuildPcDataWAllocMem(&pSyncHdr->source->locName, 669 p_Content->target->locName->length, 670 (UINT8 *)p_Content->target->locName->content); 671 } 672 else 673 { 674 pSyncHdr->source->locName = NULL; 675 } 676 } 677 678 /* Don't free the pSyncHdr memory until the BuildFinishSyncHdr() is called.*/ 679 return SYNCML_DM_SUCCESS; 680 } 681 682 683 /*================================================================================================== 684 FUNCTION : SYNCML_DM_BuildPackage::BuildFinishSyncHdr 685 686 DESCRIPTION : This function will be called by BuildPackageOne and HandleStartMessage to 687 build up the SyncML package header. 688 689 The function finishes composing the SyncML header data, and calls the SyncML 690 toolkit smlStartMessageExt() to build the SyncHdr. 691 ARGUMENT PASSED : serverChalType 692 OUTPUT PARAMETER: 693 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL 694 IMPORTANT NOTES : 695 ==================================================================================================*/ 696 SYNCML_DM_RET_STATUS_T 697 SYNCML_DM_BuildPackage::BuildFinishSyncHdr (SYNCML_DM_CHAL_TYPE_T serverChalType) 698 { 699 UINT8 max_msg_size_str[UINT32_TYPE_STR_SIZE_10]; 700 UINT8 *p_CredFormat = NULL; 701 UINT8 *p_CredType = NULL; 702 UINT8 *p_CredData = NULL; 703 Ret_t sml_ret_stat; 704 SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS; 705 SYNCMLDM_MD5_SEC_INFO_T md5SecInfo; 706 SYNCMLDM_BASIC_SEC_INFO_T basicSecInfo; 707 DMClientServerCreds *pClientServerCreds; 708 SYNCMLDM_SEC_CREDENTIALS_T *pGenCred = NULL; 709 UINT8 decodedNonce[MAX_BIN_NONCE_LEN]; 710 UINT32 encodedNonceLen; 711 UINT32 decodedNonceLen; 712 MemSize_t freeSpace; 713 714 715 pClientServerCreds = pDmMgmtSessionObj->GetClientServerCreds(); 716 717 // change the auth method from server. 718 pClientServerCreds->SetPrefClientAuth(serverChalType); 719 720 /* The HMAC Credentials are always sent. So we do not need to do anything extra if challenged 721 * for HMAC.*/ 722 if ((serverChalType != SYNCML_DM_CHAL_NONE) && (serverChalType != SYNCML_DM_CHAL_HMAC)) 723 { 724 725 if (serverChalType == SYNCML_DM_CHAL_MD5) 726 { 727 /* The ClientNonce string is b64 encoded and must be decoded now.*/ 728 encodedNonceLen = DmStrlen((const char *)pClientServerCreds->pClientNonce); 729 decodedNonceLen = base64Decode((unsigned char *)decodedNonce, 730 MAX_BIN_NONCE_LEN, 731 (unsigned char*)pClientServerCreds->pClientNonce.c_str(), 732 (unsigned long*)&encodedNonceLen); 733 734 /* We need to build up our MD5 credentials.*/ 735 md5SecInfo.pb_user_name_or_server_id = (UINT8*)pClientServerCreds->pClientUserName.c_str(); 736 md5SecInfo.pb_password = (UINT8*)pClientServerCreds->pClientPW.c_str(); 737 md5SecInfo.pb_nonce = decodedNonce; 738 md5SecInfo.o_encode_base64 = TRUE; 739 md5SecInfo.w_nonce_length = decodedNonceLen; 740 741 pGenCred = syncmldm_sec_build_md5_cred(&md5SecInfo); 742 743 p_CredFormat = (UINT8 *)SYNCML_B64; 744 p_CredType = (UINT8 *)SYNCML_AUTH_MD5; 745 } 746 else /* SYNCML_DM_CHAL_BASIC */ 747 { 748 /* We need to build up our Basic credentials.*/ 749 basicSecInfo.pb_user_name_or_server_id = (UINT8*)pClientServerCreds->pClientUserName.c_str(); 750 basicSecInfo.pb_password = (UINT8*)pClientServerCreds->pClientPW.c_str(); 751 752 pGenCred = syncmldm_sec_build_basic_cred(&basicSecInfo); 753 754 p_CredFormat = (UINT8 *)SYNCML_B64; 755 p_CredType = (UINT8 *)SYNCML_AUTH_BASIC; 756 } 757 758 if (pGenCred == NULL) 759 { 760 /* Something went wrong in the Security Library.*/ 761 p_CredData = NULL; 762 p_CredFormat = NULL; 763 p_CredType = NULL; 764 } 765 else 766 { 767 /* Copy over the new credential string and add the NULL char.*/ 768 p_CredData = (UINT8 *)DmAllocMem(pGenCred->w_credential_string_length + 1); 769 if ( p_CredData == NULL ) 770 { 771 DmFreeMem(pGenCred); 772 return SYNCML_DM_FAIL; 773 } 774 775 memcpy(p_CredData, pGenCred->ab_credential_string, 776 pGenCred->w_credential_string_length); 777 p_CredData[pGenCred->w_credential_string_length] = '\0'; 778 DmFreeMem(pGenCred); 779 780 /* Build the <Cred> element */ 781 if( pSyncHdr != NULL) { 782 pSyncHdr->cred = smlAllocCred(); 783 if (pSyncHdr->cred != NULL) 784 { 785 pSyncHdr->cred->meta = smlAllocPcdata(); 786 787 /* Build the MetaInfo and the PcData sections.*/ 788 if (pSyncHdr->cred->meta != NULL) 789 BuildMetaInfo(pSyncHdr->cred->meta, p_CredFormat, p_CredType, 790 NULL, NULL, NULL, NULL, NULL, NULL); 791 792 BuildPcData(pSyncHdr->cred->data, SML_PCDATA_STRING, 793 SML_EXT_UNDEFINED, 794 DmStrlen((char *)p_CredData), 795 p_CredData); 796 } 797 } 798 DmFreeMem(p_CredData); 799 } 800 } /* If Challenged */ 801 802 /* For package one header, fill in the maximum message size which client can support to the 803 pSyncHdr->meta */ 804 { 805 if( pSyncHdr != NULL) { 806 pSyncHdr->meta = smlAllocPcdata(); 807 808 /* Convert MaxmessageSize to a string */ 809 DmSprintf((char *)max_msg_size_str, "%d", MaxMessageSize); 810 811 /* Call BuildMetaInfo to set MaxMsgSize element */ 812 if (pSyncHdr->meta != NULL) 813 BuildMetaInfo(pSyncHdr->meta, 814 NULL, NULL, NULL, 815 NULL, NULL, NULL, 816 max_msg_size_str, 817 NULL); 818 } 819 } 820 821 /* Start a new message, toolkit will build up the DM package SyncHdr part */ 822 if( pSyncHdr != NULL) { 823 if ( dmTreeObj.IsVersion_12() ) 824 sml_ret_stat = smlStartMessageExt(sendInstanceId, pSyncHdr, SML_VERS_1_2); 825 else 826 sml_ret_stat = smlStartMessageExt(sendInstanceId, pSyncHdr, SML_VERS_1_1); 827 if (sml_ret_stat != SML_ERR_OK) 828 { 829 ret_stat = SYNCML_DM_FAIL; 830 } 831 } 832 freeSpace = smlGetFreeBuffer(sendInstanceId); 833 834 /* Free the memory. smlFreeSyncHdr will free every element in SmlSyncHdrPtr_t structure, 835 including ones we allocated. */ 836 if( pSyncHdr != NULL) 837 smlFreeSyncHdr(pSyncHdr); 838 pSyncHdr = NULL; 839 840 return (ret_stat); 841 } 842 843 844 /*================================================================================================== 845 FUNCTION : SYNCML_DM_BuildPackage::BuildAlertCommand 846 847 DESCRIPTION : This method calls the SyncML Toolkit functions to build up the SyncML package 848 ALERT command as part of the SyncBody. 849 ARGUMENT PASSED : session_Direction 850 OUTPUT PARAMETER: 851 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL if memory allocation failed. 852 IMPORTANT NOTES : 853 ==================================================================================================*/ 854 SYNCML_DM_RET_STATUS_T 855 SYNCML_DM_BuildPackage::BuildAlert1226Command () 856 { 857 SmlAlertPtr_t p_alert; 858 UINT8 command_id_str[UINT16_TYPE_STR_SIZE_5]; 859 if(firmAlertVec.size() < 1) 860 { 861 return SYNCML_DM_SUCCESS; 862 } 863 DMFirmAlertVector * pFirmAlerts = &firmAlertVec; 864 char * alertStr = "1226"; 865 866 for (INT32 i=0; i<pFirmAlerts->size(); i++) 867 { 868 p_alert = smlAllocAlert(); 869 870 if ( p_alert == NULL ) 871 return (SYNCML_DM_FAIL); 872 873 /* Convert the commandId to a string */ 874 DmSprintf((char *)command_id_str, "%d", commandId++); 875 BuildPcData(p_alert->cmdID, SML_PCDATA_STRING,SML_EXT_UNDEFINED, 876 DmStrlen((char *)command_id_str),command_id_str); 877 878 /* Credentials are not sent in the Alert.*/ 879 p_alert->cred = NULL; 880 881 BuildPcDataWAllocMem (&p_alert->data,4,(UINT8*)alertStr); 882 if ( p_alert->data == NULL ) 883 { 884 smlFreeAlert(p_alert); 885 return (SYNCML_DM_FAIL); 886 } 887 888 SmlItemPtr_t p_item = p_alert->itemList->item; 889 const DmtFirmAlert& alert = (*pFirmAlerts)[i]; 890 DMString uri = alert.getPackageURI(); 891 892 if(uri.Encode() == FALSE) 893 { 894 smlFreeAlert(p_alert); 895 return (SYNCML_DM_FAIL); 896 } 897 898 if ( !alert.getCorrelator().empty() ) 899 { 900 p_alert->correlator = smlAllocPcdata(); 901 if ( !p_alert->correlator ) 902 { 903 smlFreeAlert(p_alert); 904 return (SYNCML_DM_FAIL); 905 } 906 907 BuildPcData(p_alert->correlator, SML_PCDATA_STRING,SML_EXT_UNDEFINED, 908 alert.getCorrelator().length(), (UINT8*)alert.getCorrelator().c_str() ); 909 } 910 911 /* Dont build the LocURI if its length is zero */ 912 if( uri.length() != 0 ) 913 { 914 p_item->source = smlAllocSource(); 915 if ( p_item->source == NULL ) 916 { 917 smlFreeAlert(p_alert); 918 return (SYNCML_DM_FAIL); 919 } 920 BuildPcData(p_item->source->locURI,SML_PCDATA_STRING, 921 SML_EXT_UNDEFINED,uri.length(),(UINT8*)uri.c_str()); 922 } 923 924 UINT8* pType = alert.getAlertType().empty() ? NULL : (UINT8*)alert.getAlertType().c_str(); 925 UINT8* pFormat = alert.getAlertFormat().empty() ? NULL : (UINT8*)alert.getAlertFormat().c_str(); 926 UINT8* pMark = alert.getAlertMark().empty() ? NULL : (UINT8*)alert.getAlertMark().c_str(); 927 928 if ( pType || pFormat || pMark ) 929 { 930 if ((p_item->meta = smlAllocPcdata()) != NULL) 931 BuildMetaInfo(p_item->meta, pFormat, pType, pMark,NULL,NULL,NULL,NULL, NULL); 932 } 933 934 BuildPcDataWAllocMem (&p_item->data, 935 alert.getResultData().length(), 936 (UINT8*)alert.getResultData().c_str() ); 937 938 if ( p_item->data == NULL ) 939 { 940 smlFreeAlert(p_alert); 941 return (SYNCML_DM_FAIL); 942 } 943 944 945 /* Call the toolkit to build ALERT command to the DM package body. */ 946 smlAlertCmd(sendInstanceId, p_alert); 947 948 /* Free the memory. smlFreeAlert will free every element in SmlAlertPtr_t structure, 949 including ones we allocated. */ 950 smlFreeAlert(p_alert); 951 p_alert = NULL; 952 953 } 954 955 return (SYNCML_DM_SUCCESS); 956 } 957 958 959 /*================================================================================================== 960 FUNCTION : SYNCML_DM_BuildPackage::BuildAlertCommand 961 962 DESCRIPTION : This method calls the SyncML Toolkit functions to build up the SyncML package 963 ALERT command as part of the SyncBody. 964 ARGUMENT PASSED : session_Direction 965 OUTPUT PARAMETER: 966 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL if memory allocation failed. 967 IMPORTANT NOTES : 968 ==================================================================================================*/ 969 SYNCML_DM_RET_STATUS_T 970 SYNCML_DM_BuildPackage::BuildAlertCommand (UINT16 alertCode, CPCHAR pSource, CPCHAR pTarget) 971 { 972 SmlAlertPtr_t p_alert; 973 UINT8 command_id_str[UINT16_TYPE_STR_SIZE_5]; 974 UINT8 alert_str[UINT16_TYPE_STR_SIZE_5]; 975 SmlItemPtr_t p_alert_item; 976 977 if ( (p_alert = smlAllocAlert() ) == NULL) 978 return SYNCML_DM_FAIL; 979 980 /* Convert the commandId to a string */ 981 DmSprintf((char *)command_id_str, "%d", commandId++); 982 BuildPcData(p_alert->cmdID, SML_PCDATA_STRING, 983 SML_EXT_UNDEFINED, 984 DmStrlen((char *)command_id_str), 985 command_id_str); 986 987 /* Credentials are not sent in the Alert.*/ 988 p_alert->cred = NULL; 989 990 if ( (p_alert->data = smlAllocPcdata()) != NULL) 991 { 992 /* We need to indicate whether the alert type is SERVER_INITIATED_SESSION or 993 * CLIENT_INITIATED_SESSION */ 994 DmSprintf((char *)alert_str, "%d", alertCode); 995 BuildPcData(p_alert->data, SML_PCDATA_STRING, 996 SML_EXT_UNDEFINED, 997 DmStrlen((char *)alert_str), 998 alert_str); 999 } 1000 1001 /* Free p_alert->itemList, set it as NULL since we don't have data for it. Otherwise, empty 1002 <ITEM/> will be generated for SyncHdr. */ 1003 if(pSource == NULL && pTarget== NULL) 1004 { smlFreeItemList(p_alert->itemList); 1005 p_alert->itemList = NULL; 1006 } 1007 else 1008 { 1009 p_alert_item = p_alert->itemList->item; 1010 1011 // Source 1012 if(pSource != NULL) 1013 { p_alert_item->source = smlAllocSource(); 1014 if (p_alert_item->source == NULL ) 1015 { 1016 smlFreeAlert(p_alert); 1017 return (SYNCML_DM_FAIL); 1018 } 1019 DMString strSourceUri(pSource); 1020 1021 if(strSourceUri.Encode() == FALSE) 1022 { 1023 smlFreeAlert(p_alert); 1024 return (SYNCML_DM_INVALID_URI); 1025 } 1026 1027 BuildPcData(p_alert_item->source->locURI, SML_PCDATA_STRING, 1028 SML_EXT_UNDEFINED, 1029 strSourceUri.length(), 1030 (UINT8 *) strSourceUri.c_str()); 1031 } 1032 1033 // Target 1034 if(pTarget != NULL) 1035 { p_alert_item->target = smlAllocSource(); 1036 if (p_alert_item->target == NULL ) 1037 { 1038 smlFreeAlert(p_alert); 1039 return (SYNCML_DM_FAIL); 1040 } 1041 DMString strTargetUri(pTarget); 1042 1043 if(strTargetUri.Encode() == FALSE) 1044 { 1045 smlFreeAlert(p_alert); 1046 return (SYNCML_DM_INVALID_URI); 1047 } 1048 1049 BuildPcData(p_alert_item->target->locURI, SML_PCDATA_STRING, 1050 SML_EXT_UNDEFINED, 1051 strTargetUri.length(), 1052 (UINT8 *) strTargetUri.c_str()); 1053 } 1054 } 1055 1056 /* Call the toolkit to build ALERT command to the DM package body. */ 1057 smlAlertCmd(sendInstanceId, p_alert); 1058 1059 /* Free the memory. smlFreeAlert will free every element in SmlAlertPtr_t structure, 1060 including ones we allocated. */ 1061 smlFreeAlert(p_alert); 1062 1063 return SYNCML_DM_SUCCESS; 1064 } 1065 1066 /*================================================================================================== 1067 FUNCTION : SYNCML_DM_BuildPackage::BuildReplaceCommand 1068 1069 DESCRIPTION : This method calls the SyncML Toolkit functions to build up the SyncML package 1070 REPLACE command as part of the SyncBody of DM package one. It will query the DM 1071 tree to get all DevInfo data to place in the REPLACE command. 1072 ARGUMENT PASSED : 1073 OUTPUT PARAMETER: 1074 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL if memory allocation failed. 1075 IMPORTANT NOTES : 1076 ==================================================================================================*/ 1077 SYNCML_DM_RET_STATUS_T 1078 SYNCML_DM_BuildPackage::BuildReplaceCommand () 1079 { 1080 UINT8 command_id_str[UINT16_TYPE_STR_SIZE_5]; 1081 SmlReplacePtr_t p_replace; 1082 SmlItemPtr_t p_replace_item; 1083 SmlItemListPtr_t p_replace_item_list; 1084 DMGetData devInfoData; 1085 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 1086 SYNCML_DM_URI_RESULT_T dm_uri_result; 1087 BOOLEAN first_item_on_list = TRUE; 1088 1089 SYNCML_DM_GET_ON_LIST_RET_DATA_T p_get_struct_data; 1090 1091 if ( (p_replace = (SmlReplacePtr_t)smlAllocReplace()) == NULL) 1092 return (SYNCML_DM_FAIL); 1093 1094 /* Convert the commandId to a string */ 1095 DmSprintf((char *)command_id_str, "%d", commandId++); 1096 BuildPcData(p_replace->cmdID, SML_PCDATA_STRING, 1097 SML_EXT_UNDEFINED, 1098 DmStrlen((char *)command_id_str), 1099 (UINT8 *)command_id_str); 1100 1101 p_replace_item = p_replace->itemList->item; 1102 p_replace_item_list = p_replace->itemList; 1103 1104 1105 /* Call DMTNM to get all children nodes of devinfo from DM tree */ 1106 dm_stat = dmTreeObj.InitListAndGetListFirstItem( DM_DEV_INFO_URI_PAK1, 1107 SYNCML_DM_GET_ON_LIST_STRUCT, 1108 p_get_struct_data); 1109 1110 if (dm_stat != SYNCML_DM_SUCCESS) 1111 { 1112 smlFreeGeneric(p_replace); 1113 FreeGetStructData(p_get_struct_data); 1114 return (SYNCML_DM_FAIL); 1115 } 1116 1117 /* Loop through all data from Get Struct */ 1118 while (p_get_struct_data.psRetData != NULL) 1119 { 1120 /* If it is an interior node, we don't send it in the package one. */ 1121 if (p_get_struct_data.psRetData->m_nFormat != SYNCML_DM_FORMAT_NODE) 1122 { 1123 if (first_item_on_list != TRUE) 1124 { 1125 /* It is the first item, allocate the memory for the next replace item. */ 1126 p_replace_item_list->next = smlAllocItemList(); 1127 if (p_replace_item_list->next != NULL) 1128 { 1129 p_replace_item_list = p_replace_item_list->next; 1130 p_replace_item = p_replace_item_list->item; 1131 } 1132 } 1133 else 1134 { 1135 /* This is the first item. Set the flag to False for the next time around.*/ 1136 first_item_on_list = FALSE; 1137 } 1138 1139 /* Allocate the memory for p_replace_item->source */ 1140 p_replace_item->source = smlAllocSource(); 1141 1142 if ( p_replace_item->source == NULL ) 1143 { 1144 smlFreeGeneric(p_replace); 1145 FreeGetStructData(p_get_struct_data); 1146 return (SYNCML_DM_FAIL); 1147 } 1148 1149 DMString strGetetUri( p_get_struct_data._pbURI ); 1150 1151 if(strGetetUri.Encode() == FALSE) 1152 { 1153 smlFreeGeneric(p_replace); 1154 FreeGetStructData(p_get_struct_data); 1155 return (SYNCML_DM_INVALID_URI); 1156 } 1157 1158 BuildPcData(p_replace_item->source->locURI, SML_PCDATA_STRING, 1159 SML_EXT_UNDEFINED, 1160 strGetetUri.length(), 1161 (UINT8 *) strGetetUri.c_str()); 1162 1163 /* Validate the URI */ 1164 dm_uri_result = dmTreeObj.URIValidateAndParse( p_get_struct_data._pbURI); 1165 if ((dm_uri_result == SYNCML_DM_COMMAND_ON_UNKNOWN_PROPERTY) || 1166 (dm_uri_result == SYNCML_DM_COMMAND_INVALID_URI) || 1167 (dm_uri_result == SYNCML_DM_COMMAND_URI_TOO_LONG) || 1168 (dm_uri_result == SYNCML_DM_COMMAND_LIST_STRUCT)) 1169 { 1170 smlFreeGeneric(p_replace); 1171 FreeGetStructData(p_get_struct_data); 1172 return (SYNCML_DM_INVALID_URI); 1173 } 1174 1175 /* Get data for each node of devinfo */ 1176 dm_stat = dmTreeObj.Get(p_get_struct_data._pbURI, devInfoData,SYNCML_DM_REQUEST_TYPE_INTERNAL); 1177 1178 FreeGetStructData(p_get_struct_data); 1179 1180 /* Check if there is data on this node.*/ 1181 if (dm_stat != SYNCML_DM_SUCCESS) 1182 { 1183 smlFreeGeneric(p_replace); 1184 return (SYNCML_DM_FAIL); 1185 } 1186 1187 p_replace_item->data = smlAllocPcdata(); 1188 if (p_replace_item->data != NULL) 1189 BuildPcData(p_replace_item->data, SML_PCDATA_STRING, SML_EXT_UNDEFINED, 1190 devInfoData.m_oData.getSize(), 1191 devInfoData.m_oData.getBuffer()); 1192 1193 /* Replace doesn't have any meta.*/ 1194 p_replace_item->meta = NULL; 1195 1196 } 1197 1198 else /* bDataFormat == SYNCML_DM_FORMAT_NODE */ 1199 { 1200 /* We need to free the memory for the interior node.*/ 1201 FreeGetStructData(p_get_struct_data); 1202 } 1203 1204 /* Move to the next item. */ 1205 dm_stat = dmTreeObj.GetListNextItem(p_get_struct_data); 1206 if (dm_stat != SYNCML_DM_SUCCESS) 1207 { 1208 smlFreeGeneric(p_replace); 1209 FreeGetStructData(p_get_struct_data); 1210 return (SYNCML_DM_FAIL); 1211 } 1212 } 1213 1214 /* All replace command data are set, call toolkit to build REPLACE into the DM package body. */ 1215 smlReplaceCmd(sendInstanceId, p_replace); 1216 1217 /* Free the memory. smlFreeGeneric will free every element of SmlReplacePtr_t structure. */ 1218 smlFreeGeneric(p_replace); 1219 1220 return (SYNCML_DM_SUCCESS); 1221 } 1222 1223 /*================================================================================================== 1224 FUNCTION : SYNCML_DM_BuildPackage::AllocateStatus 1225 1226 DESCRIPTION : This function calls the SyncML Toolkit functions to build up the STATUS command 1227 ARGUMENT PASSED : p_CmdRefData 1228 p_CmdName 1229 p_TargetRefData 1230 p_SourceRefData 1231 pCientChal 1232 status_Code 1233 OUTPUT PARAMETER: 1234 RETURN VALUE : newly constructed status 1235 IMPORTANT NOTES : 1236 ==================================================================================================*/ 1237 SmlStatusPtr_t SYNCML_DM_BuildPackage::AllocateStatus( 1238 UINT8 *p_CmdRefData, /* Receiving DM package command Id */ 1239 UINT8 *p_CmdName, 1240 UINT8 *p_SourceRefData, 1241 UINT8 *p_TargetRefData, 1242 DM_CHALLENGE_T *pClientChal, 1243 SYNCML_DM_RET_STATUS_T status_Code, 1244 const DMStringVector* responses ) 1245 { 1246 UINT8 status_code_str[UINT16_TYPE_STR_SIZE_5]; 1247 SmlStatusPtr_t p_status = smlAllocStatus(); 1248 1249 if ( !p_status ) 1250 return NULL; 1251 1252 BuildPcData(p_status->msgRef, SML_PCDATA_STRING, 1253 SML_EXT_UNDEFINED, 1254 DmStrlen(pMessageIdOfServer), 1255 (UINT8*)pMessageIdOfServer.c_str()); 1256 1257 if (p_CmdRefData != NULL) 1258 { 1259 BuildPcData(p_status->cmdRef, SML_PCDATA_STRING, 1260 SML_EXT_UNDEFINED, 1261 DmStrlen((char *)p_CmdRefData), 1262 p_CmdRefData); 1263 } 1264 1265 if (p_CmdName != NULL) 1266 { 1267 BuildPcData(p_status->cmd, SML_PCDATA_STRING, 1268 SML_EXT_UNDEFINED, 1269 DmStrlen((char *)p_CmdName), 1270 p_CmdName); 1271 } 1272 1273 if (p_SourceRefData != NULL) 1274 { 1275 if ( (p_status->sourceRefList = smlAllocSourceRefList()) != NULL) 1276 { 1277 BuildPcData(p_status->sourceRefList->sourceRef, SML_PCDATA_STRING, 1278 SML_EXT_UNDEFINED, 1279 DmStrlen((char *)p_SourceRefData), 1280 p_SourceRefData); 1281 } 1282 } 1283 1284 if (p_TargetRefData != NULL) 1285 { 1286 if (0 == DmStrcmp((char *)p_TargetRefData, FDR_URI)) 1287 { 1288 SmlItemPtr_t p_status_item = NULL; 1289 SmlItemListPtr_t p_status_list_item = NULL; 1290 p_status->itemList = smlAllocItemList(); 1291 p_status_list_item = p_status->itemList; 1292 p_status_item = p_status_list_item->item; 1293 if ((p_status_item->source = smlAllocSource()) != NULL) 1294 BuildPcData(p_status_item->source->locURI, SML_PCDATA_STRING, 1295 SML_EXT_UNDEFINED, 1296 DmStrlen((char *)p_TargetRefData), 1297 p_TargetRefData); 1298 } 1299 else 1300 { 1301 if ((p_status->targetRefList = smlAllocTargetRefList()) != NULL) 1302 BuildPcData(p_status->targetRefList->targetRef, SML_PCDATA_STRING, 1303 SML_EXT_UNDEFINED, 1304 DmStrlen((char *)p_TargetRefData), 1305 p_TargetRefData); 1306 } 1307 } 1308 1309 if (pClientChal != NULL) 1310 { 1311 if (( pClientChal->pChalFormat != NULL ) || 1312 ( pClientChal->pChalType != NULL ) || 1313 ( pClientChal->pChalNonce != NULL )) 1314 { 1315 if ( (p_status->chal = smlAllocChal() ) != NULL) 1316 BuildMetaInfo(p_status->chal->meta, 1317 pClientChal->pChalFormat, 1318 pClientChal->pChalType, 1319 NULL, 1320 NULL, 1321 pClientChal->pChalNonce, 1322 NULL, NULL, NULL); 1323 } 1324 } 1325 1326 /* Convert the status_Code to a string */ 1327 if ( status_Code == SYNCML_DM_SUCCESS ) 1328 status_Code = 200; 1329 else if ( status_Code == SYNCML_DM_PROCESS_ACCEPTED ) 1330 status_Code = 1200; 1331 else 1332 { 1333 if ( status_Code < 100 || status_Code > 600 ) 1334 status_Code = 500; 1335 } 1336 1337 1338 DmSprintf((char *)status_code_str, "%d", (int)status_Code); 1339 BuildPcData(p_status->data, SML_PCDATA_STRING, 1340 SML_EXT_UNDEFINED, 1341 DmStrlen((char *)status_code_str), 1342 status_code_str); 1343 1344 if (responses && responses->size() > 0) { 1345 1346 p_status->itemList = smlAllocItemList(); 1347 SmlItemListPtr_t itemListPtr_t = p_status->itemList; 1348 int i = 0; 1349 do { 1350 if ( itemListPtr_t != NULL) 1351 { 1352 if ( (itemListPtr_t->item->data = smlAllocPcdata() ) != NULL) 1353 BuildPcData(itemListPtr_t->item->data, SML_PCDATA_STRING, 1354 SML_EXT_UNDEFINED, 1355 (UINT32)DmStrlen((*responses)[i].c_str()), 1356 (UINT8*)(*responses)[i].c_str()); 1357 } 1358 i++; 1359 if (i < responses->size()) { 1360 if ( itemListPtr_t != NULL) 1361 { 1362 itemListPtr_t->next = smlAllocItemList(); 1363 itemListPtr_t = itemListPtr_t->next; 1364 } 1365 } 1366 } while (i < responses->size()); 1367 } 1368 return p_status; 1369 } 1370 1371 SYNCML_DM_RET_STATUS_T SYNCML_DM_BuildPackage::BuildStatus(SmlStatusPtr_t p_status ) 1372 { 1373 MemSize_t freeSpace = 0; 1374 Ret_t sml_ret_stat = 0; 1375 SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS; 1376 UINT8 command_id_str[UINT16_TYPE_STR_SIZE_5]; 1377 1378 /* Convert the commandId to a string */ 1379 DmSprintf((char *)command_id_str, "%d", commandId++); 1380 1381 BuildPcData(p_status->cmdID, SML_PCDATA_STRING, 1382 SML_EXT_UNDEFINED, 1383 DmStrlen((char *)command_id_str), 1384 command_id_str); 1385 1386 1387 /* Call the toolkit to construct the STATUS command */ 1388 smlStartEvaluation(sendInstanceId); 1389 sml_ret_stat = smlStatusCmd(sendInstanceId, p_status); 1390 smlEndEvaluation(sendInstanceId, &freeSpace); 1391 1392 /* Note that freeSpace accounts for the EndSyncmlDoc overhead as well.*/ 1393 if (freeSpace > 0) 1394 { 1395 sml_ret_stat = smlStatusCmd(sendInstanceId, p_status); 1396 } 1397 else 1398 { 1399 ret_stat = SYNCML_DM_RESULTS_TOO_LARGE; 1400 } 1401 1402 /* Free the memory. smlFreeStatus will free every element in the SmlStatusPtr_t structure. */ 1403 //smlFreeStatus(p_status); 1404 1405 return (ret_stat); 1406 } 1407 1408 #ifdef TNDS_SUPPORT 1409 BOOLEAN SYNCML_DM_BuildPackage::ListTndsProp( CPCHAR uri, CPCHAR prop, BOOLEAN &listProp) 1410 { 1411 // Include property '+' and remove property '-' are not possible 1412 // to combine in the same Get command 1413 BOOLEAN includeProp = NULL != DmStrchr(uri, '+'); 1414 BOOLEAN removeProp = NULL != DmStrchr(uri, '-'); 1415 if ( includeProp && removeProp ) 1416 { 1417 listProp = false; 1418 return false; 1419 } 1420 1421 // Return all properties by default 1422 if ( !includeProp && !removeProp ) 1423 { 1424 listProp = true; 1425 return true; 1426 } 1427 1428 // Return selected properties only 1429 char *szQPos = DmStrstr(uri, prop); 1430 if ( includeProp ) 1431 { 1432 listProp = NULL != szQPos; 1433 if ( listProp && *(szQPos-1) != '+' ) 1434 { 1435 KCDBG("Invalid URI: %s, prop: %s\n", uri, prop); 1436 listProp = false; 1437 return false; 1438 } 1439 } 1440 1441 if ( removeProp ) 1442 { 1443 listProp = NULL == szQPos; 1444 if ( !listProp && *(szQPos-1) != '-' ) 1445 { 1446 KCDBG("Invalid URI: %s, prop: %s\n", uri, prop); 1447 listProp = false; 1448 return false; 1449 } 1450 } 1451 1452 return true; 1453 } 1454 #endif //TNDS_SUPPORT 1455 1456 #ifdef TNDS_SUPPORT 1457 SYNCML_DM_RET_STATUS_T 1458 SYNCML_DM_BuildPackage::AllocateTndsResult( CPCHAR p_target_uri, 1459 DMGetData *p_get_ret_data, 1460 const SYNCML_DM_GET_ON_LIST_RET_DATA_T& oGetStructData, 1461 SmlPcdataPtr_t pPcDataPtr ) 1462 { 1463 BOOLEAN listACL, listFormat, listName, listSize, listTitle, listTStamp, listVerNo, listValue; 1464 1465 BOOLEAN listProps = ListTndsProp(p_target_uri, "ACL", listACL) && 1466 ListTndsProp(p_target_uri, "Format", listFormat) && 1467 ListTndsProp(p_target_uri, "Name", listName) && 1468 ListTndsProp(p_target_uri, "Size", listSize) && 1469 ListTndsProp(p_target_uri, "Title", listTitle) && 1470 ListTndsProp(p_target_uri, "TStamp", listTStamp) && 1471 ListTndsProp(p_target_uri, "VerNo", listVerNo) && 1472 ListTndsProp(p_target_uri, "Value", listValue); 1473 if ( !listProps ) 1474 { 1475 return SYNCML_DM_COMMAND_INVALID_URI; 1476 } 1477 1478 SmlDmTndPtr_t p_tnd_info = NULL; 1479 UINT32 data_length = 0; 1480 UINT32 data_size; 1481 1482 // Allocate TNDS object 1483 data_size = sizeof(SmlDmTndPtr_t); 1484 p_tnd_info = smlAllocDmTnd(); 1485 if ( p_tnd_info == NULL) 1486 { 1487 return SYNCML_DM_DEVICE_FULL; 1488 } 1489 data_length += data_size; 1490 1491 // Append VerDTD Tag 1492 data_size = 3; 1493 BuildPcDataWAllocMem (&p_tnd_info->verdtd, data_size, (UINT8*)SYNCML_DM_PROTOCOL_VERSION_1_2+3); 1494 data_length += data_size; 1495 1496 // Append Mod Tag 1497 SYNCML_DM_RET_STATUS_T nRes = SYNCML_DM_SUCCESS; 1498 DMGetData tmpGetData; 1499 nRes = dmTreeObj.Get(DM_DEV_INFO_MOD_URI, tmpGetData, SYNCML_DM_REQUEST_TYPE_INTERNAL); 1500 if (nRes != SYNCML_DM_SUCCESS) 1501 { 1502 smlFreeDmTnd(p_tnd_info); 1503 return (SYNCML_DM_FAIL); 1504 } 1505 data_size = tmpGetData.m_oData.getSize(); 1506 if (data_size != 0) 1507 { 1508 BuildPcDataWAllocMem(&p_tnd_info->mod, data_size, (UINT8*) tmpGetData.getCharData()); 1509 data_length += data_size; 1510 } 1511 1512 // Append Man Tag 1513 nRes = dmTreeObj.Get(DM_DEV_INFO_MAN_URI, tmpGetData, SYNCML_DM_REQUEST_TYPE_INTERNAL); 1514 if (nRes != SYNCML_DM_SUCCESS) 1515 { 1516 smlFreeDmTnd(p_tnd_info); 1517 return (SYNCML_DM_FAIL); 1518 } 1519 data_size = tmpGetData.m_oData.getSize(); 1520 if (data_size != 0) 1521 { 1522 BuildPcDataWAllocMem(&p_tnd_info->man, data_size, (UINT8*) tmpGetData.getCharData()); 1523 data_length += data_size; 1524 } 1525 1526 // TNDS last node list 1527 p_tnd_info->nodelist = NULL; 1528 SmlDmTndNodeListPtr_t last = NULL; 1529 1530 // Allocate TNDS node object(s) 1531 SYNCML_DM_GET_ON_LIST_RET_DATA_T oTmpGetStructData = oGetStructData; 1532 DMGetData *pTmpGetData = NULL; 1533 CPCHAR pTmpTargetUri = p_target_uri; 1534 nRes = dmTreeObj.GetListNextItem(oTmpGetStructData); 1535 if ( nRes == SYNCML_DM_SUCCESS ) 1536 { 1537 pTmpGetData = oTmpGetStructData.psRetData; 1538 oTmpGetStructData.psRetData = NULL; 1539 pTmpTargetUri = oTmpGetStructData._pbURI; 1540 } 1541 1542 DMString targetUri = oTmpGetStructData.m_strStartURI; 1543 DMString tmpNodeUri = ""; 1544 DMString tmpStr = ""; 1545 DmtAttributes oAttr; 1546 while ( nRes == SYNCML_DM_SUCCESS && NULL != pTmpGetData ) 1547 { 1548 // Get DMT node attribute 1549 nRes = dmTreeObj.GetAttributes( pTmpTargetUri, oAttr, SYNCML_DM_REQUEST_TYPE_INTERNAL ); 1550 if ( nRes != SYNCML_DM_SUCCESS ) 1551 { 1552 break; 1553 } 1554 1555 // Allocate TNDS node list object 1556 data_size = sizeof(SmlDmTndNodeListPtr_t); 1557 SmlDmTndNodeListPtr_t p_tnd_nodelist = smlAllocDmTndNodeList(); 1558 if ( p_tnd_info == NULL) 1559 { 1560 return SYNCML_DM_DEVICE_FULL; 1561 } 1562 if ( NULL == p_tnd_info->nodelist ) 1563 { 1564 p_tnd_info->nodelist = p_tnd_nodelist; 1565 } 1566 else 1567 { 1568 last->next = p_tnd_nodelist; 1569 } 1570 last = p_tnd_nodelist; 1571 data_length += data_size; 1572 1573 // Append Node tag 1574 data_size = sizeof(SmlDmTndNodePtr_t); 1575 SmlDmTndNodePtr_t p_tnd_node = smlAllocDmTndNode(); 1576 if ( p_tnd_node == NULL) 1577 { 1578 return SYNCML_DM_DEVICE_FULL; 1579 } 1580 p_tnd_nodelist->node = p_tnd_node; 1581 data_length += data_size; 1582 1583 // Append NodeName tag 1584 data_size = oAttr.GetName().length(); 1585 BuildPcDataWAllocMem (&p_tnd_node->nodename, data_size, (UINT8*)oAttr.GetName().c_str()); 1586 data_length += data_size; 1587 1588 // Append Path tag 1589 tmpNodeUri = ""; 1590 if ( (int)strlen(pTmpTargetUri) > targetUri.length() + 1591 oAttr.GetName().length() + 1) 1592 { 1593 tmpNodeUri.assign(pTmpTargetUri + targetUri.length() + 1, 1594 strlen(pTmpTargetUri) - 1595 targetUri.length() - 1596 oAttr.GetName().length() - 2 ); 1597 } 1598 if ( tmpNodeUri.length() > 0 ) 1599 { 1600 data_size = tmpNodeUri.length(); 1601 BuildPcDataWAllocMem (&p_tnd_node->path, data_size, (UINT8*)tmpNodeUri.c_str()); 1602 data_length += data_size; 1603 } 1604 1605 // Append RTProperties start tag 1606 data_size = sizeof(SmlDmTndRTPropsPtr_t); 1607 SmlDmTndRTPropsPtr_t p_tnd_node_rtprops = smlAllocDmTndRTProps(); 1608 if ( p_tnd_node_rtprops == NULL) 1609 { 1610 return SYNCML_DM_DEVICE_FULL; 1611 } 1612 p_tnd_node->rtprops = p_tnd_node_rtprops; 1613 data_length += data_size; 1614 1615 // Append ACL Property 1616 if ( listACL ) 1617 { 1618 data_size = oAttr.GetAcl().toString().length(); 1619 BuildPcDataWAllocMem (&p_tnd_node_rtprops->acl, data_size, (UINT8*)oAttr.GetAcl().toString().c_str()); 1620 data_length += data_size; 1621 } 1622 1623 // Append Format Property 1624 if ( listFormat ) 1625 { 1626 data_size = sizeof(SmlDmTndFormatPtr_t); 1627 SmlDmTndFormatPtr_t p_tnd_node_format = smlAllocDmTndFormat(); 1628 if ( p_tnd_node_format == NULL) 1629 { 1630 return SYNCML_DM_DEVICE_FULL; 1631 } 1632 p_tnd_node_rtprops->format = p_tnd_node_format; 1633 data_length += data_size; 1634 1635 data_size = oAttr.GetFormat().length(); 1636 BuildPcDataWAllocMem (&p_tnd_node_rtprops->format->value, data_size, (UINT8*)oAttr.GetFormat().c_str()); 1637 data_length += data_size; 1638 } 1639 1640 // Append Name Property 1641 if ( listName ) 1642 { 1643 data_size = oAttr.GetName().length(); 1644 BuildPcDataWAllocMem (&p_tnd_node_rtprops->name, data_size, (UINT8*)oAttr.GetName().c_str()); 1645 data_length += data_size; 1646 } 1647 1648 // Append Size Property 1649 if ( listSize ) 1650 { 1651 char pTmpStr[UINT32_TYPE_STR_SIZE_10+1]; 1652 DmSprintf(pTmpStr, "%d", oAttr.GetSize()); 1653 data_size = DmStrlen(pTmpStr); 1654 BuildPcDataWAllocMem (&p_tnd_node_rtprops->size, data_size, (UINT8*)pTmpStr); 1655 data_length += data_size; 1656 } 1657 1658 // Append Title Property 1659 if ( listTitle ) 1660 { 1661 data_size = oAttr.GetTitle().length(); 1662 BuildPcDataWAllocMem (&p_tnd_node_rtprops->title, data_size, (UINT8*)oAttr.GetTitle().c_str()); 1663 data_length += data_size; 1664 } 1665 1666 // Append TStamp Property 1667 if ( listTStamp ) 1668 { 1669 tmpStr = ""; 1670 if ( oAttr.GetTimestamp() != 0 ) 1671 { 1672 // convert msec to sec 1673 time_t timestamp = (time_t)(oAttr.GetTimestamp()/1000L); 1674 tmpStr = (CPCHAR)ctime(×tamp); 1675 tmpStr.SetAt(tmpStr.length()-1, '\0'); 1676 } 1677 data_size = tmpStr.length(); 1678 BuildPcDataWAllocMem (&p_tnd_node_rtprops->tstamp, data_size, (UINT8*)tmpStr.c_str()); 1679 data_length += data_size; 1680 } 1681 1682 // Append Type Property 1683 data_size = sizeof(SmlDmTndTypePtr_t); 1684 SmlDmTndTypePtr_t p_tnd_node_type = smlAllocDmTndType(); 1685 if ( p_tnd_node_type == NULL) 1686 { 1687 return SYNCML_DM_DEVICE_FULL; 1688 } 1689 p_tnd_node->rtprops->type = p_tnd_node_type; 1690 data_length += data_size; 1691 1692 data_size = oAttr.GetType().length(); 1693 BuildPcDataWAllocMem (&p_tnd_node_rtprops->type->mime, data_size, (UINT8*)oAttr.GetType().c_str()); 1694 data_length += data_size; 1695 1696 // Append VerNo Property 1697 if ( listVerNo ) 1698 { 1699 char pTmpStr[UINT32_TYPE_STR_SIZE_10+1]; 1700 DmSprintf(pTmpStr, "%d", oAttr.GetVersion()); 1701 data_size = DmStrlen(pTmpStr); 1702 BuildPcDataWAllocMem (&p_tnd_node_rtprops->verno, data_size, (UINT8*)pTmpStr); 1703 data_length += data_size; 1704 } 1705 1706 // Append Value Tag 1707 if ( listValue ) 1708 { 1709 data_size = DmStrlen(pTmpGetData->getCharData()); 1710 BuildPcDataWAllocMem (&p_tnd_node->value, data_size, (UINT8*)pTmpGetData->getCharData()); 1711 data_length += data_size; 1712 } 1713 1714 if ( pTmpGetData ) 1715 { 1716 delete pTmpGetData; 1717 pTmpGetData = NULL; 1718 } 1719 1720 nRes = dmTreeObj.GetListNextItem(oTmpGetStructData); 1721 if ( nRes != SYNCML_DM_SUCCESS || oTmpGetStructData._pbURI == p_target_uri ) 1722 { 1723 break; 1724 } 1725 pTmpGetData = oTmpGetStructData.psRetData; 1726 oTmpGetStructData.psRetData = NULL; 1727 pTmpTargetUri = oTmpGetStructData._pbURI; 1728 } 1729 1730 if ( pTmpGetData ) 1731 { 1732 delete pTmpGetData; 1733 pTmpGetData = NULL; 1734 } 1735 1736 if ( nRes == SYNCML_DM_SUCCESS ) 1737 { 1738 p_get_ret_data->m_nFormat = SYNCML_DM_FORMAT_XML; 1739 p_get_ret_data->m_oMimeType.clear(); 1740 p_get_ret_data->m_oMimeType.assign( pDmMgmtSessionObj->IsWBXMLEncoding() ? SYNCML_CONTENT_TYPE_DM_TNDS_WBXML: SYNCML_CONTENT_TYPE_DM_TNDS_XML); 1741 p_get_ret_data->m_oData.clear(); 1742 1743 pPcDataPtr->content = p_tnd_info; 1744 pPcDataPtr->length = data_length; 1745 pPcDataPtr->contentType = SML_PCDATA_EXTENSION; 1746 pPcDataPtr->extension = SML_EXT_DMTND; 1747 } 1748 1749 return SYNCML_DM_SUCCESS; 1750 } 1751 #endif //TNDS_SUPPORT 1752 1753 /* 1754 Allocates and fill in memory structure for result 1755 */ 1756 SYNCML_DM_RET_STATUS_T 1757 SYNCML_DM_BuildPackage::AllocateResult(SmlResultsPtr_t & p_results, 1758 CPCHAR p_target_uri, 1759 CPCHAR p_CmdIdRef, 1760 DMGetData *p_get_ret_data, 1761 BOOLEAN is_ThisGetStructResult, 1762 BOOLEAN isFirstGetStruct, 1763 BOOLEAN isThisGetPropResult, 1764 CPCHAR szMsgID, 1765 SmlPcdataPtr_t p_data ) 1766 { 1767 DMString strTargetUri(p_target_uri); 1768 1769 if ( !strTargetUri.Encode() ) 1770 return SYNCML_DM_DEVICE_FULL; 1771 1772 p_results = smlAllocResults(); 1773 if ( !p_results ) 1774 return SYNCML_DM_DEVICE_FULL; 1775 1776 SmlItemListPtr_t p_results_list_item = p_results->itemList; 1777 SmlItemPtr_t p_results_item = p_results_list_item->item; 1778 1779 UINT8 data_size_str[UINT32_TYPE_STR_SIZE_10]; 1780 UINT8 *pEncData = NULL; 1781 1782 p_results_item->source = smlAllocSource(); 1783 if ( p_results_item->source == NULL ) 1784 { 1785 smlFreeResults(p_results); 1786 p_results = NULL; 1787 return (SYNCML_DM_FAIL); 1788 } 1789 1790 BuildPcData( p_results_item->source->locURI, 1791 SML_PCDATA_STRING, 1792 SML_EXT_UNDEFINED, 1793 strTargetUri.length(), 1794 (UINT8*)strTargetUri.c_str()); 1795 1796 /* Set receiving package command id reference */ 1797 BuildPcData(p_results->cmdRef, SML_PCDATA_STRING, 1798 SML_EXT_UNDEFINED, 1799 DmStrlen((char *)p_CmdIdRef), 1800 (UINT8*)p_CmdIdRef); 1801 1802 /* Call BuildPcDataWAllocMem to allocate the memory for p_results->msgRef, also construct the 1803 data. */ 1804 CPCHAR sMsg = szMsgID ? szMsgID : (CPCHAR)pMessageIdOfServer; 1805 BuildPcDataWAllocMem(&p_results->msgRef,DmStrlen(sMsg),(UINT8*)sMsg); 1806 1807 /* If p_get_ret_data is NULL, we don't construct further <RESULT> */ 1808 if (p_get_ret_data == NULL) 1809 return SYNCML_DM_SUCCESS; 1810 1811 1812 INT32 totalSize = p_get_ret_data->m_oData.getSize(); 1813 // special case for binary data 1814 if ( !is_ThisGetStructResult && 1815 p_get_ret_data->m_nFormat == SYNCML_DM_FORMAT_BIN && 1816 !p_get_ret_data->IsESN()) 1817 { 1818 if ( totalSize > 0 ) 1819 { 1820 UINT32 encLen = base64GetSize((BufferSize_t)p_get_ret_data->m_oData.getSize()); 1821 pEncData = (UINT8 *)DmAllocMem(encLen+1); 1822 if (pEncData == NULL) 1823 { 1824 smlFreeResults(p_results); p_results = NULL; 1825 return SYNCML_DM_DEVICE_FULL; 1826 } 1827 1828 memset(pEncData, 0, encLen+1); 1829 1830 UINT32 offset = 0; 1831 UINT32 dataSize = p_get_ret_data->m_oData.getSize(); 1832 totalSize = base64Encode (pEncData, encLen, 1833 p_get_ret_data->m_oData.getBuffer(), 1834 (BufferSize_t *)&dataSize, 1835 (BufferSize_t *)&offset, 0, NULL); 1836 } 1837 p_get_ret_data->m_nFormat = SYNCML_DM_FORMAT_B64; 1838 } 1839 /* Convert the dwRetDataSize to a string */ 1840 if(p_get_ret_data->IsESN()) 1841 { 1842 if ( !is_ThisGetStructResult && 1843 p_get_ret_data->m_nFormat == SYNCML_DM_FORMAT_BIN && 1844 p_get_ret_data->IsESN()) 1845 { 1846 if(p_get_ret_data->m_TotalSize != 0) 1847 totalSize = base64GetSize((BufferSize_t)p_get_ret_data->m_TotalSize); 1848 p_get_ret_data->m_nFormat = SYNCML_DM_FORMAT_B64; 1849 } 1850 else 1851 totalSize = p_get_ret_data->m_TotalSize; 1852 } 1853 DmSprintf((char *)data_size_str, "%d", p_get_ret_data->m_oData.getSize()); 1854 1855 // Is data size too large ? 1856 if(IsLargerThanMaxObjSize(totalSize, p_get_ret_data->IsESN(), TRUE)) 1857 { 1858 if (pEncData != NULL) 1859 { 1860 DmFreeMem(pEncData); 1861 } 1862 1863 smlFreeResults(p_results); p_results = NULL; 1864 return SYNCML_DM_REQUEST_ENTITY_TOO_LARGE; 1865 } 1866 1867 if (!isThisGetPropResult) 1868 { 1869 p_results_item->meta = smlAllocPcdata(); 1870 if (p_results_item->meta == NULL) 1871 { 1872 if (pEncData != NULL) 1873 { 1874 DmFreeMem(pEncData); 1875 } 1876 smlFreeResults(p_results); p_results = NULL; 1877 return SYNCML_DM_DEVICE_FULL; 1878 } 1879 1880 DMString strFormat; 1881 SYNCML_DM_RET_STATUS_T res = DMTree::ConvertFormat( p_get_ret_data->m_nFormat, strFormat); 1882 1883 if (res != SYNCML_DM_SUCCESS) 1884 { 1885 if (pEncData != NULL) 1886 { 1887 DmFreeMem(pEncData); 1888 } 1889 smlFreeResults(p_results); p_results = NULL; 1890 return res; 1891 } 1892 1893 if ((p_get_ret_data->m_oMimeType.getSize() == 0) || isFirstGetStruct) 1894 { 1895 BuildMetaInfo(p_results_item->meta, 1896 (UINT8 *)strFormat.GetBuffer(), 1897 NULL,NULL, NULL, NULL, NULL, NULL, NULL); 1898 } 1899 else 1900 { 1901 if (p_get_ret_data->m_nFormat == SYNCML_DM_FORMAT_B64) 1902 { 1903 BuildMetaInfo(p_results_item->meta, 1904 (UINT8 *)strFormat.GetBuffer(), 1905 NULL,NULL, 1906 data_size_str, 1907 NULL, NULL, NULL, NULL); 1908 } 1909 else 1910 { 1911 if (p_get_ret_data->m_nFormat == SYNCML_DM_FORMAT_CHR ) 1912 { 1913 BuildMetaInfo(p_results_item->meta, 1914 NULL,NULL,NULL,data_size_str, 1915 NULL, NULL, NULL, NULL); 1916 } 1917 else 1918 { 1919 BuildMetaInfo(p_results_item->meta, 1920 (UINT8 *)strFormat.GetBuffer(), 1921 (UINT8*)p_get_ret_data->getType(), 1922 NULL, 1923 data_size_str, 1924 NULL, NULL, NULL, NULL); 1925 } 1926 } 1927 } 1928 } 1929 1930 /* Set the p_results_item->data */ 1931 /* When data is from GET command on Struct, no need to construct <Data> element. */ 1932 if (!is_ThisGetStructResult) 1933 { 1934 /* Client construct <Data> element no matter there are data from GET command or not. */ 1935 p_results_item->data = smlAllocPcdata(); 1936 if(p_results_item->data == NULL) 1937 { 1938 if (pEncData != NULL) 1939 { 1940 DmFreeMem(pEncData); 1941 } 1942 smlFreeResults(p_results); p_results = NULL; 1943 return SYNCML_DM_DEVICE_FULL; 1944 } 1945 #ifdef LOB_SUPPORT 1946 if(pDmMgmtSessionObj->IsLargeObjectSupported() && p_get_ret_data->IsESN()) 1947 { 1948 p_results_item->data->length = totalSize; 1949 p_results_item->flags |= SmlESNData_f; 1950 // Need to encode binary data 1951 if(p_get_ret_data->m_nFormat == SYNCML_DM_FORMAT_B64) 1952 p_results_item->flags |= SmlESNBinary_f; 1953 } 1954 else 1955 #endif 1956 { 1957 if(p_get_ret_data->IsESN()) 1958 { 1959 if (pEncData != NULL) 1960 { 1961 DmFreeMem(pEncData); 1962 } 1963 smlFreeResults(p_results); p_results = NULL; 1964 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 1965 } 1966 UINT8 *pData = (pEncData == NULL) ? p_get_ret_data->m_oData.getBuffer() : pEncData; 1967 1968 #ifdef TNDS_SUPPORT 1969 if ( NULL != p_data ) 1970 { 1971 p_results_item->data->content = p_data->content; 1972 p_results_item->data->length = p_data->length; 1973 p_results_item->data->contentType = p_data->contentType; 1974 p_results_item->data->extension = p_data->extension; 1975 } 1976 else 1977 #endif 1978 { 1979 BuildPcData(p_results_item->data, 1980 SML_PCDATA_STRING, 1981 SML_EXT_UNDEFINED, 1982 totalSize, 1983 pData); 1984 1985 } 1986 } 1987 } 1988 1989 if (pEncData != NULL) 1990 DmFreeMem(pEncData); 1991 1992 #ifdef LOB_SUPPORT 1993 if(pDmMgmtSessionObj->IsLargeObjectSupported()) 1994 { 1995 return SYNCML_DM_SUCCESS; 1996 } 1997 #endif 1998 // check the size 1999 MemSize_t freeSpace = 0, initialBufferSize = smlGetFreeBuffer(sendInstanceId); 2000 SML_API Ret_t smlErr = SML_ERR_OK; 2001 smlStartEvaluation(sendInstanceId); 2002 smlErr = smlResultsCmd(sendInstanceId, p_results); 2003 smlEndEvaluation(sendInstanceId, &freeSpace); 2004 2005 if ( smlErr != SML_ERR_OK ) 2006 { 2007 smlFreeResults(p_results); p_results = NULL; 2008 return (SYNCML_DM_FAIL); 2009 } 2010 2011 /* DM_MSG_OVERHEAD is defined as the size of the syncHdr and the status 2012 to Alert (DM_NEXT_MESSAGE). The size should be 531 bytes for XML and ? for WBXML */ 2013 2014 MemSize_t nRequired = initialBufferSize - freeSpace; 2015 2016 if (nRequired > (g_iDMWorkspaceSize - DM_MSG_OVERHEAD) ) 2017 { 2018 smlFreeResults(p_results); p_results = NULL; 2019 return SYNCML_DM_RESULTS_TOO_LARGE; 2020 } 2021 2022 return SYNCML_DM_SUCCESS; 2023 } 2024 2025 /*================================================================================================== 2026 FUNCTION : SYNCML_DM_BuildPackage::BuildResultsCommand 2027 2028 DESCRIPTION : This function will be called by HandleGetCommand to add the GET results to the DM 2029 package. 2030 2031 This method calls the SyncML Toolkit function smlResultsCommand() to add results 2032 into the SyncBody for the DM message. 2033 ARGUMENT PASSED : p_CmdIdRef 2034 p_TargetUri 2035 p_results 2036 OUTPUT PARAMETER: 2037 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL 2038 IMPORTANT NOTES : 2039 2040 2041 ==================================================================================================*/ 2042 SYNCML_DM_RET_STATUS_T 2043 SYNCML_DM_BuildPackage::BuildResultsCommand( SmlResultsPtr_t p_results ) 2044 { 2045 UINT8 command_id_str[UINT16_TYPE_STR_SIZE_5]; 2046 2047 /* Convert the commandId to a string */ 2048 DmSprintf((char *)command_id_str, "%d", commandId++); 2049 BuildPcData(p_results->cmdID, SML_PCDATA_STRING, 2050 SML_EXT_UNDEFINED, 2051 DmStrlen((char *)command_id_str), 2052 command_id_str); 2053 2054 SML_API Ret_t smlErr = SML_ERR_OK; 2055 #ifdef LOB_SUPPORT 2056 smlErr = smlResultsCmd(sendInstanceId, p_results); 2057 if ( smlErr != SML_ERR_OK ) 2058 { 2059 return SYNCML_DM_RESULTS_TOO_LARGE; 2060 } 2061 2062 #else 2063 MemSize_t freeSpace; 2064 MemSize_t initialBufferSize; 2065 initialBufferSize = smlGetFreeBuffer(sendInstanceId); 2066 2067 smlStartEvaluation(sendInstanceId); 2068 smlErr = smlResultsCmd(sendInstanceId, p_results); 2069 smlEndEvaluation(sendInstanceId, &freeSpace); 2070 if ( smlErr != SML_ERR_OK ) 2071 { 2072 return (SYNCML_DM_FAIL); 2073 } 2074 2075 /* Note that freeSpace accounts for the EndSyncmlDoc overhead as well.*/ 2076 if (freeSpace > 0) { 2077 /* Call the toolkit to construct RESULTS for GET command. */ 2078 smlErr = smlResultsCmd(sendInstanceId, p_results); 2079 } else 2080 return SYNCML_DM_RESULTS_TOO_LARGE; 2081 #endif 2082 /* We cannot free any memory here since it may be used later in multiple messages.*/ 2083 if ( smlErr != SML_ERR_OK ) 2084 { 2085 return (SYNCML_DM_FAIL); 2086 } 2087 2088 return (SYNCML_DM_SUCCESS); 2089 } 2090 2091 2092 /*================================================================================================== 2093 FUNCTION : SYNCML_DM_BuildPackage::EndSyncmlDoc 2094 2095 DESCRIPTION : This function will be called by BuildPackageOne and HandleStartMessage to add the 2096 last element to the DM package. 2097 2098 This method calls the SyncML Toolkit function smlEndMessage() to add a Final element 2099 into the SyncBody for the DM message. 2100 ARGUMENT PASSED : final 2101 OUTPUT PARAMETER: 2102 RETURN VALUE : 2103 IMPORTANT NOTES : 2104 2105 2106 ==================================================================================================*/ 2107 SYNCML_DM_RET_STATUS_T 2108 SYNCML_DM_BuildPackage::EndSyncmlDoc(Boolean_t final) 2109 { 2110 Ret_t sml_ret_stat; 2111 SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS; 2112 2113 /* This ends the SyncML document it has been assembled */ 2114 /* SmlFinal_f says this is the last message in the SyncML package */ 2115 #ifdef LOB_SUPPORT 2116 if (m_bProcessingLargeObject && largeObjectCmd!= DM_COMMAND_RESULTS) 2117 { 2118 ret_stat = BuildAlertCommand(DM_ALERT_NEXT_MESSAGE, NULL, NULL); 2119 if (ret_stat != SYNCML_DM_SUCCESS) 2120 return ret_stat; 2121 // No <Final> statement 2122 final = FALSE; 2123 } 2124 #endif 2125 2126 sml_ret_stat = smlEndMessage(sendInstanceId, final); 2127 if (sml_ret_stat != SML_ERR_OK) 2128 { 2129 ret_stat = SYNCML_DM_FAIL; 2130 } 2131 return (ret_stat); 2132 } 2133 2134 2135 /*================================================================================================== 2136 FUNCTION : SYNCML_DM_BuildPackage::getDirection 2137 2138 DESCRIPTION : This function returns session direction in unsigned short. 2139 ARGUMENT PASSED : 2140 OUTPUT PARAMETER: 2141 RETURN VALUE : session direction 2142 IMPORTANT NOTES : 2143 2144 2145 ==================================================================================================*/ 2146 SYNCML_DM_SESSION_DIRECTION_T 2147 SYNCML_DM_BuildPackage::getDirection() const 2148 { 2149 return sessionDirection; 2150 } 2151 2152 2153 /*================================================================================================== 2154 FUNCTION : SYNCML_DM_BuildPackage::BuildPackageOne 2155 2156 DESCRIPTION : This function calls SYNCML_DM_BuildPackage class functions to build up the package one. 2157 ARGUMENT PASSED : session_Direction 2158 p_ParsedPk0 2159 OUTPUT PARAMETER: 2160 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL 2161 IMPORTANT NOTES : 2162 2163 2164 ==================================================================================================*/ 2165 SYNCML_DM_RET_STATUS_T 2166 SYNCML_DM_BuildPackage::BuildPackageOne(CPCHAR pServerID, DmtSessionProp * pSessionProp) 2167 { 2168 SYNCML_DM_RET_STATUS_T ret_stat; 2169 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 2170 SmlSyncHdrPtr_t p_hdr_content; 2171 char session_id_str[UINT16_TYPE_STR_SIZE_5]; 2172 DMGetData portNbrData; 2173 DMGetData devID; 2174 char *p_server_uri = NULL; 2175 CPCHAR parent_name = NULL; 2176 DMString strServerURI; 2177 CPCHAR devIMEI = NULL; 2178 bool sessionid_check = false; 2179 UINT32 finalUriLength; 2180 DMClientServerCreds *pClientServerCreds; 2181 2182 /* Allocate the memory for pSyncHdr */ 2183 2184 sessionDirection = pSessionProp->getDirection(); 2185 p_hdr_content = smlAllocSyncHdr(); 2186 if ( p_hdr_content == NULL) 2187 { 2188 return (SYNCML_DM_DEVICE_FULL); 2189 } 2190 2191 /* Fill in message id as 1 into the sync header */ 2192 BuildPcData(p_hdr_content->msgID, SML_PCDATA_STRING, 2193 SML_EXT_UNDEFINED, 2194 DmStrlen((char *)DEFAULT_MESSAGE_ID), 2195 (UINT8 *)DEFAULT_MESSAGE_ID); 2196 2197 sessionid_check = IsSessionId(); 2198 if(sessionid_check == true) 2199 { 2200 /* Fill in the SessionId data which come from p_ParsedPk0, must be in upper case hex */ 2201 DmSprintf(session_id_str, "%X", pSessionProp->getSessionID()); 2202 } 2203 else 2204 { 2205 /* Fill in the SessionId data which come from p_ParsedPk0, must be in decimal */ 2206 DmSprintf(session_id_str, "%d", pSessionProp->getSessionID()); 2207 } 2208 2209 BuildPcData(p_hdr_content->sessionID, 2210 SML_PCDATA_STRING,SML_EXT_UNDEFINED, 2211 DmStrlen(session_id_str), 2212 (UINT8*)session_id_str); 2213 2214 /* We can use the DMAccNodeName that was stored in ConnectServer().*/ 2215 pClientServerCreds = pDmMgmtSessionObj->GetClientServerCreds(); 2216 parent_name = (CPCHAR)pClientServerCreds->pDMAccNodeName; 2217 if (parent_name == NULL) 2218 { 2219 smlFreeSyncHdr(p_hdr_content); 2220 return (SYNCML_DM_FAIL); 2221 } 2222 2223 /* Call the local method to retrieve the value of "./SyncML/DMAcc/<parent_name>/Addr" */ 2224 DMGetData oDataAddrType, oAddr; 2225 2226 ret_stat = dmTreeObj.GetDefAccountAddrInfo( parent_name, 2227 oAddr, 2228 oDataAddrType, 2229 portNbrData ); 2230 2231 if ( (dm_stat != SYNCML_DM_SUCCESS) || (oAddr.m_oData.getSize() == 0) ) 2232 { 2233 smlFreeSyncHdr(p_hdr_content); 2234 return (SYNCML_DM_FAIL); 2235 } 2236 2237 /* If port number is NULL, means its value is defaulted as 80, we don't need to do anything. 2238 Otherwise, insert port number into the server address */ 2239 if ( portNbrData.m_oData.getSize() != 0 ) 2240 { 2241 char * pUriBeg; 2242 char * pUriMid; 2243 2244 /* Locate the position of '://' */ 2245 pUriBeg = (char*)DmStrstr(oAddr.getCharData(), "://"); 2246 if (pUriBeg == NULL) 2247 { 2248 pUriBeg = (char*)oAddr.getCharData(); 2249 } 2250 else 2251 { 2252 pUriBeg += 3; 2253 } 2254 char* pUriBeg2 = NULL; 2255 char* pPortNumber = NULL; 2256 2257 /* Locate the position of ':' */ 2258 pPortNumber = DmStrchr(pUriBeg, ':'); 2259 2260 /* Locate the position of '/' */ 2261 pUriMid = DmStrchr(pUriBeg, '/'); 2262 if (pUriMid == NULL) 2263 { 2264 pUriBeg2 = (char*)DmAllocMem(DmStrlen(pUriBeg)+2); 2265 if ( pUriBeg2 == NULL ) 2266 { 2267 smlFreeSyncHdr(p_hdr_content); 2268 return (SYNCML_DM_DEVICE_FULL); 2269 } 2270 2271 DmStrcpy(pUriBeg2,pUriBeg); 2272 2273 /* Insert '/' at the end of URL */ 2274 DmStrcat(pUriBeg2, "/"); 2275 DmFreeMem(pUriBeg); 2276 2277 pUriBeg = pUriBeg2; 2278 pUriMid = DmStrchr(pUriBeg, '/'); 2279 if ( pUriMid == NULL ) 2280 { 2281 if ( pUriBeg2 != NULL ) 2282 { 2283 DmFreeMem(pUriBeg2); 2284 } 2285 smlFreeSyncHdr(p_hdr_content); 2286 return (SYNCML_DM_FAIL); 2287 } 2288 } 2289 /* Calculate the length of the final server address */ 2290 finalUriLength = oAddr.m_oData.getSize() + portNbrData.m_oData.getSize() + 2; 2291 2292 /* Allocate memory for the new URL, copy addr and portNbr to new uri */ 2293 p_server_uri = (char*)DmAllocMem(finalUriLength); 2294 if ( p_server_uri == NULL ) 2295 { 2296 if ( pUriBeg2 != NULL ) 2297 { 2298 DmFreeMem(pUriBeg2); 2299 } 2300 smlFreeSyncHdr(p_hdr_content); 2301 return (SYNCML_DM_DEVICE_FULL); 2302 } 2303 memset(p_server_uri, 0, finalUriLength); 2304 DmStrncpy(p_server_uri, oAddr.getCharData(),pUriMid - oAddr.getCharData()); 2305 2306 if(portNbrData.m_oData.getSize() == 0 || pPortNumber != NULL) 2307 DmStrcat(p_server_uri,pUriMid); 2308 else 2309 { 2310 DmStrcat((char*)p_server_uri, ":"); 2311 DmStrcat((char*)p_server_uri, portNbrData.getCharData()); 2312 DmStrcat((char*)p_server_uri, pUriMid); 2313 } 2314 2315 if ( pUriBeg2 != NULL ) 2316 { 2317 DmFreeMem(pUriBeg2); 2318 } 2319 } 2320 else 2321 { 2322 oAddr.m_oData.copyTo(&p_server_uri); 2323 if ( p_server_uri == NULL ) 2324 { 2325 smlFreeSyncHdr(p_hdr_content); 2326 return (SYNCML_DM_DEVICE_FULL); 2327 } 2328 } 2329 2330 2331 /* Call MgmtSession object to set server URI here to reduce code for transport module, since 2332 we have constructed server uri with server address and port number */ 2333 strServerURI = (CPCHAR)p_server_uri; 2334 pDmMgmtSessionObj->SetURI(strServerURI.c_str()); 2335 if(strServerURI.Encode()== FALSE) 2336 { 2337 if ( p_server_uri != NULL ) 2338 DmFreeMem(p_server_uri); 2339 smlFreeSyncHdr(p_hdr_content); 2340 return (SYNCML_DM_FAIL); 2341 } 2342 2343 if(p_hdr_content->source == NULL) 2344 { 2345 if ( p_server_uri != NULL ) 2346 DmFreeMem(p_server_uri); 2347 smlFreeSyncHdr(p_hdr_content); 2348 return (SYNCML_DM_FAIL); 2349 } 2350 2351 /* Fill in the server address information into pSyncHdr structure target->locURI element.*/ 2352 BuildPcData(p_hdr_content->source->locURI, SML_PCDATA_STRING, 2353 SML_EXT_UNDEFINED, 2354 strServerURI.length(), 2355 (UINT8 *) strServerURI.c_str()); 2356 2357 /* Free the memory of p_server_uri */ 2358 DmFreeMem(p_server_uri); 2359 2360 /* Fill in the server id information into pSyncHdr structure target->locName element. */ 2361 if (pServerID != NULL) 2362 { 2363 BuildPcDataWAllocMem(&p_hdr_content->source->locName,DmStrlen(pServerID),(UINT8*)pServerID); 2364 } 2365 2366 /* While we are retrieving things from the DM Tree, we'll get the rest of the Security info.*/ 2367 pClientServerCreds->pServerId = pServerID; 2368 if ( pClientServerCreds->pServerId != pServerID ) 2369 { 2370 XPL_LOG_DM_SESS_Error(("SYNCML_DM_BuildPackage::BuildPackageOne : unable allocate memory")); 2371 smlFreeSyncHdr(p_hdr_content); 2372 return SYNCML_DM_DEVICE_FULL; 2373 } 2374 /* Call the local method to retrieve the value of "./DevInfo/DevId" */ 2375 dm_stat = dmTreeObj.Get(DM_DEV_INFO_DEVID_URI, devID,SYNCML_DM_REQUEST_TYPE_INTERNAL); 2376 2377 if (dm_stat != SYNCML_DM_SUCCESS) 2378 { 2379 smlFreeSyncHdr(p_hdr_content); 2380 return (SYNCML_DM_FAIL); 2381 } 2382 2383 if (devID.m_oData.getSize() != 0) 2384 devIMEI = GetIMEINumber(devID.getCharData()); 2385 2386 /* Call the local method to retrieve the remaining pieces of Security Info.*/ 2387 2388 dm_stat = GetRemainingSecInfo(parent_name, pClientServerCreds, devIMEI); 2389 if ( dm_stat != SYNCML_DM_SUCCESS ) 2390 { 2391 smlFreeSyncHdr(p_hdr_content); 2392 return (SYNCML_DM_FAIL); 2393 } 2394 2395 BuildPcDataWAllocMem(&p_hdr_content->target->locName, 2396 DmStrlen((CPCHAR)(pClientServerCreds->pClientUserName)), 2397 (UINT8*)pClientServerCreds->pClientUserName.c_str()); 2398 2399 /* Fill the client dev id information into pSyncHdr structure source->locURI element. */ 2400 if (devID.m_oData.getSize() != 0) 2401 { 2402 BuildPcData(p_hdr_content->target->locURI, SML_PCDATA_STRING, 2403 SML_EXT_UNDEFINED, 2404 devID.m_oData.getSize(), 2405 devID.m_oData.getBuffer()); 2406 } 2407 2408 2409 /* Call BuildSyncHdr to construct the <SyncHdr> */ 2410 ret_stat = BuildStartSyncHdr(p_hdr_content,TRUE); 2411 smlFreeSyncHdr(p_hdr_content); 2412 if (ret_stat != SYNCML_DM_SUCCESS) 2413 { 2414 return(ret_stat); 2415 } 2416 ret_stat = BuildFinishSyncHdr(pClientServerCreds->AuthPrefCredType); 2417 2418 if (ret_stat != SYNCML_DM_SUCCESS) 2419 { 2420 return(ret_stat); 2421 } 2422 2423 /* Build up the Alert command to indicate server or client initiate the session */ 2424 ret_stat = BuildAlertCommand(sessionDirection, NULL, NULL); 2425 if (ret_stat != SYNCML_DM_SUCCESS) 2426 { 2427 return(ret_stat); 2428 } 2429 2430 /* Build the DevInfo data in REPLACE command */ 2431 ret_stat = BuildReplaceCommand(); 2432 if (ret_stat != SYNCML_DM_SUCCESS) 2433 { 2434 return(ret_stat); 2435 } 2436 2437 //DMFirmAlertVector aFirmAlert; 2438 //pSessionProp->getFirmAlerts(aFirmAlert); 2439 firmAlertVec.clear(); 2440 pSessionProp->getFirmAlerts(firmAlertVec); 2441 //if ( aFirmAlert.size() > 0 ) 2442 //{ 2443 ret_stat = BuildAlert1226Command(); 2444 if (ret_stat != SYNCML_DM_SUCCESS) 2445 { 2446 return(ret_stat); 2447 } 2448 //} 2449 2450 /* End the SyncML document */ 2451 ret_stat = EndSyncmlDoc(SmlFinal_f); 2452 return (ret_stat); 2453 } 2454 2455 2456 2457 /*================================================================================================== 2458 Function: SYNCML_DM_BuildPackage::GetRemainingSecInfo (private) 2459 2460 Description: This method is called to retrieve the remaining pieces of Security Info needed for 2461 creating credentials during this session. This method will retrieve: 2462 - ServerPW 2463 - ServerNonce 2464 - user name (client) 2465 - ClientPW 2466 - ClientNonce 2467 ARGUMENT PASSED : 2468 OUTPUT PARAMETER: 2469 RETURN VALUE : SYNCML_DM_SUCCESS or SYNCML_DM_FAIL 2470 IMPORTANT NOTES : This method assumes the DM Tree is locked and the management session is in 2471 progress. 2472 2473 ==================================================================================================*/ 2474 SYNCML_DM_RET_STATUS_T 2475 SYNCML_DM_BuildPackage::GetRemainingSecInfo (CPCHAR pParentName, 2476 DMClientServerCreds *pClientServerCreds, 2477 CPCHAR devIMEI) 2478 { 2479 DMGetData serverData; 2480 DMGetData clientData; 2481 2482 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 2483 2484 dm_stat = pClientServerCreds->LoadInitialValues(); 2485 2486 if ( dm_stat != SYNCML_DM_SUCCESS ) 2487 return dm_stat; 2488 2489 pDmMgmtSessionObj->SetSecState(DM_CLIENT_NO_SERVER_NO_AUTH); 2490 2491 return (dm_stat); 2492 } 2493 2494 /*=============================================================================== 2495 FUNCTION : CreateFactoryBootStrapUserName 2496 2497 DESCRIPTION : This function will create factory boot strap's user name 2498 2499 OUTPUT PARAMETER: 2500 RETURN VALUE : SYNCML_DM_STATUS_T 2501 =================================================================================*/ 2502 SYNCML_DM_RET_STATUS_T 2503 SYNCML_DM_BuildPackage::CreateFactoryBootStrapUserName( SYNCML_DM_FACTORY_BOOTSTRAP_T bootStrapCode, 2504 const DMString& server_id, 2505 const DMString& devIMEI, 2506 DMString& user_name ) 2507 { 2508 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 2509 2510 switch ( bootStrapCode ) 2511 { 2512 case SYNCML_DM_FACTORY_BOOTSTRAP_FCS11384: 2513 { 2514 dm_stat = BuildFactoryBootstrapCredData(user_name, 2515 devIMEI + ":" + server_id, 2516 DM_NAME); 2517 break; 2518 } 2519 case SYNCML_DM_FACTORY_BOOTSTRAP_FCS14345: 2520 { 2521 // IMEI becomes the UserName 2522 user_name = devIMEI; 2523 break; 2524 } 2525 default: 2526 { 2527 break; 2528 } 2529 } 2530 2531 if( ( SYNCML_DM_SUCCESS != dm_stat ) || 2532 ( 0 == user_name.length() ) ) 2533 { 2534 dm_stat = SYNCML_DM_DEVICE_FULL; 2535 } 2536 2537 return dm_stat; 2538 } 2539 2540 2541 2542 /*=============================================================================== 2543 FUNCTION : CreateFactoryBootStrapPW 2544 2545 DESCRIPTION : This function will create factory boot strap's server or client pass word 2546 2547 OUTPUT PARAMETER: 2548 RETURN VALUE : SYNCML_DM_STATUS_T 2549 2550 2551 =================================================================================*/ 2552 SYNCML_DM_RET_STATUS_T 2553 SYNCML_DM_BuildPackage::CreateFactoryBootStrapServerPW( SYNCML_DM_FACTORY_BOOTSTRAP_T bootStrapCode, 2554 const DMString& server_id, 2555 const DMString& abIMEI, 2556 DMString& server_password ) 2557 { 2558 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 2559 2560 switch ( bootStrapCode ) 2561 { 2562 case SYNCML_DM_FACTORY_BOOTSTRAP_FCS11384: 2563 { 2564 dm_stat = BuildFactoryBootstrapCredData(server_password, 2565 server_id, 2566 abIMEI); 2567 2568 if ( dm_stat != SYNCML_DM_SUCCESS ) 2569 return SYNCML_DM_DEVICE_FULL; 2570 break; 2571 } 2572 case SYNCML_DM_FACTORY_BOOTSTRAP_FCS14345: 2573 { 2574 2575 GeneratePassword gp; 2576 2577 gp.setIMEI(abIMEI); 2578 gp.setServerId(server_id); 2579 2580 char* srvpw = gp.generateServerPassword(); 2581 server_password = srvpw; 2582 DmFreeMem(srvpw); 2583 break; 2584 } 2585 default: 2586 { 2587 return dm_stat; 2588 } 2589 } 2590 2591 return dm_stat; 2592 } 2593 2594 2595 /*=============================================================================== 2596 FUNCTION : CreateFactoryBootStrapPW 2597 2598 DESCRIPTION : This function will create factory boot strap's server or client pass word 2599 2600 OUTPUT PARAMETER: 2601 RETURN VALUE : SYNCML_DM_STATUS_T 2602 2603 2604 =================================================================================*/ 2605 SYNCML_DM_RET_STATUS_T 2606 SYNCML_DM_BuildPackage::CreateFactoryBootStrapClientPW( SYNCML_DM_FACTORY_BOOTSTRAP_T bootStrapCode, 2607 const DMString& server_id, 2608 const DMString& abIMEI, 2609 DMString& client_password ) 2610 { 2611 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 2612 2613 switch (bootStrapCode) 2614 { 2615 case SYNCML_DM_FACTORY_BOOTSTRAP_FCS11384: 2616 { 2617 dm_stat = BuildFactoryBootstrapCredData( client_password, 2618 abIMEI, 2619 server_id ); 2620 2621 if ( dm_stat != SYNCML_DM_SUCCESS ) 2622 { 2623 dm_stat = SYNCML_DM_DEVICE_FULL; 2624 } 2625 2626 break; 2627 } 2628 case SYNCML_DM_FACTORY_BOOTSTRAP_FCS14345: 2629 { 2630 GeneratePassword gp; 2631 2632 gp.setIMEI(abIMEI); 2633 gp.setServerId( server_id ); 2634 2635 char* clnpw = gp.generateClientPassword(); 2636 client_password = clnpw; 2637 DmFreeMem(clnpw); 2638 break; 2639 } 2640 default: 2641 { 2642 break; 2643 } 2644 } 2645 2646 return dm_stat; 2647 } 2648 2649 2650 /*============================================================================= 2651 FUNCTION:BuildFactoryBootstrapCredData 2652 DESCRIPTION: 2653 This function builds the B64 encoded MD5 credential information. 2654 The credential string is credential data:IMEI number . That string is then b64 encoded. 2655 2656 ARGUMENTS PASSED: 2657 2658 REFERENCE ARGUMENTS PASSED: 2659 char **pp_credential_data - Output variable containing the encoded credential data 2660 const char *p_CredData - credential_data . 2661 const char *p_IMEI - Phone IMEI number. 2662 2663 2664 RETURN VALUE: 2665 N/A 2666 2667 PRE-CONDITIONS: 2668 2669 POST-CONDITIONS: 2670 2671 ================================================================================*/ 2672 SYNCML_DM_RET_STATUS_T 2673 SYNCML_DM_BuildPackage::BuildFactoryBootstrapCredData(DMString& pp_credential_data, 2674 CPCHAR p_CredData, 2675 CPCHAR p_CredData1 ) 2676 { 2677 char *p_CredData_IMEI; 2678 MD5_CTX md5_context; 2679 char md5hash[SYNCML_DM_HASHLEN + 1]; /* Add 1 character for NULL */ 2680 BufferSize_t offset = 0; 2681 BufferSize_t md5_hash_length = SYNCML_DM_HASHLEN; 2682 BufferSize_t total_length; 2683 2684 memset(md5hash, '\0', SYNCML_DM_HASHLEN + 1); 2685 2686 char* pCredData = pp_credential_data.AllocateBuffer(SYNCML_DM_BAS64_ENCODING_SIZE_IN_MD5 + 1); 2687 2688 if ( pCredData == NULL ) 2689 { 2690 XPL_LOG_DM_SESS_Error(("BuildFactoryBootstrapCredData : unable allocate memory")); 2691 return SYNCML_DM_DEVICE_FULL; 2692 } 2693 2694 memset(pCredData, 0, SYNCML_DM_BAS64_ENCODING_SIZE_IN_MD5+1); 2695 /* Add space for the ":" and NULL character */ 2696 total_length= DmStrlen(p_CredData) + DmStrlen(p_CredData1) + 2; 2697 p_CredData_IMEI = (char *)DmAllocMem(total_length); 2698 2699 if ( p_CredData_IMEI == NULL ) 2700 { 2701 XPL_LOG_DM_SESS_Error(("BuildFactoryBootstrapCredData : unable allocate memory")); 2702 return SYNCML_DM_DEVICE_FULL; 2703 } 2704 2705 memset(p_CredData_IMEI, '\0', total_length); 2706 DmStrcpy(p_CredData_IMEI, p_CredData); 2707 DmStrcat(p_CredData_IMEI, ":"); 2708 DmStrcat(p_CredData_IMEI, p_CredData1); 2709 2710 smlMD5Init(&md5_context); 2711 smlMD5Update(&md5_context, (unsigned char *)p_CredData_IMEI,DmStrlen(p_CredData_IMEI)); 2712 smlMD5Final((unsigned char*)md5hash, &md5_context); 2713 md5hash[SYNCML_DM_HASHLEN] = 0; 2714 DmFreeMem(p_CredData_IMEI); 2715 2716 base64Encode((UINT8*)pCredData, 2717 SYNCML_DM_BAS64_ENCODING_SIZE_IN_MD5+1, 2718 (unsigned char *)md5hash, 2719 &md5_hash_length, 2720 &offset, 2721 1, /* Encode as single block */ 2722 NULL); /* No incomplete bl*/ 2723 return SYNCML_DM_SUCCESS; 2724 2725 } 2726 2727 SYNCML_DM_FACTORY_BOOTSTRAP_T SYNCML_DM_BuildPackage::GetBootStrapCodeUserName(const DMString& user_name ) 2728 { 2729 if( user_name == DMACC_FACTORY_BOOTSTRAP_USERNAME_FCS11384 ) 2730 { 2731 return SYNCML_DM_FACTORY_BOOTSTRAP_FCS11384; 2732 } 2733 else if ( user_name == DMACC_FACTORY_BOOTSTRAP_USERNAME_FCS14345 ) 2734 { 2735 return SYNCML_DM_FACTORY_BOOTSTRAP_FCS14345; 2736 } 2737 2738 return SYNCML_DM_FACTORY_BOOTSTRAP_UNKNOWN; 2739 } 2740 2741 SYNCML_DM_FACTORY_BOOTSTRAP_T SYNCML_DM_BuildPackage::GetBootStrapCodeClientPW(const DMString& password ) 2742 { 2743 if ( password == DMACC_FACTORY_BOOTSTRAP_CLIENTPW_FCS11384 ) 2744 { 2745 return SYNCML_DM_FACTORY_BOOTSTRAP_FCS11384; 2746 } 2747 else if ( password == DMACC_FACTORY_BOOTSTRAP_CLIENTPW_FCS14345 ) 2748 { 2749 return SYNCML_DM_FACTORY_BOOTSTRAP_FCS14345; 2750 } 2751 2752 return SYNCML_DM_FACTORY_BOOTSTRAP_UNKNOWN; 2753 } 2754 2755 SYNCML_DM_FACTORY_BOOTSTRAP_T SYNCML_DM_BuildPackage::GetBootStrapCodeServerPW(const DMString& password ) 2756 { 2757 if ( password == DMACC_FACTORY_BOOTSTRAP_SERVERPW_FCS11384 ) 2758 { 2759 return SYNCML_DM_FACTORY_BOOTSTRAP_FCS11384; 2760 } 2761 else if ( password == DMACC_FACTORY_BOOTSTRAP_SERVERPW_FCS14345 ) 2762 { 2763 return SYNCML_DM_FACTORY_BOOTSTRAP_FCS14345; 2764 } 2765 2766 return SYNCML_DM_FACTORY_BOOTSTRAP_UNKNOWN; 2767 } 2768 2769 /*================================================================= 2770 2771 ===================================================================*/ 2772 CPCHAR 2773 SYNCML_DM_BuildPackage::GetIMEINumber(CPCHAR devID) 2774 { 2775 char *retValue = (char*)DmStrchr(devID, ':'); 2776 if( retValue == NULL ) 2777 return devID; 2778 else 2779 return (++retValue); 2780 } 2781 2782 /*================================================================================================== 2783 FUNCTION :DecodBase64Data 2784 2785 DESCRIPTION : Handling of SYNCML_DM_FORMAT_B64 2786 ARGUMENT PASSED : 2787 OUTPUT PARAMETER: 2788 RETURN VALUE : 2789 IMPORTANT NOTES : 2790 2791 ==================================================================================================*/ 2792 SYNCML_DM_RET_STATUS_T 2793 SYNCML_DM_BuildPackage::DecodBase64Data(SmlItemPtr_t &p_add_item, DMAddData & oAddData, BOOLEAN decodeB64) 2794 { 2795 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 2796 if (p_add_item->data != NULL) 2797 { 2798 // special-case handling of SYNCML_DM_FORMAT_B64 2799 if (oAddData.m_nFormat == SYNCML_DM_FORMAT_B64 && decodeB64) 2800 { 2801 UINT8 *decDataBuf; 2802 UINT32 dataLen = p_add_item->data->length;; 2803 UINT32 decDataLen; 2804 UINT32 decMaxBufLen = dataLen*3/4+2; 2805 2806 decDataBuf = (UINT8*)DmAllocMem(decMaxBufLen); 2807 if(decDataBuf == NULL) 2808 return SYNCML_DM_DEVICE_FULL; 2809 decDataLen = base64Decode(decDataBuf , decMaxBufLen, (DataBuffer_t) p_add_item->data->content, 2810 (BufferSize_t *)&dataLen); 2811 if (decDataLen == 0) 2812 { 2813 DmFreeMem(decDataBuf); 2814 return SYNCML_DM_BAD_REQUEST; 2815 } 2816 2817 oAddData.m_oData.assign(decDataBuf, decDataLen); 2818 2819 if ( oAddData.m_oData.getBuffer() == NULL ) 2820 { 2821 DmFreeMem(decDataBuf); 2822 return SYNCML_DM_DEVICE_FULL; 2823 } 2824 DmFreeMem(decDataBuf); 2825 oAddData.m_nFormat = SYNCML_DM_FORMAT_BIN; 2826 } 2827 else 2828 { 2829 if ( p_add_item->data->length ) 2830 { 2831 oAddData.m_oData.assign((UINT8*)p_add_item->data->content, p_add_item->data->length); 2832 if ( oAddData.m_oData.getBuffer() == NULL ) 2833 dm_stat = SYNCML_DM_DEVICE_FULL; 2834 } 2835 } 2836 2837 } 2838 return dm_stat; 2839 } 2840 /*================================================================================================== 2841 FUNCTION :IsLargerThanMaxObjSize 2842 2843 DESCRIPTION : Is data size larger than MaxObjSize 2844 ARGUMENT PASSED : 2845 OUTPUT PARAMETER: 2846 RETURN VALUE : 2847 IMPORTANT NOTES : 2848 2849 ==================================================================================================*/ 2850 BOOLEAN 2851 SYNCML_DM_BuildPackage::IsLargerThanMaxObjSize( int dataSize, BOOLEAN isESN, BOOLEAN isToServer) 2852 { 2853 // If data size is larger then MaxObjSize 2854 XPL_FS_SIZE_T maxSize = MaxObjectSize; 2855 2856 #ifdef LOB_SUPPORT 2857 if(!isToServer) 2858 { if(isESN) 2859 { 2860 DMString m_strEsnDir; 2861 dmTreeObj.GetWritableFileSystemFullPath( m_strEsnDir ); 2862 maxSize = XPL_FS_FreeDiskSpace(m_strEsnDir.c_str()); 2863 } 2864 else 2865 { 2866 maxSize = MaxObjectSize = pDmMgmtSessionObj->GetDefaultMaxObjectSize(); 2867 } 2868 } 2869 #endif 2870 2871 // <MaxObjSize> is missing 2872 if(maxSize == 0) 2873 { 2874 if(isESN) 2875 maxSize = SYNCML_DM_MAX_OBJ_SIZE; 2876 else 2877 maxSize = MaxMessageSize * 2; 2878 } 2879 if(dataSize > (int)maxSize) 2880 return TRUE; 2881 else 2882 return FALSE; 2883 } 2884 #ifdef LOB_SUPPORT 2885 /*================================================================================================== 2886 FUNCTION :LargeObjectClear 2887 2888 DESCRIPTION : Clears large object related variables 2889 ARGUMENT PASSED : 2890 OUTPUT PARAMETER: 2891 RETURN VALUE : 2892 IMPORTANT NOTES : 2893 2894 ==================================================================================================*/ 2895 void 2896 SYNCML_DM_BuildPackage::LargeObjectClear() 2897 { 2898 m_bProcessingLargeObject = FALSE; 2899 m_bESN = FALSE; 2900 m_bBinary = FALSE; 2901 if(m_pChunkData != NULL) 2902 delete m_pChunkData; 2903 2904 m_pChunkData = NULL; 2905 m_ChunkOffset = 0; 2906 2907 largeObjectCmdSize = 0; 2908 largeObjectSize = 0; 2909 largeObjectBufferUsedSize = 0; 2910 largeObjectMsgRef = 0; 2911 largeObjectChunkSize = 0; 2912 largeObjectChunkOffset = 0; 2913 2914 largeObjectBuffer.free(); 2915 largeObjectCmdRef = NULL; 2916 largeObjectMsgRef = NULL; 2917 2918 largeObjectTURI.free(); 2919 largeObjectSURI.free(); 2920 largeObjectType.free(); 2921 largeObjectFormat = SYNCML_DM_FORMAT_INVALID; 2922 largeObjectCmd = DM_COMMAND_INVALID; 2923 if(largeObjFileHandle != NULL) 2924 { largeObjFileHandle->deleteFile(); 2925 delete largeObjFileHandle; 2926 largeObjFileHandle = NULL; 2927 } 2928 largeObjFileName = NULL; 2929 2930 } 2931 /*================================================================================================== 2932 FUNCTION : AllocateChunkBuffer 2933 2934 DESCRIPTION : Allocate chunk buffer 2935 ARGUMENT PASSED : 2936 OUTPUT PARAMETER: 2937 RETURN VALUE : 2938 IMPORTANT NOTES : 2939 2940 ==================================================================================================*/ 2941 DmtDataChunk * 2942 SYNCML_DM_BuildPackage::AllocateChunkBuffer() 2943 { 2944 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 2945 DmtDataChunk *chunkData; 2946 2947 chunkData = new DmtDataChunk(); 2948 if(chunkData == NULL) 2949 return NULL; 2950 2951 dm_stat = chunkData->AllocateChunkBuffer(); 2952 if (dm_stat != SYNCML_DM_SUCCESS) 2953 { 2954 delete chunkData; 2955 return NULL; 2956 } 2957 return chunkData; 2958 } 2959 2960 /*================================================================================================== 2961 FUNCTION : SetEngineChunkData 2962 2963 DESCRIPTION : Set chunk data to engine 2964 ARGUMENT PASSED : 2965 OUTPUT PARAMETER: 2966 RETURN VALUE : 2967 IMPORTANT NOTES : 2968 2969 ==================================================================================================*/ 2970 SYNCML_DM_RET_STATUS_T 2971 SYNCML_DM_BuildPackage:: SetChunkDataToEngine(DMAddData & oAddData, BOOLEAN isAllSet) 2972 { 2973 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 2974 DMAddData oReplace; 2975 2976 oReplace.m_oURI.assign(oAddData.getURI()); 2977 if(oReplace.m_oURI.getBuffer() == NULL) 2978 return SYNCML_DM_DEVICE_FULL; 2979 2980 oReplace.m_bLastChunk = isAllSet; 2981 oReplace.chunkData = m_pChunkData; 2982 oReplace.m_chunkOffset = m_ChunkOffset; 2983 2984 retStatus = dmTreeObj.Replace(oReplace,SYNCML_DM_REQUEST_TYPE_SERVER); 2985 return retStatus; 2986 } 2987 /*================================================================================================== 2988 FUNCTION : SetLastChunkDataFromFile 2989 2990 DESCRIPTION : Set last chunk data from file 2991 ARGUMENT PASSED : 2992 OUTPUT PARAMETER: 2993 RETURN VALUE : 2994 IMPORTANT NOTES : 2995 2996 ==================================================================================================*/ 2997 SYNCML_DM_RET_STATUS_T 2998 SYNCML_DM_BuildPackage::SetLastChunkDataFromFile(DMAddData & oAddData, 2999 DMBuffer &lastData, 3000 UINT8**szBuf, 3001 int chunksize, 3002 UINT8 *decDataBuf, 3003 UINT32 decMaxBufLen, 3004 UINT32 &lastChunkSize) 3005 { 3006 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 3007 int setLen = 0; 3008 BOOLEAN isAllSet = FALSE; 3009 int offset = 0; 3010 UINT32 dataLen = largeObjectSize; 3011 UINT32 decDataLen = 0; 3012 DMBuffer remainData; 3013 3014 // Close it first 3015 largeObjFileHandle->close(); 3016 delete largeObjFileHandle; 3017 largeObjFileHandle = NULL; 3018 retStatus = OpenESNTempFile(); 3019 if (retStatus != SYNCML_DM_SUCCESS) 3020 return retStatus; 3021 3022 m_pChunkData->GetChunkData(szBuf); // the chunk data is available 3023 3024 while (offset < largeObjectBufferUsedSize && !isAllSet) 3025 { 3026 setLen = largeObjectBufferUsedSize - offset; 3027 if(setLen > chunksize) 3028 setLen = chunksize; 3029 else 3030 isAllSet = TRUE; 3031 if(largeObjFileHandle->seek(XPL_FS_SEEK_SET, offset) != SYNCML_DM_SUCCESS) 3032 return SYNCML_DM_IO_FAILURE; 3033 3034 if(largeObjFileHandle->read(*szBuf, setLen) != SYNCML_DM_SUCCESS) 3035 return SYNCML_DM_IO_FAILURE; 3036 3037 // special-case handling of SYNCML_DM_FORMAT_B64 3038 if(decDataBuf != NULL) 3039 { 3040 dataLen = setLen; 3041 decDataLen = base64Decode(decDataBuf , decMaxBufLen, (DataBuffer_t) *szBuf, 3042 (BufferSize_t *)&dataLen); 3043 if (decDataLen == 0) 3044 return SYNCML_DM_BAD_REQUEST; 3045 if(dataLen != 0) 3046 remainData.assign((CPCHAR)& (*szBuf[0]), dataLen); 3047 3048 m_pChunkData->SetChunkData(decDataBuf, decDataLen); 3049 setLen -= dataLen; 3050 3051 } 3052 else 3053 m_pChunkData->SetChunkData(NULL, setLen); 3054 3055 retStatus = SetChunkDataToEngine(oAddData, FALSE); 3056 if(retStatus !=SYNCML_DM_SUCCESS) 3057 return retStatus; 3058 3059 if(decDataBuf != NULL) 3060 m_ChunkOffset += decDataLen; 3061 else 3062 m_ChunkOffset += setLen; 3063 3064 offset += setLen; 3065 } 3066 3067 if(decDataBuf != NULL && dataLen != 0) 3068 { 3069 // Allocate the Large Object Buffer based on the size 3070 lastChunkSize = lastData.getSize() + dataLen; 3071 3072 largeObjectBuffer.allocate( lastChunkSize + 1); 3073 if ( largeObjectBuffer.getBuffer() == NULL ) 3074 return SYNCML_DM_DEVICE_FULL; 3075 3076 // All non-processed data are shifted to the start of the input buffer 3077 largeObjectBuffer = remainData; 3078 largeObjectBuffer.append( lastData.getBuffer(),lastData.getSize()); 3079 *szBuf = largeObjectBuffer.getBuffer(); 3080 } 3081 else 3082 { 3083 *szBuf = lastData.getBuffer(); 3084 lastChunkSize = lastData.getSize(); 3085 } 3086 return retStatus; 3087 } 3088 /*================================================================================================== 3089 FUNCTION : SetLastChunkRemainData 3090 3091 DESCRIPTION : Processing all the remaining data 3092 ARGUMENT PASSED : 3093 OUTPUT PARAMETER: 3094 RETURN VALUE : 3095 IMPORTANT NOTES : 3096 3097 ==================================================================================================*/ 3098 SYNCML_DM_RET_STATUS_T 3099 SYNCML_DM_BuildPackage::SetLastChunkRemainData(DMAddData & oAddData, 3100 DMBuffer &lastData, 3101 UINT8* szBuf, 3102 int chunksize, 3103 UINT8 *decDataBuf, 3104 UINT32 decMaxBufLen, 3105 UINT32 lastChunkSize) 3106 { 3107 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 3108 BOOLEAN isAllSet = FALSE; 3109 int offset = 0; 3110 int setLen = 0; 3111 UINT32 dataLen = largeObjectSize; 3112 UINT32 decDataLen; 3113 3114 offset = 0; 3115 while (offset <= (int)lastChunkSize && !isAllSet) 3116 { setLen = lastChunkSize - offset; 3117 if(setLen > chunksize) 3118 setLen = chunksize; 3119 else 3120 isAllSet = TRUE; 3121 3122 if(szBuf != NULL) 3123 { 3124 // special-case handling of SYNCML_DM_FORMAT_B64 3125 if(decDataBuf != NULL) 3126 { 3127 dataLen = setLen; 3128 decDataLen = base64Decode(decDataBuf , decMaxBufLen, (DataBuffer_t) &szBuf[offset], 3129 (BufferSize_t *)&dataLen); 3130 if (decDataLen == 0) 3131 return SYNCML_DM_BAD_REQUEST; 3132 3133 m_pChunkData->SetChunkData(decDataBuf, decDataLen); 3134 setLen -= dataLen; 3135 } 3136 else 3137 { 3138 m_pChunkData->SetChunkData((const UINT8 *)&szBuf[offset], setLen); 3139 } 3140 } 3141 3142 retStatus = SetChunkDataToEngine(oAddData,isAllSet); 3143 if(retStatus !=SYNCML_DM_SUCCESS) 3144 return retStatus; 3145 offset += setLen; 3146 3147 } 3148 3149 return retStatus; 3150 3151 } 3152 3153 3154 /*================================================================================================== 3155 FUNCTION : SetLastChunkData 3156 3157 DESCRIPTION : Set last chunk data 3158 ARGUMENT PASSED : 3159 OUTPUT PARAMETER: 3160 RETURN VALUE : 3161 IMPORTANT NOTES : 3162 3163 ==================================================================================================*/ 3164 SYNCML_DM_RET_STATUS_T 3165 SYNCML_DM_BuildPackage::SetLastChunkData(DMAddData & oAddData, DMCommandType cmdType) 3166 { 3167 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 3168 UINT8 *decDataBuf = NULL; 3169 DMBuffer lastData; 3170 m_ChunkOffset = 0; 3171 UINT8* szBuf; 3172 int chunksize = m_pChunkData->GetChunkSize(); 3173 UINT32 decMaxBufLen = chunksize*3/4+2; 3174 3175 if(oAddData.m_oData.getSize() != 0) 3176 lastData.attach(oAddData.m_oData.getBuffer(), oAddData.m_oData.getSize()+1); 3177 oAddData.m_oData.reset(); 3178 UINT32 lastChunkSize = lastData.getSize(); 3179 3180 // special-case handling of SYNCML_DM_FORMAT_B64 3181 if (oAddData.m_nFormat == SYNCML_DM_FORMAT_B64) 3182 { 3183 decDataBuf = (UINT8*)DmAllocMem(decMaxBufLen); 3184 if(decDataBuf == NULL) 3185 return SYNCML_DM_DEVICE_FULL; 3186 oAddData.m_nFormat = SYNCML_DM_FORMAT_BIN; 3187 } 3188 3189 // Create the leaf node first with empty data 3190 if(cmdType == DM_COMMAND_ADD) 3191 { 3192 retStatus = dmTreeObj.Add( oAddData, SYNCML_DM_REQUEST_TYPE_SERVER ); 3193 if ( retStatus != SYNCML_DM_SUCCESS ) 3194 goto setchunkdatafailed; 3195 3196 if(largeObjFileHandle == NULL && m_ChunkOffset == 0 && lastData.getSize() ==0) 3197 { 3198 if(decDataBuf != NULL) 3199 DmFreeMem(decDataBuf); 3200 return retStatus; 3201 } 3202 } 3203 3204 if(m_pChunkData == NULL) 3205 { m_pChunkData = AllocateChunkBuffer(); 3206 if(m_pChunkData == NULL) 3207 { retStatus = SYNCML_DM_DEVICE_FULL; 3208 goto setchunkdatafailed; 3209 } 3210 } 3211 // Is there is temoprary file ? 3212 if(largeObjFileHandle != NULL) 3213 { 3214 retStatus = SetLastChunkDataFromFile(oAddData,lastData, &szBuf, chunksize,decDataBuf,decMaxBufLen,lastChunkSize); 3215 if ( retStatus != SYNCML_DM_SUCCESS ) 3216 goto setchunkdatafailed; 3217 } 3218 else 3219 { szBuf = lastData.getBuffer(); 3220 lastChunkSize = lastData.getSize(); 3221 } 3222 3223 retStatus = SetLastChunkRemainData(oAddData, 3224 lastData, 3225 szBuf, 3226 chunksize, 3227 decDataBuf, 3228 decMaxBufLen, 3229 lastChunkSize); 3230 3231 if ( retStatus != SYNCML_DM_SUCCESS ) 3232 goto setchunkdatafailed; 3233 3234 if(decDataBuf != NULL) 3235 DmFreeMem(decDataBuf); 3236 return retStatus; 3237 3238 setchunkdatafailed: 3239 if(decDataBuf != NULL) 3240 DmFreeMem(decDataBuf); 3241 if(cmdType == DM_COMMAND_ADD) 3242 dmTreeObj.Delete( oAddData.getURI(), SYNCML_DM_REQUEST_TYPE_SERVER ); 3243 return retStatus; 3244 } 3245 3246 /*================================================================================================== 3247 FUNCTION : SetChunkData 3248 3249 DESCRIPTION : Set chunk data 3250 ARGUMENT PASSED : 3251 OUTPUT PARAMETER: 3252 RETURN VALUE : 3253 IMPORTANT NOTES : 3254 3255 ==================================================================================================*/ 3256 SYNCML_DM_RET_STATUS_T 3257 SYNCML_DM_BuildPackage::SetChunkData(DMAddData & oAddData,DMCommandType cmdType, BOOLEAN isLastChunk) 3258 { 3259 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 3260 3261 // Save data in temporary file 3262 if(!isLastChunk) 3263 { 3264 3265 if(largeObjFileHandle->seek(XPL_FS_SEEK_SET, largeObjectBufferUsedSize) != SYNCML_DM_SUCCESS) 3266 return SYNCML_DM_IO_FAILURE; 3267 if(largeObjFileHandle->write((CPCHAR)oAddData.m_oData.getBuffer(), oAddData.m_oData.getSize()) != SYNCML_DM_SUCCESS) 3268 return SYNCML_DM_IO_FAILURE; 3269 } 3270 else 3271 retStatus = SetLastChunkData(oAddData, cmdType); 3272 3273 return retStatus; 3274 } 3275 /*================================================================================================== 3276 FUNCTION : CreateESNTempFile 3277 3278 DESCRIPTION : Create and open a temporary ESN file 3279 ARGUMENT PASSED : 3280 OUTPUT PARAMETER: 3281 RETURN VALUE : 3282 IMPORTANT NOTES : 3283 3284 ==================================================================================================*/ 3285 SYNCML_DM_RET_STATUS_T 3286 SYNCML_DM_BuildPackage::CreateESNTempFile() 3287 { 3288 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3289 INT32 modeFlag = XPL_FS_FILE_WRITE; 3290 3291 largeObjFileName = XPL_FS_TempEsnDir(); 3292 XPL_FS_MkDir(largeObjFileName); 3293 largeObjFileName += "##lob##.lob"; 3294 3295 largeObjFileHandle = new DMFileHandler(largeObjFileName.c_str(), FALSE); 3296 if(largeObjFileHandle == NULL) 3297 return SYNCML_DM_IO_FAILURE; 3298 3299 if (largeObjFileHandle->open(modeFlag) != SYNCML_DM_SUCCESS) 3300 return SYNCML_DM_IO_FAILURE; 3301 return dm_stat; 3302 } 3303 /*================================================================================================== 3304 FUNCTION : OpenESNTempFile 3305 3306 DESCRIPTION : Open the temporary ESN file 3307 ARGUMENT PASSED : 3308 OUTPUT PARAMETER: 3309 RETURN VALUE : 3310 IMPORTANT NOTES : 3311 3312 ==================================================================================================*/ 3313 SYNCML_DM_RET_STATUS_T 3314 SYNCML_DM_BuildPackage::OpenESNTempFile() 3315 { 3316 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3317 INT32 modeFlag = XPL_FS_FILE_RDWR; 3318 // Open again using different flag 3319 largeObjFileHandle = new DMFileHandler(largeObjFileName.c_str(), FALSE); 3320 if(largeObjFileHandle == NULL) 3321 return SYNCML_DM_IO_FAILURE; 3322 3323 if (largeObjFileHandle->open(modeFlag) != SYNCML_DM_SUCCESS) 3324 dm_stat = SYNCML_DM_IO_FAILURE; 3325 return dm_stat; 3326 } 3327 /*================================================================================================== 3328 FUNCTION : PreProcessFirstMoreData 3329 3330 DESCRIPTION : Handle more data case 3331 ARGUMENT PASSED : 3332 OUTPUT PARAMETER: 3333 RETURN VALUE : 3334 IMPORTANT NOTES : 3335 3336 ==================================================================================================*/ 3337 SYNCML_DM_RET_STATUS_T 3338 SYNCML_DM_BuildPackage::PreProcessFirstMoreData(DMAddData & oAddData, 3339 DMCommandType cmdType, 3340 SmlItemPtr_t p_data_item, 3341 int &size ) 3342 { 3343 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3344 SmlMetInfMetInfPtr_t p_meta_info; 3345 if(!pDmMgmtSessionObj->IsLargeObjectSupported()) 3346 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 3347 3348 /* Set the ADD data */ 3349 dm_stat = DecodBase64Data(p_data_item, oAddData, FALSE); 3350 if ( dm_stat != SYNCML_DM_SUCCESS ) 3351 return dm_stat; 3352 3353 // Get size 3354 if(p_data_item->meta == NULL || p_data_item->meta->content == NULL) 3355 return SYNCML_DM_INCOMPLETE_COMMAND; 3356 3357 p_meta_info = (SmlMetInfMetInfPtr_t)p_data_item->meta->content; 3358 // <Size> element MUST only be specified in the first data chunk 3359 if(p_meta_info->size != NULL && 3360 p_meta_info->size->content != 0) 3361 { 3362 size = DmAtoi((const char *)p_meta_info->size->content); 3363 if(IsLargerThanMaxObjSize(size, m_bESN, FALSE)) 3364 return SYNCML_DM_REQUEST_ENTITY_TOO_LARGE; 3365 3366 // Size of data chunk greater than/equal to specified object size 3367 if((int)oAddData.m_oData.getSize() >= size) 3368 return SYNCML_DM_SIZE_MISMATCH; 3369 3370 largeObjectCmd = cmdType; 3371 largeObjectTURI = oAddData.m_oURI; 3372 largeObjectFormat = oAddData.m_nFormat; 3373 largeObjectSize = size; 3374 largeObjectType = oAddData.m_oMimeType; 3375 m_ChunkOffset = 0; 3376 largeObjectBufferUsedSize = 0; 3377 // Create temporary file for the Large Object 3378 if(m_bESN) 3379 dm_stat =CreateESNTempFile(); 3380 3381 if(dm_stat == SYNCML_DM_SUCCESS) 3382 m_bProcessingLargeObject = TRUE; 3383 } 3384 else 3385 { 3386 // Meta->Size /Item->Meta-Size missing 3387 dm_stat = SYNCML_DM_INCOMPLETE_COMMAND; 3388 } 3389 return dm_stat; 3390 } 3391 3392 /*================================================================================================== 3393 FUNCTION : LargeObjectRecvFirstChunk 3394 3395 DESCRIPTION : Receives the first chunk of a large object data 3396 ARGUMENT PASSED : 3397 OUTPUT PARAMETER: 3398 RETURN VALUE : 3399 IMPORTANT NOTES : 3400 3401 ==================================================================================================*/ 3402 SYNCML_DM_RET_STATUS_T 3403 SYNCML_DM_BuildPackage::LargeObjectRecvFirstChunk(DMAddData & oAddData, 3404 DMCommandType cmdType, 3405 SmlItemPtr_t p_data_item) 3406 { 3407 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3408 int size = 0; 3409 BOOLEAN lsLastChunk = FALSE; 3410 BOOLEAN bMoreData = (p_data_item->flags & SmlMoreData_f) ==SmlMoreData_f; 3411 3412 if(bMoreData && pDmMgmtSessionObj->IsProcessScript()) 3413 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 3414 3415 // Is ESN 3416 dm_stat = dmTreeObj.IsESN(oAddData.getURI(), m_bESN); 3417 if ( dm_stat != SYNCML_DM_SUCCESS ) 3418 return dm_stat; 3419 3420 // Normal nodes 3421 if( !bMoreData) 3422 { 3423 if(m_bESN) 3424 { 3425 /* Set the ADD data */ 3426 dm_stat = DecodBase64Data(p_data_item, oAddData, FALSE); 3427 if ( dm_stat != SYNCML_DM_SUCCESS ) 3428 return dm_stat; 3429 lsLastChunk = TRUE; 3430 } 3431 else 3432 { 3433 /* Set the ADD data */ 3434 dm_stat = DecodBase64Data(p_data_item, oAddData, TRUE); 3435 if ( dm_stat != SYNCML_DM_SUCCESS ) 3436 return dm_stat; 3437 3438 if(cmdType == DM_COMMAND_ADD) 3439 dm_stat = dmTreeObj.Add( oAddData, SYNCML_DM_REQUEST_TYPE_SERVER ); 3440 else 3441 dm_stat = dmTreeObj.Replace( oAddData, SYNCML_DM_REQUEST_TYPE_SERVER ); 3442 return dm_stat; 3443 } 3444 } 3445 else 3446 { 3447 dm_stat= PreProcessFirstMoreData(oAddData, cmdType, p_data_item, size ); 3448 if(dm_stat != SYNCML_DM_SUCCESS) 3449 { BuildAlertCommand(DM_ALERT_SESSION_ABORT, NULL, NULL); 3450 return dm_stat; 3451 } 3452 3453 } 3454 if(m_bESN) 3455 { 3456 dm_stat = SetChunkData(oAddData, cmdType, lsLastChunk); 3457 if(dm_stat != SYNCML_DM_SUCCESS) 3458 goto receivefirstchunkfailed; 3459 3460 if(bMoreData) 3461 dm_stat = SYNCML_DM_CHUNK_BUFFERED; 3462 } 3463 else 3464 { 3465 // Allocate the Large Object Buffer based on the size 3466 largeObjectBuffer.allocate(size+1); 3467 if ( largeObjectBuffer.getBuffer() == NULL ) 3468 goto receivefirstchunkfailed; 3469 largeObjectBuffer = oAddData.m_oData; 3470 3471 dm_stat = SYNCML_DM_CHUNK_BUFFERED; 3472 } 3473 largeObjectBufferUsedSize += oAddData.m_oData.getSize(); 3474 return dm_stat; 3475 receivefirstchunkfailed: 3476 if(m_bProcessingLargeObject) 3477 { 3478 BuildAlertCommand(DM_ALERT_SESSION_ABORT, NULL, NULL); 3479 LargeObjectClear(); 3480 } 3481 return dm_stat; 3482 3483 } 3484 /*================================================================================================== 3485 FUNCTION : LargeObjectRecvDecodeData 3486 3487 DESCRIPTION : Decode binary LOB data 3488 ARGUMENT PASSED : 3489 OUTPUT PARAMETER: 3490 RETURN VALUE : 3491 IMPORTANT NOTES : 3492 3493 ==================================================================================================*/ 3494 SYNCML_DM_RET_STATUS_T 3495 SYNCML_DM_BuildPackage::LargeObjectRecvDecodeData(DMAddData & oAddData, 3496 DMCommandType cmdType, 3497 SmlItemPtr_t p_data_item) 3498 { 3499 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3500 SmlMetInfMetInfPtr_t p_meta_info = NULL; 3501 3502 // Check if it is the correct item 3503 if (m_bProcessingLargeObject && (largeObjectCmd!=cmdType || 3504 DmStrcmp((CPCHAR)largeObjectTURI.getBuffer(), oAddData.getURI()) !=0)) 3505 3506 { 3507 // Alert 1225 : End of data for chunked object not received 3508 BuildAlertCommand(DM_ALERT_END_OF_DATA_NOT_RECEIVED, NULL,(CPCHAR) largeObjectTURI.getBuffer()); 3509 return SYNCML_DM_INCOMPLETE_COMMAND; 3510 } 3511 /* Set the ADD data */ 3512 dm_stat = DecodBase64Data(p_data_item, oAddData, FALSE); 3513 if ( dm_stat != SYNCML_DM_SUCCESS ) 3514 { 3515 LargeObjectClear(); 3516 return dm_stat; 3517 } 3518 // Check if size has been specified again 3519 if(p_data_item->meta != NULL) 3520 { p_meta_info = (SmlMetInfMetInfPtr_t)p_data_item->meta->content; 3521 3522 if (p_meta_info != NULL && p_meta_info->size != NULL ) 3523 { dm_stat = SYNCML_DM_BAD_REQUEST; 3524 LargeObjectClear(); 3525 return dm_stat; 3526 } 3527 } 3528 return dm_stat; 3529 } 3530 /*================================================================================================== 3531 FUNCTION : LargeObjectRecvLastChunk 3532 3533 DESCRIPTION : Processing the last chunk of a large object data 3534 ARGUMENT PASSED : 3535 OUTPUT PARAMETER: 3536 RETURN VALUE : 3537 IMPORTANT NOTES : 3538 3539 ==================================================================================================*/ 3540 SYNCML_DM_RET_STATUS_T 3541 SYNCML_DM_BuildPackage::LargeObjectRecvLastChunk(DMAddData & oAddData, 3542 DMCommandType cmdType, 3543 SmlItemPtr_t p_data_item) 3544 { 3545 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3546 if(largeObjectCmd == DM_COMMAND_ADD ||largeObjectCmd == DM_COMMAND_REPLACE) 3547 { 3548 // Replace data 3549 oAddData.m_oData.free(); 3550 oAddData.m_oData.attach(largeObjectBuffer.getBuffer(), largeObjectBuffer.getSize() +1); 3551 3552 // special-case handling of SYNCML_DM_FORMAT_B64 3553 if (oAddData.m_nFormat == SYNCML_DM_FORMAT_B64) 3554 { 3555 UINT8 *decDataBuf; 3556 UINT32 dataLen = largeObjectSize; 3557 UINT32 decDataLen; 3558 UINT32 decMaxBufLen = largeObjectSize*3/4+2; 3559 3560 decDataBuf = (UINT8*)DmAllocMem(decMaxBufLen); 3561 if(decDataBuf == NULL) 3562 { 3563 return SYNCML_DM_DEVICE_FULL; 3564 } 3565 decDataLen = base64Decode(decDataBuf , decMaxBufLen, (DataBuffer_t) oAddData.m_oData.getBuffer(), 3566 (BufferSize_t *)&dataLen); 3567 if (decDataLen == 0) 3568 { 3569 DmFreeMem(decDataBuf); 3570 return SYNCML_DM_BAD_REQUEST; 3571 } 3572 3573 oAddData.m_oData.assign(decDataBuf, decDataLen); 3574 // largeObjectBuffer is freed 3575 largeObjectBuffer.reset(); 3576 3577 if ( oAddData.m_oData.getBuffer() == NULL ) 3578 { 3579 DmFreeMem(decDataBuf); 3580 return SYNCML_DM_DEVICE_FULL; 3581 } 3582 DmFreeMem(decDataBuf); 3583 oAddData.m_nFormat = SYNCML_DM_FORMAT_BIN; 3584 } 3585 3586 3587 if(largeObjectCmd == DM_COMMAND_ADD) 3588 dm_stat = dmTreeObj.Add( oAddData, SYNCML_DM_REQUEST_TYPE_SERVER ); 3589 else 3590 dm_stat = dmTreeObj.Replace( oAddData, SYNCML_DM_REQUEST_TYPE_SERVER); 3591 3592 oAddData.m_oData.reset(); 3593 } 3594 return dm_stat; 3595 } 3596 /*================================================================================================== 3597 FUNCTION : IsRecveivingLastChunk 3598 3599 DESCRIPTION : Is the last chunk of a large object data received? 3600 ARGUMENT PASSED : 3601 OUTPUT PARAMETER: 3602 RETURN VALUE : 3603 IMPORTANT NOTES : 3604 3605 ==================================================================================================*/ 3606 SYNCML_DM_RET_STATUS_T 3607 SYNCML_DM_BuildPackage::IsRecveivingLastChunk(DMAddData & oAddData, 3608 BOOLEAN bMoreData, 3609 int &size, 3610 BOOLEAN &lsLastChunk) 3611 { 3612 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3613 lsLastChunk = FALSE; 3614 size = oAddData.m_oData.getSize(); 3615 // Is data size too large 3616 if(IsLargerThanMaxObjSize(size, m_bESN, FALSE)) 3617 return SYNCML_DM_REQUEST_ENTITY_TOO_LARGE; 3618 // Object size is larger then MaxObjSize 3619 if(size > largeObjectSize - largeObjectBufferUsedSize) 3620 return SYNCML_DM_SIZE_MISMATCH; 3621 3622 // is it the last chunk ? 3623 if(bMoreData == FALSE ) 3624 { 3625 if(( size+ largeObjectBufferUsedSize)!= largeObjectSize) 3626 return SYNCML_DM_SIZE_MISMATCH; 3627 lsLastChunk = TRUE; 3628 } 3629 return dm_stat; 3630 } 3631 /*================================================================================================== 3632 FUNCTION : LargeObjectRecvNextChunk 3633 3634 DESCRIPTION : Receives the next/last chunk of a large object data 3635 ARGUMENT PASSED : 3636 OUTPUT PARAMETER: 3637 RETURN VALUE : 3638 IMPORTANT NOTES : 3639 3640 ==================================================================================================*/ 3641 SYNCML_DM_RET_STATUS_T 3642 SYNCML_DM_BuildPackage::LargeObjectRecvNextChunk(DMAddData & oAddData, 3643 DMCommandType cmdType, 3644 SmlItemPtr_t p_data_item) 3645 { 3646 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3647 BOOLEAN bMoreData = (p_data_item->flags & SmlMoreData_f) ==SmlMoreData_f; 3648 int size = 0; 3649 BOOLEAN lsLastChunk = FALSE; 3650 3651 dm_stat = LargeObjectRecvDecodeData(oAddData, cmdType,p_data_item); 3652 if(dm_stat != SYNCML_DM_SUCCESS) 3653 goto receivechunkfailed; 3654 3655 // Is it the last chunk? 3656 dm_stat = IsRecveivingLastChunk(oAddData, bMoreData, size, lsLastChunk); 3657 if(dm_stat != SYNCML_DM_SUCCESS) 3658 goto receivechunkfailed; 3659 3660 // Append to the buffer 3661 if(m_bESN) 3662 { 3663 dm_stat = SetChunkData(oAddData, cmdType, lsLastChunk); 3664 if(dm_stat != SYNCML_DM_SUCCESS) 3665 goto receivechunkfailed; 3666 } 3667 else 3668 { 3669 largeObjectBuffer.append(oAddData.m_oData.getBuffer(), oAddData.m_oData.getSize()); 3670 3671 // All the chunked data received 3672 if(lsLastChunk) 3673 { dm_stat = LargeObjectRecvLastChunk(oAddData, 3674 cmdType, 3675 p_data_item); 3676 3677 if(dm_stat != SYNCML_DM_SUCCESS) 3678 goto receivechunkfailed; 3679 } 3680 } 3681 if(bMoreData) 3682 { dm_stat = SYNCML_DM_CHUNK_BUFFERED; 3683 largeObjectBufferUsedSize += size; 3684 } 3685 else 3686 { 3687 if(m_bProcessingLargeObject) 3688 LargeObjectClear(); 3689 } 3690 return dm_stat; 3691 receivechunkfailed: 3692 if(m_bProcessingLargeObject) 3693 { 3694 BuildAlertCommand(DM_ALERT_SESSION_ABORT, NULL, NULL); 3695 LargeObjectClear(); 3696 } 3697 return dm_stat; 3698 3699 3700 } 3701 /*================================================================================================== 3702 FUNCTION : GetTargetURI 3703 3704 DESCRIPTION : Get target URI. 3705 ARGUMENT PASSED : 3706 OUTPUT PARAMETER: 3707 RETURN VALUE : 3708 IMPORTANT NOTES : 3709 3710 ==================================================================================================*/ 3711 SYNCML_DM_RET_STATUS_T 3712 SYNCML_DM_BuildPackage::GetLargeObjectTargetURI(SmlItemPtr_t p_get_item) 3713 { 3714 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3715 UINT8 * pTargetURL = NULL; 3716 if(p_get_item==NULL) 3717 { 3718 return SYNCML_DM_BAD_REQUEST; 3719 } 3720 if((p_get_item->source != NULL) && (p_get_item->source->locURI != NULL)) 3721 { 3722 DMString tempURI; 3723 pTargetURL = (UINT8*)p_get_item->source->locURI->content; 3724 tempURI.assign((CPCHAR)p_get_item->source->locURI->content,p_get_item->source->locURI->length); 3725 if ( tempURI == NULL ) 3726 return SYNCML_DM_DEVICE_FULL; 3727 3728 largeObjectTURI.assign(tempURI); 3729 3730 if(tempURI.Decode() == FALSE) 3731 return SYNCML_DM_BAD_REQUEST; 3732 3733 largeObjectSURI.assign(tempURI); 3734 3735 if(largeObjectSURI.getBuffer() == NULL) 3736 return SYNCML_DM_DEVICE_FULL; 3737 } 3738 else 3739 dm_stat = SYNCML_DM_BAD_REQUEST; 3740 3741 return dm_stat; 3742 3743 } 3744 /*================================================================================================== 3745 FUNCTION : SetEngineChunkData 3746 3747 DESCRIPTION : Set chunk data to engine 3748 ARGUMENT PASSED : 3749 OUTPUT PARAMETER: 3750 RETURN VALUE : 3751 IMPORTANT NOTES : 3752 3753 ==================================================================================================*/ 3754 SYNCML_DM_RET_STATUS_T 3755 SYNCML_DM_BuildPackage:: GetChunkDataFromEngine() 3756 { 3757 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 3758 DMGetData getData; 3759 getData.chunkData = m_pChunkData; 3760 getData.m_chunkOffset = m_ChunkOffset; 3761 3762 retStatus = dmTreeObj.Get((CPCHAR)largeObjectSURI.getBuffer(),getData, SYNCML_DM_REQUEST_TYPE_SERVER); 3763 3764 if ( retStatus != SYNCML_DM_SUCCESS ) 3765 return retStatus; 3766 3767 UINT32 returnLen =0; 3768 retStatus = m_pChunkData->GetReturnLen(returnLen); 3769 m_ChunkOffset += returnLen; 3770 3771 return retStatus; 3772 } 3773 3774 /*================================================================================================== 3775 FUNCTION : GetChunkData 3776 3777 DESCRIPTION : Read one chunk of data from ESN 3778 package. 3779 ARGUMENT PASSED : 3780 OUTPUT PARAMETER: 3781 RETURN VALUE : 3782 IMPORTANT NOTES : 3783 3784 ==================================================================================================*/ 3785 SYNCML_DM_RET_STATUS_T 3786 SYNCML_DM_BuildPackage::GetChunkData(DMBuffer & oSendData, int bufSize) 3787 { 3788 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 3789 UINT8 *bufp; 3790 3791 if(m_pChunkData == NULL) 3792 { m_pChunkData = AllocateChunkBuffer(); 3793 if(m_pChunkData == NULL) 3794 return SYNCML_DM_DEVICE_FULL; 3795 } 3796 // Is it an empty buffer 3797 if ( oSendData.getBuffer() == NULL ) 3798 return SYNCML_DM_DEVICE_FULL; 3799 3800 // Is data in temporary file already? 3801 if(largeObjFileHandle != NULL) 3802 { 3803 3804 if(largeObjFileHandle->seek(XPL_FS_SEEK_SET, largeObjectBufferUsedSize) != SYNCML_DM_SUCCESS) 3805 return SYNCML_DM_IO_FAILURE; 3806 if(largeObjFileHandle->read( oSendData.getBuffer() , bufSize) != SYNCML_DM_SUCCESS) 3807 return SYNCML_DM_IO_FAILURE; 3808 oSendData.setSize(bufSize); 3809 } 3810 else 3811 { 3812 UINT8 *pEncData = NULL; 3813 UINT32 encLen =0; 3814 // Allocate buffer for binary data encoding 3815 if(m_bBinary) 3816 { 3817 encLen = base64GetSize(bufSize); 3818 pEncData = (UINT8 *)DmAllocMem(encLen + 1); 3819 3820 if (pEncData == NULL) 3821 return SYNCML_DM_DEVICE_FULL; 3822 memset(pEncData, 0, encLen + 1); 3823 } 3824 m_pChunkData->GetChunkData(&bufp); // the chunk data is available 3825 3826 while (true) 3827 { 3828 retStatus = GetChunkDataFromEngine(); 3829 if( retStatus != SYNCML_DM_SUCCESS) 3830 { 3831 if(pEncData != NULL) 3832 DmFreeMem(pEncData); 3833 return retStatus; 3834 } 3835 m_pChunkData->GetReturnLen(largeObjectChunkSize); 3836 if(largeObjectChunkSize == 0) 3837 break; 3838 // Is binary data? 3839 if( pEncData != NULL) 3840 { 3841 UINT32 offset = 0; 3842 UINT32 dataSize = largeObjectChunkSize; 3843 UINT32 encSize = base64Encode (pEncData, encLen, 3844 (DataBuffer_t)bufp, 3845 (BufferSize_t *)&dataSize, 3846 (BufferSize_t *)&offset, 0, NULL); 3847 largeObjectChunkSize = encSize; 3848 oSendData.append(pEncData, encSize); 3849 } 3850 else 3851 oSendData.append(bufp, largeObjectChunkSize); 3852 3853 } 3854 if(pEncData != NULL) 3855 DmFreeMem(pEncData); 3856 3857 } 3858 return retStatus; 3859 } 3860 /*================================================================================================== 3861 FUNCTION : BuildLargeObjectDataNext 3862 3863 DESCRIPTION : Build the <data> item for the next chunk of a Large Object 3864 package. 3865 ARGUMENT PASSED : 3866 OUTPUT PARAMETER: 3867 RETURN VALUE : 3868 IMPORTANT NOTES : 3869 3870 ==================================================================================================*/ 3871 SYNCML_DM_RET_STATUS_T 3872 SYNCML_DM_BuildPackage::BuildLargeObjectDataNext(SmlResultsPtr_t & p_results, int dataBufferSize) 3873 { 3874 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3875 DMBuffer sendData; 3876 SmlItemListPtr_t p_results_list_item = p_results->itemList; 3877 SmlItemPtr_t p_results_item = p_results_list_item->item; 3878 3879 sendData.allocate(dataBufferSize+1); 3880 if ( sendData.getBuffer() == NULL ) 3881 return SYNCML_DM_DEVICE_FULL; 3882 3883 3884 if(m_bESN) 3885 { 3886 dm_stat = GetChunkData(sendData, dataBufferSize); 3887 if(dm_stat != SYNCML_DM_SUCCESS) 3888 return dm_stat; 3889 } 3890 else 3891 { 3892 largeObjectBuffer.copyTo(largeObjectBufferUsedSize, dataBufferSize, sendData); 3893 } 3894 largeObjectBufferUsedSize += sendData.getSize(); 3895 p_results_item->flags |= SmlMoreData_f; 3896 3897 // Build data item 3898 BuildPcData(p_results_item->data, 3899 SML_PCDATA_STRING, 3900 SML_EXT_UNDEFINED, 3901 sendData.getSize(), 3902 sendData.getBuffer()); 3903 return dm_stat; 3904 } 3905 3906 /*================================================================================================== 3907 FUNCTION : BuildLargeObjectDataLast 3908 3909 DESCRIPTION : Build the <data> item for the last chunk of a Large Object 3910 package. 3911 ARGUMENT PASSED : 3912 OUTPUT PARAMETER: 3913 RETURN VALUE : 3914 IMPORTANT NOTES : 3915 3916 ==================================================================================================*/ 3917 SYNCML_DM_RET_STATUS_T 3918 SYNCML_DM_BuildPackage::BuildLargeObjectDataLast(SmlResultsPtr_t & p_results, int size, BOOLEAN isFirstChunk) 3919 { 3920 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 3921 DMBuffer sendData; 3922 SmlItemListPtr_t p_results_list_item = p_results->itemList; 3923 SmlItemPtr_t p_results_item = p_results_list_item->item; 3924 SmlMetInfMetInfPtr_t p_meta_info; 3925 3926 // Is ESN data? 3927 if(m_bESN && size >0) 3928 { 3929 // Allocate the Large Object Buffer based on the size 3930 sendData.allocate(size+1); 3931 if ( sendData.getBuffer() == NULL ) 3932 return SYNCML_DM_DEVICE_FULL; 3933 3934 dm_stat = GetChunkData(sendData, size); 3935 if(dm_stat != SYNCML_DM_SUCCESS) 3936 return dm_stat; 3937 // If ESN data can hold one message 3938 if(isFirstChunk ) 3939 { 3940 largeObjectSize = sendData.getSize(); 3941 // Replace the <size> statement for binary data 3942 if( m_bBinary && p_results_item->meta != NULL) 3943 { 3944 p_meta_info = (SmlMetInfMetInfPtr_t)p_results_item->meta->content; 3945 if(p_meta_info != NULL && p_meta_info->size!= NULL && p_meta_info->size->content != NULL) 3946 { 3947 smlFreePcdata(p_meta_info->size); 3948 p_meta_info->size = NULL; 3949 dm_stat = BuildMetaSizeInfo(p_results_item->meta, sendData.getSize()); 3950 if(dm_stat != SYNCML_DM_SUCCESS) 3951 return dm_stat; 3952 3953 } 3954 3955 } 3956 } 3957 // Build data item 3958 BuildPcData(p_results_item->data, 3959 SML_PCDATA_STRING, 3960 SML_EXT_UNDEFINED, 3961 sendData.getSize(), 3962 sendData.getBuffer()); 3963 3964 largeObjectBufferUsedSize += sendData.getSize(); 3965 if( largeObjectBufferUsedSize != largeObjectSize) 3966 dm_stat = SYNCML_DM_SIZE_MISMATCH; 3967 3968 } 3969 else 3970 { 3971 if(!isFirstChunk && size > 0) 3972 { 3973 // Copy all the remaining data 3974 largeObjectBuffer.copyTo(largeObjectBufferUsedSize, size, sendData); 3975 largeObjectBufferUsedSize += sendData.getSize(); 3976 if( largeObjectBufferUsedSize != largeObjectSize) 3977 dm_stat = SYNCML_DM_SIZE_MISMATCH; 3978 3979 // Build data item 3980 BuildPcData(p_results_item->data, 3981 SML_PCDATA_STRING, 3982 SML_EXT_UNDEFINED, 3983 sendData.getSize(), 3984 sendData.getBuffer()); 3985 3986 3987 } 3988 } 3989 return dm_stat; 3990 } 3991 /*================================================================================================== 3992 FUNCTION : PrepareESNDataBuffer 3993 3994 DESCRIPTION : Allocate ESN buffer and encoding binary data 3995 ARGUMENT PASSED : 3996 OUTPUT PARAMETER: 3997 RETURN VALUE : 3998 IMPORTANT NOTES : 3999 ==================================================================================================*/ 4000 SYNCML_DM_RET_STATUS_T 4001 SYNCML_DM_BuildPackage::PrepareESNDataBuffer(UINT8 **pEncData, UINT32 & encLen , UINT8 **bufp) 4002 { 4003 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 4004 // Get chunk buffer 4005 if(m_pChunkData == NULL) 4006 { m_pChunkData = AllocateChunkBuffer(); 4007 if(m_pChunkData == NULL) 4008 return SYNCML_DM_DEVICE_FULL; 4009 } 4010 m_pChunkData->GetChunkData(bufp); // the chunk data is available 4011 4012 // Allocate buffer for binary data encoding 4013 if(m_bBinary) 4014 { 4015 encLen = base64GetSize((BufferSize_t)DmtDataChunk::GetChunkSize()); 4016 *pEncData = (UINT8 *)DmAllocMem(encLen + 1); 4017 4018 if (*pEncData == NULL) 4019 return SYNCML_DM_DEVICE_FULL; 4020 memset(*pEncData, 0, encLen + 1); 4021 } 4022 dm_stat =CreateESNTempFile(); 4023 if(dm_stat != SYNCML_DM_SUCCESS) 4024 { 4025 if(*pEncData != NULL) 4026 { DmFreeMem(*pEncData); 4027 *pEncData = NULL; 4028 } 4029 } 4030 return dm_stat; 4031 } 4032 4033 /*================================================================================================== 4034 FUNCTION : GetESNData2TempFile 4035 4036 DESCRIPTION : Read ESN data to a temporary file and encoding binary data 4037 ARGUMENT PASSED : 4038 OUTPUT PARAMETER: 4039 RETURN VALUE : 4040 IMPORTANT NOTES : 4041 ==================================================================================================*/ 4042 SYNCML_DM_RET_STATUS_T 4043 SYNCML_DM_BuildPackage::GetESNData2TempFile(int & dataSize) 4044 { 4045 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 4046 UINT8 *pEncData = NULL; 4047 UINT32 encLen =0; 4048 UINT8 *bufp; 4049 4050 dm_stat = PrepareESNDataBuffer(&pEncData, encLen , &bufp); 4051 if(dm_stat != SYNCML_DM_SUCCESS) 4052 return dm_stat; 4053 4054 int offset =0; 4055 UINT8 *tempPtr = bufp; 4056 if( pEncData != NULL) 4057 tempPtr = pEncData; 4058 while (true) 4059 { 4060 dm_stat = GetChunkDataFromEngine(); 4061 if( dm_stat != SYNCML_DM_SUCCESS) 4062 goto getESNdatafailed; 4063 4064 m_pChunkData->GetReturnLen(largeObjectChunkSize); 4065 if(largeObjectChunkSize == 0) 4066 break; 4067 if(largeObjFileHandle->seek(XPL_FS_SEEK_SET, offset) != SYNCML_DM_SUCCESS) 4068 { 4069 dm_stat = SYNCML_DM_IO_FAILURE; 4070 goto getESNdatafailed; 4071 } 4072 // Is binary data? 4073 if( pEncData != NULL) 4074 { 4075 UINT32 offset = 0; 4076 UINT32 dataSize = largeObjectChunkSize; 4077 UINT32 encSize = base64Encode (pEncData, encLen, 4078 (DataBuffer_t) bufp, 4079 (BufferSize_t *)&dataSize, 4080 (BufferSize_t *)&offset, 0, NULL); 4081 largeObjectChunkSize = encSize; 4082 } 4083 if(largeObjFileHandle->write((CPCHAR)tempPtr, largeObjectChunkSize) != SYNCML_DM_SUCCESS) 4084 { 4085 dm_stat = SYNCML_DM_IO_FAILURE; 4086 goto getESNdatafailed; 4087 } 4088 offset += largeObjectChunkSize; 4089 } 4090 largeObjFileHandle->close(); 4091 delete largeObjFileHandle; 4092 largeObjFileHandle = NULL; 4093 if(pEncData != NULL) 4094 DmFreeMem(pEncData); 4095 dm_stat = OpenESNTempFile(); 4096 if(dm_stat != SYNCML_DM_SUCCESS) 4097 goto getESNdatafailed; 4098 4099 // Real total size 4100 dataSize = offset; 4101 4102 return dm_stat; 4103 getESNdatafailed: 4104 if(pEncData != NULL) 4105 DmFreeMem(pEncData); 4106 return dm_stat; 4107 } 4108 /*================================================================================================== 4109 FUNCTION : LargeObjectSendFirstChunk 4110 4111 DESCRIPTION : PrepareSend result data 4112 ARGUMENT PASSED : 4113 OUTPUT PARAMETER: 4114 RETURN VALUE : 4115 IMPORTANT NOTES : 4116 ==================================================================================================*/ 4117 SYNCML_DM_RET_STATUS_T 4118 SYNCML_DM_BuildPackage::LargeObjectSendFirstChunkNoSpace(SYNCML_DM_RESULT_VALUE &pResult ,int size , int dataBufferSize ) 4119 { 4120 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 4121 SmlResultsPtr_t p_results = pResult._pGetExecResult; 4122 if (p_results == NULL) 4123 return (SYNCML_DM_FAIL); 4124 4125 SmlItemListPtr_t p_results_list_item = p_results->itemList; 4126 SmlItemPtr_t p_results_item = p_results_list_item->item; 4127 4128 // Is Large Object supported? 4129 if(!pDmMgmtSessionObj->IsLargeObjectSupported() || dataBufferSize<=0) 4130 { 4131 dm_stat = SYNCML_DM_RESULTS_TOO_LARGE; 4132 return dm_stat; 4133 } 4134 dm_stat = GetLargeObjectTargetURI(p_results_item); 4135 if(dm_stat != SYNCML_DM_SUCCESS) 4136 goto sendNoSpacefailed; 4137 4138 if(m_bESN) 4139 dm_stat = GetESNData2TempFile(size); 4140 4141 if(dm_stat != SYNCML_DM_SUCCESS) 4142 goto sendNoSpacefailed; 4143 4144 SmlMetInfMetInfPtr_t p_meta_info; 4145 // At least <Size> meta information need to be built 4146 if(p_results_item->meta == NULL) 4147 p_results_item->meta = smlAllocPcdata(); 4148 if(p_results_item->meta == NULL) 4149 { 4150 dm_stat = SYNCML_DM_DEVICE_FULL; 4151 goto sendNoSpacefailed; 4152 } 4153 // Save meta type information 4154 p_meta_info = (SmlMetInfMetInfPtr_t)p_results_item->meta->content; 4155 // Replace the <size> statement for binary data 4156 if(p_meta_info != NULL && p_meta_info->size!= NULL && p_meta_info->size->content != NULL) 4157 { 4158 smlFreePcdata(p_meta_info->size); 4159 p_meta_info->size = NULL; 4160 } 4161 // For Large Object delivery, <Size> must be built in first message 4162 dm_stat = BuildMetaSizeInfo(p_results_item->meta, size); 4163 if(dm_stat != SYNCML_DM_SUCCESS) 4164 goto sendNoSpacefailed; 4165 4166 if(p_meta_info != NULL && p_meta_info->type!= NULL && p_meta_info->type->content != NULL) 4167 largeObjectType.assign((CPCHAR)p_meta_info->type->content ,(INT32) p_meta_info->type->length); 4168 4169 4170 largeObjectSize = size; 4171 m_ChunkOffset = 0; 4172 m_bProcessingLargeObject = TRUE; 4173 largeObjectBufferUsedSize = 0; 4174 largeObjectCmd = DM_COMMAND_RESULTS; 4175 largeObjectChunkSize = 0; 4176 largeObjectChunkOffset =0; 4177 4178 largeObjectCmdRef = pResult._cmdRef; 4179 largeObjectMsgRef = pResult._msgID; 4180 // Allocate the Large Object Buffer based on the size 4181 if(dataBufferSize > size) 4182 dataBufferSize = size; 4183 4184 // Data buffer already allocated 4185 if(!m_bESN) 4186 { 4187 largeObjectBuffer.allocate(size+1); 4188 if ( largeObjectBuffer.getBuffer() == NULL ) 4189 goto sendNoSpacefailed; 4190 // Copy data in <data> to Large Object buffer 4191 largeObjectBuffer.attach((UINT8 *)p_results_item->data->content ,size +1); 4192 // Clear buffer pointer 4193 p_results_item->data->content = NULL; 4194 } 4195 dm_stat = BuildLargeObjectDataNext(p_results, dataBufferSize); 4196 if(dm_stat != SYNCML_DM_SUCCESS) 4197 goto sendNoSpacefailed; 4198 4199 // Insert a result command 4200 dm_stat = BuildResultsCommand(p_results); 4201 if(dm_stat != SYNCML_DM_SUCCESS) 4202 goto sendNoSpacefailed; 4203 4204 smlFreeResults(p_results); 4205 pResult._pGetExecResult = NULL; 4206 4207 // No <Final> statement 4208 dm_stat = SYNCML_DM_RESULTS_TOO_LARGE; 4209 return dm_stat; 4210 4211 sendNoSpacefailed: 4212 if(p_results != NULL) 4213 smlFreeResults(p_results); 4214 pResult._pGetExecResult = NULL; 4215 if(m_bProcessingLargeObject) 4216 LargeObjectClear(); 4217 return dm_stat; 4218 4219 } 4220 /*================================================================================================== 4221 FUNCTION : LargeObjectSendGetFreeSpace 4222 4223 DESCRIPTION : Get free space left 4224 ARGUMENT PASSED : 4225 OUTPUT PARAMETER: 4226 RETURN VALUE : 4227 IMPORTANT NOTES : 4228 ==================================================================================================*/ 4229 SYNCML_DM_RET_STATUS_T 4230 SYNCML_DM_BuildPackage::LargeObjectSendGetFreeSpace( SmlResultsPtr_t p_results, 4231 SmlItemPtr_t p_results_item , 4232 int &size , 4233 int &originalSize , 4234 int &dataBufferSize, 4235 MemSize_t &freeSpace ) 4236 { 4237 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 4238 size = 0; 4239 originalSize = 0; 4240 m_bESN = FALSE; 4241 m_bBinary = FALSE; 4242 4243 4244 4245 // Raw data size 4246 if(p_results_item != NULL && p_results_item->data != NULL) 4247 { size = p_results_item->data->length; 4248 originalSize = size; 4249 p_results_item->data->length = 0; 4250 } 4251 // check the size 4252 smlStartEvaluation(sendInstanceId); 4253 smlResultsCmd(sendInstanceId, p_results); 4254 smlEndEvaluation(sendInstanceId, &freeSpace); 4255 4256 // External Storage Node processing 4257 if( p_results_item != NULL && p_results_item->flags & SmlESNData_f) 4258 { m_bESN = TRUE; 4259 // Always need to clearn up 4260 m_bProcessingLargeObject = TRUE; 4261 if( p_results_item->flags & SmlESNBinary_f) 4262 m_bBinary = TRUE; 4263 } 4264 // Adjust for </moredata> statement <size> 4265 dataBufferSize = freeSpace - 100; 4266 freeSpace =freeSpace -size - 100; 4267 return dm_stat; 4268 } 4269 /*================================================================================================== 4270 FUNCTION : LargeObjectSendFirstChunk 4271 4272 DESCRIPTION : PrepareSend result data 4273 ARGUMENT PASSED : 4274 OUTPUT PARAMETER: 4275 RETURN VALUE : 4276 IMPORTANT NOTES : 4277 ==================================================================================================*/ 4278 SYNCML_DM_RET_STATUS_T 4279 SYNCML_DM_BuildPackage::LargeObjectSendFirstChunk(SYNCML_DM_RESULT_VALUE &pResult) 4280 { 4281 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 4282 SmlResultsPtr_t p_results = pResult._pGetExecResult; 4283 SmlItemListPtr_t p_results_list_item = NULL; 4284 SmlItemPtr_t p_results_item = NULL; 4285 int size = 0; 4286 int originalSize = 0; 4287 int dataBufferSize = 0; 4288 4289 4290 m_bESN = FALSE; 4291 m_bBinary = FALSE; 4292 DMBuffer sendData; 4293 MemSize_t freeSpace = 0; 4294 4295 if( p_results == NULL) 4296 return dm_stat; 4297 4298 p_results_list_item = p_results->itemList; 4299 p_results_item = p_results_list_item->item; 4300 4301 dm_stat = LargeObjectSendGetFreeSpace(p_results, p_results_item , size , originalSize , dataBufferSize, freeSpace ); 4302 4303 // Are there any free buffer left? ( </MoreData> 4304 if(freeSpace <=0) 4305 { 4306 // Is Large Object supported? 4307 if(!pDmMgmtSessionObj->IsLargeObjectSupported() || dataBufferSize<=0) 4308 { 4309 dm_stat = SYNCML_DM_RESULTS_TOO_LARGE; 4310 return dm_stat; 4311 } 4312 dm_stat = LargeObjectSendFirstChunkNoSpace( pResult , size, dataBufferSize ); 4313 } 4314 else 4315 { 4316 // Restore the length field 4317 if(p_results_item != NULL && p_results_item->data != NULL) 4318 p_results_item->data->length = originalSize; 4319 4320 if(m_bESN) 4321 { dm_stat = GetLargeObjectTargetURI(p_results_item); 4322 if(dm_stat != SYNCML_DM_SUCCESS) 4323 goto sendfirstchunkfailed; 4324 m_bProcessingLargeObject = TRUE; 4325 4326 } 4327 dm_stat = BuildLargeObjectDataLast(p_results, size,TRUE); 4328 if(dm_stat != SYNCML_DM_SUCCESS) 4329 return dm_stat; 4330 // Insert a result command 4331 dm_stat = BuildResultsCommand(p_results); 4332 smlFreeResults(p_results); 4333 pResult._pGetExecResult = NULL; 4334 if(m_bProcessingLargeObject) 4335 LargeObjectClear(); 4336 4337 } 4338 return dm_stat; 4339 4340 sendfirstchunkfailed: 4341 if(p_results != NULL) 4342 smlFreeResults(p_results); 4343 pResult._pGetExecResult = NULL; 4344 if(m_bProcessingLargeObject) 4345 LargeObjectClear(); 4346 return dm_stat; 4347 4348 } 4349 4350 /*================================================================================================== 4351 FUNCTION : AllocateLargeObjectResult 4352 4353 DESCRIPTION : Allocates and fill in memory structure for result 4354 package. 4355 ARGUMENT PASSED : 4356 OUTPUT PARAMETER: 4357 RETURN VALUE : 4358 IMPORTANT NOTES : 4359 4360 ==================================================================================================*/ 4361 4362 SYNCML_DM_RET_STATUS_T 4363 SYNCML_DM_BuildPackage::AllocateLargeObjectResult(SmlResultsPtr_t & p_results) 4364 { 4365 p_results = smlAllocResults(); 4366 if ( !p_results ) 4367 return SYNCML_DM_DEVICE_FULL; 4368 4369 SmlItemListPtr_t p_results_list_item = p_results->itemList; 4370 SmlItemPtr_t p_results_item = p_results_list_item->item; 4371 4372 p_results_item->source = smlAllocSource(); 4373 if ( p_results_item->source == NULL ) 4374 { 4375 smlFreeResults(p_results); 4376 p_results = NULL; 4377 return (SYNCML_DM_FAIL); 4378 } 4379 4380 BuildPcData( p_results_item->source->locURI, 4381 SML_PCDATA_STRING, 4382 SML_EXT_UNDEFINED, 4383 largeObjectTURI.getSize(), 4384 (UINT8*)largeObjectTURI.getBuffer()); 4385 4386 /* Set receiving package command id reference */ 4387 BuildPcData(p_results->cmdRef, SML_PCDATA_STRING, 4388 SML_EXT_UNDEFINED, 4389 largeObjectCmdRef.length(), 4390 (UINT8*)largeObjectCmdRef.c_str()); 4391 4392 CPCHAR sMsg = largeObjectMsgRef.c_str(); 4393 BuildPcDataWAllocMem(&p_results->msgRef,DmStrlen(sMsg),(UINT8*)sMsg); 4394 4395 if(largeObjectType.getSize() !=0) 4396 { 4397 if ((p_results_item->meta = smlAllocPcdata()) != NULL) 4398 BuildMetaInfo(p_results_item->meta, 4399 NULL, 4400 (UINT8*)largeObjectType.getBuffer(), 4401 NULL, 4402 NULL, 4403 NULL, NULL, NULL, NULL); 4404 } 4405 4406 p_results_item->data = smlAllocPcdata(); 4407 if ( !p_results_item->data ) 4408 return SYNCML_DM_DEVICE_FULL; 4409 4410 return SYNCML_DM_SUCCESS; 4411 } 4412 4413 /*================================================================================================== 4414 FUNCTION : LargeObjectSendNextChunk 4415 4416 DESCRIPTION : Send next Large Object chunk data 4417 package. 4418 ARGUMENT PASSED : 4419 OUTPUT PARAMETER: 4420 RETURN VALUE : 4421 IMPORTANT NOTES : 4422 4423 ==================================================================================================*/ 4424 BOOLEAN 4425 SYNCML_DM_BuildPackage::LargeObjectSendNextChunk(SYNCML_DM_RET_STATUS_T &dm_stat, BOOLEAN &isLastChunk ) 4426 { 4427 DMBuffer sendData; 4428 4429 isLastChunk = FALSE; 4430 4431 if (!m_bProcessingLargeObject || largeObjectCmd != DM_COMMAND_RESULTS) 4432 { 4433 dm_stat = SYNCML_DM_SUCCESS; 4434 return FALSE; 4435 } 4436 4437 SmlResultsPtr_t p_results = NULL; 4438 int size = largeObjectSize - largeObjectBufferUsedSize; 4439 int dataBufferSize = 0; 4440 4441 isLastChunk = TRUE; 4442 // Need to send result back to server 4443 pDmMgmtSessionObj->IncCommandCount(); 4444 4445 dm_stat = AllocateLargeObjectResult(p_results); 4446 4447 if ( dm_stat != SYNCML_DM_SUCCESS ) 4448 { if(p_results != NULL) 4449 smlFreeResults(p_results); 4450 return FALSE; 4451 4452 } 4453 4454 // check the size 4455 MemSize_t freeSpace = 0; 4456 4457 smlStartEvaluation(sendInstanceId); 4458 smlResultsCmd(sendInstanceId, p_results); 4459 smlEndEvaluation(sendInstanceId, &freeSpace); 4460 4461 // Adjust for </MoreData> 4462 dataBufferSize = freeSpace - 100; 4463 freeSpace =freeSpace -size - 100; 4464 // Are there any free buffer left? 4465 if(freeSpace <= 0) 4466 { 4467 if(dataBufferSize > size) 4468 dataBufferSize = size; 4469 4470 dm_stat = BuildLargeObjectDataNext(p_results, dataBufferSize); 4471 if(dm_stat != SYNCML_DM_SUCCESS) 4472 goto sendchunkfailed; 4473 4474 // Insert a result command 4475 dm_stat = BuildResultsCommand(p_results); 4476 if(dm_stat != SYNCML_DM_SUCCESS) 4477 goto sendchunkfailed; 4478 4479 smlFreeResults(p_results); 4480 p_results = NULL; 4481 dm_stat = SYNCML_DM_RESULTS_TOO_LARGE; 4482 } 4483 else 4484 { 4485 dm_stat = BuildLargeObjectDataLast(p_results, size,FALSE); 4486 if(dm_stat != SYNCML_DM_SUCCESS) 4487 goto sendchunkfailed; 4488 4489 // Insert a result command 4490 dm_stat = BuildResultsCommand(p_results); 4491 4492 if(dm_stat != SYNCML_DM_SUCCESS) 4493 goto sendchunkfailed; 4494 4495 smlFreeResults(p_results); 4496 LargeObjectClear(); 4497 return FALSE; 4498 } 4499 return TRUE; 4500 4501 sendchunkfailed: 4502 if(p_results != NULL) 4503 smlFreeResults(p_results); 4504 4505 if(m_bProcessingLargeObject) 4506 LargeObjectClear(); 4507 return FALSE; 4508 4509 } 4510 4511 /*================================================================================================== 4512 FUNCTION : GenerateAlertForLOB 4513 4514 DESCRIPTION : Generate alert in error conditions. 4515 package. 4516 ARGUMENT PASSED : 4517 OUTPUT PARAMETER: 4518 RETURN VALUE : 4519 IMPORTANT NOTES : 4520 4521 ==================================================================================================*/ 4522 4523 SYNCML_DM_RET_STATUS_T SYNCML_DM_BuildPackage::GenerateAlertForLOB(DMCommandType currentComm) 4524 { 4525 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 4526 if(m_bProcessingLargeObject) 4527 { 4528 if(currentComm != largeObjectCmd) 4529 { 4530 BuildAlertCommand(DM_ALERT_END_OF_DATA_NOT_RECEIVED, NULL,(CPCHAR) largeObjectTURI.getBuffer()); 4531 LargeObjectClear(); 4532 dm_stat = SYNCML_DM_INCOMPLETE_COMMAND; 4533 } 4534 } 4535 return dm_stat; 4536 } 4537 4538 // End of defination of LOB_SUPPORT 4539 #endif 4540 4541 4542 SYNCML_DM_RET_STATUS_T 4543 SYNCML_DM_BuildPackage::GetClientAuthValues( const DMString& device_id, 4544 const DMString& server_id, 4545 DMString& client_name, 4546 DMString& client_password ) 4547 { 4548 SYNCML_DM_RET_STATUS_T result = SYNCML_DM_SUCCESS; 4549 4550 for( ; ; ) 4551 { 4552 SYNCML_DM_FACTORY_BOOTSTRAP_T bootstrapCode = GetBootStrapCodeUserName( client_name ); 4553 4554 if( SYNCML_DM_FACTORY_BOOTSTRAP_UNKNOWN != bootstrapCode ) 4555 { 4556 result = CreateFactoryBootStrapUserName( bootstrapCode, 4557 server_id, 4558 device_id, 4559 client_name ); 4560 if (SYNCML_DM_SUCCESS != result ) break; 4561 } 4562 4563 SYNCML_DM_FACTORY_BOOTSTRAP_T clientPWCode = GetBootStrapCodeClientPW( client_password ); 4564 4565 if( SYNCML_DM_FACTORY_BOOTSTRAP_UNKNOWN != clientPWCode ) 4566 { 4567 result = CreateFactoryBootStrapClientPW( clientPWCode, 4568 server_id, 4569 device_id, 4570 client_password ); 4571 4572 if (SYNCML_DM_SUCCESS != result ) break; 4573 } 4574 4575 break; 4576 } 4577 4578 return result; 4579 } 4580 4581 4582 SYNCML_DM_RET_STATUS_T 4583 SYNCML_DM_BuildPackage::GetServerAuthValues( const DMString& device_id, 4584 const DMString& server_id, 4585 DMString& server_password ) 4586 { 4587 SYNCML_DM_RET_STATUS_T result = SYNCML_DM_SUCCESS; 4588 4589 for( ; ; ) 4590 { 4591 SYNCML_DM_FACTORY_BOOTSTRAP_T serverPWCode = GetBootStrapCodeServerPW( server_password ); 4592 if ( SYNCML_DM_FACTORY_BOOTSTRAP_UNKNOWN != serverPWCode ) 4593 { 4594 4595 result = CreateFactoryBootStrapServerPW( serverPWCode, 4596 server_id, 4597 device_id, 4598 server_password ); 4599 if (SYNCML_DM_SUCCESS != result ) break; 4600 } 4601 4602 break; 4603 } 4604 4605 return result; 4606 } 4607 4608 SYNCML_DM_RET_STATUS_T 4609 SYNCML_DM_BuildPackage::GetDeviceID( DMString& device_id ) 4610 { 4611 DMGetData devID; 4612 SYNCML_DM_RET_STATUS_T result = dmTreeObj.Get(DM_DEV_INFO_DEVID_URI, devID, SYNCML_DM_REQUEST_TYPE_INTERNAL); 4613 4614 if( ( SYNCML_DM_SUCCESS == result ) && 4615 ( devID.m_oData.getSize() != 0 ) ) 4616 { 4617 device_id = GetIMEINumber( devID.getCharData() ); 4618 } 4619 4620 return result; 4621 } 4622 4623 //SessionId option/FLEX is flexible feature. 4624 //TRUE - Session id will be converted into hex format which will be used for Dm sessions 4625 //FALSE - Session id will be in decimal format which will be used for Dm sessions 4626 //PATH,Value Stored : ./DevDetail/Ext/Conf/PMF/Agents/syncmldm/Sessionid 4627 4628 BOOLEAN 4629 SYNCML_DM_BuildPackage::IsSessionId() 4630 { 4631 4632 CPCHAR path = XPL_DM_GetEnv(SYNCML_DM_SESSION_ID); 4633 if ( !path ) 4634 return TRUE; 4635 4636 DMGetData sessionId; 4637 SYNCML_DM_RET_STATUS_T result = dmTreeObj.Get(path, 4638 sessionId, 4639 SYNCML_DM_REQUEST_TYPE_INTERNAL); 4640 4641 if( result != SYNCML_DM_SUCCESS ) 4642 return TRUE; 4643 4644 return sessionId.m_oData.compare("true"); 4645 4646 } 4647