tizen 2.3 release
[framework/connectivity/multirat.git] / src / multirat_file_manager.c
1 #include "multirat_file_buffer.h"
2 #include "multirat_file_manager.h"
3 #include "multirat_process.h"
4 #include "multirat_conf.h"
5 #include "multirat_process.h"
6 #define MAX_TIMEFORALL_BY0 5
7 #define MAX_TIMEFORALL_BY1 4
8
9 #define SAME_INTERFACE_NO_DIVIDE 0
10 #define CHANGE_INTERFACE_NO_DIVIDE 2
11 #define DIVIDE 1
12
13 void file_manager_init(fileStream *fStream, fileManager *fileMgr)
14 {
15         fileMgr->ExpectedBytes = (fStream->mainSockExpBytes);
16         fileMgr->rspRead = fStream->mainSockRead;
17         fileMgr->totalLen = fStream->totalLen;
18         fileMgr->strtOffset = fStream->strtOffset;
19         fileMgr->fbuffer = &fStream->fileBuff;
20         fileMgr->thread_exception = B_FALSE;
21         pthread_mutex_init(&(fileMgr->mutex), NULL);
22 }
23
24 fileBuffer *file_manager_getNextChunkForFileThread(int64 *chunkInfo, SmartBondingData *SBData)
25 {
26         fileManager *fileMgr = SBData->fStream->fileMgr;
27         fileStream *fStream = SBData->fStream;
28         fileThread *fThread = fStream->fThread;
29         fileBuffer *newfileBuf = NULL;
30
31         pthread_mutex_lock(&(fileMgr->mutex));
32         TIZEN_LOGD("Get Next Chunk For File Thread");
33
34         // This is First Chunk Alloted for the File Thread
35         if(*fileMgr->fbuffer == NULL)
36         {
37                 TIZEN_LOGD("First Chunk");
38                 chunkInfo[0] = *fileMgr->ExpectedBytes + fileMgr->strtOffset;
39                 chunkInfo[1] =  fileMgr->totalLen - 1 + fileMgr->strtOffset;
40
41                 newfileBuf = (fileBuffer *)malloc(sizeof(fileBuffer));
42                 if(newfileBuf == NULL)
43                 {
44                         TIZEN_LOGD("File Buffer Allocation Failed");
45                         pthread_mutex_unlock(&(fileMgr->mutex));
46                         return NULL;
47                 }
48                 memset(newfileBuf, 0, sizeof(fileBuffer));
49                 file_buffer_init_node(newfileBuf, chunkInfo, -1, FILE_NODE, SBData, 0);
50                 newfileBuf->next = NULL;
51                 *fileMgr->fbuffer = newfileBuf;
52
53                 TIZEN_LOGD("New Node Created [%x] and Total length [%llu] New Node [%x]", newfileBuf, file_buffer_getTotalLen(newfileBuf), fStream->fileBuff);
54         }
55         // This is For handling the case where File Thread just comes up and starts downloading but main is reading File Buffer ...
56         // In that it will continue to use File Buffer:
57         // IO Exception of Main Thread And IO exception of File Thread handled Similarly
58         if(SBData->status == MAIN_COMPLETE)
59         {
60                 TIZEN_LOGD("Main Complete");
61                 fThread->status = MAIN_COMPLETE;
62         }
63         // This is Handling Case When File Thread vitness IO Exception or Main Thread IO Exception
64         if(fThread->status == FILE_IO_EXCEPTION)
65         {
66                 TIZEN_LOGD("File Io Exception");
67                 newfileBuf = file_manager_get_next_chunk_handle_file_io_exception(fileMgr, chunkInfo);
68         }
69
70         // This is For Handling Case When Main Thread is Complete
71         else if(fThread->status == MAIN_COMPLETE)
72         {
73                 TIZEN_LOGD("Main Thread Completed");
74                 newfileBuf = file_manager_get_next_chunk_handle_main_complete(fileMgr, chunkInfo);
75         }
76
77         // This is For Handling Case When File Thread has Finished
78         else if(fThread->status == FILE_COMPLETE)
79         {
80                 TIZEN_LOGD("File Thread Complete");
81                 newfileBuf = file_manager_get_next_chunk_handle_file_complete(fileMgr, chunkInfo);
82         }
83
84         // Finally Setting main thread Status to Start
85         SBData->status = MAIN_START;
86         pthread_mutex_unlock(&(fileMgr->mutex));
87         return newfileBuf;
88 }
89
90
91 fileBuffer *file_manager_getReadingNode(fileManager *fileMgr)
92 {
93         fileBuffer *tempBuff = *fileMgr->fbuffer;
94         uint32 state = 0;
95
96         while(tempBuff != NULL)
97         {
98                 state = file_buffer_getState(tempBuff);
99                 if(state == NODE_STATE_DOWNLOADING || state == NODE_STATE_BLOCKED || state == NODE_STATE_FULL_READ)
100                 {
101                         break;
102                 }
103                 tempBuff = tempBuff->next;
104         }
105         return tempBuff;
106 }
107
108
109 fileBuffer *file_manager_getDownloadingNode(fileManager *fileMgr)
110 {
111         fileBuffer *tempBuff = *fileMgr->fbuffer;
112         uint32 state = 0;
113
114         while(tempBuff != NULL)
115         {
116                 state = file_buffer_getState(tempBuff);
117                 if(state == NODE_STATE_DOWNLOADING || state == NODE_STATE_BLOCKED)
118                 {
119                         break;
120                 }
121                 tempBuff = tempBuff->next;
122         }
123         return tempBuff;
124 }
125
126 fileBuffer *file_manager_getDownloadingFileNode(fileManager *fileMgr)
127 {
128         fileBuffer *tempBuff = *fileMgr->fbuffer;
129         uint32 state = 0;
130         uint32 type = 0;
131         while(tempBuff != NULL)
132         {
133                 state = file_buffer_getState(tempBuff);
134                 type = file_buffer_getType(tempBuff);
135                 if((state == NODE_STATE_DOWNLOADING || state == NODE_STATE_BLOCKED) && (type == FILE_NODE))
136                 {
137                         break;
138                 }
139                 tempBuff = tempBuff->next;
140         }
141         TIZEN_LOGD("Download File Node [%x]",tempBuff);
142         return tempBuff;
143 }
144
145 uint32 file_manager_divideCont(uint64 remCont, int64 *contInfo, fileManager *fileMgr, uint32 nodeType)
146 {
147         double temp2 = 0;
148         uint64 temp = 0;
149         SmartBondingData *SBData = fileMgr->SBData;
150         uint32 other_index = 0;
151
152         uint32 index_main = file_manager_get_main_thread_interface(fileMgr);
153         uint32 index_file = file_manager_get_file_thread_interface(fileMgr);
154
155         uint64 interfaceSpeed0 = 0;
156         uint64 interfaceSpeed1 = 0;
157
158         if(nodeType == FILE_NODE)
159         {
160                 other_index = index_main;
161                 interfaceSpeed0 = SBData->speed[index_file];
162                 interfaceSpeed1 = SBData->speed[index_main];
163         }
164         else
165         {
166                 other_index = index_file;
167                 interfaceSpeed1 = SBData->speed[index_file];
168                 interfaceSpeed0 = SBData->speed[index_main];
169         }
170
171         uint64 temp_cal = 0;
172         uint64 temp_time0 = 0;
173         double ratio = 0;
174         uint64 time0= 0;
175         uint64 time1= 0;
176         if(interfaceSpeed1)
177                 ratio = MAX(0.1, MIN(10,(float)interfaceSpeed0/(float)interfaceSpeed1));
178         else
179         {
180                 TIZEN_LOGD("ratio assigned 10 value as interfaceSpeed1 is 0");
181                 ratio = 10;
182         }
183
184         TIZEN_LOGD("RemainContent [%llu] Interface0 Speed [%llu] Interface1 Speed [%llu] Ratio [%lf]", remCont, interfaceSpeed0, interfaceSpeed1, ratio);
185         temp2 = (float)(remCont)/(ratio + 1);
186         temp = abs(temp2);
187         time0 = (temp2 * 8 )/interfaceSpeed0;
188         time1 = (temp2 * 8 )/interfaceSpeed1;
189
190         TIZEN_LOGD("temp [%llu] temp2 [%lf] time0 [%llu] time1 [%llu]", temp, temp2,time0,time1);
191
192
193         temp_time0 = ((remCont - temp)*8)/interfaceSpeed0;
194         TIZEN_LOGD("temp_time0 [%llu]", temp_time0);
195
196         // 2 sec for slow start
197         if(time0 < 2)
198         {
199                 TIZEN_LOGD("Time Less Than 2 Sec, same inter. no divide");
200                 return SAME_INTERFACE_NO_DIVIDE;
201         }
202         else
203         {
204                 TIZEN_LOGD("Dividing");
205                 /* Stores the seconds for which we have initial bytes captured for this interface */
206                 uint64 new_connection_slow_time = MIN(SBData->sStat.timeArray[other_index], MAX_HISTORY-1);
207                 uint64 bytes_loss1 = 0;
208                 uint64 bytes_loss0 = 0;
209
210                 if(time1 < new_connection_slow_time)
211                         new_connection_slow_time = time1;
212
213                 uint64 bytes_speed = 0; /* Bytes based on speed in specific time */
214                 uint64 bytes_loss_slow_start = 0; /* Bytes loss as connection was in slow start initially */
215                 /* Initial new_connection_slow_time seconds we get only below bytes in temp_cal */
216                 temp_cal = SBData->sStat.dataArray[other_index][new_connection_slow_time];
217
218                 /* As per the interfacespeed we should get this many bytes*/
219                 bytes_speed = new_connection_slow_time * interfaceSpeed1/8;
220                 if(bytes_speed > temp_cal)
221                         bytes_loss_slow_start = bytes_speed - temp_cal;
222
223                 /* Now we should divide again this more load bytes_loss_slow_start on other_index
224                 across two interfaces, so divide this in two parts based on speed ration and
225                 now see  */
226                 bytes_loss1 = (float)(bytes_loss_slow_start)/(ratio + 1);
227                 bytes_loss0 = bytes_loss_slow_start - bytes_loss1;
228                 if(temp > bytes_loss0)
229                         temp -= bytes_loss0;
230
231                 TIZEN_LOGD("new_conn_slow [%llu] loss0 [%llu] loss1 [%llu] bytes_speed [%llu], temp_cal [%llu], bytes_loss_slow_start [%llu] temp [%llu]", new_connection_slow_time, bytes_loss0, bytes_loss1, bytes_speed,temp_cal, bytes_loss_slow_start, temp);
232
233                 contInfo[1] = temp;
234                 contInfo[0] = remCont - temp;
235         }
236         TIZEN_LOGD("First Part [%lld] Second part [%lld]", contInfo[0], contInfo[1]);
237         return DIVIDE;
238 }
239
240 uint32 file_manager_divideRemCont(uint64 remCont, fileManager *fileMgr, uint32 nodeType)
241 {
242         TIZEN_LOGD("Divide remCont [%llu]", remCont);
243         SmartBondingData *SBData = fileMgr->SBData;
244         uint32 index_main = file_manager_get_main_thread_interface(fileMgr);
245         uint32 index_file = file_manager_get_file_thread_interface(fileMgr);
246         uint32 other_index = 0;
247         uint64 temp_data1 = 0;
248         if(SBData->division_count++ > 5)
249         {
250                 TIZEN_LOGD("MAX DIVISION COUNT REACHED...  No more division ");
251                 return SAME_INTERFACE_NO_DIVIDE;
252         }
253         TIZEN_LOGD("DIVISION COUNT is [%d]",SBData->division_count);
254
255         if(remCont > (MAX_BLOCK_SIZE* 4))
256         {
257                 double interfaceTime0 = 0;
258                 double interfaceTime1 = 0;
259                 uint64 interfaceSpeed0 = 0;
260                 uint64 interfaceSpeed1 = 0;
261
262                 if(nodeType == FILE_NODE)
263                 {
264                         other_index = index_main;
265                         if((SBData->speed[index_file] == 0))
266                         {
267                                 TIZEN_LOGD("idx main [%d] file [%d] speed file index 0, CHANGE_INTERFACE_NO_DIVIDE", index_main, index_file);
268                                 return CHANGE_INTERFACE_NO_DIVIDE;
269                         }
270                         if((SBData->speed[index_main] == 0))
271                         {
272                                 TIZEN_LOGD("idx main [%d] file [%d] speed main index 0, SAME_INTERFACE_NO_DIVIDE", index_main, index_file);
273                                 return SAME_INTERFACE_NO_DIVIDE;
274                         }
275                         interfaceSpeed0 = SBData->speed[index_file];
276                         interfaceSpeed1 = SBData->speed[index_main];
277                         interfaceTime0 = (float)(remCont*8)/ (float)interfaceSpeed0;
278                         interfaceTime1 = (float)(remCont*8)/ (float)interfaceSpeed1;
279                 }
280                 else
281                 {
282                         other_index = index_file;
283                         if((SBData->speed[index_main] == 0))
284                         {
285                                 TIZEN_LOGD("Skt idx main [%d] file [%d] speed main index 0, CHANGE_INTERFACE_NO_DIVIDE", index_main, index_file);
286                                 return CHANGE_INTERFACE_NO_DIVIDE;
287                         }
288                         if((SBData->speed[index_file] == 0))
289                         {
290                                 TIZEN_LOGD("Skt idx main [%d] file [%d] speed file index 0, SAME_INTERFACE_NO_DIVIDE", index_main, index_file);
291                                 return SAME_INTERFACE_NO_DIVIDE;
292                         }
293                         interfaceSpeed1 = SBData->speed[index_file];
294                         interfaceSpeed0 = SBData->speed[index_main];
295                         interfaceTime1 = (float)(remCont*8)/ (float)interfaceSpeed1;
296                         interfaceTime0 = (float)(remCont*8)/ (float)interfaceSpeed0;
297                 }
298
299                 TIZEN_LOGD("Interface0 Speed [%llu] Interface1 Speed [%llu]", interfaceSpeed0, interfaceSpeed1);
300                 TIZEN_LOGD("Interface0 Time [%lf] Interface1 time [%lf]", interfaceTime0, interfaceTime1);
301                 TIZEN_LOGD("Time Array Other Interface Index [%llu]", SBData->sStat.timeArray[other_index]);
302                 if(SBData->sStat.timeArray[other_index] < MAX_TIMEFORALL_BY1)
303                 {
304
305                         temp_data1 = SBData->sStat.dataArray[other_index][SBData->sStat.timeArray[other_index]] + (interfaceSpeed1 *
306                         (MAX_TIMEFORALL_BY1 - SBData->sStat.timeArray[other_index]))/8;
307                 }
308                 else
309                 {
310                         temp_data1 = SBData->sStat.dataArray[other_index][MAX_TIMEFORALL_BY1];
311                 }
312
313                 TIZEN_LOGD("tmpdata1 Data in 4 secs [%llu]", temp_data1);
314                 if(interfaceTime0 < MAX_TIMEFORALL_BY0)
315                 {
316                         TIZEN_LOGD("The Current interface Time Less Than 5");
317                         return SAME_INTERFACE_NO_DIVIDE;
318                 }
319                 else if((interfaceTime1 < MAX_TIMEFORALL_BY1) && (remCont <= temp_data1))
320                 {
321                         TIZEN_LOGD("Other interface Time Less Than 4");
322                         return CHANGE_INTERFACE_NO_DIVIDE;
323                 }
324                 else if(interfaceSpeed1 < 2000)
325                 {
326                         TIZEN_LOGD("Speed of other Interface is less");
327                         return SAME_INTERFACE_NO_DIVIDE;
328                 }
329                 else if(interfaceSpeed0 < 2000)
330                 {
331                         TIZEN_LOGD("Speed of This Interface is less");
332                         return CHANGE_INTERFACE_NO_DIVIDE;
333                 }
334                 return DIVIDE;
335         }
336         else
337         {
338                 TIZEN_LOGD("Remaing Content is Less");
339                 return SAME_INTERFACE_NO_DIVIDE;
340         }
341 }
342
343 void file_manager_setSpeed(uint32 index, uint32 speed, SmartBondingData *SBData)
344 {
345         SBData->speed[index] = speed;
346 }
347
348 void file_manager_exit(fileManager *fileMgr)
349 {
350         pthread_mutex_destroy(&(fileMgr->mutex));
351 }
352
353 uint32 file_manager_get_file_thread_interface(fileManager *fileMgr)
354 {
355         return  fileMgr->interface[FILE_THREAD];
356 }
357 uint32 file_manager_get_main_thread_interface(fileManager *fileMgr)
358 {
359         return fileMgr->interface[MAIN_THREAD];
360 }
361
362 uint32 file_manager_check_main_thread_status(fileManager *fileMgr)
363 {
364         return fileMgr->SBData->status;
365 }
366
367 fileBuffer * file_manager_get_next_chunk_handle_file_io_exception(fileManager *fileMgr, int64 *chunkInfo)
368 {
369         fileBuffer *tempBuff = file_manager_getDownloadingFileNode(fileMgr);
370         fileBuffer *newfileBuf = NULL;
371         if(tempBuff != NULL)
372         {
373                 pthread_mutex_lock(&(tempBuff->mut));
374                 uint64 socketOffset = file_buffer_getOffset(tempBuff);
375                 TIZEN_LOGD("Data in File Node is [%llu]", socketOffset);
376                 newfileBuf = tempBuff;
377                 chunkInfo[0] = tempBuff->startOffset + socketOffset;
378                 chunkInfo[1] = tempBuff->endOffset;
379                 file_buffer_reinit_node(newfileBuf, -1, FILE_NODE);
380                 pthread_mutex_unlock(&(tempBuff->mut));
381         }
382         return newfileBuf;
383 }
384
385 fileBuffer * file_manager_get_next_chunk_handle_main_complete(fileManager *fileMgr, int64 *chunkInfo)
386 {
387         fileBuffer *newfileBuf = NULL;
388         fileBuffer *tempBuff = file_manager_getDownloadingFileNode(fileMgr);
389         uint64 remContent = 0;
390         uint32 divide = B_FALSE;
391         int64 contInfo[2] = {0};
392
393         if(tempBuff != NULL)
394         {
395                 pthread_mutex_lock(&(tempBuff->mut));
396                 TIZEN_LOGD("Offset of Downloading File Buffer [%llu]", file_buffer_getOffset(tempBuff));
397                 uint64 socketOffset = file_buffer_getOffset(tempBuff);
398
399                 if(socketOffset == 0)
400                 {
401                         TIZEN_LOGD("Data in File Node is Zero Making as Socket Node");
402                         file_manager_SwitchSocketNoData(tempBuff, fileMgr);
403                         pthread_mutex_unlock(&(tempBuff->mut));
404                         return NULL;
405                 }
406
407                 remContent = file_buffer_getTotalLen(tempBuff) - socketOffset;
408                 TIZEN_LOGD("Remaining Content [%llu] offset [%llu]", remContent, socketOffset);
409
410                 divide =  file_manager_divideRemCont(remContent, fileMgr, FILE_NODE);
411                 //divide = 1;
412                 if(!divide)
413                 {
414                         TIZEN_LOGD("Make This File Node as Socket Node and Continue Downloading");
415                         TIZEN_LOGD("Data in File Node is Not Zero Creating New Socket Node and Use Same Interface");
416                         newfileBuf = file_manager_SwitchSocketData(tempBuff, fileMgr, chunkInfo, 0);
417                 }
418                 else
419                 {       //divide = 2;
420                         if(divide == CHANGE_INTERFACE_NO_DIVIDE)
421                         {
422                                 TIZEN_LOGD("Data in File Node is Not Zero Creating New Socket Node and Use Diff Interface");
423                                 newfileBuf = file_manager_SwitchSocketData(tempBuff, fileMgr, chunkInfo, 1);
424                         }
425                         else
426                         {
427                                 TIZEN_LOGD("Division According to Speed");
428                                 divide = file_manager_divideCont(remContent, contInfo, fileMgr, FILE_NODE);
429                                 TIZEN_LOGD("Divide [%d]",divide);
430                                 //divide = 1;
431                                 if(!divide)
432                                 {
433                                         TIZEN_LOGD("Data in File is not Zero, Creating new Socket Node and Use Same Interface");
434                                         newfileBuf = file_manager_SwitchSocketData(tempBuff, fileMgr, chunkInfo, 0);
435                                 }
436                                 else
437                                 {
438                                         TIZEN_LOGD("Need to Divide File Node");
439                                         fileBuffer *newfileBuftemp =  NULL;
440                                         TIZEN_LOGD("Data in File is not Zero, Make 3 Nodes");
441                                         file_buffer_setTotalLen(socketOffset, tempBuff);
442                                         TIZEN_LOGD("Set the Total Lenght to offset [%llu]", socketOffset);
443
444                                         check_set_filebuff_state(tempBuff);
445
446                                         newfileBuf = (fileBuffer *)malloc(sizeof(fileBuffer));
447                                         memset(newfileBuf, 0, sizeof(fileBuffer));
448                                         chunkInfo[0] = file_buffer_getStrtOffset(tempBuff) + file_buffer_getTotalLen(tempBuff);
449                                         chunkInfo[1] = chunkInfo[0] + contInfo[0] - 1;
450                                         TIZEN_LOGD("Start Offset [%llu] Total length [%llu]", file_buffer_getStrtOffset(tempBuff), file_buffer_getTotalLen(tempBuff));
451                                         TIZEN_LOGD("Chunk 0 [%lld] Chunk 1 [%lld] cont [%lld]", chunkInfo[0], chunkInfo[1], contInfo[0]);
452                                         //TIZEN_LOGD("ichunk 0 %lld ichunk 1 %lld cont %lld", chunkInfo[0], chunkInfo[1], contInfo[0]);
453                                         file_buffer_init_node(newfileBuf, chunkInfo, tempBuff->socketId, SOCKET_NODE, fileMgr->SBData, 0);
454                                         fileMgr->interface[MAIN_THREAD] = (fileMgr->interface[MAIN_THREAD] + 1) % 2;
455                                         fileMgr->interface[FILE_THREAD] = (fileMgr->interface[FILE_THREAD] + 1) % 2;
456                                         fileMgr->SBData->interface_index = fileMgr->interface[MAIN_THREAD];
457                                         newfileBuf->next = tempBuff->next;
458                                         tempBuff->next = newfileBuf;
459
460                                         TIZEN_LOGD("New Node Created [%x] and Total length [%llu]", newfileBuf, file_buffer_getTotalLen(newfileBuf));
461                                         newfileBuftemp = (fileBuffer *)malloc(sizeof(fileBuffer));
462                                         memset(newfileBuftemp, 0, sizeof(fileBuffer));
463
464                                         chunkInfo[0] = chunkInfo[1] + 1;
465                                         chunkInfo[1] = tempBuff->endOffset;
466
467                                         tempBuff->endOffset = file_buffer_getStrtOffset(tempBuff) + file_buffer_getTotalLen(tempBuff) - 1;
468
469                                         file_buffer_init_node(newfileBuftemp, chunkInfo, -1, FILE_NODE, fileMgr->SBData, 0);
470                                         newfileBuftemp->next = newfileBuf->next;
471                                         newfileBuf->next = newfileBuftemp;
472                                         newfileBuf = newfileBuftemp;
473                                         TIZEN_LOGD("New Node Created [%x] and Total length [%llu]", newfileBuf, file_buffer_getTotalLen(newfileBuf));
474                                 }
475                         }
476                 }
477                 pthread_mutex_unlock(&(tempBuff->mut));
478         }
479         return newfileBuf;
480 }
481
482 fileBuffer * file_manager_get_next_chunk_handle_file_complete(fileManager *fileMgr, int64 *chunkInfo)
483 {
484         fileBuffer *newfileBuf = NULL;
485         uint64 remContent = 0;
486         uint32 divide = B_FALSE;
487         int64 contInfo[2] = {0};
488
489         if(*fileMgr->rspRead < *fileMgr->ExpectedBytes)
490         {
491                 remContent = *fileMgr->ExpectedBytes - *fileMgr->rspRead;
492                 TIZEN_LOGD("File Thread Finished File Node ... Checking Dividing Expected Bytes [%llu] Remaing Content [%llu]", *fileMgr->ExpectedBytes, remContent);
493                 divide =  file_manager_divideRemCont(remContent, fileMgr, SOCKET_NODE);
494                 if(divide)
495                 {
496                         if(divide == CHANGE_INTERFACE_NO_DIVIDE)
497                         {
498                                 TIZEN_LOGD("No Need to Divide Main Socket Just Change Interface");
499                                 if(fileMgr->SBData->node_exception == 0) // Only if Main Socket is not going for exception Close this
500                                 {
501                                         CLOSE_SOCKET(fileMgr->SBData->socket_fd);
502                                 }
503                         }
504                         else
505                         {
506                                 TIZEN_LOGD("Division According to Speed");
507                                 if(file_manager_divideCont(remContent, contInfo, fileMgr, SOCKET_NODE))
508                                 {
509                                         newfileBuf = (fileBuffer *)malloc(sizeof(fileBuffer));
510                                         if(newfileBuf != NULL)
511                                         {
512                                                 memset(newfileBuf, 0, sizeof(fileBuffer));
513                                                 chunkInfo[1] = *fileMgr->ExpectedBytes - 1 + fileMgr->strtOffset;
514                                                 *fileMgr->ExpectedBytes = *fileMgr->rspRead + contInfo[0];
515                                                 chunkInfo[0] = *fileMgr->ExpectedBytes + fileMgr->strtOffset;
516                                                 file_buffer_init_node(newfileBuf, chunkInfo, -1, FILE_NODE, fileMgr->SBData, 0);
517                                                 /* Attach to head head */
518                                                 newfileBuf->next = *fileMgr->fbuffer;
519                                                 *fileMgr->fbuffer = newfileBuf;
520
521                                                 TIZEN_LOGD("New Node Created [%x] and Total length [%llu] Reduce Expected Bytes [%llu]", newfileBuf, file_buffer_getTotalLen(newfileBuf), *fileMgr->ExpectedBytes);
522                                         }
523                                 }
524                         }
525                 }
526         }
527         else
528         {
529                 TIZEN_LOGD("File Thread Dividing Socket Node");
530                 fileBuffer *tempBuff = file_manager_getDownloadingNode(fileMgr);
531                 if(tempBuff != NULL)
532                 {
533                         pthread_mutex_lock(&(tempBuff->mut));
534                         uint64 socketOffset = file_buffer_getOffset(tempBuff);
535                         remContent = file_buffer_getTotalLen(tempBuff) - socketOffset;
536                         TIZEN_LOGD("Rem Con [%llu] offset [%llu]",remContent, socketOffset);
537                         divide =  file_manager_divideRemCont(remContent, fileMgr, SOCKET_NODE);
538                         if(divide)
539                         {
540                                 if(divide == CHANGE_INTERFACE_NO_DIVIDE)
541                                 {
542                                         TIZEN_LOGD("No Need to Divide Socket Node Just Change Interface");
543
544                                         if(fileMgr->SBData->node_exception == 0) // Only if Main Socket is not going for exception Close this
545                                         {
546                                                 CLOSE_SOCKET(tempBuff->socketId);
547                                         }
548                                         //tempBuff->socketId = 0;
549                                 }
550                                 else
551                                 {
552                                         TIZEN_LOGD("Division According to Speed");
553                                         if(file_manager_divideCont(remContent, contInfo, fileMgr, SOCKET_NODE))
554                                         {
555                                                 newfileBuf = (fileBuffer *)malloc(sizeof(fileBuffer));
556                                                 if(newfileBuf != NULL)
557                                                 {
558                                                         memset(newfileBuf, 0, sizeof(fileBuffer));
559                                                         file_buffer_setTotalLen(socketOffset + contInfo[0], tempBuff);
560
561                                                         check_set_filebuff_state(tempBuff);
562
563                                                         chunkInfo[0] = file_buffer_getStrtOffset(tempBuff) + file_buffer_getTotalLen(tempBuff);
564                                                         chunkInfo[1] =  tempBuff->endOffset;
565
566                                                         tempBuff->endOffset = chunkInfo[0] - 1;
567
568                                                         TIZEN_LOGD("End Offset Node [%x] [%llu] Total length [%llu]", tempBuff, tempBuff->endOffset, file_buffer_getTotalLen(tempBuff));
569                                                         file_buffer_init_node(newfileBuf, chunkInfo, -1, FILE_NODE, fileMgr->SBData, 0);
570                                                         /* Attach new node after current node */
571                                                         newfileBuf->next = tempBuff->next;
572                                                         tempBuff->next = newfileBuf;
573                                                         TIZEN_LOGD("New Node Created [%x] and Total length [%llu]", newfileBuf, file_buffer_getTotalLen(newfileBuf));
574                                                 }
575                                         }
576                                 }
577                         }
578                         pthread_mutex_unlock(&(tempBuff->mut));
579                 }
580         }
581         return newfileBuf;
582 }
583
584 void file_manager_update_socket_node(uint64 offset, SmartBondingData *SBData)
585 {
586         fileBuffer *tempBuff = file_manager_getDownloadingNode(SBData->fStream->fileMgr);
587         TIZEN_LOGD("Socket Node [%x] setting offset [%llu] Socket [%d]", tempBuff, offset, SBData->socket_fd);
588         tempBuff->offset = tempBuff->offset + offset;
589         tempBuff->appReadLen = tempBuff->appReadLen + offset;
590         tempBuff->socketId = SBData->socket_fd;
591 }
592
593 void file_manager_SwitchSocketNoData(fileBuffer *tempBuff, fileManager *fileMgr)
594 {
595         if(tempBuff->fThread_read)
596         {
597                 TIZEN_LOGD("Created During File Thread socket Read");
598                 tempBuff->fThread_read = 0;
599                 fileMgr->interface[MAIN_THREAD] = (fileMgr->interface[MAIN_THREAD] + 1) % 2;
600                 fileMgr->interface[FILE_THREAD] = (fileMgr->interface[FILE_THREAD] + 1) % 2;
601                 fileMgr->SBData->interface_index = fileMgr->interface[MAIN_THREAD];
602         }
603
604         CLOSE_SOCKET(tempBuff->socketId);
605         tempBuff->socketId = -1;
606         file_buffer_reinit_node(tempBuff, -1, SOCKET_NODE);
607 }
608
609 fileBuffer *file_manager_SwitchSocketData(fileBuffer *tempBuff, fileManager *fileMgr, int64 *chunkInfo, int ifacechange)
610 {
611         fileBuffer *newfileBuf = (fileBuffer *)malloc(sizeof(fileBuffer));
612         uint32 newfilebuf_null = 0;
613         uint64 socketOffset = file_buffer_getOffset(tempBuff);
614         if(newfileBuf != NULL)
615         {
616                 memset(newfileBuf, 0, sizeof(fileBuffer));
617                 file_buffer_setTotalLen(socketOffset, tempBuff);
618                 check_set_filebuff_state(tempBuff);
619                 chunkInfo[0] = file_buffer_getStrtOffset(tempBuff) + file_buffer_getTotalLen(tempBuff);
620                 chunkInfo[1] =  tempBuff->endOffset;
621                 if(ifacechange == 0)
622                 {
623                         TIZEN_LOGD("No Need to Change Interface");
624                         if((tempBuff->bRafMode) || (tempBuff->fThread_read) || (socketOffset < MIN_FILE_NODE_SIZE))
625                         {
626                                 file_buffer_init_node(newfileBuf, chunkInfo, tempBuff->socketId, SOCKET_NODE, fileMgr->SBData, 0);
627                                 fileMgr->interface[MAIN_THREAD] = (fileMgr->interface[MAIN_THREAD] + 1) % 2;
628                                 fileMgr->interface[FILE_THREAD] = (fileMgr->interface[FILE_THREAD] + 1) % 2;
629                                 fileMgr->SBData->interface_index = fileMgr->interface[MAIN_THREAD];
630                                 newfilebuf_null = 1;
631                         }
632                         else
633                         {
634                                 TIZEN_LOGD("Raf Mode OFF making File Thread Read From Socket");
635                                 file_buffer_init_node(newfileBuf, chunkInfo, tempBuff->socketId, FILE_NODE, fileMgr->SBData, FILE_THREAD_SOCK_READ);
636                         }
637                 }
638                 else
639                 {
640                         TIZEN_LOGD("Change The Interface");
641                         if((tempBuff->bRafMode) || (tempBuff->fThread_read) || (socketOffset < MIN_FILE_NODE_SIZE))
642                         {
643                                 file_buffer_init_node(newfileBuf, chunkInfo, -1, SOCKET_NODE, fileMgr->SBData, 0);
644                                 newfilebuf_null = 1;
645                         }
646                         else
647                         {
648                                 TIZEN_LOGD("Raf Mode OFF Making File Thread Read From Socket");
649                                 file_buffer_init_node(newfileBuf, chunkInfo, -1, FILE_NODE, fileMgr->SBData, FILE_THREAD_SOCK_CREATE);
650                                 fileMgr->interface[MAIN_THREAD] = (fileMgr->interface[MAIN_THREAD] + 1) % 2;
651                                 fileMgr->interface[FILE_THREAD] = (fileMgr->interface[FILE_THREAD] + 1) % 2;
652                                 fileMgr->SBData->interface_index = fileMgr->interface[MAIN_THREAD];
653                         }
654                 }
655                 /* Attach new node after current node */
656                 newfileBuf->next = tempBuff->next;
657                 tempBuff->next = newfileBuf;
658                 TIZEN_LOGD("New Node Created [%x] and Total length [%llu]", newfileBuf, file_buffer_getTotalLen(newfileBuf));
659                 if(newfilebuf_null)
660                 {
661                         newfileBuf = NULL;
662                         tempBuff->fThread_read = 0;
663                 }
664         }
665         return newfileBuf;
666 }
667
668 uint32 file_manager_file_node_block_handle(SmartBondingData *SBData)
669 {
670         fileManager *fileMgr = SBData->fStream->fileMgr;
671         fileBuffer *tempBuff = NULL;
672         uint64 socketOffset = 0;
673         uint32 retval = B_FALSE;
674         pthread_mutex_lock(&(fileMgr->mutex));
675         SBData->fStream->fThread->status = FILE_COMPLETE;
676         tempBuff = file_manager_getDownloadingNode(fileMgr);
677         if(tempBuff == NULL)
678         {
679                 pthread_mutex_unlock(&(fileMgr->mutex));
680                 return B_TRUE;
681         }
682         pthread_mutex_lock(&(tempBuff->mut));
683         if(tempBuff->state !=  NODE_STATE_BLOCKED)
684         {
685                 retval =  B_TRUE;
686         }
687         else
688         {
689                 TIZEN_LOGD("File Node in Blocked State");
690                 socketOffset = file_buffer_getOffset(tempBuff);
691                 if(socketOffset == 0)
692                 {
693                         TIZEN_LOGD("Data in File Node is Zero Making as Socket Node");
694                         file_manager_SwitchSocketNoData(tempBuff, fileMgr);
695                         retval = B_TRUE;
696                 }
697                 else
698                 {
699                         int64 contInfo[2] = {0};
700                         fileBuffer *newfileBuf = (fileBuffer *)malloc(sizeof(fileBuffer));
701                         if(newfileBuf != NULL)
702                         {
703                                 memset(newfileBuf, 0, sizeof(fileBuffer));
704                                 file_buffer_setTotalLen(socketOffset, tempBuff);
705
706                                 check_set_filebuff_state(tempBuff);
707
708                                 contInfo[0] = file_buffer_getStrtOffset(tempBuff) + file_buffer_getTotalLen(tempBuff);
709                                 contInfo[1] =  tempBuff->endOffset;
710                                 file_buffer_init_node(newfileBuf, contInfo, -1, SOCKET_NODE, SBData, 0);
711                                 /* Attach new node after current node */
712                                 newfileBuf->next = tempBuff->next;
713                                 tempBuff->next = newfileBuf;
714                                 TIZEN_LOGD("New Node Created [%x] and Total length [%llu]", newfileBuf, file_buffer_getTotalLen(newfileBuf));
715                                 retval = B_TRUE;
716                         }
717                         else
718                         {
719                                 retval = B_FALSE;
720                         }
721                 }
722         }
723         pthread_mutex_unlock(&(tempBuff->mut));
724         pthread_mutex_unlock(&(fileMgr->mutex));
725
726         return retval;
727 }
728