tizen 2.3 release
[framework/connectivity/multirat.git] / src / multirat_multisocket.c
1 #include "multirat_libapi.h"
2 #include "multirat_multisocket.h"
3 #include "multirat_block_manager.h"
4 #include "multirat_data_buffer.h"
5 #include "multirat_range_request_thread.h"
6 #include "multirat_process.h"
7 #include "multirat_watch_dog_thread.h"
8 #include "multirat_watchthread.h"
9 void multisocket_init(MultiSockInput *mSockInput, SmartBondingData *SBData)
10 {
11         MultiSocket *mSocket = NULL;
12         DataBuffer *commbuffer = NULL;
13         BlockManager *bmanager = NULL;
14
15         mSocket = malloc(sizeof(MultiSocket));
16         if (mSocket == NULL)
17                 return;
18
19         memset(mSocket, 0, sizeof(MultiSocket));
20
21         mSocket->rspOffset = mSockInput->rspOffset;
22         mSocket->noOfChunks = mSockInput->noOfChunks;
23         mSocket->strtOffset =  SBData->req.rangeStart;
24         mSocket->compRspLen = SBData->resp.cLen ;
25
26         mSocket->appReadLen = 0;
27         mSocket->compRspRcvdFlag = 1;
28         mSocket->currentChunkId = 0;
29         mSocket->conn = mSockInput->conn;
30
31         commbuffer = (DataBuffer *)malloc(mSocket->noOfChunks * sizeof(DataBuffer));
32         if(commbuffer == NULL)
33         {
34                 TIZEN_LOGD("Error !!! commbuffer allocation failure");
35                 free(mSocket);
36                 return ;
37         }
38         memset(commbuffer, 0, mSocket->noOfChunks * sizeof(DataBuffer));
39
40         mSocket->commBuffer = commbuffer;
41         SBData->msocket = mSocket;
42
43         data_buffer_init(commbuffer, mSocket->noOfChunks, SBData->cthread->threadId);
44
45         /* Initialize and Sending Block data to Block Manager */
46         bmanager = (BlockManager *)malloc(sizeof(BlockManager));
47         if(bmanager == NULL)
48         {
49                 TIZEN_LOGD("Error !!! blockMgr allocation failure");
50                 free(commbuffer);
51                 free(mSocket);
52                 return ;
53         }
54         memset(bmanager, 0, sizeof(BlockManager));
55         mSocket->blockMgr = bmanager;
56
57         block_manager_init(mSocket, bmanager,mSockInput);
58         mSocket->SBData =  SBData;
59         bmanager->SBData = SBData;
60
61 }/* End of MultiSocket() */
62
63 uint32 multisocket_start(SmartBondingData *SBData)
64 {
65         uint32 i = 0;
66         uint32 multiThreadStarted[MAX_INTERFACES] = {0};
67         MultiSocket *msocket = SBData->msocket;
68
69         TIZEN_D_LOGD("multisocket_start");
70
71         for (i = 0; i < MAX_INTERFACES; i++ )
72         {
73                 msocket->reqThread[i] = (RangeRequestThread *)malloc(sizeof (RangeRequestThread));
74                 if(msocket->reqThread[i] == NULL)
75                 {
76                         TIZEN_LOGD("Error !!! msocket->reqThread[%d] allocation failure\n", i);
77                         return 0;
78                 }
79                 memset(msocket->reqThread[i], 0, sizeof (RangeRequestThread));
80                 msocket->reqThread[i]->threadId = i;
81                 range_request_thread_init(msocket->reqThread[i], SBData);
82                 multiThreadStarted[i] = range_request_thread_start(msocket->reqThread[i]);
83         }
84         return (multiThreadStarted[0] && multiThreadStarted[1]);
85 }/* End of start() */
86
87 int32 multisocket_get_firstrange_status(MultiSocket *msocket)
88 {
89         int32 retval = FIRST_RSP_STATUS_PENDING;
90
91         if (RANGE_REQUEST_THREAD_GET_FIRST_RANGE_STATUS(msocket->reqThread[0]) == FIRST_RSP_STATUS_FAILED ||
92                         RANGE_REQUEST_THREAD_GET_FIRST_RANGE_STATUS(msocket->reqThread[1]) == FIRST_RSP_STATUS_FAILED)
93                 retval = FIRST_RSP_STATUS_FAILED;
94
95         else if (RANGE_REQUEST_THREAD_GET_FIRST_RANGE_STATUS(msocket->reqThread[0]) == FIRST_RSP_STATUS_PENDING ||
96                         RANGE_REQUEST_THREAD_GET_FIRST_RANGE_STATUS(msocket->reqThread[1]) == FIRST_RSP_STATUS_PENDING)
97                 retval = FIRST_RSP_STATUS_PENDING;
98
99         else if (RANGE_REQUEST_THREAD_GET_FIRST_RANGE_STATUS(msocket->reqThread[0]) == FIRST_RSP_STATUS_SUCCESS &&
100                         RANGE_REQUEST_THREAD_GET_FIRST_RANGE_STATUS(msocket->reqThread[1]) == FIRST_RSP_STATUS_SUCCESS)
101                 retval = FIRST_RSP_STATUS_SUCCESS;
102
103         return retval;
104 }/* End of getFirstRangeStatus() */
105
106 int32 multisocket_read(int8 *appBuff, uint32 maxAppLen, SmartBondingData *SBData)
107 {
108         uint32 tempLen = 0;
109         uint32 toBeRead = 0;
110         DataBuffer *currChunk = NULL;
111         MultiSocket *msocket = SBData->msocket;
112
113         TIZEN_D_LOGD("multisocket_read current chunk %d\n", msocket->currentChunkId);
114         if(msocket->currentChunkId >= msocket->noOfChunks)
115         {
116                 return -1;
117         }
118
119         currChunk = msocket->commBuffer + msocket->currentChunkId;
120         while (tempLen != maxAppLen)
121         {
122                 if (DATA_BUFFER_GET_TOTAL_LEN(currChunk) == 0)
123                 {
124                         /* Block not yet assigned to thread */
125                         if(currChunk->isContinueChunk == 1)
126                         {
127                                 if(tempLen > 0)
128                                 {
129                                         break;
130                                 }
131                                 SBData->interface_index = (currChunk->threadId + 1) % 2;
132                                 TIZEN_LOGD("End of multisocket as continue Chunk is present total lenght 0");
133                                 return -2;
134                         }
135                         return 0;
136                 }
137
138                 if (DATA_BUFFER_GET_TOTAL_LEN(currChunk) ==
139                                 DATA_BUFFER_GET_READ_RES_LEN(currChunk))
140                 {
141                         data_buffer_freeBuffer(currChunk);
142                         msocket->currentChunkId++;
143                         if (msocket->currentChunkId >= msocket->noOfChunks)
144                         {
145                                 msocket->compRspRcvdFlag = 0;
146                                 break;
147                         }
148                         currChunk = msocket->commBuffer + msocket->currentChunkId;
149                         TIZEN_LOGD("started reading block = %d", msocket->currentChunkId);
150                 }
151
152                 if (DATA_BUFFER_GET_RES_BYTES(currChunk)== 0)
153                 {
154                         if(currChunk->isContinueChunk == 1)
155                         {
156                                 if(tempLen > 0)
157                                 {
158                                         break;
159                                 }
160                                 SBData->interface_index = (currChunk->threadId + 1) % 2;
161                                 TIZEN_LOGD("End of multisocket as continue Chunk is present");
162                                 return -2;
163                         }
164                         if(DATA_BUFFER_GET_TOTAL_LEN(currChunk) ==
165                                         DATA_BUFFER_GET_READ_RES_LEN(currChunk))
166                         {
167                                 /* This is for Continued chunk */
168                                 continue;
169                         }
170                         break;
171                 }/* End of if */
172
173                 toBeRead = MIN((maxAppLen - tempLen), DATA_BUFFER_GET_RES_BYTES(currChunk));
174                 data_buffer_read_portion(appBuff + tempLen, toBeRead, currChunk);
175                 tempLen = tempLen + toBeRead;
176         }/* End of while */
177
178         msocket->appReadLen = msocket->appReadLen + tempLen;
179         TIZEN_D_LOGD("multisocket_read Application read length %d calculated  %d total lenght %d,tempLen %d\n", msocket->appReadLen,
180                         (msocket->appReadLen + msocket->rspOffset), msocket->compRspLen,tempLen);
181         if((msocket->appReadLen + msocket->rspOffset) == msocket->compRspLen)
182         {
183                 /* Complete response read by application */
184                 TIZEN_LOGD ("Complete response read by application\n");;
185                 msocket->compRspRcvdFlag = 0;
186         }
187         return tempLen;
188
189 }/* End of read() */
190
191 int32 multisocket_read_sync(int8 *appBuff, uint32 maxAppLen, SmartBondingData *SBData)
192 {
193         uint32 tempLen = 0;
194         uint32 toBeRead = 0;
195         uint32 rspPresent = 0;
196         uint64 startTime = 0;
197         DataBuffer *currChunk = NULL;
198         MultiSocket *msocket = SBData->msocket;
199
200         TIZEN_D_LOGD("multisocket_read current chunk %d\n", msocket->currentChunkId);
201
202         if(msocket->currentChunkId >= msocket->noOfChunks)
203         {
204                 return -1;
205         }
206
207         currChunk = msocket->commBuffer + msocket->currentChunkId;
208         while (tempLen != maxAppLen)
209         {
210                 if (DATA_BUFFER_GET_TOTAL_LEN(currChunk) == 0)
211                 {
212                         if(currChunk->isContinueChunk == 1)
213                         {
214                                 if(tempLen > 0)
215                                 {
216                                         break;
217                                 }
218                                 SBData->interface_index = (currChunk->threadId + 1) % 2;
219                                 TIZEN_LOGD("End of multisocket as continue Chunk is present total lenght 0");
220                                 return -2;
221                         }
222                         /* Block not yet assigned to thread */
223                         usleep(1000);
224                         continue;
225                 }
226
227                 if (DATA_BUFFER_GET_TOTAL_LEN(currChunk) ==
228                                 DATA_BUFFER_GET_READ_RES_LEN(currChunk))
229                 {
230                         data_buffer_freeBuffer(currChunk);
231                         msocket->currentChunkId++;
232                         if (msocket->currentChunkId >= msocket->noOfChunks)
233                         {
234                                 msocket->compRspRcvdFlag = 0;
235                                 if(tempLen > 0)
236                                         break;
237                         }
238                         currChunk = msocket->commBuffer + msocket->currentChunkId;
239                         TIZEN_LOGD("started reading block = %d", msocket->currentChunkId);
240                 }
241
242                 startTime = get_time_in_sec();
243                 rspPresent = 0;
244                 while (DATA_BUFFER_GET_RES_BYTES(currChunk) == 0)
245                 {
246                         if(currChunk->isContinueChunk == 1)
247                         {
248                                 if(tempLen > 0)
249                                 {
250                                         rspPresent = 1;
251                                         break;
252                                 }
253                                 SBData->interface_index = (currChunk->threadId + 1) % 2;
254                                 TIZEN_LOGD("End of multisocket as continue Chunk is present");
255                                 return -2;
256                         }
257
258                         if (DATA_BUFFER_GET_TOTAL_LEN(currChunk) ==
259                                         DATA_BUFFER_GET_READ_RES_LEN(currChunk))
260                         {
261                                 /* This is for Continued chunk */
262                                 rspPresent = 2;
263                                 break;
264                         }
265                         else if(tempLen > 0)
266                         {
267                                 rspPresent = 1;
268                                 break;
269                         }
270                         else if (((get_time_in_sec() - startTime) > SBData->timeout)|| (SBData->cancel == 1))
271                         {
272                                 TIZEN_LOGD("No Interface available Exiting multiSocket or Cancel Session" );
273                                 rspPresent = 1;
274                                 break;
275                         }
276                         usleep(5000);
277                 }
278
279                 if(2 == rspPresent)
280                 {
281                         continue;
282                 }
283                 if(1 == rspPresent)
284                 {
285                         break;
286                 }
287
288                 toBeRead = MIN((maxAppLen -tempLen), (DATA_BUFFER_GET_RES_BYTES(currChunk)));
289                 data_buffer_read_portion(appBuff + tempLen, toBeRead, currChunk);
290                 tempLen = tempLen + toBeRead;
291         }/* End of while */
292
293         msocket->appReadLen = msocket->appReadLen + tempLen;
294         TIZEN_D_LOGD("multisocket_read Application read length %d calculated  %d total lenght %d\n",
295                         msocket->appReadLen,(msocket->appReadLen + msocket->rspOffset), msocket->compRspLen);
296         if((msocket->appReadLen + msocket->rspOffset) == msocket->compRspLen)
297         {
298                 /* Complete response read by application */
299                 TIZEN_LOGD ("Complete response read by application\n");;
300                 msocket->compRspRcvdFlag = 0;
301         }
302         return tempLen;
303 }/* End of read() */
304
305 void multisocket_exit(MultiSocket *msocket)
306 {
307         uint32 i = 0;
308         TIZEN_LOGD("multisocket_exit %p", msocket);
309         msocket->compRspRcvdFlag = 0;
310
311         for (i = 0; i < MAX_INTERFACES; i++)
312         {
313                 TIZEN_LOGD("multisocket_exit reqThread[%d] %p", i, msocket->reqThread[i]);
314                 if (NULL != msocket->reqThread[i])
315                 {
316                         range_request_thread_exit (msocket->reqThread[i]);
317                         msocket->reqThread[i] = NULL;
318                 }
319         }
320
321         TIZEN_LOGD("multisocket_exit blockMgr %p", msocket->blockMgr);
322         if(NULL != msocket->blockMgr)
323         {
324                 block_manager_exit(msocket->blockMgr);
325                 free(msocket->blockMgr);
326                 TIZEN_LOGD("Block Manager Freed");
327         }
328         msocket->blockMgr = NULL;
329
330         for (i = 0; i < msocket->noOfChunks; i++)
331         {
332                 TIZEN_LOGD("multisocket_exit commBuffer[%d] %p", i, msocket->commBuffer + i);
333                 if (NULL != msocket->commBuffer + i)
334                 {
335                         data_buffer_exit(msocket->commBuffer + i);
336                 }
337         }
338
339         TIZEN_LOGD("multisocket_exit commBuffer %p", msocket->commBuffer);
340         if(msocket->commBuffer != NULL)
341         {
342                 free(msocket->commBuffer);
343         }
344         msocket->commBuffer = NULL;
345         free(msocket);
346         msocket = NULL;
347         TIZEN_LOGD("multisocket_exit finished\n");
348 }/* End of ~MultiSocket() */
349
350 uint32 is_multirat_read(SmartBondingData *SBData)
351 {
352         /* Read First range request */
353         if (NULL != SBData->cthread)
354         {
355                 /*multiSocketThreadStarted*/
356                 TIZEN_D_LOGD ("about to exit cthread");
357                 cthread_exit(SBData->cthread);
358                 SBData->cthread = NULL;
359         }
360         if (SBData->response_body_read >= SBData->totalExpectedBytes)
361         {
362                 if((SBData->sync))
363                 {
364                         uint64 start_time = get_time_in_sec();
365                         while(multisocket_get_firstrange_status(SBData->msocket) == FIRST_RSP_STATUS_PENDING)
366                         {
367                                 if(((get_time_in_sec() - start_time) > SBData->timeout)||(SBData->cancel == 1))
368                                 {
369                                         TIZEN_LOGD("Cancel Session or timeout in is_multirat_read");
370                                         break;
371                                 }
372                                 usleep(10000); // sleep for 10 ms
373                         }
374                 }
375                 else if(SBData->curl)
376                 {
377                         if(multisocket_get_firstrange_status(SBData->msocket) == FIRST_RSP_STATUS_PENDING)
378                         {
379                                 if(SBData->CurlStartTime == 0)
380                                         SBData->CurlStartTime = get_time_in_sec();
381
382                                 if((get_time_in_sec() - SBData->CurlStartTime) > SBData->timeout)
383                                 {
384                                         TIZEN_LOGD("Curl Taken More than TImeout For Buffer Preperation");
385                                         return CURL_TIMEOUT_MULTIRAT_READ;
386                                 }
387
388                                 return CURL_BLOCK_MULTIRAT_READ;
389                         }
390                 }
391                 if(multisocket_get_firstrange_status(SBData->msocket) == FIRST_RSP_STATUS_SUCCESS)
392                 {
393                         SBData->mSocketDataBufferReady = B_TRUE;
394                         close(SBData->socket_fd);
395                         SBData->socket_fd = 0;
396                         TIZEN_LOGD("FirstRangeRequest Success Is Multirat Read\n");
397                 }
398                 else
399                 {
400                         SBData->mSocketDataBufferReady =  B_FALSE;
401                         SBData->multiSocketThreadStarted = B_FALSE;
402                         SBData->enableMultiRat = B_FALSE;
403                         TIZEN_LOGD("FirstRangeRequest FAILED");
404                         multisocket_exit(SBData->msocket);
405                         SBData->msocket = NULL;
406                 }
407         }
408         return 0;
409 }
410
411 int32 read_from_buffer(SmartBondingData *SBData,int8 *buffer, uint32 size, int32 *my_nread)
412 {
413         if(SBData->sync)
414         {
415                 *my_nread = multisocket_read_sync(buffer, size, SBData);
416                 if(*my_nread == 0)
417                         return SB_ERR;
418         }
419         else
420         {
421                 *my_nread = multisocket_read(buffer,size, SBData);
422                 if(*my_nread == 0)
423                 {
424                         if(SBData->CurlStartTime == 0)
425                                 SBData->CurlStartTime = get_time_in_sec();
426
427                         if((get_time_in_sec() - SBData->CurlStartTime) > SBData->timeout)
428                         {
429                                 TIZEN_LOGD("Timeout on Reading from Buffer in Curl");
430                                 return SB_ERR;
431                         }
432                         return SB_WOULD_BLOCK;
433                 }
434         }
435         if (*my_nread == -2)
436         {
437                 SBData->multiSocketThreadStarted = B_FALSE;
438                 SBData->mSocketDataBufferReady = B_FALSE;
439                 SBData->enableMultiRat = B_FALSE;
440                 SBData->socket_fd = 0;
441                 return handleMainSocExp (SBData,buffer, size, my_nread);
442         }
443
444         if(0 != SBData->curl)
445                 SBData->CurlStartTime = 0;
446         return SB_OK;
447 }
448