63e656bd172965323e62c454c0f50118d5846ebe
[profile/ivi/download-provider.git] / src / download-provider-receiver.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/socket.h>
4 #include <sys/un.h>
5 #include <unistd.h>
6 #include <sys/stat.h>
7 #include <time.h>
8 #include <sys/time.h>
9
10 #include <glib.h>
11
12 #include <net_connection.h>
13
14 #include "download-provider-config.h"
15 #include "download-provider-log.h"
16 #include "download-provider-pthread.h"
17 #include "download-provider-notification.h"
18 #include "download-provider-ipc.h"
19 #include "download-provider-db.h"
20 #include "download-provider-utils.h"
21
22 #include "download-agent-defs.h"
23 #include "download-agent-interface.h"
24
25 int _init_agent(void);
26 void _deinit_agent(void);
27 static void __downloading_info_cb(user_downloading_info_t *download_info,
28                                         void *user_data);
29 static void __download_info_cb(user_download_info_t *download_info,
30                                         void *user_data);
31 static void __notify_cb(user_notify_info_t *notify_info, void *user_data);
32 static int __change_error(int err);
33 static int __change_state(da_state state);
34
35 void TerminateDaemon(int signo);
36
37 pthread_attr_t g_download_provider_thread_attr;
38 fd_set g_download_provider_socket_readset;
39 fd_set g_download_provider_socket_exceptset;
40
41 void *_start_download(void *args)
42 {
43         int da_ret = -1;
44         int req_dl_id = -1;
45
46         download_clientinfo_slot *clientinfoslot =
47                 (download_clientinfo_slot *) args;
48         if (!clientinfoslot) {
49                 TRACE_DEBUG_MSG("[NULL-CHECK] download_clientinfo_slot");
50                 return 0;
51         }
52         download_clientinfo *clientinfo =
53                 (download_clientinfo *) clientinfoslot->clientinfo;
54         if (!clientinfo) {
55                 TRACE_DEBUG_MSG("[NULL-CHECK] download_clientinfo");
56                 return 0;
57         }
58
59         CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
60         clientinfo->state = DOWNLOAD_STATE_READY;
61         clientinfo->err = DOWNLOAD_ERROR_NONE;
62         CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
63
64         // call start_download() of download-agent
65         if (clientinfo->requestinfo->headers.rows > 0) {
66                 int len = 0;
67                 int i = 0;
68                 char **req_header = NULL;
69                 len = clientinfo->requestinfo->headers.rows;
70                 req_header = calloc(len, sizeof(char *));
71                 if (!req_header) {
72                         TRACE_DEBUG_MSG("fail to calloc");
73                         return 0;
74                 }
75                 for (i = 0; i < len; i++)
76                         req_header[i] =
77                                 strdup(clientinfo->requestinfo->headers.str[i].str);
78                 if (clientinfo->requestinfo->install_path.length > 0)
79                         da_ret =
80                                 da_start_download_with_extension(clientinfo->requestinfo->
81                                                         url.str, &req_dl_id,
82                                                         DA_FEATURE_REQUEST_HEADER,
83                                                         req_header, &len,
84                                                         DA_FEATURE_INSTALL_PATH,
85                                                         clientinfo->requestinfo->install_path.str,
86                                                         DA_FEATURE_USER_DATA,
87                                                         (void *)clientinfoslot,
88                                                         NULL);
89                 else
90                         da_ret =
91                                 da_start_download_with_extension(clientinfo->requestinfo->
92                                                         url.str, &req_dl_id,
93                                                         DA_FEATURE_REQUEST_HEADER,
94                                                         req_header, &len,
95                                                         DA_FEATURE_USER_DATA,
96                                                         (void *)clientinfoslot,
97                                                         NULL);
98                 for (i = 0; i < len; i++) {
99                         if (req_header[i])
100                                 free(req_header[i]);
101                 }
102         } else {
103                 if (clientinfo->requestinfo->install_path.length > 0)
104                         da_ret =
105                                 da_start_download_with_extension(clientinfo->requestinfo->
106                                                         url.str, &req_dl_id,
107                                                         DA_FEATURE_INSTALL_PATH,
108                                                         clientinfo->requestinfo->install_path.str,
109                                                         DA_FEATURE_USER_DATA,
110                                                         (void *)clientinfoslot,
111                                                         NULL);
112                 else
113                         da_ret =
114                                 da_start_download_with_extension(clientinfo->requestinfo->
115                                                         url.str, &req_dl_id,
116                                                         DA_FEATURE_USER_DATA,
117                                                         (void *)clientinfoslot,
118                                                         NULL);
119         }
120
121         // if start_download() return error cause of maximun download limitation, set state to DOWNLOAD_STATE_PENDED.
122         if (da_ret == DA_ERR_ALREADY_MAX_DOWNLOAD) {
123                 TRACE_DEBUG_MSG("change to pended request [%d]", da_ret);
124                 CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
125                 clientinfo->state = DOWNLOAD_STATE_PENDED;
126                 clientinfo->err = DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS;
127                 download_provider_db_requestinfo_update_column(clientinfo,
128                                                                         DOWNLOAD_DB_STATE);
129                 ipc_send_request_stateinfo(clientinfo);
130                 CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
131                 return 0;
132         } else if (da_ret != DA_RESULT_OK) {
133                 TRACE_DEBUG_MSG("Fail to request start [%d]", da_ret);
134                 /* FIXME : need to seperate in detail according to error return values */
135                 CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
136                 clientinfo->state = DOWNLOAD_STATE_FAILED;
137                 clientinfo->err = DOWNLOAD_ERROR_INVALID_PARAMETER;
138                 download_provider_db_requestinfo_remove(clientinfo->
139                                                         requestinfo->requestid);
140                 ipc_send_request_stateinfo(clientinfo);
141                 CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
142                 clear_clientinfoslot(clientinfoslot);
143                 return 0;
144         }
145
146         CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
147
148         TRACE_DEBUG_MSG("started download [%d]", da_ret);
149
150         clientinfo->req_id = req_dl_id;
151         clientinfo->state = DOWNLOAD_STATE_DOWNLOADING;
152         clientinfo->err = DOWNLOAD_ERROR_NONE;
153
154         download_provider_db_requestinfo_update_column(clientinfo,
155                                                                 DOWNLOAD_DB_STATE);
156
157         // sync return  // client should be alive till this line at least.
158         ipc_send_request_stateinfo(clientinfo);
159
160         CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
161         return 0;
162 }
163
164 int _handle_new_connection(download_clientinfo_slot *clientinfo_list, download_clientinfo *request_clientinfo)
165 {
166         uint searchslot = 0;
167
168         // NULL - checking
169         if (!clientinfo_list || !request_clientinfo ) {
170                 TRACE_DEBUG_MSG("NULL-CHECK");
171                 return -1;
172         }
173
174         CLIENT_MUTEX_INIT(&(request_clientinfo->client_mutex), NULL);
175
176 #ifdef SO_PEERCRED
177         socklen_t cr_len =
178                 sizeof(request_clientinfo->credentials);
179         if (getsockopt
180                 (request_clientinfo->clientfd, SOL_SOCKET,
181                 SO_PEERCRED, &request_clientinfo->credentials,
182                 &cr_len) == 0) {
183                 TRACE_DEBUG_MSG
184                         ("Client Info : pid=%d, uid=%d, gid=%d\n",
185                         request_clientinfo->credentials.pid,
186                         request_clientinfo->credentials.uid,
187                         request_clientinfo->credentials.gid);
188         }
189 #endif
190
191         download_controls type =
192                 ipc_receive_header(request_clientinfo->clientfd);
193         TRACE_DEBUG_MSG("[ACCEPT] HEADER : [%d] ", type);
194         // first of all, receive requestinfo .
195         if (type <= 0 || ipc_receive_request_msg(request_clientinfo) < 0) {
196                 TRACE_DEBUG_MSG("Ignore this connection, Invalid command");
197                 clear_clientinfo(request_clientinfo);
198                 return -1;
199         }
200
201         if (type == DOWNLOAD_CONTROL_STOP
202                 || type == DOWNLOAD_CONTROL_GET_STATE_INFO) {
203                 // get requestid from socket.
204                 if (request_clientinfo->requestinfo
205                         && request_clientinfo->requestinfo->requestid > 0) {
206                         // search requestid in slots.
207                         int searchindex = get_same_request_slot_index
208                                                         (clientinfo_list,
209                                                         request_clientinfo->requestinfo->requestid);
210                         if (type == DOWNLOAD_CONTROL_STOP) {
211                                 TRACE_DEBUG_MSG("Request : DOWNLOAD_CONTROL_STOP");
212                                 // remove info from downloading table.
213                                 download_provider_db_requestinfo_remove
214                                         (request_clientinfo->requestinfo->requestid);
215                                 if (searchindex >= 0) {
216                                         CLIENT_MUTEX_LOCK(&
217                                                 (clientinfo_list[searchindex].clientinfo->client_mutex));
218                                         if (da_cancel_download
219                                                 (clientinfo_list[searchindex].clientinfo->req_id)
220                                                 == DA_RESULT_OK) {
221                                                 request_clientinfo->state = DOWNLOAD_STATE_STOPPED;
222                                                 request_clientinfo->err = DOWNLOAD_ERROR_NONE;
223                                         } else {
224                                                 request_clientinfo->state = DOWNLOAD_STATE_FAILED;
225                                                 request_clientinfo->err = DOWNLOAD_ERROR_INVALID_PARAMETER;
226                                         }
227                                         ipc_send_stateinfo(request_clientinfo);
228                                         CLIENT_MUTEX_UNLOCK(&
229                                                 (clientinfo_list[searchindex].clientinfo->client_mutex));
230                                 }
231                         } else if (type == DOWNLOAD_CONTROL_GET_STATE_INFO)
232                         {
233                                 // not implemented yet
234                                 // search slots/downloading db/history db
235                                 // estabilish the spec of return value.
236                         }
237                 }
238                 clear_clientinfo(request_clientinfo);
239                 return 0;
240         }
241
242         if (type != DOWNLOAD_CONTROL_START) {
243                 TRACE_DEBUG_MSG
244                         ("Now, DOWNLOAD_CONTROL_START is only supported");
245                 clear_clientinfo(request_clientinfo);
246                 return -1;
247         }
248
249         // check whether requestinfo has requestid or not.
250         if (request_clientinfo->requestinfo
251                 && request_clientinfo->requestinfo->requestid > 0) {
252                 // search same request id.
253                 int searchindex = get_same_request_slot_index(clientinfo_list,
254                                                 request_clientinfo->requestinfo->requestid);
255                 if (searchindex < 0) {
256                         CLIENT_MUTEX_LOCK(&(request_clientinfo->client_mutex));
257                         TRACE_DEBUG_MSG("Not Found Same Request ID");
258                         request_clientinfo->requestinfo->requestid = 0;
259                         // Invalid id
260                         request_clientinfo->state = DOWNLOAD_STATE_FAILED;
261                         request_clientinfo->err = DOWNLOAD_ERROR_INVALID_PARAMETER;
262                         ipc_send_request_stateinfo(request_clientinfo);
263                         CLIENT_MUTEX_UNLOCK(&(request_clientinfo->client_mutex));
264                         clear_clientinfo(request_clientinfo);
265                         return 0;
266                 } else {        // found request id. // how to deal etag ?
267                         // connect to slot.
268                         TRACE_DEBUG_MSG("Found Same Request ID slot[%d]", searchindex);
269                         CLIENT_MUTEX_LOCK(&(request_clientinfo->client_mutex));
270                         // close previous socket.
271                         if (clientinfo_list[searchindex].clientinfo->clientfd > 0)
272                                 close(clientinfo_list[searchindex].clientinfo->clientfd);
273                         // change to new socket.
274                         clientinfo_list[searchindex].clientinfo->clientfd =
275                                 request_clientinfo->clientfd;
276                         ipc_send_request_stateinfo(clientinfo_list[searchindex].clientinfo);
277                         // update some info.
278                         clientinfo_list[searchindex].clientinfo->requestinfo->callbackinfo =
279                                 request_clientinfo->requestinfo->callbackinfo;
280                         clientinfo_list[searchindex].clientinfo->requestinfo->notification =
281                                 request_clientinfo->requestinfo->notification;
282                         request_clientinfo->clientfd = 0;       // prevent to not be disconnected.
283                         CLIENT_MUTEX_UNLOCK(&(request_clientinfo->client_mutex));
284                         clear_clientinfo(request_clientinfo);
285                         return 0;
286                 }
287         }
288
289         // new request.
290         searchslot = get_empty_slot_index(clientinfo_list);
291         if (searchslot < 0) {
292                 TRACE_DEBUG_MSG("download-provider is busy, try later");
293                 clear_clientinfo(request_clientinfo);
294                 sleep(5);       // provider need the time of refresh.
295                 return -1;
296         }
297         // create new unique id, and insert info to DB.
298         if (request_clientinfo->requestinfo
299                 && request_clientinfo->requestinfo->requestid <= 0) {
300                 request_clientinfo->requestinfo->requestid =
301                         get_download_request_id();
302                 if (download_provider_db_requestinfo_new
303                         (request_clientinfo) < 0) {
304                         clear_clientinfo(request_clientinfo);
305                         sleep(5);       // provider need the time of refresh.
306                         return -1;
307                 }
308         }
309
310         clientinfo_list[searchslot].clientinfo = request_clientinfo;
311
312         TRACE_DEBUG_MSG("New Connection slot [%d] max [%d] max once [%d]",
313                                                                                         searchslot,
314                                                                                         MAX_CLIENT,
315                                                                                         DA_MAX_DOWNLOAD_REQ_AT_ONCE);
316
317         if (get_downloading_count(clientinfo_list) >=
318                 DA_MAX_DOWNLOAD_REQ_AT_ONCE) {
319                 CLIENT_MUTEX_LOCK(&(clientinfo_list[searchslot].clientinfo->client_mutex));
320                 // deal as pended job.
321                 clientinfo_list[searchslot].clientinfo->state = DOWNLOAD_STATE_PENDED;
322                 clientinfo_list[searchslot].clientinfo->err = DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS;
323                 download_provider_db_requestinfo_update_column
324                         (clientinfo_list[searchslot].clientinfo,
325                         DOWNLOAD_DB_STATE);
326                 ipc_send_request_stateinfo(clientinfo_list[searchslot].clientinfo);
327                 TRACE_DEBUG_MSG ("Pended Request is saved to [%d/%d]",
328                         searchslot, MAX_CLIENT);
329                 CLIENT_MUTEX_UNLOCK(&(clientinfo_list[searchslot].clientinfo->client_mutex));
330                 sleep(5);       // provider need the time of refresh.
331         } else {
332                 // create thread for receiving the reqeust info from client.
333                 // and if possible, it will create the thread for listening the event.
334                 if (pthread_create
335                         (&clientinfo_list[searchslot].clientinfo->thread_pid,
336                         &g_download_provider_thread_attr, _start_download,
337                         &clientinfo_list[searchslot]) != 0) {
338                         TRACE_DEBUG_MSG("failed to call pthread_create for client");
339                         TRACE_DEBUG_MSG("Change to pended job");
340                         CLIENT_MUTEX_LOCK(&(clientinfo_list[searchslot].clientinfo->client_mutex));
341                         clientinfo_list[searchslot].clientinfo->state =
342                                 DOWNLOAD_STATE_PENDED;
343                         clientinfo_list[searchslot].clientinfo->err =
344                                 DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS;
345                         download_provider_db_requestinfo_update_column
346                                 (clientinfo_list[searchslot].clientinfo,
347                                 DOWNLOAD_DB_STATE);
348                         ipc_send_request_stateinfo(clientinfo_list[searchslot].clientinfo);
349                         CLIENT_MUTEX_UNLOCK(&(clientinfo_list[searchslot].clientinfo->client_mutex));
350                         sleep(5);       // provider need the time of refresh.
351                 }
352         }
353         return 0;
354 }
355
356 int _handle_client_request(download_clientinfo* clientinfo)
357 {
358         int da_ret = 0;
359         int msgType = 0;
360
361         // NULL - checking
362         if (!clientinfo) {
363                 TRACE_DEBUG_MSG("NULL-CHECK");
364                 return -1;
365         }
366
367         CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
368         switch (msgType = ipc_receive_header(clientinfo->clientfd)) {
369         case DOWNLOAD_CONTROL_STOP:
370                 TRACE_DEBUG_MSG("DOWNLOAD_CONTROL_STOP");
371                 da_ret = da_cancel_download(clientinfo->req_id);
372                 if (da_ret != DA_RESULT_OK) {
373                         /* FIXME : need to seperate in detail according to error return values */
374                         clientinfo->state = DOWNLOAD_STATE_FAILED;
375                         clientinfo->err = DOWNLOAD_ERROR_INVALID_PARAMETER;
376                         TRACE_DEBUG_MSG("Fail to request cancel [%d]", da_ret);
377                 } else {
378                         clientinfo->state = DOWNLOAD_STATE_STOPPED;
379                         clientinfo->err = DOWNLOAD_ERROR_NONE;
380                 }
381                 ipc_send_stateinfo(clientinfo);
382                 break;
383         case DOWNLOAD_CONTROL_PAUSE:
384                 TRACE_DEBUG_MSG("DOWNLOAD_CONTROL_PAUSE");
385                 da_ret = da_suspend_download(clientinfo->req_id);
386                 if (da_ret != DA_RESULT_OK) {
387                         /* FIXME : need to seperate in detail according to error return values */
388                         clientinfo->state = DOWNLOAD_STATE_FAILED;
389                         clientinfo->err = DOWNLOAD_ERROR_INVALID_PARAMETER;
390                         TRACE_DEBUG_MSG("Fail to request suspend [%d]", da_ret);
391                 } else {
392                         clientinfo->state = DOWNLOAD_STATE_PAUSE_REQUESTED;
393                         clientinfo->err = DOWNLOAD_ERROR_NONE;
394                 }
395                 ipc_send_stateinfo(clientinfo);
396                 break;
397         case DOWNLOAD_CONTROL_RESUME:
398                 TRACE_DEBUG_MSG("DOWNLOAD_CONTROL_RESUME");
399                 da_ret = da_resume_download(clientinfo->req_id);
400                 if (da_ret != DA_RESULT_OK) {
401                         /* FIXME : need to seperate in detail according to error return values */
402                         clientinfo->state = DOWNLOAD_STATE_FAILED;
403                         clientinfo->err = DOWNLOAD_ERROR_INVALID_PARAMETER;
404                         TRACE_DEBUG_MSG("Fail to request resume [%d]", da_ret);
405                 } else {
406                         clientinfo->state = DOWNLOAD_STATE_DOWNLOADING;
407                         clientinfo->err = DOWNLOAD_ERROR_NONE;
408                 }
409                 ipc_send_stateinfo(clientinfo);
410                 break;
411         case DOWNLOAD_CONTROL_GET_STATE_INFO:   // sync call
412                 TRACE_DEBUG_MSG("DOWNLOAD_CONTROL_GET_STATE_INFO");
413                 ipc_send_stateinfo(clientinfo);
414                 break;
415         case DOWNLOAD_CONTROL_GET_DOWNLOAD_INFO:        // sync call
416                 TRACE_DEBUG_MSG("DOWNLOAD_CONTROL_GET_DOWNLOAD_INFO");
417                 ipc_send_downloadinfo(clientinfo);
418                 break;
419         case -1:
420         case 0:
421                 TRACE_DEBUG_MSG("(Closed Socket ) terminate event thread (%d)",
422                         msgType);
423                 // bloken socket... it seems the client is dead or closed by agent thread.
424                 // close socket, this will break the loop. and terminate this thread.
425                 clear_socket(clientinfo);
426                 CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
427                 return -1;
428         default:
429                 TRACE_DEBUG_MSG("Unknow message [%d]", msgType);
430                 CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
431                 return -1;
432         }
433         CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
434         return 0;
435 }
436
437 void *run_manage_download_server(void *args)
438 {
439         int listenfd = 0;       // main socket to be albe to listen the new connection
440         int maxfd;
441         int ret = 0;
442         fd_set rset, exceptset;
443         struct timeval timeout;
444         long flexible_timeout;
445         download_clientinfo_slot *clientinfo_list;
446         uint searchslot = 0;
447         uint count_downloading_threads = 0;
448         download_clientinfo *request_clientinfo;
449         int check_retry = 1;
450         int i = 0;
451
452         socklen_t clientlen;
453         struct sockaddr_un listenaddr, clientaddr;
454
455         GMainLoop *mainloop = (GMainLoop *) args;
456
457         ret = _init_agent();
458         if (ret != DOWNLOAD_ERROR_NONE) {
459                 TRACE_DEBUG_MSG("failed to init agent");
460                 TerminateDaemon(SIGTERM);
461                 return 0;
462         }
463
464         if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
465                 TRACE_DEBUG_MSG("failed to create socket");
466                 TerminateDaemon(SIGTERM);
467                 return 0;
468         }
469
470         bzero(&listenaddr, sizeof(listenaddr));
471         listenaddr.sun_family = AF_UNIX;
472         strcpy(listenaddr.sun_path, DOWNLOAD_PROVIDER_IPC);
473
474         if (bind(listenfd, (struct sockaddr *)&listenaddr, sizeof listenaddr) !=
475                 0) {
476                 TRACE_DEBUG_MSG("failed to call bind");
477                 TerminateDaemon(SIGTERM);
478                 return 0;
479         }
480
481         if (chmod(listenaddr.sun_path, 0777) < 0) {
482                 TRACE_DEBUG_MSG
483                         ("failed to change the permission of socket file");
484                 TerminateDaemon(SIGTERM);
485                 return 0;
486         }
487
488         if (listen(listenfd, MAX_CLIENT) != 0) {
489                 TRACE_DEBUG_MSG("failed to call listen");
490                 TerminateDaemon(SIGTERM);
491                 return 0;
492         }
493
494         maxfd = listenfd;
495         TRACE_DEBUG_MSG("Ready to listen IPC [%d][%s]", listenfd,
496                         DOWNLOAD_PROVIDER_IPC);
497
498         // allocation the array structure for managing the clients.
499         clientinfo_list =
500                 (download_clientinfo_slot *) calloc(MAX_CLIENT,
501                                                         sizeof(download_clientinfo_slot));
502         if (clientinfo_list == NULL) {
503                 TRACE_DEBUG_MSG("failed to allocate the memory for client list");
504                 TerminateDaemon(SIGTERM);
505                 return 0;
506         }
507
508         if (pthread_attr_init(&g_download_provider_thread_attr) != 0) {
509                 TRACE_DEBUG_MSG("failed to call pthread_attr_init for client");
510                 TerminateDaemon(SIGTERM);
511                 return 0;
512         }
513         if (pthread_attr_setdetachstate(&g_download_provider_thread_attr,
514                                                                         PTHREAD_CREATE_DETACHED) != 0) {
515                 TRACE_DEBUG_MSG("failed to set detach option");
516                 TerminateDaemon(SIGTERM);
517                 return 0;
518         }
519
520         flexible_timeout = DOWNLOAD_PROVIDER_CARE_CLIENT_MIN_INTERVAL;
521
522         FD_ZERO(&g_download_provider_socket_readset);
523         FD_ZERO(&g_download_provider_socket_exceptset);
524         FD_SET(listenfd, &g_download_provider_socket_readset);
525         FD_SET(listenfd, &g_download_provider_socket_exceptset);
526
527         while (g_main_loop_is_running(mainloop)) {
528
529                 // clean slots
530                 for (i=0; i < MAX_CLIENT; i++) {
531                         if (!clientinfo_list[i].clientinfo)
532                                 continue;
533                         CLIENT_MUTEX_LOCK(&(clientinfo_list[i].clientinfo->client_mutex));
534                         // clear slot.
535                         if (clientinfo_list[i].clientinfo->state >= DOWNLOAD_STATE_FINISHED) {
536                                 CLIENT_MUTEX_UNLOCK(&(clientinfo_list[i].clientinfo->client_mutex));
537                                 clear_clientinfoslot(&clientinfo_list[i]);
538                                 continue;
539                         }
540                         CLIENT_MUTEX_UNLOCK(&(clientinfo_list[i].clientinfo->client_mutex));
541                 }
542
543                 rset = g_download_provider_socket_readset;
544                 exceptset = g_download_provider_socket_exceptset;
545
546                 timeout.tv_sec = flexible_timeout;
547
548                 if (select((maxfd + 1), &rset, 0, &exceptset, &timeout) < 0) {
549                         TRACE_DEBUG_MSG
550                                 ("select error, provider can't receive any request from client.");
551                         TerminateDaemon(SIGTERM);
552                         break;
553                 }
554
555                 for (i=0; i < MAX_CLIENT; i++) {  // find the socket received the packet.
556                         if (!clientinfo_list[i].clientinfo)
557                                 continue;
558                         // ignore if finished
559                         //if (clientinfo_list[i].clientinfo->state >= DOWNLOAD_STATE_FINISHED)
560                                 //continue;
561                         //Even if no socket, downloading should be progressed.
562                         if (clientinfo_list[i].clientinfo->clientfd <= 0)
563                                 continue;
564                         if (FD_ISSET(clientinfo_list[i].clientinfo->clientfd, &rset) > 0) {
565                                 TRACE_DEBUG_MSG("FD_ISSET [%d] readset slot[%d]",
566                                         clientinfo_list[i].clientinfo->clientfd, i);
567                                 _handle_client_request(clientinfo_list[i].clientinfo);
568                         } else if (FD_ISSET(clientinfo_list[i].clientinfo->clientfd, &exceptset) > 0) {
569                                 TRACE_DEBUG_MSG("FD_ISSET [%d] exceptset slot[%d]", clientinfo_list[i].clientinfo->clientfd, i);
570                                 clear_clientinfoslot(&clientinfo_list[i]);
571                         }
572                 } // MAX_CLIENT
573
574                 if (FD_ISSET(listenfd, &exceptset) > 0) {
575                         TRACE_DEBUG_MSG("meet listenfd Exception of socket");
576                         TerminateDaemon(SIGTERM);
577                         break;
578                 } else if (FD_ISSET(listenfd, &rset) > 0) { // new connection
579                         TRACE_DEBUG_MSG("FD_ISSET listenfd rset");
580                         // reset timeout.
581                         flexible_timeout =
582                                 DOWNLOAD_PROVIDER_CARE_CLIENT_MIN_INTERVAL;
583                         // ready the buffer.
584                         request_clientinfo =
585                                 (download_clientinfo *) calloc(1,
586                                                         sizeof(download_clientinfo));
587                         if (!request_clientinfo) {
588                                 TRACE_DEBUG_MSG
589                                         ("download-provider can't allocate the memory, try later");
590                                 clientlen = sizeof(clientaddr);
591                                 int clientfd = accept(listenfd,
592                                         (struct sockaddr *)&clientaddr, &clientlen);
593                                 close(clientfd);        // disconnect.
594                                 sleep(5);       // provider need the time of refresh.
595                                 continue;
596                         }
597                         // accept client.
598                         clientlen = sizeof(clientaddr);
599                         request_clientinfo->clientfd = accept(listenfd,
600                                                                 (struct sockaddr*)&clientaddr,
601                                                                 &clientlen);
602                         if (request_clientinfo->clientfd < 0) {
603                                 clear_clientinfo(request_clientinfo);
604                                 sleep(5);       // provider need the time of refresh.
605                                 continue;
606                         }
607                         FD_SET(request_clientinfo->clientfd, &g_download_provider_socket_readset);      // add new descriptor to set
608                         FD_SET(request_clientinfo->clientfd, &g_download_provider_socket_exceptset);
609                         if (request_clientinfo->clientfd > maxfd )
610                                 maxfd = request_clientinfo->clientfd;   /* for select */
611
612                         if (_handle_new_connection(clientinfo_list, request_clientinfo) < 0) {
613                                 sleep(1);
614                                 continue;
615                         }
616                 }
617
618                 if (i >= MAX_CLIENT) { // timeout
619                         // If there is better solution to be able to know
620                         // the number of downloading threads, replace below rough codes.
621                         count_downloading_threads =
622                                 get_downloading_count(clientinfo_list);
623                         // check whether the number of downloading is already maximum.
624                         if (count_downloading_threads >=
625                                 DA_MAX_DOWNLOAD_REQ_AT_ONCE)
626                                 continue;
627
628                         // search pended request
629                         for (searchslot = 0; searchslot < MAX_CLIENT;
630                                 searchslot++) {
631                                 if (clientinfo_list[searchslot].clientinfo) {
632                                         if (clientinfo_list[searchslot].clientinfo->state ==
633                                                 DOWNLOAD_STATE_PENDED) {
634                                                 TRACE_DEBUG_MSG
635                                                         ("Retry Pended Request [%d/%d] state [%d/%d]",
636                                                         searchslot, MAX_CLIENT,
637                                                         count_downloading_threads,
638                                                         DA_MAX_DOWNLOAD_REQ_AT_ONCE);
639                                                 // create thread for restarting the pended download.
640                                                 if (pthread_create
641                                                         (&clientinfo_list[searchslot].clientinfo->thread_pid,
642                                                         &g_download_provider_thread_attr,
643                                                         _start_download,
644                                                         &clientinfo_list[searchslot]) != 0) {
645                                                         TRACE_DEBUG_MSG
646                                                                 ("failed to call pthread_create for client");
647                                                 }
648                                                 count_downloading_threads++;
649                                                 usleep(1000);   // sleep in busy state.
650                                                 break;
651                                         }
652                                 }
653                         }
654
655                         if (check_retry
656                                 && count_downloading_threads <
657                                 DA_MAX_DOWNLOAD_REQ_AT_ONCE) {
658                                 // Auto re-download feature. ethernet may be connected with other downloading items.
659                                 connection_h network_handle = NULL;
660                                 connection_ethernet_state_e system_network_state
661                                         = CONNECTION_ETHERNET_STATE_DISCONNECTED;
662                                 if (connection_create(&network_handle) < 0) {
663                                         TRACE_DEBUG_MSG
664                                                 ("Failed connection_create");
665                                         continue;
666                                 }
667                                 if (connection_get_ethernet_state(network_handle,
668                                                                                         &system_network_state) !=
669                                         CONNECTION_ERROR_NONE)
670                                         TRACE_DEBUG_MSG
671                                                 ("Failed connection_get_ethernet_state");
672                                 if (connection_destroy(network_handle) !=
673                                         CONNECTION_ERROR_NONE)
674                                         TRACE_DEBUG_MSG
675                                                 ("Failed connection_destroy");
676                                 if (system_network_state !=
677                                         CONNECTION_ETHERNET_STATE_CONNECTED)
678                                         continue;
679                                 // check auto-retrying list regardless state. pended state is also included to checking list.
680                                 int i = 0;
681                                 download_dbinfo_list *db_list =
682                                         download_provider_db_get_list(DOWNLOAD_STATE_NONE);
683                                 if (!db_list || db_list->count <= 0) {
684                                         TRACE_DEBUG_MSG
685                                                 ("provider does not need to check DB anymore. in this life.");
686                                         check_retry = 0;        // provider does not need to check DB anymore. in this life.
687                                         if (db_list)
688                                                 download_provider_db_list_free(db_list);
689                                         continue;
690                                 }
691                                 for (i = 0;
692                                         count_downloading_threads <
693                                         DA_MAX_DOWNLOAD_REQ_AT_ONCE
694                                         && i < db_list->count; i++) {
695                                         if (db_list->item[i].requestid <= 0)
696                                                 continue;
697                                         if (get_same_request_slot_index
698                                                 (clientinfo_list,db_list->item[i].requestid) < 0) {
699                                                 // not found requestid in memory
700                                                 TRACE_DEBUG_MSG
701                                                         ("Retry download [%d]",
702                                                         db_list->item[i].requestid);
703                                                 //search empty slot. copy db info to slot.
704                                                 searchslot =
705                                                         get_empty_slot_index(clientinfo_list);
706                                                 if (searchslot < 0) {
707                                                         TRACE_DEBUG_MSG
708                                                                 ("download-provider is busy, try later");
709                                                         flexible_timeout =
710                                                                 flexible_timeout * 2;
711                                                         break;
712                                                 }
713                                                 // allocte requestinfo to empty slot.
714                                                 request_clientinfo =
715                                                         (download_clientinfo *)
716                                                         calloc(1, sizeof(download_clientinfo));
717                                                 if (!request_clientinfo)
718                                                         continue;
719                                                 request_clientinfo->requestinfo
720                                                         =
721                                                         download_provider_db_get_requestinfo
722                                                         (&db_list->item[i]);
723                                                 if (!request_clientinfo->requestinfo) {
724                                                         free(request_clientinfo);
725                                                         request_clientinfo = NULL;
726                                                         continue;
727                                                 }
728
729                                                 clientinfo_list[searchslot].clientinfo =
730                                                         request_clientinfo;
731
732                                                 TRACE_DEBUG_MSG
733                                                         ("Retry download [%d/%d][%d/%d]",
734                                                         searchslot, MAX_CLIENT,
735                                                         count_downloading_threads,
736                                                         DA_MAX_DOWNLOAD_REQ_AT_ONCE);
737                                                 if (pthread_create
738                                                         (&clientinfo_list[searchslot].clientinfo->thread_pid,
739                                                         &g_download_provider_thread_attr,
740                                                         _start_download,
741                                                         &clientinfo_list[searchslot])
742                                                         != 0) {
743                                                         TRACE_DEBUG_MSG
744                                                                 ("failed to call pthread_create for client");
745                                                         clientinfo_list[searchslot].clientinfo->state =
746                                                                 DOWNLOAD_STATE_PENDED;
747                                                         clientinfo_list[searchslot].clientinfo->err =
748                                                                 DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS;
749                                                         sleep(5);
750                                                 }
751                                                 count_downloading_threads++;
752                                                 usleep(1000);   // sleep in busy state.
753                                         }
754                                 }
755                                 if (i >= db_list->count)        // do not search anymore.
756                                         check_retry = 0;
757                                 download_provider_db_list_free(db_list);
758                         }
759
760                         // save system resource (CPU)
761                         if (check_retry == 0 && count_downloading_threads == 0
762                                 && flexible_timeout <
763                                 DOWNLOAD_PROVIDER_CARE_CLIENT_MAX_INTERVAL)
764                                 flexible_timeout = flexible_timeout * 2;
765                         if (flexible_timeout >
766                                 DOWNLOAD_PROVIDER_CARE_CLIENT_MAX_INTERVAL)
767                                 flexible_timeout =
768                                         DOWNLOAD_PROVIDER_CARE_CLIENT_MAX_INTERVAL;
769                         TRACE_DEBUG_MSG("Next Timeout after [%ld] sec",
770                                         flexible_timeout);
771
772                 } // if (i >= MAX_CLIENT) { // timeout
773         }
774
775         FD_CLR(listenfd, &rset);
776         FD_CLR(listenfd, &exceptset);
777         FD_CLR(listenfd, &g_download_provider_socket_readset);
778         FD_CLR(listenfd, &g_download_provider_socket_exceptset);
779
780         // close accept socket.
781         if (listenfd)
782                 close(listenfd);
783
784         _deinit_agent();
785
786         // close all sockets for client. .. 
787         // client thread will terminate by itself through catching this closing.
788         for (searchslot = 0; searchslot < MAX_CLIENT; searchslot++)
789                 if (clientinfo_list[searchslot].clientinfo)
790                         clear_clientinfoslot(&clientinfo_list[searchslot]);
791
792         if (clientinfo_list)
793                 free(clientinfo_list);
794
795         pthread_exit(NULL);
796         return 0;
797 }
798
799 void __download_info_cb(user_download_info_t *download_info, void *user_data)
800 {
801         int len = 0;
802         if (!user_data) {
803                 TRACE_DEBUG_MSG("[CRITICAL] clientinfoslot is NULL");
804                 return;
805         }
806         download_clientinfo_slot *clientinfoslot =
807                 (download_clientinfo_slot *) user_data;
808         download_clientinfo *clientinfo =
809                 (download_clientinfo *) clientinfoslot->clientinfo;
810         if (!clientinfo) {
811                 TRACE_DEBUG_MSG("[CRITICAL] clientinfo is NULL");
812                 return;
813         }
814         TRACE_DEBUG_MSG("id[%d],size[%lu]",
815                         download_info->da_dl_req_id, download_info->file_size)
816
817         if (clientinfo->req_id != download_info->da_dl_req_id) {
818                 TRACE_DEBUG_MSG("[CRITICAL] req_id[%d] da_dl_req_id[%d}",
819                                 clientinfo->req_id,
820                                 download_info->da_dl_req_id);
821                 return;
822         }
823         CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
824         if (!clientinfo->downloadinfo)
825                 clientinfo->downloadinfo =
826                         (download_content_info *) calloc(1, sizeof(download_content_info));
827         if (clientinfo->downloadinfo)
828                 clientinfo->downloadinfo->file_size = download_info->file_size;
829         if (download_info->file_type) {
830                 TRACE_DEBUG_MSG("mime[%s]", download_info->file_type);
831
832                 len = strlen(download_info->file_type);
833                 if (len > (DP_MAX_STR_LEN - 1))
834                         len = DP_MAX_STR_LEN - 1;
835                 if (clientinfo->downloadinfo) {
836                         strncpy(clientinfo->downloadinfo->mime_type,
837                                 download_info->file_type, len);
838                         download_provider_db_requestinfo_update_column
839                                 (clientinfo, DOWNLOAD_DB_MIMETYPE);
840                 }
841         }
842         if (download_info->tmp_saved_path) {
843                 char *str = NULL;
844                 TRACE_DEBUG_MSG("tmp path[%s]", download_info->tmp_saved_path);
845                 clientinfo->tmp_saved_path =
846                         strdup(download_info->tmp_saved_path);
847                 download_provider_db_requestinfo_update_column(clientinfo,
848                                                                         DOWNLOAD_DB_SAVEDPATH);
849                 str = strrchr(download_info->tmp_saved_path, '/');
850                 if (str) {
851                         str++;
852                         len = strlen(str);
853                         if (len > (DP_MAX_STR_LEN - 1))
854                                 len = DP_MAX_STR_LEN - 1;
855                         if (clientinfo->downloadinfo) {
856                                 strncpy(clientinfo->downloadinfo->content_name,
857                                         str, len);
858                                 download_provider_db_requestinfo_update_column
859                                         (clientinfo, DOWNLOAD_DB_FILENAME);
860                                 TRACE_DEBUG_MSG("content_name[%s]",
861                                                 clientinfo->downloadinfo->
862                                                 content_name);
863                         }
864                 }
865         }
866
867         if (clientinfo->requestinfo->callbackinfo.started)
868                 ipc_send_downloadinfo(clientinfo);
869
870         CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
871 }
872
873 void __downloading_info_cb(user_downloading_info_t *download_info,
874                            void *user_data)
875 {
876         int len = 0;
877         if (!user_data) {
878                 TRACE_DEBUG_MSG("[CRITICAL] clientinfoslot is NULL");
879                 return;
880         }
881         download_clientinfo_slot *clientinfoslot =
882                 (download_clientinfo_slot *) user_data;
883         download_clientinfo *clientinfo =
884                 (download_clientinfo *) clientinfoslot->clientinfo;
885         if (!clientinfo) {
886                 TRACE_DEBUG_MSG("[CRITICAL] clientinfo is NULL");
887                 return;
888         }
889         CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
890         if (clientinfo->req_id != download_info->da_dl_req_id) {
891                 TRACE_DEBUG_MSG("[CRITICAL] req_id[%d] da_dl_req_id[%d}",
892                                 clientinfo->req_id,
893                                 download_info->da_dl_req_id);
894                 CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
895                 return;
896         }
897         if (!clientinfo->downloadinginfo)
898                 clientinfo->downloadinginfo = (downloading_state_info *) calloc(1,
899                                                                         sizeof(downloading_state_info));
900         if (clientinfo->downloadinginfo)
901                 clientinfo->downloadinginfo->received_size =
902                         download_info->total_received_size;
903         if (download_info->saved_path) {
904                 TRACE_DEBUG_MSG("tmp path[%s]", download_info->saved_path);
905                 len = strlen(download_info->saved_path);
906                 if (len > (DP_MAX_PATH_LEN - 1))
907                         len = DP_MAX_PATH_LEN - 1;
908                 if (clientinfo->downloadinginfo)
909                         strncpy(clientinfo->downloadinginfo->saved_path,
910                                 download_info->saved_path, len);
911         }
912
913         static size_t updated_second;
914         time_t tt = time(NULL);
915         struct tm *localTime = localtime(&tt);
916
917         if (updated_second != localTime->tm_sec || download_info->saved_path) { // every 1 second.
918                 if (clientinfo->requestinfo
919                         && clientinfo->requestinfo->notification)
920                         set_downloadinginfo_appfw_notification(clientinfo);
921                 if (clientinfo->requestinfo->callbackinfo.progress)
922                         ipc_send_downloadinginfo(clientinfo);
923                 updated_second = localTime->tm_sec;
924         }
925         CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
926 }
927
928 void __notify_cb(user_notify_info_t *notify_info, void *user_data)
929 {
930         if (!user_data) {
931                 TRACE_DEBUG_MSG("[CRITICAL] clientinfoslot is NULL");
932                 return;
933         }
934         download_clientinfo_slot *clientinfoslot =
935                 (download_clientinfo_slot *) user_data;
936         download_clientinfo *clientinfo =
937                 (download_clientinfo *) clientinfoslot->clientinfo;
938         if (!clientinfo) {
939                 TRACE_DEBUG_MSG("[CRITICAL] clientinfo is NULL");
940                 return;
941         }
942         CLIENT_MUTEX_LOCK(&(clientinfo->client_mutex));
943         TRACE_DEBUG_MSG("id[%d],state[%d],err[%d]",
944                         notify_info->da_dl_req_id,
945                         notify_info->state, notify_info->err);
946         if (clientinfo->req_id != notify_info->da_dl_req_id) {
947                 TRACE_DEBUG_MSG("[CRITICAL] req_id[%d] da_dl_req_id[%d}",
948                                 clientinfo->req_id, notify_info->da_dl_req_id);
949                 CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
950                 return;
951         }
952
953         clientinfo->state = __change_state(notify_info->state);
954         clientinfo->err = __change_error(notify_info->err);
955         if (clientinfo->state >= DOWNLOAD_STATE_FINISHED) {
956                 if (clientinfo->requestinfo) {
957                         if (clientinfo->requestinfo->notification)
958                                 set_downloadedinfo_appfw_notification(clientinfo);
959                         download_provider_db_requestinfo_remove(clientinfo->
960                                 requestinfo->requestid);
961                 }
962                 download_provider_db_history_new(clientinfo);
963                 TRACE_DEBUG_MSG("[TEST]Finish clientinfo[%p],fd[%d]",
964                         clientinfo, clientinfo->clientfd);
965         }
966
967         TRACE_DEBUG_MSG("state[%d]", clientinfo->state);
968         ipc_send_stateinfo(clientinfo);
969
970         CLIENT_MUTEX_UNLOCK(&(clientinfo->client_mutex));
971 }
972
973 int __change_state(da_state state)
974 {
975         int ret = DOWNLOAD_STATE_NONE;
976         switch (state) {
977         case DA_STATE_WAITING:
978         case DA_STATE_DOWNLOAD_STARTED:
979                 TRACE_DEBUG_MSG("DA_STATE_DOWNLOAD_STARTED");
980                 ret = DOWNLOAD_STATE_READY;
981                 break;
982         case DA_STATE_DOWNLOADING:
983                 TRACE_DEBUG_MSG("DA_STATE_DOWNLOADING");
984                 ret = DOWNLOAD_STATE_DOWNLOADING;
985                 break;
986         case DA_STATE_DOWNLOAD_COMPLETE:
987                 TRACE_DEBUG_MSG("DA_STATE_COMPLETE");
988                 ret = DOWNLOAD_STATE_INSTALLING;
989                 break;
990         case DA_STATE_CANCELED:
991                 TRACE_DEBUG_MSG("DA_STATE_CANCELED");
992                 ret = DOWNLOAD_STATE_STOPPED;
993                 break;
994         case DA_STATE_CANCELED_ALL:
995                 TRACE_DEBUG_MSG("DA_STATE_CANCELED_ALL");
996                 break;
997         case DA_STATE_SUSPENDED:
998                 TRACE_DEBUG_MSG("DA_STATE_SUSPENDED");
999                 ret = DOWNLOAD_STATE_PAUSED;
1000                 break;
1001         case DA_STATE_SUSPENDED_ALL:
1002                 TRACE_DEBUG_MSG("DA_STATE_SUSPENDED_ALL");
1003                 break;
1004         case DA_STATE_RESUMED:
1005                 TRACE_DEBUG_MSG("DA_STATE_RESUMED");
1006                 ret = DOWNLOAD_STATE_DOWNLOADING;
1007                 break;
1008         case DA_STATE_RESUMED_ALL:
1009                 TRACE_DEBUG_MSG("DA_STATE_RESUMED_ALL");
1010                 break;
1011         case DA_STATE_FINISHED:
1012                 TRACE_DEBUG_MSG("DA_STATE_FINISHED");
1013                 ret = DOWNLOAD_STATE_FINISHED;
1014                 break;
1015         case DA_STATE_FAILED:
1016                 TRACE_DEBUG_MSG("DA_STATE_FAILED");
1017                 ret = DOWNLOAD_STATE_FAILED;
1018                 break;
1019         default:
1020                 break;
1021         }
1022         return ret;
1023 }
1024
1025 int __change_error(int err)
1026 {
1027         int ret = DOWNLOAD_ERROR_UNKOWN;
1028         switch (err) {
1029         case DA_RESULT_OK:
1030                 ret = DOWNLOAD_ERROR_NONE;
1031                 break;
1032         case DA_ERR_INVALID_ARGUMENT:
1033                 ret = DOWNLOAD_ERROR_INVALID_PARAMETER;
1034                 break;
1035         case DA_ERR_FAIL_TO_MEMALLOC:
1036                 ret = DOWNLOAD_ERROR_OUT_OF_MEMORY;
1037                 break;
1038         case DA_ERR_UNREACHABLE_SERVER:
1039                 ret = DOWNLOAD_ERROR_NETWORK_UNREACHABLE;
1040                 break;
1041         case DA_ERR_HTTP_TIMEOUT:
1042                 ret = DOWNLOAD_ERROR_CONNECTION_TIMED_OUT;
1043                 break;
1044         case DA_ERR_DISK_FULL:
1045                 ret = DOWNLOAD_ERROR_NO_SPACE;
1046                 break;
1047         case DA_ERR_INVALID_STATE:
1048                 ret = DOWNLOAD_ERROR_INVALID_STATE;
1049                 break;
1050         case DA_ERR_NETWORK_FAIL:
1051                 ret = DOWNLOAD_ERROR_CONNECTION_FAILED;
1052                 break;
1053         case DA_ERR_INVALID_URL:
1054                 ret = DOWNLOAD_ERROR_INVALID_URL;
1055                 break;
1056         case DA_ERR_INVALID_INSTALL_PATH:
1057                 ret = DOWNLOAD_ERROR_INVALID_DESTINATION;
1058                 break;
1059         case DA_ERR_ALREADY_MAX_DOWNLOAD:
1060                 ret = DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS;
1061                 break;
1062         case DA_ERR_FAIL_TO_INSTALL_FILE:
1063                 ret = DOWNLOAD_ERROR_INSTALL_FAIL;
1064                 break;
1065         case DA_ERR_FAIL_TO_CREATE_THREAD:
1066         case DA_ERR_FAIL_TO_OBTAIN_MUTEX:
1067         case DA_ERR_FAIL_TO_ACCESS_FILE:
1068         case DA_ERR_FAIL_TO_GET_CONF_VALUE:
1069         case DA_ERR_FAIL_TO_ACCESS_STORAGE:
1070         case DA_ERR_DLOPEN_FAIL:
1071                 ret = DOWNLOAD_ERROR_IO_ERROR;
1072                 break;
1073         }
1074         return ret;
1075 }
1076
1077 int _init_agent()
1078 {
1079         int da_ret = 0;
1080         da_client_cb_t da_cb = {
1081                 __notify_cb,
1082                 __download_info_cb,
1083                 __downloading_info_cb
1084         };
1085         da_ret = da_init(&da_cb, DA_DOWNLOAD_MANAGING_METHOD_AUTO);
1086         if (da_ret != DA_RESULT_OK) {
1087                 return DOWNLOAD_ERROR_FAIL_INIT_AGENT;
1088         }
1089         return DOWNLOAD_ERROR_NONE;
1090 }
1091
1092 void _deinit_agent()
1093 {
1094         da_deinit();
1095 }