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_file_manager.h"
7 #include "multirat_file_buffer.h"
8 #include "multirat_decode_http.h"
9 #include "multirat_file_thread.h"
10 #include "multirat_watch_dog_thread.h"
14 void file_thread_init(fileThread *fThread, SmartBondingData *SBData, fileStream *fStream)
16 TIZEN_LOGD("File Thread Init");
17 fThread->pthreadId = 0;
18 fThread->compRspRcvdFlag = &(fStream->compRspRcvdFlag);
19 fThread->compRspLen = SBData->resp.cLen ;
20 fThread->contRngLen = SBData->resp.instanceSize;
21 fThread->SBData = SBData;
22 fThread->conn = &SBData->conn;
23 fThread->socketId = -1;
24 fThread->fileMgr = fStream->fileMgr;
25 fThread->firstRngStatus = FIRST_RSP_STATUS_PENDING;
28 uint32 file_thread_start(fileThread *fThread)
30 uint32 multiThreadStarted = B_TRUE;
31 if(0 != pthread_create(&fThread->pthreadId, NULL, &FileThreadCallBack, fThread))
33 TIZEN_LOGD("File thread failed");
34 multiThreadStarted = B_FALSE;
36 return multiThreadStarted;
39 void *FileThreadCallBack(void *ptr)
41 fileThread *fileReq = (fileThread*)ptr;
42 file_thread_run(fileReq);
46 void file_thread_run(fileThread *fThread)
48 int8 *newRequest = NULL;
49 int8 tempBuff[2*MAX_BLOCK_SIZE] = {0};
50 int8 rcvBuff[MAX_HEADER_SIZE + 1] = {0};
51 int32 headerRcvd = B_FALSE;
52 int32 IOException = B_TRUE;
53 int32 FIRST_TIME = B_TRUE;
54 int64 chunkInfo[CHUNK_INFO_SIZE] ={0};
56 uint32 minBlockLen = MIN_BLOCK_SIZE;
59 uint32 ifaceidx = fThread->interface_index;
60 uint64 currChunkLen = 0;
62 uint64 blockOffset = 0;
66 fileBuffer *fbuffer = NULL;
67 fThread->status = FILE_START;
68 SmartBondingData *SBData = NULL;
69 fileManager *fileMgr = fThread->fileMgr;
70 SBData = fThread->SBData;
71 TIZEN_LOGD("File Thread Main");
73 while(*fThread->compRspRcvdFlag)
77 fThread->interface_index = file_manager_get_file_thread_interface(fileMgr);
78 ifaceidx = fThread->interface_index;
79 TIZEN_LOGD("Interface Index [%d]", fThread->interface_index );
81 if (IOException == B_TRUE)
85 retval = file_thread_handleIOExp(fThread,&ifCount,SBData->conn.ip_family);
87 if(THREAD_EXIT == retval)
91 else if (THREAD_CONTINUE == retval)
98 fbuffer = file_manager_getNextChunkForFileThread(chunkInfo, SBData);
105 fThread->status = FILE_START;
106 fThread->interface_index = file_manager_get_file_thread_interface(fileMgr);
108 if(fbuffer->fThread_read != FILE_THREAD_SOCK_READ)
110 if(ifaceidx != fThread->interface_index)
114 retval = file_thread_handleIOExp(fThread,&ifCount,SBData->conn.ip_family);
116 if(THREAD_EXIT == retval)
120 else if (THREAD_CONTINUE == retval)
126 ifaceidx = fThread->interface_index ;
128 if((FIRST_TIME != B_TRUE))
130 return_val = file_thread_connet_server_interface(fThread);
131 if(THREAD_EXIT == return_val)
135 else if (THREAD_CONTINUE == return_val)
141 fThread->req = SBData->req.request[ifaceidx] ;
142 fThread->headerLen = strlen(SBData->req.request[ifaceidx]);
144 if(newRequest != NULL)
147 newRequest = (int8 *)malloc(fThread->headerLen + MAX_RANGE_FIELD_LEN);
148 if(NULL == newRequest)
153 memset(newRequest,0,(fThread->headerLen + MAX_RANGE_FIELD_LEN));
154 reqLen = file_thread_rebuildReq(newRequest, chunkInfo, fThread);
156 SECURE_DB_INFO("In file thread New Request [%s]",newRequest) ;
158 if(-1 == send(fThread->socketId,newRequest,reqLen,0))
160 TIZEN_LOGD("Sending of HTTP Req from File Thread Failed");
163 headerRcvd = B_FALSE;
168 TIZEN_LOGD("First Time File Thread Connection");
169 result = file_thread_FirstConnection(fThread->SBData, fThread, chunkInfo, rcvBuff, &lengthRcvd);
170 return_val = file_thread_connect_server_interface_first(result, fThread);
171 if(THREAD_EXIT == return_val)
175 else if (THREAD_CONTINUE == return_val)
180 headerRcvd = B_FALSE;
182 fbuffer->socketId = fThread->socketId ;
186 fThread->socketId = fbuffer->socketId;
189 currChunkLen = chunkInfo[1] - chunkInfo[0] + 1;
190 TIZEN_LOGD("File Thread Interface Index [%d]",fThread->interface_index);
191 TIZEN_LOGD("currChunkLen [%llu]",currChunkLen);
192 IOException = B_FALSE;
193 minBlockLen = MIN_BLOCK_SIZE;
196 while(rcvdLen < currChunkLen && *fThread->compRspRcvdFlag)
200 blockLen = MIN(minBlockLen, currChunkLen - rcvdLen);
201 minBlockLen = MIN((2*MAX_BLOCK_SIZE),(minBlockLen << 2));
202 memset(tempBuff,0,2*MAX_BLOCK_SIZE);
204 /*If Main thread Read stops for more than 2 sec , file thread stops reading */
205 if(SBData->read_state_check == MAIN_SOCK_READ_INACTIVE)
211 TIZEN_LOGD("File Thread Total Len [%llu] received [%llu] Block Len [%llu]",file_buffer_getTotalLen(fbuffer), rcvdLen, blockLen);
212 status = file_manager_check_main_thread_status(fileMgr);
213 if((status == MAIN_IO_EXCEPTION) && (SBData->file_status != NO_REDIVISION))
215 TIZEN_LOGD("IO Exception of Main Socket");
216 fThread->status = FILE_IO_EXCEPTION;
217 fbuffer->state = NODE_STATE_BLOCKED;
218 IOException = B_TRUE;
221 else if((status == MAIN_COMPLETE)&& (SBData->file_status != NO_REDIVISION))
223 TIZEN_LOGD("Main Thread is Completed");
224 fThread->status = MAIN_COMPLETE;
225 fbuffer->state = NODE_STATE_BLOCKED;
226 IOException = B_TRUE;
229 if(B_FALSE == headerRcvd)
231 int32 retval = HTTP_RSP_DECODING_ERROR;
232 if(FIRST_TIME == B_TRUE)
234 retval = file_thread_range_request_recv_rng_rsp_headers_first_req(&blockOffset, tempBuff, currChunkLen, &connClose, fThread, rcvBuff, lengthRcvd);
235 FIRST_TIME = B_FALSE;
238 retval = file_thread_range_request_recv_rng_rsp_headers(&blockOffset, tempBuff, currChunkLen, &connClose, fThread);
239 if(HTTP_RSP_DECODING_SUCCESS != retval)
241 if((fThread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
242 && (retval == HTTP_RSP_DECODING_ERROR))
244 TIZEN_LOGD("First Response failed");
245 *fThread->compRspRcvdFlag = 0;
246 fThread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
250 IOException = B_TRUE;
251 TIZEN_LOGD("File Thread got Exception during recv headers");
258 if(fThread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
260 fThread->firstRngStatus = FIRST_RSP_STATUS_SUCCESS;
261 TIZEN_LOGD("First Response Success");
265 uint64 temp_history = 0;
266 uint64 temp_data = 0;
267 speedStat *sStat = &(SBData->sStat);
268 file_buffer_add(fbuffer, tempBuff, blockOffset, chunkInfo, rcvdLen, SBData);
271 sprintf(SBData->FileData,"%lld-%llu",chunkInfo[0],file_buffer_getOffset(fbuffer));
273 rcvdLen = rcvdLen + blockOffset;
275 temp_data = sStat->recv_length[fThread->interface_index];
276 sStat->recv_length[fThread->interface_index] = sStat->recv_length[fThread->interface_index] + blockOffset;
277 if(sStat->start_recv_time[fThread->interface_index] == 0)
278 sStat->start_recv_time[fThread->interface_index] = get_time_in_microsec();
279 sStat->prev_recv_time[fThread->interface_index] = get_time_in_microsec();
280 temp_history = (sStat->prev_recv_time[fThread->interface_index] - sStat->start_recv_time[fThread->interface_index])/1000000;
281 if((sStat->timeArray[fThread->interface_index] < (MAX_HISTORY)) && (temp_history < MAX_HISTORY) && (temp_history > sStat->timeArray[fThread->interface_index]))
284 sStat->dataArray[fThread->interface_index][temp_history] = sStat->recv_length[fThread->interface_index];
285 for( i = sStat->timeArray[fThread->interface_index] + 1 ; i < temp_history; i++)
287 sStat->dataArray[fThread->interface_index][i] = temp_data;
289 sStat->timeArray[fThread->interface_index] = temp_history;
290 TIZEN_LOGD("Data History Time [%llu] Data [%llu]", temp_history, sStat->dataArray[fThread->interface_index][temp_history]);
291 TIZEN_LOGD("temp_hist [%llu] tdata [%llu] Data [%llu]", temp_history, temp_data, sStat->dataArray[fThread->interface_index][temp_history]);
293 TIZEN_LOGD("File Thread Total Len [%llu] received [%llu] Block Len [%llu]",file_buffer_getTotalLen(fbuffer), rcvdLen, blockLen);
300 while(blockOffset != blockLen)
302 if (file_thread_conn_poll(fThread->socketId, SBData) <= 0)
304 TIZEN_LOGD("File Thread Fail Polling");
305 IOException = B_TRUE;
309 lenRcvd = recv(fThread->socketId, tempBuff+blockOffset, blockLen-blockOffset,0);
310 if((lenRcvd == -1) || (lenRcvd == 0))
316 blockOffset = blockOffset + lenRcvd;
317 uint64 temp_history = 0;
318 uint64 temp_data = 0;
319 speedStat *sStat = &(SBData->sStat);
320 temp_data = sStat->recv_length[fThread->interface_index];
322 sStat->recv_length[fThread->interface_index] = sStat->recv_length[fThread->interface_index] + lenRcvd;
324 if(sStat->start_recv_time[fThread->interface_index] == 0)
325 sStat->start_recv_time[fThread->interface_index] = get_time_in_microsec();
327 sStat->prev_recv_time[fThread->interface_index] = get_time_in_microsec();
329 temp_history = (sStat->prev_recv_time[fThread->interface_index] - sStat->start_recv_time[fThread->interface_index])/1000000;
330 if((sStat->timeArray[fThread->interface_index] < (MAX_HISTORY)) && (temp_history < MAX_HISTORY) && (temp_history > sStat->timeArray[fThread->interface_index]))
333 sStat->dataArray[fThread->interface_index][temp_history] = sStat->recv_length[fThread->interface_index];
334 for( i = sStat->timeArray[fThread->interface_index] + 1 ; i < temp_history; i++)
336 sStat->dataArray[fThread->interface_index][i] = temp_data;
338 sStat->timeArray[fThread->interface_index] = temp_history;
339 TIZEN_LOGD("idx [%d] Data History Time [%llu] Data [%llu]", fThread->interface_index, temp_history, sStat->dataArray[fThread->interface_index][temp_history]);
343 if(blockOffset != blockLen)
346 TIZEN_LOGD("File Thread IOException during read");
347 IOException = B_TRUE;
352 TIZEN_LOGD("File Buffer Write [%x]", fbuffer);
353 //file_buffer_add(fbuffer, tempBuff, blockOffset);
354 file_buffer_add(fbuffer, tempBuff, blockOffset,chunkInfo,rcvdLen,SBData);
358 sprintf(SBData->FileData,"%lld-%llu",chunkInfo[0],file_buffer_getOffset(fbuffer));
360 rcvdLen = rcvdLen + blockOffset;
361 TIZEN_D_LOGD("File Thread Total Len [%llu] received [%llu] Block Len [%llu]", file_buffer_getTotalLen(fbuffer), rcvdLen, blockLen);
365 if((IOException == B_TRUE) && (file_buffer_getTotalLen(fbuffer) != rcvdLen))
367 fbuffer->state = NODE_STATE_BLOCKED;
368 IOException = B_TRUE;
369 if(SBData->file_status == NO_REDIVISION)
371 TIZEN_LOGD("Close Socket ID As Exception and No Redivision");
372 fThread->status = FILE_IO_EXCEPTION;
373 CLOSE_SOCKET(fbuffer->socketId);
374 fbuffer->socketId = 0;
375 fThread->socketId = 0;
377 else if((fThread->SBData->status == MAIN_COMPLETE))
379 TIZEN_LOGD("Dont Close Socket ID As Main Complete");
382 TIZEN_LOGD("File Buffer Write [%x] Data Length [%llu]", fbuffer, blockOffset);
383 file_buffer_add(fbuffer, tempBuff, blockOffset,chunkInfo,rcvdLen,SBData);
386 sprintf(SBData->FileData,"%lld-%llu",chunkInfo[0],file_buffer_getOffset(fbuffer));
389 fThread->status = MAIN_COMPLETE;
393 TIZEN_LOGD("Close Socket ID As Exception and Main is not Complete");
394 fThread->status = FILE_IO_EXCEPTION;
395 CLOSE_SOCKET(fbuffer->socketId);
396 fbuffer->socketId = -1;
397 fThread->socketId = -1;
400 TIZEN_LOGD("File Thread Interupted Download FILE NODE [%x] Total length [%llu] Received [%llu]", fbuffer, file_buffer_getTotalLen(fbuffer), file_buffer_getOffset(fbuffer));
404 fThread->status = FILE_COMPLETE; // Means here it is complete
405 TIZEN_LOGD("File Thread Finished Downloading FILE NODE [%x] Total length [%llu] Received [%llu]", fbuffer, file_buffer_getTotalLen(fbuffer), file_buffer_getOffset(fbuffer));
407 if(fThread->SBData->file_status == NO_REDIVISION)
408 *fThread->compRspRcvdFlag = 0;
410 if(NULL == fbuffer->next)
412 TIZEN_LOGD("Close Socket ID as No Available Buffer");
413 CLOSE_SOCKET(fbuffer->socketId);
414 fbuffer->socketId = -1;
415 fThread->socketId = -1;
416 fThread->status = FILE_COMPLETE;
417 IOException = B_TRUE;
419 if(NULL != fbuffer->next && fThread->socketId != file_buffer_getSocketId(fbuffer->next))
421 TIZEN_LOGD("Close Socket ID as Next Avalaible Buffer Socket is Not Same");
422 CLOSE_SOCKET(fbuffer->socketId);
423 fbuffer->socketId = -1;
424 fThread->socketId = -1;
425 fThread->status = FILE_COMPLETE;
426 IOException = B_TRUE;
430 TIZEN_LOGD("Exiting FILE THREAD");
431 if(NULL != newRequest)
436 TIZEN_LOGD("Exiting FILE THREAD ...");
440 int file_thread_handleIOExp(fileThread *fThread, uint32 *ifCount,int iptype)
442 /* Check if interface is available */
443 if (!connection_is_ifaceup(fThread->interface_index, fThread->conn->ifaceInfo,iptype))
445 if((fThread->firstRngStatus == FIRST_RSP_STATUS_PENDING) && (*ifCount++ > 2))
447 fThread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
448 *(fThread->compRspRcvdFlag) = 0;
449 TIZEN_LOGD("First Response Failed for File ThreadId");
454 return THREAD_CONTINUE;
457 /* IOException case */
462 int file_thread_connect_server_interface_first(int32 result, fileThread *fThread)
464 fThread->socketId = result;
465 TIZEN_LOGD("File Thread socketId [%d]", fThread->socketId);
466 if ((-1 == fThread->socketId) || (!(*(fThread->compRspRcvdFlag))))
468 if (fThread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
470 fThread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
471 TIZEN_LOGD("First Response failed");;
472 /* server doest support Range Request */
473 /* Exit all threads */
474 *(fThread->compRspRcvdFlag) = 0;
475 TIZEN_LOGD("First Response Failed for File ThreadId");
480 if(fThread->SBData->file_status == NO_REDIVISION)
482 fThread->status = FILE_IO_EXCEPTION;
484 else if(fThread->SBData->status == MAIN_COMPLETE)
486 fThread->status = MAIN_COMPLETE;
490 fThread->status = FILE_IO_EXCEPTION;
492 return THREAD_CONTINUE;
498 int file_thread_connet_server_interface(fileThread *fThread)
500 file_thread_connect_server(fThread);
501 TIZEN_LOGD("File Thread socketId [%d]", fThread->socketId);
503 if ((0 > fThread->socketId) || (!(*(fThread->compRspRcvdFlag))))
505 if (fThread->firstRngStatus == FIRST_RSP_STATUS_PENDING)
507 fThread->firstRngStatus = FIRST_RSP_STATUS_FAILED;
508 TIZEN_LOGD("First Response failed");;
509 /* server doest support Range Request */
510 /* Exit all threads */
511 *(fThread->compRspRcvdFlag) = 0;
512 TIZEN_LOGD("First Response Failed for File ThreadId");
517 if(fThread->SBData->file_status == NO_REDIVISION)
519 fThread->status = FILE_IO_EXCEPTION;
521 else if(fThread->SBData->status == MAIN_COMPLETE)
523 fThread->status = MAIN_COMPLETE;
527 fThread->status = FILE_IO_EXCEPTION;
529 return THREAD_CONTINUE;
537 int32 file_thread_range_request_recv_rng_rsp_headers_first_req(uint64 *bodyLen, char *blockSize, uint64 currChunkLen, uint32 *connClose, fileThread *fThread, int8 *rcvBuff, int32 lengthRcvd)
539 uint32 offset = lengthRcvd;
542 int8 rspPrint[MAX_HEADERS_SIZE] = {0};
544 uint64 instanceSize = fThread->contRngLen;
545 uint64 respLen = fThread->compRspLen;
546 len = decode_http_find_str(rcvBuff, END_OF_HEADERS);
547 uint32 headerLen = (len+4);
548 *bodyLen = (uint64)(offset - headerLen);
549 memcpy(rspPrint, rcvBuff, headerLen);
550 SECURE_DB_INFO("Response [%s]", rspPrint);
551 TIZEN_LOGD("Total Data Received [%d]", lengthRcvd);
552 memset(&httpRsp, 0, sizeof(httpResp));
553 decode_http_rsp_init(rcvBuff, headerLen, &httpRsp);
554 retval = process_http_rsp(&httpRsp);
555 if(HTTP_RSP_DECODING_SUCCESS == retval)
557 TIZEN_LOGD("File Thread Response Decode Success");
558 retval = range_request_validate_rsp(instanceSize, &httpRsp, currChunkLen, respLen, connClose);
559 if((retval == HTTP_RSP_DECODING_SUCCESS) && (*bodyLen > 0))
561 memcpy(blockSize,rcvBuff+headerLen,*bodyLen);
564 delete_http_rsp(&httpRsp);
565 TIZEN_LOGD("File Thread Response Decode Success ...");
569 int32 file_thread_range_request_recv_rng_rsp_headers(uint64 *bodyLen, char *blockSize, uint64 currChunkLen, uint32 *connClose, fileThread *fThread)
575 int8 rspSize[MAX_HEADERS_SIZE] = {0};
576 int8 rspPrint[MAX_HEADERS_SIZE] = {0};
578 uint64 instanceSize = fThread->contRngLen;
579 uint64 respLen = fThread->compRspLen;
582 TIZEN_LOGD("Recv Response");
583 if (file_thread_conn_poll(fThread->socketId, fThread->SBData) <= 0)
585 TIZEN_LOGD("File Thread Fail Polling");
586 return HTTP_RSP_SOCKET_ERROR;
588 TIZEN_LOGD("Recved Response");
589 rcvdLen = recv(fThread->socketId,rspSize+offset,MAX_HEADERS_SIZE-offset,0);
592 rspSize[offset + rcvdLen +1] = '\0';
593 len = decode_http_find_str(rspSize,END_OF_HEADERS);
596 uint32 headerLen = len+4;
597 offset = offset + rcvdLen;
598 *bodyLen = offset-headerLen;
599 memcpy(rspPrint, rspSize, headerLen);
600 SECURE_DB_INFO("Response [%s]", rspPrint);
601 memset(&httpRsp, 0, sizeof(httpResp));
602 decode_http_rsp_init(rspSize, headerLen, &httpRsp);
603 retval = process_http_rsp(&httpRsp);
604 if(HTTP_RSP_DECODING_SUCCESS == retval)
606 TIZEN_LOGD("File Thread Response Decode Success");
607 retval = range_request_validate_rsp(instanceSize,
608 &httpRsp, currChunkLen, respLen, connClose);
609 if((retval == HTTP_RSP_DECODING_SUCCESS) && (*bodyLen > 0))
611 memcpy(blockSize,rspSize+headerLen,*bodyLen);
614 delete_http_rsp(&httpRsp);
615 TIZEN_LOGD("File Thread Response Decode Success ...");
620 offset = offset + rcvdLen;
621 if (offset == MAX_HEADERS_SIZE)
623 /* Rsp header too large */
624 retval = HTTP_RSP_DECODING_ERROR;
631 retval = HTTP_RSP_SOCKET_ERROR;
638 int32 file_thread_rebuildReq(char *newRequest, int64 *chunkInfo, fileThread *fThread)
641 int8 rangeField[MAX_RANGE_FIELD_LEN] = {0};
642 rangeLen = sprintf(rangeField,"%s%llu%s%llu%s","Range: bytes=",chunkInfo[0],"-",chunkInfo[1],"\r\n\r\n");
643 memcpy(newRequest, fThread->req, fThread->headerLen - 2);
644 memcpy(newRequest + fThread->headerLen -2, rangeField, rangeLen);
645 return (rangeLen+fThread->headerLen);
648 void file_thread_exit(fileThread *fThread)
650 TIZEN_LOGD("File_Thread_Exit [%p]", fThread);
652 if (0 < fThread->socketId)
654 shutdown(fThread->socketId, 1);
657 if (0 != fThread->pthreadId)
659 pthread_join(fThread->pthreadId,NULL);
660 TIZEN_LOGD("File Thread Closed");
661 fThread->pthreadId = 0;
663 if (0 < fThread->socketId)
665 CLOSE_SOCKET(fThread->socketId);
666 fThread->socketId = -1;
670 TIZEN_LOGD("File Thread Exit Sucess [%p]", fThread);