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// Module Name: dm_tpt_connection.cc 20// 21// General Description: This file contains the Implementation of 22// SYNCML_DM_OTAConnection class 23// 24//------------------------------------------------------------------------ 25 26#include "dm_tpt_connection.H" 27#include "dm_tree_util.h" 28#include "xpl_Logger.h" 29#include "xpl_File.h" 30 31//------------------------------------------------------------------------ 32// LOCAL MACROS 33//------------------------------------------------------------------------ 34 35// Size of MD5 string 36#define DMTPT_MD5_STRING_SIZE 3 37 38// Maximum size of the MAC string size 39#define DMTPT_MAX_MAC_SIZE 100 40 41// Maximiun size of the Algorithm string 42#define DMTPT_MAX_ALGO_SIZE 10 43 44// Maximiun value of the Request ID. 45#define DMTPT_MAX_REQ_ID_VALUE 30000 46 47// Language to be used 48#define DMTPT_HTTP_LANGUAGE "en" 49 50// Name of the DM Client 51#define DMTPT_CLIENT_NAME "Motorola SyncML DM Client ["DMTPT_HTTP_LANGUAGE"] " 52 53// Version of the HTTP protocol used 54#define DMTPT_HTTP_VERSION "HTTP/1.0" 55 56#define DMTPT_HTTP_MIME_TYPES "application/vnd.syncml.dm+wbxml" 57 58// Specifying the Cache-control Http header field option 59#define DMTPT_HTTP_CACHECONTROL "private" 60 61// Defining location string 62// WSP module converts headers to lower-case 63#define DMTPT_FIELD_LOCATION "location:" 64 65// Defining location string 66// HTTP stack maintains headers in mixed-case 67#define DMTPT_FIELD_LOCATION_HTTP "Location:" 68 69// Size of the Location string 70#define DMTPT_LOCATION_SIZE 9 71 72// User Agent Header Field 73#define DMTPT_USER_AGENT_HF "User-Agent: " 74#define DMTPT_USER_AGENT_HF_LEN 12 75 76//Accept Haeder field 77#define DMTPT_ACCEPT_HF "Accept: " 78#define DMTPT_ACCEPT_HF_LEN 8 79 80//Accept language header field 81#define DMTPT_ACCEPT_LANG_HF "Accept-Language: " 82#define DMTPT_ACCEPT_LANG_HF_LEN 17 83 84//Accept Charset header 85#define DMTPT_ACCEPT_CHARSET "Accept-Charset: utf-8" 86#define DMTPT_ACCEPT_CHARSET_LEN 21 87 88//Cache control header field 89#define DMTPT_CACHE_CONTROL_HF "Cache-Control: " 90#define DMTPT_CACHE_CONTROL_HF_LEN 15 91 92//Content type header field 93#define DMTPT_CONT_TYPE_HF "Content-type: " 94#define DMTPT_CONT_TYPE_HF_LEN 14 95 96 97//HMAC Algo 98#define DMTPT_HMAC_ALGO_HF "x-syncml-hmac: algorithm=" 99#define DMTPT_HMAC_ALGO_HF_LEN 25 100 101//HMAC uname 102#define DMTPT_HMAC_UNAME_HF ", username=" 103#define DMTPT_HMAC_UNAME_HF_LEN 11 104 105//HMAC mac 106#define DMTPT_HMAC_MAC_HF ", mac=" 107#define DMTPT_HMAC_MAC_HF_LEN 6 108 109//Carriage return line feed string 110#define DMTPT_CR_LF "\r\n" 111#define DMTPT_CR_LF_LEN 2 112 113// two double quotes " " 114#define DMTPT_TWO_DOUBLEQUOTES 2 115 116 117//------------------------------------------------------------------------ 118// CLASS IMPLEMENTATION 119//------------------------------------------------------------------------ 120 121SYNCML_DM_OTAConnection::SYNCML_DM_OTAConnection() 122{ 123 bNumRetries = 0; 124 m_hConnection = 0; 125 psSendSyncMLDoc = NULL; 126 psRecvSyncMLDoc = NULL; 127} 128 129SYNCML_DM_OTAConnection::~SYNCML_DM_OTAConnection() 130{ 131 if ( m_hConnection ) 132 XPL_HTTP_Close(m_hConnection); 133} 134 135//======================================================================== 136// 137// DESCRIPTION: Init routine 138// 139// ARGUMENTS PASSED: 140// INPUT : UINT32 dwMaxAcptSize - Maximum size of the message 141// UINT8 bWebSessIndex - Web session index to be used 142// UINT16 wWapGatePortno - WAP Gateway port number 143// SYNCML_DM_ADDR_TYPE_T AddressType - Address type 144// provided by the DMUA. 145// 146// 147// 148// OUTPUT: 149// None 150// 151// RETURN VALUE: None 152// 153// 154// IMPORTANT NOTES: The constructor gets called when the SYNCML_DM_OTATransport 155// creates a new SYNCML_DM_OTAConnection object. 156//=========================================================================== 157 158SYNCML_DM_RET_STATUS_T SYNCML_DM_OTAConnection::Init(UINT32 dwMaxAcptSize, 159 XPL_ADDR_TYPE_T AddressType, 160 CPCHAR ConRef) 161{ 162 163 // Initialize the member variables 164 dwMaxAcceptSize = dwMaxAcptSize; 165 AddrType = AddressType; 166 167 // Copy the new ConRef to the pConRef member variable. 168 if(ConRef != NULL && ConRef[0] != 0) 169 { 170 m_szConRef = ConRef; 171 if( m_szConRef.GetBuffer() ==NULL ) 172 { 173 XPL_LOG_DM_SESS_Error(("SYNCML_DM_OTAConnection::Init : unable allocate memory\n")); 174 return SYNCML_DM_DEVICE_FULL; 175 } 176 } 177 178#ifdef DM_DUMP_SYNCML_PACKAGE 179 dump_path = XPL_DM_GetEnv(SYNCML_DM_DUMP_SESSION_PACKAGE_PATH); 180 181 if (dump_path == NULL) 182 { 183 dump_path="/tmp"; 184 } 185 package_counter = 1; 186 187 HTTP_HEADER_SERVER = "Server"; 188 HTTP_HEADER_DATE = "Date"; 189 HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges"; 190 HTTP_HEADER_CACHE_CONTROL = "Cache-Control"; 191 HTTP_HEADER_CONNECTION = "Connection"; 192 HTTP_HEADER_CONTENT_TYPE = "Content-Type"; 193 HTTP_HEADER_X_SYNCML_HMAC = "x-syncml-hmac"; 194 195 bodyFileName = "/package"; 196 bodyFileExt = ".xml"; 197 198 hdrFileName = "/header"; 199 hdrFileExt = ".txt"; 200#endif 201 202 return SYNCML_DM_SUCCESS; 203} 204 205//============================================================================== 206// FUNCTION: SYNCML_DM_OTAConnection::Send 207// 208// DESCRIPTION: This function sends the data to the Server 209// 210// ARGUMENTS PASSED: 211// INPUT : psSendSyncMLDocument - Pointer to the SyncML DM document 212// to be sent 213// psRecvSyncMLDocument - Pointer to the memory, where 214// the received document will be stored. 215// pbContType - Pointer to the content type of the 216// SyncML DM document that will be sent. 217// psCredHdr - Pointer to the HMAC Credential header 218// 219// 220// 221// OUTPUT: 222// 223// 224// RETURN VALUE: SYNCML_DM_RET_STATUS_T 225// SYNCML_DM_SUCCESS - If data is sent successfully to the Fetch Agent 226// 227// SYNCML_DM_FAIL - There were some problems either with the data 228// or while sending 229// 230// SYNCML_DM_SEC_CONN_NOT_AVAILABLE - Secure connection is required, 231// but it is not available. 232// 233// 234// 235// IMPORTANT NOTES: DMUA calls this function to send the data to the Server. 236//============================================================================== 237 238SYNCML_DM_RET_STATUS_T SYNCML_DM_OTAConnection::Send( 239 const SYNCML_DM_INDIRECT_BUFFER_T *psSendSyncMLDocument, 240 SYNCML_DM_INDIRECT_BUFFER_T *psRecvSyncMLDocument, 241 const UINT8 *pbContType, 242 const DMCredHeaders * psCredHdr) 243{ 244 245 XPL_LOG_DM_SESS_Debug(("Enter SYNCML_DM_OTAConnection::Send \n")); 246 247 SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS; 248 249 m_pCredHeaders = (DMCredHeaders*)psCredHdr; 250 251 // Check whether the input parameters are valid 252 253 if ((psSendSyncMLDocument EQ NULL) OR 254 (psSendSyncMLDocument->pData EQ NULL) OR 255 (psSendSyncMLDocument->dataSize EQ 0 )) 256 { 257 return SYNCML_DM_FAIL; 258 } 259 260 if ((psRecvSyncMLDocument EQ NULL) OR 261 (psRecvSyncMLDocument->pData EQ NULL)) 262 { 263 return SYNCML_DM_FAIL; 264 } 265 266 if ((pbContType EQ NULL) OR (pbContType[0] EQ '\0')) 267 { 268 return SYNCML_DM_FAIL; 269 } 270 271 // Check whether psCredHdr is valid 272 if ( psCredHdr->isCorrect() == FALSE ) 273 return SYNCML_DM_FAIL; 274 275 276 psSendSyncMLDoc = (SYNCML_DM_INDIRECT_BUFFER_T*)psSendSyncMLDocument; 277 278 psRecvSyncMLDoc = psRecvSyncMLDocument; 279 280 //Call PrepareRequestHeaders method of this class with pbConType, 281 //psCredHdr parameters to prepare the HTTP headers. 282 ret_status = PrepareRequestHeaders(pbContType); 283 284 if (ret_status == SYNCML_DM_SUCCESS ) 285 ret_status = SendInitialChunk(); 286 287 return ret_status; 288 289} 290 291 292//============================================================================== 293// FUNCTION: SYNCML_DM_Connection::SetURI 294// 295// DESCRIPTION: This method sets the URL of the Server 296// 297// ARGUMENTS PASSED: 298// INPUT : pbUrl - URL of the Server 299// 300// 301// OUTPUT: None 302// 303// RETURN VALUE: SYNCML_DM_RET_STATUS_T 304// SYNCML_DM_SUCCESS - Whether the new URL has been set 305// successfully 306// SYNCML_DM_FAIL - Setting the new URL met with failure 307 308// 309// 310// IMPORTANT NOTES: This method is called by the DMUA and the 311// SYNCML_DM_OTATransport to set the new URL of the Server. 312//============================================================================== 313 314SYNCML_DM_RET_STATUS_T SYNCML_DM_Connection::SetURI(CPCHAR szURL) 315{ 316 if (szURL EQ NULL) 317 return SYNCML_DM_FAIL; 318 319 m_szURL = szURL; 320 if ( m_szURL.GetBuffer() == NULL ) 321 { 322 XPL_LOG_DM_SESS_Error(("SYNCML_DM_OTAConnection::SetURI : unable allocate memory\n")); 323 return SYNCML_DM_DEVICE_FULL; 324 } 325 return SYNCML_DM_SUCCESS; 326 327} 328 329 330//============================================================================== 331// FUNCTION: SYNCML_DM_OTAConnection::PrepareRequestHeaders 332// 333// DESCRIPTION: This method prepares the Request Headers 334// 335// ARGUMENTS PASSED: 336// INPUT : pbContentTypetoSend -Pointer to the Content type of the 337// document to be sent 338// psCredHeaderstoSend - Pointer to the Credential headers to 339// be sent. 340// 341// 342// OUTPUT: 343// None 344// 345// RETURN VALUE: BOOLEAN - TRUE - Successfully prepared the HTTP headers 346// FALSE - HTTP headers preparation failed. 347// 348// 349// IMPORTANT NOTES: The SYNCML_DM_OTAConnection class this method. 350//============================================================================== 351SYNCML_DM_RET_STATUS_T SYNCML_DM_OTAConnection::PrepareRequestHeaders(const UINT8 *pbContentTypetoSend) 352{ 353 char *pBuffer = NULL; 354 UINT32 size = 0; 355 356 XPL_LOG_DM_SESS_Debug(("Enter SYNCML_DM_OTAConnection::PrepareRequestHeaders \n")); 357 358 // Free the old HTTP headers 359 m_oHttpHdr.clear(); 360 361 // Compute the HTTP header string length 362 size = ComputeHTTPHeaderLength(pbContentTypetoSend); 363 364 // Allocate memory for the new string 365 m_oHttpHdr.allocate(size); 366 pBuffer = (char*)m_oHttpHdr.getBuffer(); 367 if ( pBuffer == NULL ) 368 return SYNCML_DM_DEVICE_FULL; 369 370 371 // Prepare General HTTP header fields 372 size = DmSprintf(pBuffer,DMTPT_CACHE_CONTROL_HF \ 373 DMTPT_HTTP_CACHECONTROL \ 374 DMTPT_CR_LF); 375 376 377 // Prepare Request HTTP header fields 378 size += DmSprintf(pBuffer + size,DMTPT_USER_AGENT_HF \ 379 DMTPT_CLIENT_NAME \ 380 DMTPT_CR_LF \ 381 DMTPT_ACCEPT_HF \ 382 DMTPT_HTTP_MIME_TYPES \ 383 DMTPT_CR_LF \ 384 DMTPT_ACCEPT_LANG_HF \ 385 DMTPT_HTTP_LANGUAGE \ 386 DMTPT_CR_LF ); 387 388 // Prepare Entity HTTP header fields 389 size += DmSprintf(pBuffer + size,DMTPT_CONT_TYPE_HF "%s" DMTPT_CR_LF,pbContentTypetoSend); 390 391 if ( m_pCredHeaders->empty() == FALSE ) 392 { 393 UINT8 bTempAlgo[DMTPT_MAX_ALGO_SIZE+1] = {0}; 394 if ( m_pCredHeaders->m_oAlgorithm.getSize() == 0 ) 395 DmStrcpy((char*)bTempAlgo,"MD5"); 396 else 397 m_pCredHeaders->m_oAlgorithm.copyTo((char*)bTempAlgo); 398 399 size += DmSprintf(pBuffer + size,DMTPT_HMAC_ALGO_HF "%s" \ 400 DMTPT_HMAC_UNAME_HF "\"%s\"" \ 401 DMTPT_HMAC_MAC_HF "%s" DMTPT_CR_LF, 402 bTempAlgo, 403 (CPCHAR)m_pCredHeaders->m_oUserName.getBuffer(), 404 (CPCHAR)m_pCredHeaders->m_oMac.getBuffer()); 405 406 } 407 m_oHttpHdr.setSize(size); 408 return SYNCML_DM_SUCCESS; 409} 410 411//============================================================================== 412// FUNCTION: SYNCML_DM_OTAConnection::ComputeHTTPHeaderLength 413// 414// DESCRIPTION: This method computes the length of the HTTP header fields 415// 416// ARGUMENTS PASSED: 417// INPUT : pbContentTypetoSend -Pointer to the Content type of the 418// document to be sent 419// psCredHeaderstoSend - Pointer to the Credential headers to 420// be sent. 421// 422// 423// OUTPUT: 424// None 425// 426// RETURN VALUE: Length of the HTTP Header fields 427// 428// 429// IMPORTANT NOTES: This class calls this method. We support ATMOST 64K chunk of 430// data to be sent to the Server. That's why the return type is 431// UINT16. 432//============================================================================== 433 434UINT16 SYNCML_DM_OTAConnection::ComputeHTTPHeaderLength(const UINT8 *pbContentTypetoSend) 435{ 436 437 //Find the length of the following individual header fields to compute 438 // the total length of the HTTP header: Cache-Control, User-Agent, 439 //Accept, Accept-Language, Accept-Charset, Content-Type, Content-Length, 440 //x-syncml-hmac. 441 442 UINT16 wTotalLength =0; 443 UINT8 bCrLfLen =0; 444 445 bCrLfLen = DmStrlen(DMTPT_CR_LF) ; 446 447 wTotalLength = DMTPT_USER_AGENT_HF_LEN + DmStrlen(DMTPT_CLIENT_NAME) + 448 bCrLfLen + 449 DMTPT_ACCEPT_HF_LEN + DmStrlen(DMTPT_HTTP_MIME_TYPES) + 450 bCrLfLen + 451 DMTPT_ACCEPT_LANG_HF_LEN + DmStrlen(DMTPT_HTTP_LANGUAGE) + 452 bCrLfLen + 453 DMTPT_ACCEPT_CHARSET_LEN + bCrLfLen + 454 DMTPT_CACHE_CONTROL_HF_LEN + DmStrlen(DMTPT_HTTP_CACHECONTROL)+ 455 bCrLfLen ; 456 457 wTotalLength += DMTPT_CONT_TYPE_HF_LEN + DmStrlen((CPCHAR)pbContentTypetoSend) + bCrLfLen ; 458 459 if ( m_pCredHeaders->empty() == FALSE ) 460 { 461 462 wTotalLength += DMTPT_HMAC_ALGO_HF_LEN + DMTPT_HMAC_UNAME_HF_LEN + 463 m_pCredHeaders->m_oUserName.getSize() + 464 DMTPT_HMAC_MAC_HF_LEN + 465 m_pCredHeaders->m_oMac.getSize() + 466 DMTPT_TWO_DOUBLEQUOTES + 467 bCrLfLen; 468 469 if ( m_pCredHeaders->m_oAlgorithm.getSize() == 0) 470 wTotalLength += DMTPT_MD5_STRING_SIZE; 471 else 472 wTotalLength += m_pCredHeaders->m_oAlgorithm.getSize(); 473 } 474 475 return wTotalLength; 476 477} 478 479 480//============================================================================== 481// FUNCTION: SYNCML_DM_OTAConnection::ProcessCredHeaders 482// 483// DESCRIPTION: This method extracts the Credential headers from the 484// Response headers 485// 486// ARGUMENTS PASSED: 487// INPUT : Pointer to the Response header 488// 489// 490// OUTPUT: None 491// 492// RETURN VALUE: BOOLEAN 493// TRUE - If handled successfully 494// FALSE - If there is some failure 495 496// 497// 498// IMPORTANT NOTES: The HandleOTARedirect method calls this method. 499//============================================================================== 500SYNCML_DM_RET_STATUS_T SYNCML_DM_OTAConnection::ProcessCredHeaders(CPCHAR pbOrigHmacStr) 501{ 502 503 UINT8 *pbHmacString = NULL; 504 UINT8 *pbInitialHmacString = NULL; 505 UINT8 *pbParam = NULL; 506 UINT8 *pbValue = NULL; 507 char *pbAlgo = NULL; 508 char *pbUname = NULL; 509 char *pbMAC = NULL; 510 511 XPL_LOG_DM_SESS_Debug(("Enter SYNCML_DM_OTAConnection::ProcessCredHeaders\n")); 512 if(pbOrigHmacStr EQ NULL) 513 return TRUE; 514 515 //Trim the blank space and tabs 516 pbHmacString = DMTPTTrimString((UINT8*)pbOrigHmacStr); 517 if (pbHmacString EQ NULL) 518 { 519 return SYNCML_DM_FAIL; 520 } 521 522 pbInitialHmacString = pbHmacString; 523 524 pbHmacString = (UINT8*)DmStrstr((CPCHAR)pbHmacString, "algorithm"); 525 526 if (pbHmacString EQ NULL) 527 pbHmacString = (UINT8*)DmStrstr((CPCHAR)pbInitialHmacString,"username"); 528 529 //Extract the algorithm, Username and mac from 530 //the x-syncml-hmac header 531 while (pbHmacString NE NULL) 532 { 533 pbHmacString = DM_TPT_splitParamValue(pbHmacString,&pbParam,&pbValue); 534 535 if ((pbParam NE NULL) AND (pbParam [0] NE '\0')) 536 { 537 if (!DmStrcmp ((CPCHAR)pbParam, "algorithm")) 538 { 539 pbAlgo = (char*)pbValue; 540 } 541 else 542 if (!DmStrcmp ((CPCHAR)pbParam, "username")) 543 { 544 pbUname = (char*)pbValue; 545 } 546 else 547 if (!DmStrcmp ((CPCHAR)pbParam, "mac")) 548 { 549 pbMAC = (char*)pbValue; 550 } 551 } 552 } 553 554 // Allocate memory to hold username, mac, algorithm 555 if (pbUname == NULL || pbMAC == NULL) 556 { 557 DmFreeMem(pbInitialHmacString); 558 return SYNCML_DM_FAIL; 559 } 560 561 if (pbAlgo NE NULL) 562 m_pCredHeaders->m_oAlgorithm.assign(pbAlgo); 563 else 564 m_pCredHeaders->m_oAlgorithm.assign("MD5"); 565 566 if ( m_pCredHeaders->m_oAlgorithm.getBuffer() == NULL ) 567 { 568 DmFreeMem(pbInitialHmacString); 569 return SYNCML_DM_DEVICE_FULL; 570 } 571 572 m_pCredHeaders->m_oUserName.assign(pbUname); 573 574 if ( m_pCredHeaders->m_oUserName.getBuffer() == NULL ) 575 { 576 DmFreeMem(pbInitialHmacString); 577 return SYNCML_DM_DEVICE_FULL; 578 } 579 580 m_pCredHeaders->m_oMac.assign(pbMAC); 581 582 if ( m_pCredHeaders->m_oMac.getBuffer() == NULL ) 583 { 584 DmFreeMem(pbInitialHmacString); 585 return SYNCML_DM_DEVICE_FULL; 586 } 587 588 DmFreeMem(pbInitialHmacString); 589 XPL_LOG_DM_SESS_Debug(("Leave SYNCML_DM_OTAConnection::ProcessCredHeaders\n")); 590 return SYNCML_DM_SUCCESS; 591} 592 593 594SYNCML_DM_RET_STATUS_T SYNCML_DM_OTAConnection::ConvertXPLCode(XPL_HTTP_RET_STATUS_T http_result) 595{ 596 SYNCML_DM_RET_STATUS_T return_result; 597 switch ( http_result ) 598 { 599 case XPL_HTTP_RET_NW_NOT_AVAILABLE: 600 return_result = SYNCML_DM_SESSION_NW_NOT_AVAILABLE; 601 break; 602 603 case XPL_HTTP_RET_NO_CONNECT: 604 return_result = SYNCML_DM_SESSION_NO_CONNECT; 605 break; 606 607 default : 608 return_result = SYNCML_DM_FAIL; 609 break; 610 } 611 return return_result; 612} 613 614 615/******************************************************************************* 616* 617* Function : FA_issue_urlRequest() 618* Parameters : user id, request id, URL, method type, headers, 619* data buffer(post), content preferences, 620* progress indicator. 621* Return Value : Boolean (success or failure) 622* Description : This api checks for the validity of the parameters received. 623* Additional check for data buffer is made for Put and Post 624* requests. Finally a message FA_GET_URL is constructed and 625* posted to the Fetch Module. 626* 627********************************************************************************/ 628 629SYNCML_DM_RET_STATUS_T SYNCML_DM_OTAConnection::IssueURLRequest(XPL_HTTP_CODE_T *ret_code) 630{ 631 char * value = NULL; 632 UINT32 receivedLength = 0; 633 SYNCML_DM_RET_STATUS_T return_result = SYNCML_DM_SUCCESS; 634 XPL_HTTP_RET_STATUS_T http_result = XPL_HTTP_OK_200; 635 636 XPL_LOG_DM_SESS_Debug(("Enter SYNCML_DM_OTAConnection::IssueURLRequest \n")); 637 638#ifdef DM_DUMP_SYNCML_PACKAGE 639 640 XPL_FS_HANDLE_T hBodyFile = XPL_FS_HANDLE_INVALID; 641 XPL_FS_HANDLE_T hHeaderFile = XPL_FS_HANDLE_INVALID; 642 XPL_FS_RET_STATUS_T nStatus = XPL_FS_RET_FAIL; 643 char szName [512]; 644 645 DmSprintf( szName, "%s%s%d_request%s", dump_path.c_str(), hdrFileName.c_str(), 646 package_counter, hdrFileExt.c_str() ); 647 648 hHeaderFile = XPL_FS_Open( szName, 649 XPL_FS_FILE_WRITE, 650 &nStatus ); 651#endif 652 653 // Use open method for the first time 654 if (m_hConnection == 0) 655 m_hConnection = XPL_HTTP_Open((CPCHAR)m_szURL, (CPCHAR)m_szConRef, AddrType,&http_result); 656 else 657 http_result = XPL_HTTP_SetUrl(m_hConnection,(CPCHAR)m_szURL, (CPCHAR)m_szConRef, AddrType); 658 659 if ( http_result != XPL_HTTP_RET_SUCCESS ) 660 return SYNCML_DM_FAIL; 661 662 663 http_result = XPL_HTTP_SetRequestMethod(m_hConnection,XPL_HTTP_METHOD_POST); 664 if ( http_result != XPL_HTTP_RET_SUCCESS) 665 { 666 return_result = ConvertXPLCode(http_result); 667 goto GetResponseCode; 668 } 669 670 http_result = XPL_HTTP_SetRequestProperty(m_hConnection,(CPCHAR)m_oHttpHdr.getBuffer()); 671 if ( http_result != XPL_HTTP_RET_SUCCESS) 672 { 673 return_result = ConvertXPLCode(http_result); 674 goto GetResponseCode; 675 } 676 677 678#ifdef DM_DUMP_SYNCML_PACKAGE 679 // capture header info 680 if ( XPL_FS_HANDLE_INVALID != hHeaderFile ) 681 { 682 XPL_FS_Write( hHeaderFile, 683 m_oHttpHdr.getBuffer(), 684 m_oHttpHdr.getSize(), 685 &nStatus ); 686 687 XPL_FS_Close( hHeaderFile ); 688 hHeaderFile = XPL_FS_HANDLE_INVALID; 689 } 690 691 DmSprintf( szName, "%s%s%d_request%s", dump_path.c_str(), bodyFileName.c_str(), 692 package_counter++, bodyFileExt.c_str() ); 693 694 hBodyFile = XPL_FS_Open( szName, 695 XPL_FS_FILE_WRITE, 696 &nStatus ); 697 698 if ( XPL_FS_HANDLE_INVALID != hBodyFile ) 699 { 700 XPL_FS_Write( hBodyFile, 701 psSendSyncMLDoc->pData, 702 psSendSyncMLDoc->dataSize, 703 &nStatus ); 704 705 XPL_FS_Close( hBodyFile ); 706 hBodyFile = XPL_FS_HANDLE_INVALID; 707 } 708#endif 709 710 // Upload buffer 711 http_result = XPL_HTTP_Send(m_hConnection,(CPCHAR)psSendSyncMLDoc->pData,psSendSyncMLDoc->dataSize); 712 if ( http_result != XPL_HTTP_RET_SUCCESS) 713 { 714 return_result = ConvertXPLCode(http_result); 715 goto GetResponseCode; 716 } 717 718 receivedLength = XPL_HTTP_GetResponseLength(m_hConnection); 719 720 if (receivedLength EQ 0) 721 { 722 receivedLength = dwMaxAcceptSize; 723 } 724 725 if (receivedLength GT dwMaxAcceptSize) 726 { 727 return_result = SYNCML_DM_FAIL; 728 goto GetResponseCode; 729 } 730 731 psRecvSyncMLDoc->dataSize = receivedLength; 732 733 http_result = XPL_HTTP_GetResponse(m_hConnection,(char *)psRecvSyncMLDoc->pData,(INT32)receivedLength); 734 if ( http_result != XPL_HTTP_RET_SUCCESS) 735 { 736 return_result = ConvertXPLCode(http_result); 737 goto GetResponseCode; 738 } 739 740#ifdef DM_DUMP_SYNCML_PACKAGE 741 // open a file to capture response header info 742 value=(char*)DmAllocMem(512); 743 DmSprintf( szName, "%s%s%d_response%s", dump_path.c_str(), hdrFileName.c_str(), package_counter, hdrFileExt.c_str() ); 744 745 hHeaderFile = XPL_FS_Open( szName, 746 XPL_FS_FILE_WRITE, 747 &nStatus ); 748 749 // capture header info 750 if ( XPL_FS_HANDLE_INVALID != hHeaderFile ) 751 { 752 const char szCRLF[] = "\r\n"; 753 const XPL_FS_COUNT_T nCRLFlen = DmStrlen(szCRLF); 754 755 if((XPL_HTTP_GetHeaderField(m_hConnection,HTTP_HEADER_SERVER, &value)) EQ XPL_HTTP_RET_SUCCESS) 756 { 757 XPL_FS_Write( hHeaderFile, 758 value, 759 DmStrlen(value), 760 &nStatus ); 761 762 XPL_FS_Write( hHeaderFile, 763 (void*)szCRLF, 764 nCRLFlen, 765 &nStatus ); 766 } 767 768 if((XPL_HTTP_GetHeaderField(m_hConnection,HTTP_HEADER_DATE, &value)) EQ XPL_HTTP_RET_SUCCESS) 769 { 770 XPL_FS_Write( hHeaderFile, 771 value, 772 DmStrlen(value), 773 &nStatus ); 774 775 XPL_FS_Write( hHeaderFile, 776 (void*)szCRLF, 777 nCRLFlen, 778 &nStatus ); 779 } 780 781 if((XPL_HTTP_GetHeaderField(m_hConnection,HTTP_HEADER_ACCEPT_RANGES, &value)) EQ XPL_HTTP_RET_SUCCESS) 782 { 783 XPL_FS_Write( hHeaderFile, 784 value, 785 DmStrlen(value), 786 &nStatus ); 787 788 XPL_FS_Write( hHeaderFile, 789 (void*)szCRLF, 790 nCRLFlen, 791 &nStatus ); 792 } 793 794 if((XPL_HTTP_GetHeaderField(m_hConnection,HTTP_HEADER_CACHE_CONTROL, &value)) EQ XPL_HTTP_RET_SUCCESS) 795 { 796 XPL_FS_Write( hHeaderFile, 797 value, 798 DmStrlen(value), 799 &nStatus ); 800 801 XPL_FS_Write( hHeaderFile, 802 (void*)szCRLF, 803 nCRLFlen, 804 &nStatus ); 805 } 806 807 if((XPL_HTTP_GetHeaderField(m_hConnection,HTTP_HEADER_CONNECTION, &value)) EQ XPL_HTTP_RET_SUCCESS) 808 { 809 XPL_FS_Write( hHeaderFile, 810 value, 811 DmStrlen(value), 812 &nStatus ); 813 814 XPL_FS_Write( hHeaderFile, 815 (void*)szCRLF, 816 nCRLFlen, 817 &nStatus ); 818 } 819 820 if((XPL_HTTP_GetHeaderField(m_hConnection,HTTP_HEADER_CONTENT_TYPE, &value)) EQ XPL_HTTP_RET_SUCCESS) 821 { 822 XPL_FS_Write( hHeaderFile, 823 value, 824 DmStrlen(value), 825 &nStatus ); 826 827 XPL_FS_Write( hHeaderFile, 828 (void*)szCRLF, 829 nCRLFlen, 830 &nStatus ); 831 } 832 833 if((XPL_HTTP_GetHeaderField(m_hConnection,HTTP_HEADER_X_SYNCML_HMAC, &value)) EQ XPL_HTTP_RET_SUCCESS) 834 { 835 XPL_FS_Write( hHeaderFile, 836 value, 837 DmStrlen(value), 838 &nStatus ); 839 840 XPL_FS_Write( hHeaderFile, 841 (void*)szCRLF, 842 nCRLFlen, 843 &nStatus ); 844 } 845 846 XPL_FS_Close( hHeaderFile ); 847 hHeaderFile = XPL_FS_HANDLE_INVALID; 848 } 849 850 DmSprintf( szName, "%s%s%d_response%s", dump_path.c_str(), bodyFileName.c_str(), package_counter++, bodyFileExt.c_str() ); 851 852 hBodyFile = XPL_FS_Open( szName, 853 XPL_FS_FILE_WRITE, 854 &nStatus ); 855 856 if ( XPL_FS_HANDLE_INVALID != hBodyFile ) 857 { 858 XPL_FS_Write( hBodyFile, 859 psRecvSyncMLDoc->pData, 860 receivedLength, 861 &nStatus ); 862 863 XPL_FS_Close( hBodyFile ); 864 hBodyFile = XPL_FS_HANDLE_INVALID; 865 } 866 867 DmFreeMem(value); 868 value = NULL; 869#endif 870 871 // Clean the Previously received Credential headers 872 m_pCredHeaders->clear(); 873 value=(char*)DmAllocMem(512); 874 http_result = XPL_HTTP_GetHeaderField(m_hConnection,"x-syncml-hmac", &value); 875 if ( http_result == XPL_HTTP_RET_SUCCESS) 876 { 877 return_result = ProcessCredHeaders(value); 878 if ( return_result != SYNCML_DM_SUCCESS ) 879 { 880 DmFreeMem(value); 881 XPL_HTTP_CloseReq(m_hConnection); 882 return SYNCML_DM_FAIL; 883 } 884 } 885 else 886 return_result = ConvertXPLCode(http_result); 887 DmFreeMem(value); 888 889 GetResponseCode: 890 891 *ret_code = XPL_HTTP_GetResponseCode(m_hConnection); 892 XPL_HTTP_CloseReq(m_hConnection); 893 894 XPL_LOG_DM_SESS_Debug(("Exit from IssueURLRequest\n", return_result)); 895 896 return SYNCML_DM_SUCCESS; 897} 898 899//============================================================================== 900// FUNCTION: SYNCML_DM_OTAConnection::SendInitialChunk 901// 902// DESCRIPTION: This method sends the initial chunk of data to the server. 903// 904// ARGUMENTS PASSED: 905// INPUT : None 906// 907// 908// OUTPUT: 909// None 910// 911// RETURN VALUE: BOOLEAN - 912// TRUE - Whether the data is successfully posted to the 913// Fetch agent 914// FALSE - posting the data to the Fetch Agent met with failure. 915// 916// 917// IMPORTANT NOTES: Send method calls this method. 918//============================================================================== 919SYNCML_DM_RET_STATUS_T SYNCML_DM_OTAConnection::SendInitialChunk() 920{ 921 922 923 SYNCML_DM_RET_STATUS_T return_result; 924 int wNumRetries = 0; 925 XPL_HTTP_CODE_T ret_code = XPL_HTTP_OK_200; 926 927 XPL_LOG_DM_SESS_Debug(("Enter SYNCML_DM_OTAConnection::SendInitialChunk \n")); 928 929 if (m_szURL == NULL) 930 return SYNCML_DM_FAIL; 931 932 while (wNumRetries LT DMTPT_MAX_RETRIES) 933 { 934 return_result = IssueURLRequest(&ret_code); 935 if(return_result != SYNCML_DM_SUCCESS) 936 return return_result; 937 938 switch(ret_code) 939 { 940 case XPL_HTTP_REQUEST_TIMEOUT_408: 941 case XPL_HTTP_INTERNAL_SERVER_ERROR_500: 942 case XPL_HTTP_BAD_GATEWAY_502: 943 case XPL_HTTP_SERVICE_UNAVAILABLE_503: 944 case XPL_HTTP_GATEWAY_TIMEOUT_504: 945 wNumRetries++; 946 break; 947 948 case XPL_HTTP_OK_200: 949 return SYNCML_DM_SUCCESS; 950 951 default: 952 return SYNCML_DM_FAIL; 953 } 954 } 955 956 XPL_LOG_DM_SESS_Debug(("OTAConnection send failed due failure in SendInitialChunk\n")); 957 return SYNCML_DM_FAIL; 958} 959