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