tizen 2.3 release
[framework/connectivity/multirat.git] / src / multirat_watch_dog_thread.c
1 #include "multirat_conf.h"
2 #include "multirat_process.h"
3 #include "multirat_libapi.h"
4 #include "multirat_watch_dog_thread.h"
5 #include "multirat_multisocket.h"
6 #include "multirat_decode_http.h"
7 #include "multirat_range_request_thread.h"
8 #include <vconf.h>
9 #include <vconf-keys.h>
10 #include "multirat_file_stream.h"
11 #include "multirat_file_manager.h"
12 #include "multirat_file_buffer.h"
13 #include "multirat_watchthread.h"
14
15 #ifdef TIZEN_UX_SUPPORT
16 #include "smartbonding-client.h"
17 #endif
18
19 void get_proxy_info(SmartBondingData *SBData, int interface_index)
20 {
21         connection *conn =  &(SBData->conn);
22         get_proxy_ip_port(conn->ifaceInfo[interface_index].proxy_addr, &(conn->ifaceInfo[interface_index].proxy_port));
23         if(strlen(conn->ifaceInfo[interface_index].proxy_addr) != 0)
24         {
25                 memset(SBData->conn.ifaceInfo[interface_index].server_ip,0,INET_ADDRSTRLEN);
26                 memcpy(conn->ifaceInfo[interface_index].server_ip, conn->ifaceInfo[interface_index].proxy_addr, strlen(conn->ifaceInfo[interface_index].proxy_addr));
27                 conn->ifaceInfo[interface_index].server_port = conn->ifaceInfo[interface_index].proxy_port;
28                 conn->ifaceInfo[interface_index].proxyEnable = B_TRUE;
29         }
30         else
31         {
32                 conn->ifaceInfo[interface_index].server_port = 80;
33         }
34         get_dns_ip(conn->ifaceInfo[interface_index].dns_1, conn->ifaceInfo[interface_index].dns_2);
35
36         SECURE_DB_INFO("Server/Proxy IP Address [%s]", conn->ifaceInfo[interface_index].server_ip);
37         SECURE_DB_INFO("Server/Proxy Port [%d]", conn->ifaceInfo[interface_index].server_port);
38         SECURE_DB_INFO("DNS 1 [%s]", conn->ifaceInfo[interface_index].dns_1);
39         SECURE_DB_INFO("DNS 2 [%s]", conn->ifaceInfo[interface_index].dns_2);
40 }
41
42 int32 file_thread_FirstConnection(SmartBondingData *SBData, fileThread *fThread, int64 *chunkInfo, int8 *recv_buf, int32 *lengthRcvd)
43 {
44         int8 *host = NULL;
45         int32 socket = -1;
46         uint32 redirect = 0;
47         uint32 length = 0;
48         uint32 retval_watch_dog = 1;
49         int retval = -1;
50         uint32 interface_index = 0;
51         int8 *newReq = NULL;
52         httpReq *req = &(SBData->req);
53         struct hostent *h = NULL;
54         struct sockaddr_in remote_addr;
55         struct sockaddr_in6 remote_addr_ip6;
56         httpResp httprsp;
57         connection *conn =  &(SBData->conn);
58         memset(&httprsp, 0, sizeof(httpResp));
59         interface_index = (fThread->interface_index);
60
61         SECURE_DB_INFO("Server IP Address [%s]", conn->ifaceInfo[SBData->interface_index].server_ip);
62         get_proxy_info(SBData, interface_index);
63         if(req->Rangeheader != NULL)
64         {
65                 newReq = get_new_req(req->req_buff_wo_range, 0, chunkInfo[0], chunkInfo[1], &length, req->req_wo_len, conn->ifaceInfo[interface_index].proxyEnable);
66         }
67         else
68         {
69                 newReq = get_new_req(req->req_buff, 0, chunkInfo[0], chunkInfo[1], &length, req->reqLen, conn->ifaceInfo[interface_index].proxyEnable);
70         }
71
72         SECURE_DB_INFO("HTTP New Req [%s]",newReq);
73
74         if(!SBData->conn.ifaceInfo[interface_index].proxyEnable)
75         {
76                 getHost(&host, newReq);
77                 if(NULL != host)
78                 {
79                         SECURE_DB_INFO("DNS Resolution for Proxy Case Host [%s]", host);
80                         if(!getDNSInfo(host, interface_index, SBData))
81                         {
82                                 TIZEN_LOGD("DNS Resolution Failed for Interface [%d]", interface_index);
83                                 free(host);
84                                 if(newReq != NULL)
85                                         free(newReq);
86                                 return retval;
87                         }
88                 }
89                 else
90                 {
91                         if(newReq != NULL)
92                                 free(newReq);
93                         return retval;
94                 }
95         }
96
97         while(*fThread->compRspRcvdFlag)
98         {
99                 retval_watch_dog = 1;
100                 memset(recv_buf, 0, MAX_HEADERS_SIZE + 1);
101
102                 socket = conn_get_socket_bind(conn->ifaceInfo[interface_index].ip,interface_index,conn->ip_family);
103
104                 if(socket < 0)
105                 {
106                         if(NULL != host)
107                                 free(host);
108                         if(newReq != NULL)
109                                 free(newReq);
110                         return retval;
111                 }
112
113                 TIZEN_LOGD("File Thread Socket [%d]",socket);
114
115                 redirect ++;
116
117                 if(redirect > 3)
118                 {
119                         TIZEN_LOGD("No Of Redirections Exceeded");
120                         CLOSE_SOCKET(socket);
121                         if(NULL != host)
122                                 free(host);
123                         if(newReq != NULL)
124                                 free(newReq);
125                         return retval;
126                 }
127
128                 h = gethostbyname(conn->ifaceInfo[interface_index].server_ip);
129
130                 if(SBData->conn.ip_family)
131                 {
132                         memset(&remote_addr_ip6, 0, sizeof(struct sockaddr_in6));
133                         remote_addr_ip6.sin6_family = h->h_addrtype;
134                         memcpy((char *) &remote_addr_ip6.sin6_addr.s6_addr, h->h_addr_list[0], h->h_length);
135                         remote_addr_ip6.sin6_port = htons(conn->port);
136                 }
137                 else
138                 {
139                         memset(&remote_addr, 0, sizeof(struct sockaddr_in));
140                         remote_addr.sin_family = h->h_addrtype;
141                         memcpy((char *) &remote_addr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
142                         remote_addr.sin_port = htons(conn->port);
143                 }
144
145                 if(-1 == file_thread_connServer(socket, &remote_addr, &remote_addr_ip6, SBData->timeout, SBData))
146                 {
147                         CLOSE_SOCKET(socket);
148                         if(NULL != host)
149                                 free(host);
150                         if(newReq != NULL)
151                                 free(newReq);
152                         return retval;
153                 }
154
155                 TIZEN_LOGD("Connect Success in File Thread");
156
157                 if (-1 == send(socket, newReq, length, 0))
158                 {
159                         TIZEN_LOGD("File Thread got Exception during send [%s]", strerror (errno));
160                 }
161                 else
162                 {
163                         TIZEN_LOGD("Send HTTP Request Success in File Thread");
164                         memset(recv_buf, 0, MAX_HEADERS_SIZE + 1);
165                         while (*fThread->compRspRcvdFlag)
166                         {
167                                 int32 len = 0;
168                                 int32 offset = 0;
169                                 int32 rcvdLen = 0;
170                                 int32 headerLen = 0;
171
172                                 if(file_thread_conn_poll(socket, SBData) <= 0)
173                                 {
174                                         TIZEN_LOGD("Error !!! File Thread pollfd failed Timeout or Fail or Exit");
175                                         break;
176                                 }
177
178                                 rcvdLen = recv(socket, recv_buf + offset, MAX_HEADERS_SIZE - offset, 0);
179                                 TIZEN_LOGD("Recvd length [%d]",rcvdLen);
180
181                                 if (rcvdLen > 0)
182                                 {
183                                         len = decode_http_find_str(recv_buf, END_OF_HEADERS);
184                                         if (-1 != len)
185                                         {
186                                                 headerLen = len + 4;
187                                                 TIZEN_LOGD("Header length [%d]", headerLen);
188                                                 memset(&httprsp, 0, sizeof(httpResp));
189                                                 decode_http_rsp_init(recv_buf, headerLen, &httprsp);
190                                                 SECURE_DB_INFO("File Thread Response [%s]", httprsp.resp_buff);
191
192                                                 retval = process_http_rsp(&httprsp);
193                                                 if ((HTTP_RSP_REDIRECT  == retval) && (httprsp.location != NULL))
194                                                 {
195                                                         TIZEN_LOGD("Redirection Happening and New Location [%s]", httprsp.location);
196
197                                                         if(handleRedirection(httprsp.location, interface_index, &newReq, &length, SBData) == HTTP_RSP_DECODING_SUCCESS)
198                                                         {
199                                                                 retval_watch_dog = 0;
200                                                                 CLOSE_SOCKET(socket);
201                                                                 socket = -1;
202                                                                 retval = -1;
203                                                                 break;
204                                                         }
205                                                         else
206                                                         {
207                                                                 retval = -1;
208                                                                 break;
209                                                         }
210                                                 }
211                                                 else if(HTTP_RSP_DECODING_SUCCESS != retval)
212                                                 {
213                                                         TIZEN_LOGD("HTTP Decoding Error");
214                                                         retval = -1;
215                                                         break;
216                                                 }
217                                                 retval = 0;
218                                                 TIZEN_LOGD("HTTP Response in File Trhead is SUCCESS");
219                                                 *lengthRcvd  = rcvdLen;
220                                                 break;
221                                         }
222                                         offset = offset + rcvdLen;
223                                         if(offset >= MAX_HEADERS_SIZE)
224                                         {
225                                                 retval = -1;
226                                                 break;
227                                         }
228                                 }
229                                 else
230                                 {
231                                         /* Socket error */
232                                         break;
233                                 }
234                         }
235                         delete_http_rsp(&httprsp);
236                         if(retval_watch_dog == 1)
237                                 break;
238                 }
239         }
240
241         TIZEN_LOGD("RETURN VALUE [%d]",retval);
242
243         if(retval == -1)
244         {
245                 if(socket > 0)
246                 {
247                         CLOSE_SOCKET(socket);
248                         socket = -1;
249                 }
250                 if(NULL != host)
251                         free(host);
252                 if(newReq != NULL)
253                         free(newReq);
254                 return retval;
255         }
256         if((store_interface_ip_request(newReq, SBData, interface_index) == 0))
257         {
258                 SBData->watch_dog_complete = 1;
259         }
260         if(NULL != host)
261                 free(host);
262         if(newReq != NULL)
263                 free(newReq);
264         return socket;
265 }
266
267 int32 watchdog_test_connection_type(SmartBondingData *SBData)
268 {
269         int8 *host = NULL;
270         int32 socket = -1;
271         int32 retval = 0;
272         int32 connType = 0;
273         uint32 redirect = 0;
274         uint32 length = 0;
275         uint32 retval_dns = 0;
276         uint32 retval_watch_dog = 1;
277         uint32 timeT2 = 0;
278         uint32 resp_len  = 0;
279         uint32 resp_offset = 0;
280         uint32 interface_index = 0;
281         uint64 endTime = 0;
282         uint64 startTime = 0;
283         uint64 contLength = 0;
284         int8 recv_buf[MAX_HEADERS_SIZE + 1] = {0};
285         int8 *newReq = NULL;
286         httpReq *req = &(SBData->req);
287         struct hostent *h = NULL;
288         struct sockaddr_in remote_addr;
289         struct sockaddr_in6 remote_addr_ip6;
290         httpResp httprsp;
291         connection *conn =  &SBData->conn;
292         startTime = get_time_in_microsec();
293         memset(&httprsp, 0, sizeof(httpResp));
294         TIZEN_LOGD("WatchDog test");
295         interface_index = (SBData->interface_index + 1) % 2;
296         if(req->Rangeheader != NULL)
297         {
298                 newReq = get_new_req(req->req_buff_wo_range, 0, 0, 1, &length, req->req_wo_len, conn->ifaceInfo[interface_index].proxyEnable);
299         }
300         else
301         {
302                 newReq = get_new_req(req->req_buff, 0, 0, 1, &length, req->reqLen, conn->ifaceInfo[interface_index].proxyEnable);
303         }
304         TIZEN_LOGD("UID [%d]", getuid());
305         memcpy(conn->ifaceInfo[SBData->interface_index].server_ip, conn->ip_addr, strlen(conn->ip_addr));
306         memcpy(conn->ifaceInfo[interface_index].server_ip, conn->ip_addr, strlen(conn->ip_addr));
307
308         SECURE_DB_INFO("Server IP Address [%s]", conn->ifaceInfo[SBData->interface_index].server_ip);
309
310         SECURE_DB_INFO("HTTP New Req [%s]",newReq);
311         getHost(&host, newReq);
312         if(NULL != host)
313         {
314                 SECURE_DB_INFO("DNS Resolution for Proxy Case Host [%s]", host);
315                 retval_dns = getDNSInfo(host, interface_index, SBData);
316                 free(host);
317         }
318         if(0 == retval_dns)
319         {
320                 TIZEN_LOGD("DNS Resolution Failed for Interface [%d]", interface_index);
321                 free(newReq);
322                 return -1;
323         }
324         while(SBData->cthread->threadStatus != THREAD_FINISH)
325         {
326                 retval_watch_dog = 1;
327
328                 socket = conn_get_socket_bind(conn->ifaceInfo[interface_index].ip,interface_index,conn->ip_family);
329
330                 if(socket < 0)
331                 {
332                         free(newReq);
333                         return -1;
334                 }
335
336                 TIZEN_LOGD("WatchDog Socket [%d]",socket);
337
338                 redirect ++;
339                 if(redirect > 3)
340                 {
341                         TIZEN_LOGD("No Of Redirections Exceeded");
342                         CLOSE_SOCKET(socket);
343                         return -1;
344                 }
345
346                 h = gethostbyname(conn->ifaceInfo[interface_index].server_ip);
347
348                 if(SBData->conn.ip_family)
349                 {
350
351                         memset(&remote_addr_ip6, 0, sizeof(struct sockaddr_in6));
352                         remote_addr_ip6.sin6_family = h->h_addrtype;
353                         memcpy((char *) &remote_addr_ip6.sin6_addr.s6_addr, h->h_addr_list[0], h->h_length);
354                         remote_addr_ip6.sin6_port = htons(conn->port);
355                 }
356                 else
357                 {
358                         memset(&remote_addr, 0, sizeof(struct sockaddr_in));
359                         remote_addr.sin_family = h->h_addrtype;
360                         memcpy((char *) &remote_addr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
361                         remote_addr.sin_port = htons(conn->port);
362                 }
363
364                 if(-1 == connServer(socket, &remote_addr,&remote_addr_ip6,SBData->timeout, SBData))
365                 {
366                         free(newReq);
367                         CLOSE_SOCKET(socket);
368                         return -1;
369                 }
370
371                 TIZEN_LOGD("Connect Success in Watchdog");
372
373                 if (-1 == send(socket, newReq, length, 0))
374                 {
375                         TIZEN_LOGD("Watch Dog Thread got Exception during send [%s]", strerror (errno));
376                 }
377                 else
378                 {
379                         TIZEN_LOGD("Send HTTP Request Success in Watchdog");
380                         memset(recv_buf, 0, MAX_HEADERS_SIZE + 1);
381                         while (SBData->cthread->threadStatus != THREAD_FINISH)
382                         {
383
384                                 int32 len = 0;
385                                 int32 offset = 0;
386                                 int32 rcvdLen = 0;
387                                 int32 headerLen = 0;
388                                 int retval = -1;
389
390                                 if(watchdog_conn_poll(socket, SBData) <= 0)
391                                 {
392                                         TIZEN_LOGD("Error !!! watchdog thread pollfd failed Timeout or Fail or Exit");
393                                         break;
394                                 }
395
396                                 rcvdLen = recv(socket, recv_buf + offset, MAX_HEADERS_SIZE - offset, 0);
397                                 TIZEN_LOGD("Recvd lenght [%d]",rcvdLen);
398
399                                 if (rcvdLen > 0)
400                                 {
401                                         TIZEN_D_LOGD("Watch1 Dog Thread Response [%s]",recv_buf);
402                                         len = decode_http_find_str(recv_buf, END_OF_HEADERS);
403                                         if (-1 != len)
404                                         {
405
406                                                 headerLen = len + 4;
407                                                 TIZEN_LOGD("Watch Dog Thread Response [%s]",recv_buf);
408
409                                                 memset(&httprsp, 0, sizeof(httpResp));
410
411                                                 decode_http_rsp_init(recv_buf, headerLen, &httprsp);
412                                                 retval = process_http_rsp(&httprsp);
413
414                                                 if ((HTTP_RSP_REDIRECT  == retval) && (httprsp.location != NULL))
415                                                 {
416                                                         TIZEN_LOGD("Redirection Happening and New Location [%s]", httprsp.location);
417
418                                                         if(handleRedirection(httprsp.location, interface_index, &newReq, &length, SBData) == HTTP_RSP_DECODING_SUCCESS)
419                                                         {
420                                                                 retval_watch_dog = 0;
421                                                                 CLOSE_SOCKET(socket);
422                                                                 socket = -1;
423                                                                 break;
424                                                         }
425                                                         else
426                                                         {
427                                                                 break;
428                                                         }
429                                                 }
430                                                 else if(HTTP_RSP_DECODING_SUCCESS != retval)
431                                                 {
432                                                         TIZEN_LOGD("HTTP Decoding Error");
433                                                         break;
434                                                 }
435
436                                                 TIZEN_LOGD("HTTP Response in Watch Dog is SUCCESS");
437                                                 contLength = atol(httprsp.contLen);
438
439                                                 if(httprsp.connection != NULL)
440                                                         connType = strncmp(httprsp.connection, "close", strlen("close"));
441
442                                                 if(connType != 0)
443                                                 {
444                                                         TIZEN_LOGD("Connection Type is Not CLOSE");
445                                                         connType = 1;
446                                                 }
447                                                 endTime = get_time_in_microsec();
448                                                 timeT2 = (endTime-startTime)/1000;
449
450                                                 resp_offset = offset + rcvdLen;
451                                                 resp_len = len + 4;
452                                                 TIZEN_LOGD("Response Lenght in Watch dog [%d] and Data Read till Now [%d]",resp_len, resp_offset);
453                                                 break;
454                                         }
455                                         offset = offset + rcvdLen;
456                                         if(offset >= MAX_HEADERS_SIZE)
457                                                 break;
458                                 }
459                                 else
460                                 {
461                                         /* Socket error */
462                                         break;
463                                 }
464                         }
465                         delete_http_rsp(&httprsp);
466                         if(retval_watch_dog == 1)
467                                 break;
468                 }
469         }
470         if(endTime == 0)
471         {
472                 TIZEN_LOGD("End Time is Zero");
473                 /* Error condtion abort multisocket(This interface is not stable) */
474                 retval = -1;
475         }
476         else
477         {
478                 /* Compair the time between two interfaces */
479                 retval = check_speed(SBData, timeT2, resp_offset, resp_len, recv_buf, socket, contLength);
480
481                 if(retval == 0)
482                 {
483                         retval = connType;
484                 }
485         }
486
487         CLOSE_SOCKET(socket);
488
489         if((store_interface_ip_request(newReq, SBData, interface_index) == 0))
490         {
491                 SBData->watch_dog_complete = 1;
492         }
493
494         free(newReq);
495
496         TIZEN_LOGD("RETURN VALUE [%d]",retval);
497         return retval;
498 }
499
500 int32 check_speed(SmartBondingData *SBData, uint32 timeT2, uint32 resp_offset,
501                                                                                 uint32 resp_len, int8 *recv_buf, int32 socket, uint64 contLength)
502 {
503         int32 retval = 0;
504         StatDetails *stat = &(SBData->stat);
505
506         if(stat->timeT1 > (5 * timeT2))
507         {
508                 /* Watch Dog Socket Becomes Main Socket */
509                 TIZEN_LOGD("Interface 2 Much Faster Than Interaface 1");
510                 //CLOSE_SOCKET(SBData->socket_fd);
511                 //SBData->socket_fd = 0;
512                 //retval = -1;
513         }
514         else if(timeT2 > (5 * stat->timeT1))
515         {
516                 TIZEN_LOGD("IF 1 much faster than 2 abort \n");
517                 /* Abort multi socket */
518                 //retval = -1;
519         }
520         return retval;
521 }
522
523 int32 get_bytesof_range_request(uint64 *start, int8 *rangeHeader)
524 {
525         int32 len = 0;
526         int8 *i1 = NULL;
527         int8 *i2 = NULL;
528         int8 *i3 = NULL;
529         int8 *i4 = NULL;
530         int8 temp1[100] = {0};
531
532         len = decode_http_find_str(rangeHeader, "bytes");
533         if (len != -1)
534         {
535                 i1 = strchr(rangeHeader, '=');
536                 i2 = strchr(rangeHeader, '-');
537                 i3 = strrchr(rangeHeader, '-');
538                 i4 = strchr(rangeHeader, ',');
539
540                 if ((i1 == 0) || (i2 == 0) || ((i1+1) >= i2) || (i2 != i3) || (i4!=0))
541                 {
542                         return B_FALSE;
543                 }
544                 else
545                 {
546                         strncpy(temp1, rangeHeader + 6, ((i2 -i1)-1));
547                         *start = atol(temp1);
548                         return B_TRUE;
549                 }
550         }
551         else
552         {
553                 return B_FALSE;
554         }
555 }
556
557 int32 is_connection_header_keepalive(SmartBondingData *SBData)
558 {
559         if (SBData->resp.connection != NULL)
560         {
561                 if (strcmp(SBData->resp.connection, "Keep-Alive") == 0)
562                         return 1;
563         }
564         return 0;
565 }
566
567 CThread * cthread_init()
568 {
569         CThread *cthread = malloc(sizeof(CThread));
570         if(cthread == NULL)
571         {
572                 TIZEN_LOGD("Error !!! cthread allocation failed [%d] [%s]", errno, strerror(errno));
573                 return NULL;
574         }
575         memset(cthread,0,sizeof(CThread));
576         cthread->threadId = 0;
577         return cthread;
578 }
579
580 void cthread_start_thread(SmartBondingData *SBData)
581 {
582         int32 ECode = 0;
583         pthread_t thread = 0;
584         CThread *cthread = SBData->cthread;
585         TIZEN_D_LOGD("Starting Thread");
586         if ((ECode = pthread_create(&thread, NULL, cthread_entry_function, (void *)SBData)) != 0)
587         {
588                 TIZEN_LOGD("Error !!! creating pthread [%d] [%s]", errno, strerror(errno));
589                 cthread_exit(cthread);
590         }
591         else
592         {
593                 TIZEN_D_LOGD("Init Watch Dog Thread ");
594                 cthread->threadStatus = THREAD_INIT;
595                 cthread->threadId = thread;
596         }
597 }
598
599
600 void * cthread_entry_function (void *pArg)
601 {
602         if(pArg)
603         {
604                 SmartBondingData *SBData = (SmartBondingData *)pArg;
605                 if(SBData->twoChunk == 1)
606                         file_cthread_run_thread(SBData);
607                 else
608                         cthread_run_thread(SBData);
609         }
610         else
611         {
612                 cthread_exit((CThread *)pArg);
613         }
614         return 0;
615 }
616
617 int32 cthread_get_thread_status(CThread *cthread)
618 {
619         return cthread->threadStatus;
620 }
621
622 void cthread_exit(CThread *cthread)
623 {
624         TIZEN_LOGD("Cthread Exit\n");
625         if(cthread != NULL)
626         {
627                 if(cthread->threadStatus == THREAD_INIT)
628                         usleep(100000);
629                 cthread->threadStatus = THREAD_FINISH;
630                 if(0 != cthread->threadId)
631                         pthread_join(cthread->threadId,NULL);
632                 cthread->threadId = 0;
633                 free(cthread);
634                 cthread = NULL;
635         }
636 }
637
638 int32 get_req_without_range(int8 *oldReq, int8 *newReq, int8 *rangeHeader, uint64 *rangeStart)
639 {
640         int32 len = 0;
641         int32 tempLen = 0;
642         int8 *temp = NULL;
643
644         if (get_bytesof_range_request(rangeStart, rangeHeader))
645         {
646                 len = decode_http_find_str(oldReq, RANGELEN_REQ_HEADER_CMP1);
647                 if(len == -1)
648                         len = decode_http_find_str(oldReq, RANGELEN_REQ_HEADER_CMP2);
649                 tempLen = len;
650                 memcpy(newReq, oldReq, len);
651                 TIZEN_LOGD ("Before Range [%s] Range Header [%s]", newReq, rangeHeader);
652                 temp = oldReq + len;
653                 if(!(decode_http_find_str(temp, END_OF_LINE) == decode_http_find_str(temp, END_OF_HEADERS)))
654                 {
655                         /*this will bring to point after Rnage header*/
656                         len = decode_http_find_str(temp, END_OF_LINE);
657                         temp = temp + len + 2;
658                 }
659                 else
660                 {
661                         len = decode_http_find_str(temp, END_OF_HEADERS);
662                         temp = temp + len + 2;
663                 }
664                 memcpy(newReq + tempLen, temp, strlen(temp));
665                 TIZEN_LOGD ("Successfully removed range header [%s]", newReq);
666                 return strlen(newReq);
667         }
668         else
669         {
670                 free(newReq);
671                 newReq = NULL;
672                 return 0;
673         }
674 }
675
676
677 #ifdef TIZEN_UX_SUPPORT
678 static void _smart_bonding_start_cb(smbd_event_info_t event, void *user_data)
679 {
680         TIZEN_LOGD("start bonding cb \n");
681         SmartBondingData *SBData = (SmartBondingData *)user_data;
682         switch (event.Event) {
683         case SMBD_EVENT_USER_OPTION_OK:
684                 if(SBData != NULL)
685                         SBData->user_option = USER_OK;
686                 break;
687         case SMBD_EVENT_USER_OPTION_CANCEL:
688                 if(SBData != NULL)
689                         SBData->user_option = USER_CANCEL;
690                 break;
691         default:
692                 break;
693         }
694 }
695
696 int32 user_selection(SmartBondingData *SBData)
697 {
698         int32 retval = B_FALSE;
699         int status = VCONFKEY_NETWORK_CELLULAR_NO_SERVICE;
700         CThread *cthread = SBData->cthread;
701         TIZEN_LOGD("Test For Tizen Ux Support");
702         if(!(smartbonding_client_init()))
703                 return retval;
704
705         TIZEN_LOGD("INIT UX Library User Option");
706
707         while(SBData->response_check == 0 && cthread->threadStatus != THREAD_FINISH)
708         {
709                 if(cthread->threadStatus != THREAD_FINISH)
710                         usleep(10000);
711                 else
712                         return retval;
713         }
714
715         vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &status);
716
717         TIZEN_LOGD("current LTE status [%d] and Expected LTE Status [%d]", status, VCONFKEY_NETWORK_CELLULAR_ON);
718
719         while(((status) != VCONFKEY_NETWORK_CELLULAR_ON) && (cthread->threadStatus != THREAD_FINISH))
720         {
721                 TIZEN_D_LOGD("LTE Data pack Off");
722                 usleep(100000);
723                 status = VCONFKEY_NETWORK_CELLULAR_NO_SERVICE;
724                 vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &status);
725         }
726
727         TIZEN_LOGD("Data Pack On status [%d]", status);
728
729         if (smart_bonding_start(SBData->req.url, SBData->resp.cLen, _smart_bonding_start_cb, (void *)SBData) !=  SMBD_ERR_NONE)
730         {
731                 TIZEN_LOGD("Start Bonding API failed");
732                 return retval;
733         }
734
735         TIZEN_LOGD("Start Bonding API success");
736         SBData->user_option = USER_POP_UP;
737
738         while(SBData->user_option == USER_POP_UP && cthread->threadStatus != THREAD_FINISH)
739         {
740                 if(cthread->threadStatus != THREAD_FINISH)
741                         usleep(10000);
742                 else
743                         return retval;
744         }
745
746         if(SBData->user_option != USER_OK)
747         {
748                 TIZEN_LOGD("User selected cancel");
749                 return retval;
750         }
751
752         retval  = B_TRUE;
753         TIZEN_LOGD("User selected OK");
754         return retval;
755 }
756 #endif
757
758 void file_cthread_run_thread(SmartBondingData *SBData)
759 {
760         uint32 bIsUp = 0;
761         uint32 bFileStreamStarted = 0;
762         uint64 speed_time = get_time_in_sec();
763         connection *conn = &(SBData->conn);
764         CThread *cthread = SBData->cthread;
765         cthread->threadStatus = THREAD_RUNNING;
766         float ratio =  0; /* Ratio of Wifi/LTE speed */
767         uint32 wifiSpeed = 0;
768         uint32 lteSpeed = 0;
769         uint64 expected_bytes = 0;
770         FILE *fp = NULL;
771
772         if(SBData->interface_index == 1)
773         {
774                 TIZEN_LOGD("Main Interface is LTE");
775                 return;
776         }
777
778 #ifdef TIZEN_UX_SUPPORT
779         if(!user_selection(SBData))
780                 return;
781 #endif
782
783         fp= fopen("/opt/usr/media/Ratiostat", "r");
784
785         if (fp != NULL)
786         {
787                 int32 nitems = 0;
788                 nitems = fscanf (fp, "%u %u",&lteSpeed,&wifiSpeed);
789                 nitems = nitems;
790                 TIZEN_LOGD("LTE SPEEED IS [%u] and WIFI SPEED IS [%u]",lteSpeed,wifiSpeed);
791                 if( (lteSpeed != 0) && ( wifiSpeed != 0))
792                 {
793                         ratio = (double)lteSpeed/(double)wifiSpeed;
794                 }
795                 TIZEN_LOGD("Ratio of Previous Download From History %f", ratio);
796         }
797         else
798         {
799                 TIZEN_LOGD("Failed to Open History previous Download");
800         }
801
802         while ((cthread->threadStatus != THREAD_FINISH) && ((SBData->resp.cLen - SBData->response_body_read) > (MULTIRAT_LOWER_LIMIT_TWO_CHUNK * 2)))
803         {
804                 if(ratio > 0)
805                 {
806                         ratio = MAX(0.1, MIN(10,ratio));
807                         expected_bytes = ((SBData->resp.cLen - SBData->response_body_read)/(ratio + 1));
808                 }
809                 else
810                         expected_bytes  = (SBData->resp.cLen - SBData->response_body_read)/2;
811
812                 expected_bytes += SBData->response_body_read;
813
814                 bIsUp = is_both_interface_avail(conn->ifaceInfo,conn->ip_family);
815                 if (bIsUp)
816                 {
817                         SBData->expectedbytes  = expected_bytes;
818                         TIZEN_LOGD("Expected Bytes [%llu]", SBData->expectedbytes);
819
820                         file_stream_init(SBData);
821
822                         if((bFileStreamStarted = file_stream_start(SBData)))
823                         {
824                                 SBData->fileThreadStarted = bFileStreamStarted;
825                                 TIZEN_LOGD("File Stream Started [%d]",bFileStreamStarted);
826                                 break;
827                         }
828                 }
829                 usleep(10000);
830         }
831
832         if(!(SBData->fileThreadStarted))
833                 return;
834
835         while (cthread->threadStatus != THREAD_FINISH)
836         {
837                 uint32 status = 0;
838
839                 status = speed_calc_check_compare(&speed_time, SBData);
840
841                 if(!status)
842                         break;
843
844                 usleep(20000);
845         }
846
847         cthread->threadStatus = THREAD_FINISH;
848         return ;
849 }
850
851 void cthread_run_thread(SmartBondingData *SBData)
852 {
853         uint32 bIsUp = 0;
854         uint32 chunk_div = 0;
855         uint32 min_chunk = 0;
856         uint32 max_chunk = 0;
857         uint32 bMultiSocketStarted = 0;
858         uint64 bytesForMultiSocket = 0;
859         int32 conn_type = 0;
860         connection *conn = &(SBData->conn);
861         MultiSockInput mSockInput;
862         CThread *cthread = SBData->cthread;
863         cthread->threadStatus = THREAD_RUNNING;
864         /* NOT USED FOR 2 chunk approach */
865
866         if(SBData->interface_index == 1)
867         {
868                 TIZEN_LOGD("Main Interface is LTE");
869                 return;
870         }
871
872 #ifdef TIZEN_UX_SUPPORT
873         if(!user_selection(SBData))
874                 return;
875 #endif
876
877         bytesForMultiSocket = SBData->resp.cLen - SBData->response_body_read;
878
879         while ((cthread->threadStatus != THREAD_FINISH) && (bytesForMultiSocket > MULTIRAT_LOWER_LIMIT))
880         {
881                 bIsUp = is_both_interface_avail(conn->ifaceInfo,conn->ip_family);
882                 if (bIsUp)
883                 {
884                         memset(&mSockInput, 0, sizeof(mSockInput));
885
886                         conn_type = watchdog_test_connection_type(SBData);
887                         if(conn_type == 1)
888                         {
889                                 chunk_div = MULTIRAT_BLOCK_DIV;
890                                 max_chunk = MAX_MULTIRAT_BLOCK_SIZE;
891                         }
892                         else if(conn_type == 0)
893                         {
894                                 chunk_div = 2;
895                                 max_chunk = MULTIRAT_CHUNK_SIZE;
896                         }
897                         else
898                         {
899                                 TIZEN_LOGD("Aborting watch dog");
900                                 break;
901                         }
902
903                         while(SBData->response_check == 0)
904                         {
905                                 if(cthread->threadStatus != THREAD_FINISH)
906                                         usleep(10000);
907                                 else
908                                         break;
909                         }
910
911                         min_chunk = MIN_MULTIRAT_BLOCK_SIZE;
912
913                         mSockInput.rspOffset = SBData->response_body_read + EXPECTED_BYTE;
914                         bytesForMultiSocket = SBData->resp.cLen - mSockInput.rspOffset;
915                         mSockInput.chunkSize = bytesForMultiSocket/chunk_div;
916                         mSockInput.conn = conn;
917
918                         if (mSockInput.chunkSize > max_chunk)
919                                 mSockInput.chunkSize = max_chunk;
920                         else if (mSockInput.chunkSize < min_chunk)
921                                 mSockInput.chunkSize =  min_chunk;
922
923
924                         if(bytesForMultiSocket > (mSockInput.chunkSize))
925                         {
926                                 multirat_watchdogthread_calnochunks(mSockInput.chunkSize,
927                                                 &mSockInput.noOfChunks, &mSockInput.lastChunk, bytesForMultiSocket);
928                         }
929                         else
930                         {
931                                 TIZEN_LOGD("Size too small ignoring this content");
932                                 break;
933                         }
934
935                         TIZEN_LOGD("No of Chunks = [%d],Chunk Size = [%d] bytesForMultiSocket = [%llu]",
936                                         mSockInput.noOfChunks, mSockInput.chunkSize, bytesForMultiSocket);
937
938                         multisocket_init(&mSockInput, SBData);
939                         if ((bMultiSocketStarted = multisocket_start(SBData)))
940                         {
941                                 TIZEN_LOGD ("MultiSocket  started [%d]", bMultiSocketStarted);
942                                 SBData->totalExpectedBytes = SBData->msocket->rspOffset;
943                                 SBData->multiSocketThreadStarted = bMultiSocketStarted;
944                                 break;
945                         }
946                         else
947                         {
948                                 TIZEN_LOGD ("MultiSocket  failed");
949                                 multisocket_exit(SBData->msocket);
950                                 SBData->msocket = NULL;
951                                 break;
952                         }
953                 }
954                 usleep(SLEEP_TIME);
955                 if(SBData->response_check !=0)
956                         bytesForMultiSocket = SBData->resp.cLen - SBData->response_body_read;
957         }
958         cthread->threadStatus = THREAD_FINISH;
959         return ;
960 }
961
962 void multirat_watchdogthread_calnochunks(uint32 chunkSize, uint32 *noOfChunks, uint32 *lastChunk, uint64 totalSize)
963 {
964         uint32 min = 0;
965         uint32 tempChunk = 0;
966         uint32 tempTotalChunks = 0;
967
968         TIZEN_LOGD("Multirat Watchdog Thread CalNoChunks");
969
970         tempChunk = (totalSize % chunkSize);
971         min = MIN((chunkSize/3), MIN_LAST_CHUNK);
972         if((0 != tempChunk) && (tempChunk < min))
973         {
974                 tempTotalChunks = (totalSize/chunkSize);
975                 tempChunk = chunkSize + tempChunk;
976                 TIZEN_LOGD("Last Chunk Size Changed");
977         }
978         else
979         {
980                 TIZEN_LOGD("Last Chunk Size not Chnaged");
981                 if(0 == tempChunk)
982                 {
983                         tempTotalChunks = (totalSize/chunkSize);
984                 }
985                 else
986                 {
987                         tempTotalChunks = (totalSize/chunkSize) + 1;
988                 }
989                 tempChunk = 0;
990         }
991         *lastChunk = tempChunk;
992         *noOfChunks = tempTotalChunks;
993 }
994