tizen 2.3 release
[framework/connectivity/multirat.git] / src / multirat_range_request_thread.c
1 #include "multirat_conf.h"
2 #include "multirat_process.h"
3 #include "multirat_libapi.h"
4 #include "multirat_range_request_thread.h"
5 #include "multirat_connection.h"
6 #include "multirat_block_manager.h"
7 #include "multirat_data_buffer.h"
8 #include "multirat_decode_http.h"
9 #include <sys/time.h>
10
11
12 void range_request_thread_init(RangeRequestThread *rrthread, SmartBondingData *SBData)
13 {
14         MultiSocket *mSocket = SBData->msocket;
15         int8 *default_iname = DEFAULT_INTERFACE;
16         uint32 ifaceidx = rrthread->threadId;
17
18         rrthread->pThreadId = 0;
19         rrthread->socketId = 0;
20         rrthread->minBlockSize = MIN_BLOCK_SIZE;
21         rrthread->maxBlockSize = MAX_BLOCK_SIZE;
22         rrthread->speedTimeOut = SPEED_TIMEOUT;
23         rrthread->blockForSpeed = BLOCK_SIZE_SPEED;
24         rrthread->minDataForSpeed =  MIN_DATA_FOR_SPEED;
25         rrthread->compRspLen = mSocket->compRspLen;
26         rrthread->contRngLen = SBData->resp.instanceSize;
27         rrthread->commBuffer = mSocket->commBuffer;
28         rrthread->conn = mSocket->conn;
29         rrthread->blockMgr = mSocket->blockMgr;
30         rrthread->compRspRcvdFlag = &mSocket->compRspRcvdFlag;
31         rrthread->firstRngStatus = FIRST_RSP_STATUS_PENDING;
32
33         if (0 == strncasecmp(default_iname, LTE, strlen(LTE)))
34         {
35                 /*
36                 * thread  0 should get interface LTE (1)
37                 * and thread 1 should get interface WIFI(0)
38                 */
39                 ifaceidx = (ifaceidx + 1) % 2;
40         }
41
42         rrthread->reqHeaders = SBData->req.request[ifaceidx] ;
43         rrthread->headerLen = strlen(SBData->req.request[ifaceidx]);
44
45         #if 0
46         if(SBData->req.req_buff_wo_range != NULL)
47         {
48                 rrthread->reqHeaders = SBData->req.req_buff_wo_range;
49                 rrthread->headerLen = SBData->req.req_wo_len;
50         }
51         else
52         {
53                 rrthread->reqHeaders = SBData->req.req_buff;
54                 rrthread->headerLen =  SBData->req.reqLen;
55         }
56         #endif
57         rrthread->SBData = SBData;
58
59 }/* End of RangeRequestThread() */
60
61 uint32 range_request_thread_start(RangeRequestThread *rrthread)
62 {
63         if(0 != pthread_create(&rrthread->pThreadId, NULL,
64         range_request_thread_rngreq_thread_callback, (void *)rrthread))
65         {
66                 TIZEN_LOGD("Error !!! while creating range thread");
67                 range_request_thread_exit(rrthread);
68                 rrthread = NULL;
69                 return B_FALSE;
70         }
71         TIZEN_LOGD("thread ID %d Rangethread started", rrthread->threadId);
72         return B_TRUE;
73 }
74
75 void *range_request_thread_rngreq_thread_callback(void *pArg)
76 {
77         RangeRequestThread *rngReq = ((RangeRequestThread*)pArg);
78         range_request_thread_run(rngReq);
79         return NULL;
80 }
81
82
83 int range_request_thread_handleIOExp(RangeRequestThread *rrthread, uint32 *ifCount , int iptype)
84 {
85         /* Check if interface is available */
86         if (!connection_is_ifaceup(rrthread->threadId, rrthread->conn->ifaceInfo,iptype))
87         {
88                 if((rrthread->firstRngStatus == FIRST_RSP_STATUS_PENDING) && (*ifCount++ > 2))
89                 {
90                         rrthread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
91                         *(rrthread->compRspRcvdFlag) = 0;
92                         TIZEN_LOGD("First Response Failed for ThreadId %d\n",rrthread->threadId);
93                         return THREAD_EXIT;
94                 }
95                 uint32 otherId = GET_OTHER_THREAD_ID(rrthread->threadId);
96                 if((rrthread->blockMgr->threadState[otherId] == STATE_THREAD_STOPPED) &&
97                                 (connection_is_ifaceup(otherId, rrthread->conn->ifaceInfo,iptype)))
98                 {
99                         TIZEN_LOGD("Swapping thread as other thread is stopped \n");
100                         rrthread->blockMgr->threadState[rrthread->threadId] = STATE_THREAD_STOPPED;
101                         rrthread->threadId = otherId;
102                         rrthread->blockMgr->threadState[otherId] = STATE_THREAD_RUNNING;
103                         rrthread->blockMgr->noOfIOExp[otherId] = 0;
104                 }
105                 else
106                 {
107                         return THREAD_CONTINUE;
108                 }
109         }
110         /* IOException case */
111         connect_server(rrthread);
112         TIZEN_LOGD("thread ID %d rrthread->socketId %d\n",rrthread->threadId,rrthread->socketId);
113         if ((0 == rrthread->socketId) || (!(*(rrthread->compRspRcvdFlag))))
114         {
115                 if (rrthread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
116                 {
117                         rrthread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
118                         TIZEN_LOGD("First Response failed\n");;
119                         /* server doest support Range Request */
120                         /* Exit all threads */
121                         *(rrthread->compRspRcvdFlag) = 0;
122                         TIZEN_LOGD("First Response Failed for ThreadId %d\n",rrthread->threadId);
123                         return THREAD_EXIT;
124                 }
125                 else
126                 {
127                         return THREAD_CONTINUE;
128                 }
129         }
130         return 0;
131 }
132
133 void range_request_thread_handleSendFailCase(RangeRequestThread *rrthread, int32 chunkId)
134 {
135         TIZEN_LOGD("Thread with %d got Exception during send",rrthread->threadId);
136
137         if (rrthread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
138         {
139                 rrthread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
140                 TIZEN_LOGD("First Response failed\n");;
141                 /* server doest support Range Request */
142                 /* Exit all threads */
143                 *(rrthread->compRspRcvdFlag) = 0;
144         }
145
146         if (rrthread->socketId != 0)
147         {
148                 close(rrthread->socketId);
149                 rrthread->socketId = 0;
150         }
151         if ((chunkId != -1) && (DATA_BUFFER_GET_THREAD_ID(rrthread->commBuffer + chunkId) == rrthread->threadId))
152         {
153                 /* IO Exception inform Block manager */
154                 block_manager_io_exception(rrthread->threadId, chunkId, rrthread->blockMgr);
155                 DATA_BUFFER_SET_STATE(STATE_BLOCKED, (rrthread->commBuffer + chunkId));
156         }
157 }
158
159 void range_request_thread_run(RangeRequestThread *rrthread)
160 {
161         int32 retval = 0;
162         int32 chunkId = -1;
163         int32 blockOffset = 0;
164         int32 headerRcvd = B_FALSE;
165         int32 IOException = B_TRUE;
166         uint32 reqLen = 0;
167         uint32 ifCount = 0;
168         uint32 blockLen = 0;
169         uint32 rngRspLen = 0;
170         uint32 connClose = 0;
171         uint32 waitThread = B_FALSE;
172         uint32 iface_check_count = 0;
173         uint32 minBlockLen = rrthread->minBlockSize;
174         uint64 endTime = 0;
175         uint64 startTime = 0;
176         uint64 currChunkLen = 0;
177         uint64 chunkStrTime = 0;
178         uint64 temp_startTime = 0;
179         int64 chunkInfo[CHUNK_INFO_SIZE] = {0};
180         int8 *newRequest = NULL;
181         //int8 *chunkBuff = NULL;
182         int8 tempBuff[MAX_BLOCK_SIZE] = {0};
183         DataBuffer *currChunk =  NULL;
184
185         newRequest = (char*)malloc(rrthread->headerLen + MAX_RANGE_FIELD_LEN);
186         if(NULL == newRequest)
187         {
188                 return;
189         }/* End of if */
190         while (*(rrthread->compRspRcvdFlag))
191         {
192                 /* Check the current state of thread */
193                 if(rrthread->blockMgr->threadState[rrthread->threadId] == STATE_THREAD_STOPPED)
194                 {
195                         TIZEN_LOGD("Thread %d stopped state exiting\n",rrthread->threadId);
196                         break;
197                 }
198
199                 /* Get the status of commonBuffer (memory availability) */
200                 if (1 == block_manager_check_buffer_status(rrthread->blockMgr))
201                 {
202                         usleep(30000);
203                         continue;
204                 }/* End of if */
205
206                 if(waitThread == B_TRUE)
207                 {
208                         retval =  block_manager_checkAllBufferStatus(rrthread->blockMgr,rrthread->threadId);
209                         if(THREAD_WAIT == retval)
210                         {
211                                 /* Other thread is downloading this thread has to wait */
212                                 usleep(1000000);
213                                 continue;
214                         }
215                         else if (THREAD_EXIT == retval)
216                         {
217                                 /* Wait thread should exit as other thread has completed */
218                                 TIZEN_LOGD("Download Complete by other thread Exiting Thread Id %d",rrthread->threadId);
219                                 break;
220                         }
221                         else if(THREAD_CONTINUE == retval)
222                         {
223                                 /* Other thread has chunk is blocked */
224                                 TIZEN_LOGD("waiting thread need to download chunk", rrthread->threadId);
225                                 waitThread = B_FALSE;
226                         }
227                 }
228
229                 if (IOException == B_TRUE)
230                 {
231                         retval = 0;
232                         if(iface_check_count > rrthread->SBData->timeout)
233                         {
234                                 rrthread->blockMgr->threadState[rrthread->threadId] = STATE_THREAD_STOPPED;
235                                 TIZEN_LOGD("Stopping Thread %d as Interaface is Down For Long Time");
236                                 break;
237                         }
238                         retval = range_request_thread_handleIOExp(rrthread,&ifCount,rrthread->SBData->conn.ip_family);
239                         if(THREAD_EXIT == retval)
240                         {
241                                 break;
242                         }
243                         else if (THREAD_CONTINUE == retval)
244                         {
245                                 iface_check_count++;
246                                 sleep(1);
247                                 continue;
248                         }
249                         iface_check_count = 0;
250                         IOException = B_FALSE;
251                 }
252                 memset(chunkInfo,0,CHUNK_INFO_SIZE*sizeof(int64));
253
254                 /* Block Manager for next block */
255                 block_manager_get_next_chunk(chunkInfo, rrthread->threadId,
256                                                                                 rrthread->socketId, rrthread->blockMgr);
257
258                 currChunkLen = chunkInfo[1] - chunkInfo[0] + 1;
259                 chunkId = chunkInfo[2];
260                 TIZEN_LOGD("Chunk Id %d Thread Id %d RANGE START %dRANGE END %d\n",
261                 chunkId, rrthread->threadId, chunkInfo[0] ,chunkInfo[1]);
262
263                 if (chunkId < 0)
264                 {
265                         /* This condition is for keep-alive case */
266                         waitThread = B_TRUE;
267                         continue;
268                 }
269
270                 currChunk = rrthread->commBuffer + chunkId;
271                 memset(newRequest,0,(rrthread->headerLen + MAX_RANGE_FIELD_LEN));
272                 reqLen = range_request_thread_rebuild_req(newRequest, chunkInfo, rrthread);
273
274                 startTime = get_time_in_microsec();
275
276                 if (-1 == send(rrthread->socketId, newRequest, reqLen, 0))
277                 {
278                         range_request_thread_handleSendFailCase(rrthread,chunkId);
279                         IOException = B_TRUE;
280                         continue;
281                 }/* End of if */
282
283                 rngRspLen = 0;
284                 headerRcvd = B_FALSE;
285                 connClose = 0;
286                 //chunkBuff = DATA_BUFFER_GET_BUFFER(currChunk);
287
288                 while (rngRspLen != currChunkLen)
289                 {
290                         blockLen =  MIN(minBlockLen, (currChunkLen-rngRspLen));
291                         minBlockLen = MIN(rrthread->maxBlockSize, (minBlockLen<<1));
292                         blockOffset = 0;
293                         memset(tempBuff,0,MAX_BLOCK_SIZE);
294                         if (0 == headerRcvd)
295                         {
296                                 retval = range_request_recv_rng_rsp_headers(rrthread->socketId, blockLen, TIME_OUT_MILLISEC,
297                                 rrthread->contRngLen, currChunkLen, &blockOffset, tempBuff, rrthread->compRspLen, &connClose);
298                                 if (HTTP_RSP_DECODING_SUCCESS != retval)
299                                 {
300                                         if (rrthread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
301                                         {
302                                                 TIZEN_LOGD("First Response failed\n");;
303                                                 /* server doest support Range Request */
304                                                 /* Exit all threads */
305                                                 *(rrthread->compRspRcvdFlag) = 0;
306                                                 rrthread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
307                                         }/* End of else */
308                                         else
309                                         {
310                                                 /* IO Exception */
311                                                 IOException = B_TRUE;
312                                                 TIZEN_LOGD("Thread %d got Exception during recv headers",rrthread->threadId);
313                                         }
314                                         break;
315                                 }
316                                 else
317                                 {
318                                         endTime = get_time_in_microsec();
319                                         temp_startTime = endTime;
320                                         chunkStrTime = endTime;
321                                         uint64 headSpeed = (endTime-startTime)/1000;
322
323                                         TIZEN_D_LOGD("Thread %d Header speed %d\n",rrthread->threadId,headSpeed);
324                                         SET_HEAD_SPEED(rrthread->threadId,headSpeed,rrthread->blockMgr);
325                                         headerRcvd = B_TRUE;
326
327                                         /* Success response received from server */
328                                         if (rrthread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
329                                         {
330                                                 rrthread->firstRngStatus = FIRST_RSP_STATUS_SUCCESS;
331                                                 TIZEN_LOGD("First Response Success\n");
332                                         }
333                                         if (blockOffset > 0)
334                                         {
335                                                 data_buffer_add(blockOffset, rrthread->threadId, tempBuff, currChunk);
336                                                 rngRspLen = rngRspLen + blockOffset;
337                                         }/* End of if */
338                                 }/* End of else */
339                         }/* End of if */
340                         else
341                         {
342                                 int32 lenRcvd = 0;
343                                 uint32 currOffset = 0;
344                                 uint32 prevOffset = 0;
345                                 uint32 diffOffset = 0;
346                                 uint32 temp_check = 0;
347                                 uint64 speed = 0;
348                                 uint64 avgTime = 0;
349                                 uint64 currTime = 0;
350                                 uint64 prevTime = 0;
351                                 uint64 diffTime = 0;
352                                 uint64 blockStrtTime = 0;
353                                 uint64 blockEndTime = 0;
354                                 int8 *block = tempBuff;
355
356                                 prevTime = get_time_in_microsec();
357                                 blockStrtTime = prevTime;
358                                 while (blockOffset != blockLen)
359                                 {
360                                         if (conn_poll(rrthread->socketId, TIME_OUT_MILLISEC) <= 0)
361                                         {
362                                                 TIZEN_LOGD("Thread %d pollfd <=0\n",rrthread->threadId);
363                                                 break;
364                                         }
365
366                                         lenRcvd = recv(rrthread->socketId,block + blockOffset,blockLen-blockOffset, 0);
367                                         if ((lenRcvd == -1) || (lenRcvd == 0))
368                                         {
369                                                 TIZEN_LOGD("Thread %d pollfd recv faill \n",rrthread->threadId);
370                                                 break;
371                                         }
372                                         else if (lenRcvd > 0)
373                                         {
374                                                 currOffset = currOffset + lenRcvd;
375                                                 blockOffset = blockOffset + lenRcvd;
376                                                 currTime = get_time_in_microsec();
377                                                 blockEndTime = currTime;
378                                                 diffTime = (currTime-prevTime) /1000;
379                                                 diffOffset = currOffset-prevOffset;
380                                                 if((rngRspLen > rrthread->minDataForSpeed) &&
381                                                                 ((diffOffset >= rrthread->blockForSpeed) || (diffTime >= rrthread->speedTimeOut)))
382                                                 {
383                                                         prevTime = currTime;
384                                                         prevOffset = currOffset;
385                                                         avgTime = (currTime - chunkStrTime)/1000;
386                                                         if(avgTime > 0)
387                                                         {
388                                                                 speed = ((rngRspLen + blockOffset) * 8)/avgTime;
389                                                         }/* End of if */
390                                                         SET_SPEED(rrthread->threadId,speed, rrthread->blockMgr);
391                                                 }
392                                                 if((blockEndTime-blockStrtTime) >= BLOCK_TIME_OUT)
393                                                 {
394                                                         blockLen = blockOffset;
395                                                 }
396                                         }
397                                 }
398                                 if (blockOffset != blockLen)
399                                 {
400                                         /* IO Exception */
401                                         TIZEN_LOGD("Thread %d IOException during read\n",rrthread->threadId);
402                                         IOException = B_TRUE;
403                                         break;
404                                 }
405                                 else
406                                 {
407                                         temp_check = 0;
408                                         data_buffer_add(blockOffset, rrthread->threadId, tempBuff, currChunk);
409                                         rngRspLen = rngRspLen + blockOffset;
410
411                                         TIZEN_D_LOGD("Thread %d completed block of len\n",blockLen);
412                                         /* check the other thread status */
413                                         if((currTime - temp_startTime) > TEMP_TIME_OUT)
414                                         {
415                                                 TIZEN_D_LOGD("Go For Temperature Checking");
416                                                 temp_startTime = currTime;
417                                                 temp_check = 1;
418                                         }
419                                         if(block_manager_checkOtherThread(rrthread->threadId,chunkId,rrthread->blockMgr,temp_check))
420                                         {
421                                                 TIZEN_LOGD("Thread %d IOException as other thread is blocked read\n",rrthread->threadId);
422                                                 IOException = B_TRUE;
423                                                 break;
424                                         }
425                                 }
426                         }
427                 }/* End of while */
428                 if (IOException == B_TRUE)
429                 {
430                         if ((chunkId != -1) && (DATA_BUFFER_GET_THREAD_ID(rrthread->commBuffer + chunkId) ==
431                         rrthread->threadId))
432                         {
433                                 /* close the current fd */
434                                 if (rrthread->socketId != 0)
435                                 {
436                                         close(rrthread->socketId);
437                                         rrthread->socketId = 0;
438                                 }
439                                 /* IO Exception inform Block manager */
440                                 block_manager_io_exception(rrthread->threadId,chunkId, rrthread->blockMgr);
441                                 DATA_BUFFER_SET_STATE(STATE_BLOCKED, (rrthread->commBuffer + chunkId));
442                                 if(blockOffset != blockLen)
443                                 {
444                                         /* Consider only IO Expection due to socket */
445                                         rrthread->blockMgr->noOfIOExp[rrthread->threadId]++;
446                                 }
447                         }
448                         else
449                         {
450                                 /* Current thread is slow Need to check buffer status */
451                                 if (block_manager_chunk_present(rrthread->blockMgr) <= 0)
452                                 {
453                                         waitThread = B_TRUE;
454                                         TIZEN_LOGD("Slow Thread %d is in wait state \n",rrthread->threadId);
455                                 }
456                                 rrthread->socketId = 0;
457                         }
458                 }
459                 else
460                 {
461                         TIZEN_LOGD("Thread %d  Completed chunk %d \n",rrthread->threadId, chunkId);
462                 }
463                 if ((IOException == B_FALSE) && (1 == connClose))
464                 {
465                         IOException = B_TRUE;
466                         if (block_manager_chunk_present(rrthread->blockMgr) <= 0)
467                         {
468                                 waitThread = B_TRUE;
469                                 TIZEN_LOGD("Thread %d is in wait state \n",rrthread->threadId);
470                         }
471                         if (rrthread->socketId != 0)
472                         {
473                                 close(rrthread->socketId);
474                                 rrthread->socketId = 0;
475                         }
476                 }/* End of if */
477         }/* End of while */
478
479         rrthread->blockMgr->threadState[rrthread->threadId] = STATE_THREAD_STOPPED;
480
481         if (rrthread->socketId != 0)
482         {
483                 close(rrthread->socketId);
484                 rrthread->socketId = 0;
485         }
486
487         if(NULL != newRequest)
488         {
489                 free(newRequest);
490                 newRequest = NULL;
491         }/* End of if */
492
493 }/* End of run() */
494
495 uint32 range_request_thread_rebuild_req(int8 *newRequest, int64 *chunkInfo,RangeRequestThread *rrthread)
496 {
497         int8 rangeField[50] = {0};
498         uint32 rangeLen = 0;
499
500         rangeLen = sprintf(rangeField,"%s%lld%s%lld%s","Range: bytes=", chunkInfo[0], "-",
501         chunkInfo[1], "\r\n\r\n");
502
503         memcpy(newRequest, rrthread->reqHeaders, rrthread->headerLen);
504         newRequest[rrthread->headerLen] = '\0';
505
506
507         memcpy(newRequest + (rrthread->headerLen - 2), rangeField, rangeLen);
508         newRequest[rangeLen + rrthread->headerLen-2] = '\0';
509         TIZEN_LOGD("thread ID %d range_request_thread_rebuild_req new req with range =%s\n",
510         rrthread->threadId, newRequest);
511         return (rangeLen + rrthread->headerLen -2);
512 }
513
514 void range_request_thread_exit(RangeRequestThread *rrthread)
515 {
516         TIZEN_LOGD("range_request_thread_exit %p", rrthread);
517
518         if (0 != rrthread->socketId)
519         {
520                 close(rrthread->socketId);
521                 rrthread->socketId = 0;
522         }
523
524         if (0 != rrthread->pThreadId)
525         {
526                 pthread_join(rrthread->pThreadId,NULL);
527                 rrthread->pThreadId = 0;
528         }
529
530         free(rrthread);
531         rrthread = NULL;
532         TIZEN_LOGD("range_request_thread_exit Sucess %p", rrthread);
533 }
534
535 int range_request_recv_rng_rsp_headers(int32 socket_fd, uint32 size, uint32 timeout, uint64 instanceSize,
536                                                                 uint64 currChunkLen, int32 *bodyLen, int8 *blockSize, uint64 respLen, uint32 *connClose)
537 {
538         int32 len = 0;
539         int32 rcvdLen = 0;
540         int32 retval = -1;
541         uint32 offset = 0;
542         uint32 headerLen;
543         int8 rspSize[MAX_HEADERS_SIZE + 1] = {0};
544         int8 rspPrint[MAX_HEADERS_SIZE] = {0};
545         httpResp httprsp;
546
547         memset(rspSize, 0, MAX_HEADERS_SIZE + 1);
548         memset(rspPrint, 0, MAX_HEADERS_SIZE);
549
550         while (1)
551         {
552                 if(conn_poll(socket_fd, timeout) <= 0)
553                 {
554                         TIZEN_LOGD("Poll Error in recv headers");
555                         return HTTP_RSP_SOCKET_ERROR;
556                 }/* End of if */
557                 uint32 min_size = MIN(size, (MAX_HEADERS_SIZE - offset));
558                 rcvdLen = recv(socket_fd, rspSize + offset,     min_size, 0);
559                 TIZEN_D_LOGD("thread ID recvd lenght %d\n", rcvdLen);
560                 if (rcvdLen > 0)
561                 {
562                         rspSize[offset + rcvdLen +1] = '\0';
563                         len = decode_http_find_str(rspSize, END_OF_HEADERS);
564                         if (-1 != len)
565                         {
566                                 headerLen = len+4;
567                                 offset  = offset + rcvdLen;
568                                 *bodyLen = offset - headerLen;
569
570                                 memcpy(rspPrint, rspSize, headerLen);
571                                 TIZEN_LOGD("Response %s\n", rspPrint);
572                                 /* Decode Response headers */
573                                 memset(&httprsp, 0, sizeof(httpResp));
574                                 decode_http_rsp_init(rspSize, headerLen, &httprsp);
575
576                                 retval = process_http_rsp(&httprsp);
577                                 if (HTTP_RSP_DECODING_SUCCESS == retval)
578                                 {
579                                         retval = range_request_validate_rsp(instanceSize,
580                                                                 &httprsp, currChunkLen, respLen, connClose);
581
582                                         if((retval == HTTP_RSP_DECODING_SUCCESS) && (*bodyLen > 0))
583                                         {
584                                                 /* Copy initial Response to block */
585                                                 memcpy(blockSize,rspSize + headerLen,*bodyLen);
586                                         }
587                                 }
588                                 delete_http_rsp(&httprsp);
589                                 return retval;
590                         }/* End of if */
591                         else
592                         {
593                                 offset  = offset + rcvdLen;
594                                 if (offset == MAX_HEADERS_SIZE)
595                                 {
596                                         /* Rsp header too large */
597                                         retval = HTTP_RSP_DECODING_ERROR;
598                                         break;
599                                 }
600                         }
601                 }
602                 else
603                 {
604                         TIZEN_LOGD("recv Error in recv headers");
605                         retval = HTTP_RSP_SOCKET_ERROR;
606                         break;
607                 }
608         }
609         return retval;
610 }/* End of recvRngRspHeaders() */
611
612 int range_request_validate_rsp(uint64 instanceSize, httpResp *httpRsp,
613                                                                 uint64 currChunkLen, uint64 respLen, uint32 *connClose)
614 {
615         int32 retval = HTTP_RSP_DECODING_ERROR;
616         int8 *rspCode = DECODE_HTTP_RSP_GET_RSP_CODE(httpRsp);
617         int8 *contLen =  DECODE_HTTP_RSP_GET_CONT_LEN(httpRsp);
618         int8 *conn = DECODE_HTTP_RSP_GET_CONNECTION(httpRsp);
619
620         if(conn != NULL)
621         {
622                 if(0 == strncasecmp(conn,"close",strlen("close")))
623                 {
624                         *connClose = 1;
625                 }/* End of if */
626         }
627
628         if ((rspCode != NULL) && (contLen != NULL))
629         {
630                 if ((0 == strncasecmp(rspCode, "200 OK", strlen("200 OK")))
631                                 || (0 == strncasecmp(rspCode, "206 Partial Content",strlen("206 Partial Content"))))
632                 {
633                         uint64 rcvdContLen = atol(contLen);
634                         TIZEN_LOGD("rcvdContLen %llu Expected %llu",rcvdContLen,currChunkLen);
635                         if (rcvdContLen == currChunkLen)
636                         {
637                                 uint64 rcvdContRngLen = decode_http_rsp_get_cont_rnglen(httpRsp->contRange);
638                                 TIZEN_LOGD("rcvdContRngLen %llu contRngLen %llu compRspLen %s",
639                                 rcvdContRngLen, instanceSize, contLen);
640                                 if ((instanceSize != 0) && (instanceSize == rcvdContRngLen))
641                                 {
642                                         retval = HTTP_RSP_DECODING_SUCCESS;
643                                 }
644                                 else if (rcvdContRngLen == respLen)
645                                 {
646                                         retval = HTTP_RSP_DECODING_SUCCESS;
647                                 }
648                         }
649                 }
650         }
651         return retval;
652 }