a4ae548738d7e5bb5a7c7f7ea0671f495e432069
[platform/framework/web/download-provider.git] / src / download-provider-thread-request.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20
21 #include <time.h>
22 #include <sys/time.h>
23
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/stat.h>
27
28 #include <signal.h>
29
30 #include <app_manager.h>
31
32 #include "download-provider.h"
33 #include "download-provider-log.h"
34 #include "download-provider-config.h"
35 #include "download-provider-slots.h"
36 #include "download-provider-socket.h"
37 #include "download-provider-pthread.h"
38 #include "download-provider-db.h"
39 #include "download-provider-queue.h"
40 #include "download-provider-request.h"
41 #include "download-provider-da-interface.h"
42
43 void dp_terminate(int signo);
44
45 static char *__print_command(dp_command_type cmd)
46 {
47         switch(cmd)
48         {
49                 case DP_CMD_CREATE :
50                         return "CREATE";
51                 case DP_CMD_START :
52                         return "START";
53                 case DP_CMD_PAUSE :
54                         return "PAUSE";
55                 case DP_CMD_CANCEL :
56                         return "CANCEL";
57                 case DP_CMD_DESTROY :
58                         return "DESTROY";
59                 case DP_CMD_FREE :
60                         return "FREE";
61                 case DP_CMD_ECHO :
62                         return "ECHO";
63                 case DP_CMD_SET_URL :
64                         return "SET_URL";
65                 case DP_CMD_SET_DESTINATION :
66                         return "SET_DESTINATION";
67                 case DP_CMD_SET_FILENAME :
68                         return "SET_FILENAME";
69                 case DP_CMD_SET_NOTIFICATION :
70                         return "SET_NOTIFICATION";
71                 case DP_CMD_SET_STATE_CALLBACK :
72                         return "SET_STATE_CALLBACK";
73                 case DP_CMD_SET_PROGRESS_CALLBACK :
74                         return "SET_PROGRESS_CALLBACK";
75                 case DP_CMD_SET_AUTO_DOWNLOAD :
76                         return "SET_AUTO_DOWNLOAD";
77                 case DP_CMD_SET_NETWORK_TYPE :
78                         return "SET_NETWORK_TYPE";
79                 case DP_CMD_SET_HTTP_HEADER :
80                         return "SET_HTTP_HEADER";
81                 case DP_CMD_SET_EXTRA_PARAM :
82                         return "SET_EXTRA_PARAM";
83                 case DP_CMD_DEL_HTTP_HEADER :
84                         return "DEL_HTTP_HEADER";
85                 case DP_CMD_GET_HTTP_HEADER :
86                         return "GET_HTTP_HEADER";
87                 case DP_CMD_GET_URL :
88                         return "GET_URL";
89                 case DP_CMD_GET_DESTINATION :
90                         return "GET_DESTINATION";
91                 case DP_CMD_GET_FILENAME :
92                         return "GET_FILENAME";
93                 case DP_CMD_GET_NOTIFICATION :
94                         return "GET_NOTIFICATION";
95                 case DP_CMD_GET_STATE_CALLBACK :
96                         return "GET_STATE_CALLBACK";
97                 case DP_CMD_GET_PROGRESS_CALLBACK :
98                         return "GET_PROGRESS_CALLBACK";
99                 case DP_CMD_GET_HTTP_HEADERS :
100                         return "GET_HTTP_HEADERS";
101                 case DP_CMD_GET_EXTRA_PARAM :
102                         return "GET_EXTRA_PARAM";
103                 case DP_CMD_GET_AUTO_DOWNLOAD :
104                         return "GET_AUTO_DOWNLOAD";
105                 case DP_CMD_GET_NETWORK_TYPE :
106                         return "GET_NETWORK_TYPE";
107                 case DP_CMD_GET_SAVED_PATH :
108                         return "GET_SAVED_PATH";
109                 case DP_CMD_GET_TEMP_SAVED_PATH :
110                         return "GET_TEMP_SAVED_PATH";
111                 case DP_CMD_GET_MIME_TYPE :
112                         return "GET_MIME_TYPE";
113                 case DP_CMD_GET_RECEIVED_SIZE :
114                         return "GET_RECEIVED_SIZE";
115                 case DP_CMD_GET_TOTAL_FILE_SIZE :
116                         return "GET_TOTAL_FILE_SIZE";
117                 case DP_CMD_GET_CONTENT_NAME :
118                         return "GET_CONTENT_NAME";
119                 case DP_CMD_GET_HTTP_STATUS :
120                         return "GET_HTTP_STATUS";
121                 case DP_CMD_GET_ETAG :
122                         return "DP_CMD_GET_ETAG";
123                 case DP_CMD_GET_STATE :
124                         return "GET_STATE";
125                 case DP_CMD_GET_ERROR :
126                         return "ERROR";
127                 case DP_CMD_SET_COMMAND_SOCKET :
128                         return "SET_COMMAND_SOCKET";
129                 case DP_CMD_SET_EVENT_SOCKET :
130                         return "SET_EVENT_SOCKET";
131                 default :
132                         break;
133         }
134         return "UNKNOWN COMMAND";
135 }
136
137 /* compare two string */
138 static int __cmp_string(char *s1, char *s2)
139 {
140         size_t s1_len = 0;
141         size_t s2_len = 0;
142
143         if (!s1 || !s2) {
144                 TRACE_ERROR("[CHECK PARAM]");
145                 return -1;
146         }
147
148         s1_len = strlen(s1);
149         if (s1_len <= 0) {
150                 TRACE_ERROR("[CHECK PARAM] len[%d]", s1_len);
151                 return -1;
152         }
153
154         s2_len = strlen(s2);
155         if (s2_len <= 0) {
156                 TRACE_ERROR("[CHECK PARAM] len[%d]", s2_len);
157                 return -1;
158         }
159
160         if (s1_len != s2_len) {
161                 TRACE_ERROR("[DIFF] len[%d:%d]", s1_len, s2_len);
162                 return -1;
163         }
164
165         if (strncmp(s1, s2, s1_len) != 0) {
166                 TRACE_ERROR("[DIFF] cmp[%s:%s]", s1, s2);
167                 return -1;
168         }
169
170         return 0;
171 }
172
173 //////////////////////////////////////////////////////////////////////////
174 /// @brief      return index of empty slot
175 static int __get_empty_request_index(dp_request_slots *slots)
176 {
177         int i = 0;
178
179         if (!slots)
180                 return -1;
181
182         for (i = 0; i < DP_MAX_REQUEST; i++)
183                 if (!slots[i].request)
184                         return i;
185         return -1;
186 }
187
188 //////////////////////////////////////////////////////////////////////////
189 /// @brief      return index of slot having same ID
190 /// @param      ID want to search
191 static int __get_same_request_index(dp_request_slots *slots, int id)
192 {
193         int i = 0;
194
195         if (!slots || id < 0)
196                 return -1;
197
198         for (i = 0; i < DP_MAX_REQUEST; i++) {
199                 if (slots[i].request) {
200                         if (slots[i].request->id == id) {
201                                 return i;
202                         }
203                 }
204         }
205         return -1;
206 }
207
208 //////////////////////////////////////////////////////////////////////////
209 /// @brief      return string via IPC
210 static void __send_return_string(int fd, dp_error_type errcode, char* str)
211 {
212         if (fd < 0 || !str)
213                 return ;
214         dp_ipc_send_errorcode(fd, errcode);
215         dp_ipc_send_string(fd, str);
216 }
217
218 //////////////////////////////////////////////////////////////////////////
219 /// @brief      return custom value via IPC
220 static void __send_return_custom_type(int fd, dp_error_type errcode, void *value, size_t type_size)
221 {
222         dp_ipc_send_errorcode(fd, errcode);
223         dp_ipc_send_custom_type(fd, value, type_size);
224 }
225
226 // in url-download, make 3 connection before send CREATE command.
227 // after accepting, fill info to pacakgelist.
228 // 3 socket per 1 package ( info/request/progress )
229 void *dp_thread_requests_manager(void *arg)
230 {
231         fd_set rset, eset, listen_fdset, except_fdset;
232         struct timeval timeout; // for timeout of select
233         long flexible_timeout = DP_CARE_CLIENT_MAX_INTERVAL;
234         int listenfd, clientfd, maxfd;
235         socklen_t clientlen;
236         struct sockaddr_un clientaddr;
237         dp_credential credential;
238         unsigned i, is_timeout;
239         int prev_timeout = 0;
240         dp_error_type errorcode = DP_ERROR_NONE;
241
242         dp_privates *privates = (dp_privates*)arg;
243         if (!privates || !privates->groups) {
244                 TRACE_ERROR("[CRITICAL] Invalid Address");
245                 dp_terminate(SIGTERM);
246                 pthread_exit(NULL);
247                 return 0;
248         }
249
250         listenfd = privates->listen_fd;
251         maxfd = listenfd;
252
253         TRACE_INFO("Ready to listen [%d][%s]", listenfd, DP_IPC);
254
255         FD_ZERO(&listen_fdset);
256         FD_ZERO(&except_fdset);
257         FD_SET(listenfd, &listen_fdset);
258         FD_SET(listenfd, &except_fdset);
259
260         while (privates && privates->listen_fd) {
261
262                 // select with timeout
263                 // initialize timeout structure for calling timeout exactly
264                 memset(&timeout, 0x00, sizeof(struct timeval));
265                 timeout.tv_sec = flexible_timeout;
266                 clientfd = -1;
267                 credential.pid = -1;
268                 credential.uid = -1;
269                 credential.gid = -1;
270                 is_timeout = 1;
271
272                 rset = listen_fdset;
273                 eset = except_fdset;
274
275                 if (select((maxfd + 1), &rset, 0, &eset, &timeout) < 0) {
276                         TRACE_STRERROR("[CRITICAL] select");
277                         break;
278                 }
279
280                 if (!privates) {
281                         TRACE_INFO("Terminate Thread");
282                         break;
283                 }
284
285                 if (FD_ISSET(listenfd, &eset) > 0) {
286                         TRACE_ERROR("[CRITICAL] listenfd Exception of socket");
287                         break;
288                 } else if (FD_ISSET(listenfd, &rset) > 0) {
289                         // new client(package) called url_download_create API.
290                         // update g_dp_request_max_fd & g_dp_info_max_fd
291                         // add to socket to g_dp_request_rset & g_dp_info_rset
292
293                         is_timeout = 0;
294
295                         // Anyway accept client.
296                         clientlen = sizeof(clientaddr);
297                         clientfd = accept(listenfd,
298                                                         (struct sockaddr*)&clientaddr,
299                                                         &clientlen);
300
301                         TRACE_INFO("[New Connection]");
302
303                         if (clientfd < 0) {
304                                 TRACE_ERROR("[CRITICAL] accept provider was crashed ?");
305                                 // provider need the time of refresh.
306                                 break;
307                         }
308
309                         dp_command_type connect_cmd = DP_CMD_NONE;
310                         if (dp_ipc_read_custom_type(clientfd,
311                                         &connect_cmd, sizeof(dp_command_type)) < 0) {
312                                 TRACE_ERROR("[CRITICAL] CAPI not support CONNECT CMD");
313                                 close(clientfd);
314                                 continue;
315                         }
316                         if (connect_cmd <= 0) {
317                                 TRACE_ERROR("[CRITICAL] peer terminate ?");
318                                 close(clientfd);
319                                 continue;
320                         }
321                         if (connect_cmd != DP_CMD_SET_COMMAND_SOCKET
322                                 && connect_cmd != DP_CMD_SET_EVENT_SOCKET) {
323                                 TRACE_ERROR("[CRITICAL] Bad access, ignore this client");
324                                 close(clientfd);
325                                 continue;
326                         }
327
328                         #ifdef SO_PEERCRED
329                         // getting the info of client
330                         socklen_t cr_len = sizeof(credential);
331                         if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED,
332                                 &credential, &cr_len) == 0) {
333                                 TRACE_INFO
334                                         ("credential : pid=%d, uid=%d, gid=%d",
335                                         credential.pid, credential.uid, credential.gid);
336                         }
337                         #else // In case of not supported SO_PEERCRED
338                         int client_pid = 0;
339                         if (dp_ipc_read_custom_type(clientfd,
340                                         &client_pid, sizeof(int)) < 0) {
341                                 TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
342                                 close(clientfd);
343                                 continue;
344                         }
345                         if (client_pid <= 0) {
346                                 TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
347                                 close(clientfd);
348                                 continue;
349                         }
350                         credential.pid = client_pid;
351                         credential.uid = 5000;
352                         credential.gid = 5000;
353                         #endif
354
355                         struct timeval tv_timeo; // 2.5 sec
356                         tv_timeo.tv_sec = 2;
357                         tv_timeo.tv_usec = 500000;
358                         if (setsockopt(clientfd, SOL_SOCKET, SO_SNDTIMEO, &tv_timeo,
359                                 sizeof( tv_timeo ) ) < 0) {
360                                 TRACE_STRERROR("[CRITICAL] setsockopt SO_SNDTIMEO");
361                                 close(clientfd);
362                                 continue;
363                         }
364                         if (setsockopt(clientfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo,
365                                 sizeof( tv_timeo ) ) < 0) {
366                                 TRACE_STRERROR("[CRITICAL] setsockopt SO_SNDTIMEO");
367                                 close(clientfd);
368                                 continue;
369                         }
370
371                         if (connect_cmd == DP_CMD_SET_COMMAND_SOCKET) {
372
373                                 // search in groups.
374                                 // if same group. update it.
375                                 // search same pkg or pid in groups
376                                 int group_index = -1;
377                                 int pkgname_length = 0;
378                                 char *client_pkgname = NULL;
379
380                                 // getting the package name via pid
381                                 int errcode =
382                                 app_manager_get_package(credential.pid, &client_pkgname);
383                                 if (errcode == APP_MANAGER_ERROR_NONE && client_pkgname
384                                         && strlen(client_pkgname) < DP_MAX_STR_LEN) {
385                                         TRACE_INFO("package : %s", client_pkgname);
386                                 } else
387                                         TRACE_ERROR("[CRITICAL] app_manager_get_package");
388
389                                 if (client_pkgname
390                                         && (pkgname_length = strlen(client_pkgname)) > 1) {
391                                         for (i = 0; i < DP_MAX_GROUP; i++) {
392                                                 if (privates->groups[i].group) {
393                                                         if (privates->groups[i].group->cmd_socket
394                                                                 <= 0
395                                                                 || !privates->groups[i].group->pkgname) {
396                                                                 dp_client_group_free
397                                                                         (privates->groups[i].group);
398                                                                 privates->groups[i].group = NULL;
399                                                                 continue;
400                                                         }
401                                                         if (strlen
402                                                                         (privates->groups[i].group->pkgname)
403                                                                         == pkgname_length
404                                                                 && strncmp
405                                                                         (privates->groups[i].group->pkgname,
406                                                                         client_pkgname, pkgname_length)
407                                                                         == 0 ) {
408                                                                 // Found Same Group
409                                                                 TRACE_INFO
410                                                                 ("UPDATE Group : I %d [%s] PID [%d] cmd_socket[%d]",
411                                                                 i, client_pkgname, credential.pid, clientfd);
412                                                                 if (privates->groups[i].group->cmd_socket
413                                                                         > 0
414                                                                         && privates->groups[i].group->cmd_socket
415                                                                         != clientfd) {
416                                                                         FD_CLR
417                                                                         (privates->groups[i].group->cmd_socket,
418                                                                         &listen_fdset);
419                                                                         dp_socket_free
420                                                                         (privates->groups[i].group->cmd_socket);
421                                                                 }
422                                                                 privates->groups[i].group->cmd_socket = clientfd;
423                                                                 FD_SET(privates->groups[i].group->cmd_socket, &listen_fdset);
424                                                                 if (privates->groups[i].group->cmd_socket > maxfd)
425                                                                 maxfd = privates->groups[i].group->cmd_socket;
426                                                                 group_index = i;
427                                                                 break;
428                                                         }
429                                                 }
430                                         }
431                                 }
432                                 if (group_index == -1) { // search emtpy slot in groups
433                                         // search empty slot in groups
434                                         for (i = 0; i < DP_MAX_GROUP; i++)
435                                                 if (!privates->groups[i].group)
436                                                         break;
437                                         if (i >= DP_MAX_GROUP) {
438                                                 TRACE_ERROR("[CRITICAL] No space in groups");
439                                                 close(clientfd); // how to deal in url-download ?
440                                                 if (client_pkgname)
441                                                         free(client_pkgname);
442                                                 continue;
443                                         }
444
445                                         //// TEST CODE ... to allow sample client ( no package name ).
446                                         if (!client_pkgname) {
447                                                 client_pkgname = dp_strdup("unknown_app");
448                                                 TRACE_INFO("package : %s", client_pkgname);
449                                         }
450
451                                         TRACE_INFO
452                                         ("New Group : GI %d [%s] PID [%d] cmd_socket[%d]",
453                                         i, client_pkgname, credential.pid, clientfd);
454
455                                         // allocation
456                                         privates->groups[i].group =
457                                                 (dp_client_group *) calloc(1,
458                                                         sizeof(dp_client_group));
459                                         if (!privates->groups[i].group) {
460                                                 TRACE_ERROR
461                                                         ("[CRITICAL] calloc, ignore this client");
462                                                 close(clientfd);
463                                                 if (client_pkgname)
464                                                         free(client_pkgname);
465                                                 continue;
466                                         }
467                                         // fill info
468                                         privates->groups[i].group->cmd_socket = clientfd;
469                                         privates->groups[i].group->event_socket = -1;
470                                         privates->groups[i].group->queued_count = 0;
471                                         privates->groups[i].group->pkgname =
472                                                 dp_strdup(client_pkgname);
473                                         privates->groups[i].group->credential.pid =
474                                                 credential.pid;
475                                         privates->groups[i].group->credential.uid =
476                                                 credential.uid;
477                                         privates->groups[i].group->credential.gid =
478                                                 credential.gid;
479                                         FD_SET(privates->groups[i].group->cmd_socket,
480                                                 &listen_fdset);
481                                         if (privates->groups[i].group->cmd_socket > maxfd)
482                                                 maxfd = privates->groups[i].group->cmd_socket;
483                                         TRACE_INFO
484                                                 ("Group : GI [%d] [%s] S [%d] Max [%d]",
485                                                 i, client_pkgname,
486                                                 privates->groups[i].group->cmd_socket, maxfd);
487                                 }
488                                 if (client_pkgname)
489                                         free(client_pkgname);
490
491                         } else if (connect_cmd == DP_CMD_SET_EVENT_SOCKET) {
492
493                                 // search same pid in groups. have same life-cycle with cmd_socket
494                                 TRACE_INFO
495                                         ("Group event IPC: PID [%d] cmd_socket[%d]",
496                                         credential.pid, clientfd);
497                                 // search same pkg or pid in groups
498                                 for (i = 0; i < DP_MAX_GROUP; i++) {
499                                         if (privates->groups[i].group) {
500                                                 dp_client_group *group =
501                                                         privates->groups[i].group;
502                                                 if (group->credential.pid == credential.pid) {
503                                                         TRACE_INFO
504                                                         ("Found Group : I %d [%s] PID [%d] \
505                                                         socket (%d/%d)", i,
506                                                         group->pkgname, credential.pid,
507                                                         group->cmd_socket, group->event_socket);
508                                                         if (group->event_socket > 0
509                                                                 && group->event_socket != clientfd)
510                                                                 dp_socket_free(group->event_socket);
511                                                         group->event_socket = clientfd;
512                                                         TRACE_INFO
513                                                         ("Found Group : I %d PID [%d] \
514                                                         event_socket[%d]",
515                                                         i, credential.pid, clientfd);
516                                                         break;
517                                                 }
518                                         }
519                                 }
520                                 if (i >= DP_MAX_GROUP) {
521                                         TRACE_ERROR
522                                                 ("[CRITICAL] Not found group for PID [%d]",
523                                                 credential.pid);
524                                         close(clientfd);
525                                         continue;
526                                 }
527                         }
528                 } // New Connection
529
530                 // listen cmd_socket of all group
531                 for (i = 0; i < DP_MAX_GROUP; i++) {
532                         if (!privates->groups[i].group)
533                                 continue;
534                         if (privates->groups[i].group->cmd_socket < 0) {
535                                 continue;
536                         }
537                         if (FD_ISSET(privates->groups[i].group->cmd_socket, &rset)
538                                 > 0) {
539                                 dp_client_group *group = privates->groups[i].group;
540                                 dp_command client_cmd;
541                                 int index = -1;
542
543                                 is_timeout = 0;
544                                 client_cmd.cmd = DP_CMD_NONE;
545                                 client_cmd.id = -1;
546
547                                 if (dp_ipc_read_custom_type(group->cmd_socket,
548                                                         &client_cmd, sizeof(dp_command)) < 0) {
549                                         TRACE_STRERROR("failed to read cmd");
550                                         //Resource temporarily unavailable
551                                         continue;
552                                 }
553
554                                 // print detail info
555                                 TRACE_INFO
556                                         ("[%s][%d] FD[%d] CLIENT[%s] PID[%d] GINDEX[%d]",
557                                         __print_command(client_cmd.cmd), client_cmd.id,
558                                         group->cmd_socket, group->pkgname,
559                                         group->credential.pid, i);
560
561                                 if (client_cmd.cmd == 0) { // Client meet some Error.
562                                         TRACE_INFO
563                                         ("[Closed Peer] group[%d][%s] socket[%d]",
564                                         i, group->pkgname, group->cmd_socket);
565                                         // check all request included to this group
566                                         for (index = 0; index < DP_MAX_REQUEST; index++) {
567                                                 if (!privates->requests[index].request)
568                                                         continue;
569                                                 if (!privates->requests[index].request->group)
570                                                         continue;
571                                                 if (privates->requests[index].request->id <= 0)
572                                                         continue;
573                                                 dp_request *request =
574                                                         privates->requests[index].request;
575
576                                                 CLIENT_MUTEX_LOCK(&request->mutex);
577                                                 if (request->group != group ||
578                                                         request->group->cmd_socket !=
579                                                         group->cmd_socket) {
580                                                         CLIENT_MUTEX_UNLOCK(&request->mutex);
581                                                         continue;
582                                                 }
583                                                 int auto_download =
584                                                         dp_db_get_int_column(request->id,
585                                                                         DP_DB_TABLE_REQUEST_INFO,
586                                                                         DP_DB_COL_AUTO_DOWNLOAD);
587                                                 if (auto_download <= 0) {
588                                                         int agentid = request->agent_id;
589                                                         int requestid = request->id;
590                                                         int state = request->state;
591                                                         TRACE_INFO("[CANCEL][%d] [%s] fd[%d]",
592                                                                 requestid, request->group->pkgname,
593                                                                 request->group->cmd_socket);
594
595                                                         if ((state == DP_STATE_READY ||
596                                                                 state == DP_STATE_QUEUED ||
597                                                                 state == DP_STATE_CONNECTING ||
598                                                                 state == DP_STATE_DOWNLOADING ||
599                                                                 state == DP_STATE_PAUSE_REQUESTED ||
600                                                                 state == DP_STATE_PAUSED)) {
601                                                                 request->state = DP_STATE_FAILED;
602                                                                 request->error = DP_ERROR_CLIENT_DOWN;
603                                                                 if (dp_db_set_column
604                                                                                 (request->id, DP_DB_TABLE_LOG,
605                                                                                 DP_DB_COL_STATE,
606                                                                                 DP_DB_COL_TYPE_INT,
607                                                                                 &request->state) < 0) {
608                                                                         TRACE_ERROR("[ERROR][%d][SQL]",
609                                                                                 requestid);
610                                                                         dp_db_remove_all(request->id);
611                                                                 } else {
612                                                                         if (dp_db_set_column
613                                                                                 (request->id, DP_DB_TABLE_LOG,
614                                                                                 DP_DB_COL_ERRORCODE,
615                                                                                 DP_DB_COL_TYPE_INT,
616                                                                                 &request->error) < 0) {
617                                                                         TRACE_ERROR("[ERROR][%d][SQL]",
618                                                                                 requestid);
619                                                                         }
620                                                                 }
621                                                         }
622                                                         CLIENT_MUTEX_UNLOCK(&request->mutex);
623                                                         dp_request_free(request);
624                                                         privates->requests[index].request = NULL;
625
626                                                         // call cancel_agent after free.
627                                                         if (agentid > 0 &&
628                                                                 dp_is_alive_download(agentid)) {
629                                                                 TRACE_INFO
630                                                                         ("[CANCEL-AGENT][%d] state [%s]",
631                                                                         requestid, dp_print_state(state));
632                                                                 if (dp_cancel_agent_download(agentid) <
633                                                                         0)
634                                                                         TRACE_INFO("[CANCEL FAILURE]");
635                                                         }
636
637                                                         continue;
638                                                 }
639
640
641                                                 TRACE_INFO("[DISCONNECT][%d] [%s] fd[%d]",
642                                                         request->id, request->group->pkgname,
643                                                         request->group->cmd_socket);
644
645                                                 request->group = NULL;
646                                                 request->state_cb = 0;
647                                                 request->progress_cb = 0;
648
649                                                 CLIENT_MUTEX_UNLOCK(&request->mutex);
650                                                 // yield to agent thread before free
651                                                 CLIENT_MUTEX_LOCK(&request->mutex);
652                                                 // free finished slot without client process
653                                                 if (request->state == DP_STATE_COMPLETED
654                                                         || request->state == DP_STATE_FAILED
655                                                         || request->state == DP_STATE_CANCELED) {
656                                                         TRACE_INFO
657                                                                 ("[FREE][%d] state[%s]", request->id,
658                                                                 dp_print_state(request->state));
659                                                         CLIENT_MUTEX_UNLOCK(&request->mutex);
660                                                         dp_request_free(request);
661                                                         privates->requests[index].request = NULL;
662                                                         continue;
663                                                 }
664                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
665                                         }
666                                         // clear this group
667                                         FD_CLR(group->cmd_socket, &listen_fdset);
668                                         dp_client_group_free(group);
669                                         privates->groups[i].group = NULL;
670                                         continue;
671                                 }
672
673                                 // Echo .client can check whether provider is busy
674                                 if (client_cmd.cmd == DP_CMD_ECHO) {
675                                         // provider can clear read buffer here
676                                         TRACE_INFO("[ECHO] fd[%d]", group->cmd_socket);
677                                         dp_ipc_send_errorcode
678                                                 (group->cmd_socket, DP_ERROR_NONE);
679                                         continue;
680                                 }
681
682                                 if (client_cmd.cmd == DP_CMD_CREATE) {
683                                         // search empty slot in privates->requests
684                                         index = __get_empty_request_index(privates->requests);
685                                         if (index < 0) {
686                                                 TRACE_ERROR("[CHECK] [DP_ERROR_QUEUE_FULL]");
687                                                 // Busy, No Space in slot
688                                                 dp_ipc_send_errorcode(group->cmd_socket,
689                                                         DP_ERROR_QUEUE_FULL);
690                                         } else {
691                                                 dp_error_type ret = DP_ERROR_NONE;
692                                                 ret = dp_request_create(client_cmd.id, group,
693                                                         &privates->requests[index].request);
694                                                 if (ret == DP_ERROR_NONE) {
695                                                         TRACE_INFO
696                                                                 ("[CREATE] GOOD ID[%d] SLOT[%d]",
697                                                                 privates->requests[index].request->id,
698                                                                 index);
699                                                         __send_return_custom_type(group->cmd_socket,
700                                                                 DP_ERROR_NONE,
701                                                                 &privates->requests[index].request->id,
702                                                                 sizeof(int));
703                                                 } else {
704                                                         TRACE_ERROR
705                                                                 ("[ERROR][%s]", dp_print_errorcode(ret));
706                                                         dp_ipc_send_errorcode
707                                                                 (group->cmd_socket, ret);
708                                                 }
709                                         }
710                                         continue;
711                                 }
712
713                                 // below commands must need ID
714                                 // check exception before searching slots.
715                                 if (client_cmd.id < 0) {
716                                         TRACE_ERROR("[CHECK PROTOCOL] ID should not be -1");
717                                         dp_ipc_send_errorcode(group->cmd_socket,
718                                                 DP_ERROR_INVALID_PARAMETER);
719                                         // disconnect this group, bad client
720                                         FD_CLR(group->cmd_socket, &listen_fdset);
721                                         dp_client_group_free(group);
722                                         privates->groups[i].group = NULL;
723                                         continue;
724                                 }
725
726                                 // search id in requests slot
727                                 index = __get_same_request_index
728                                                         (privates->requests, client_cmd.id);
729
730                                 dp_request *request = NULL;
731                                 if (index >= 0)
732                                         request = privates->requests[index].request;
733
734                                 char *auth_pkgname = NULL;
735                                 if (request != NULL) {
736                                         auth_pkgname = dp_strdup(request->packagename);
737                                 } else {
738                                         auth_pkgname = dp_db_get_text_column(client_cmd.id,
739                                                         DP_DB_TABLE_LOG, DP_DB_COL_PACKAGENAME);
740                                         if (auth_pkgname == NULL) {
741                                                 TRACE_ERROR
742                                                         ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
743                                                         client_cmd.id);
744                                                 dp_ipc_send_errorcode
745                                                 (group->cmd_socket, DP_ERROR_ID_NOT_FOUND);
746                                                 continue;
747                                         }
748                                 }
749
750                                 // auth by pkgname
751                                 if (__cmp_string
752                                         (group->pkgname, auth_pkgname) < 0) {
753                                         TRACE_ERROR
754                                                 ("[ERROR][%d] Auth [%s]/[%s]", client_cmd.id,
755                                                 group->pkgname, auth_pkgname);
756                                         dp_ipc_send_errorcode
757                                         (group->cmd_socket, DP_ERROR_INVALID_PARAMETER);
758                                         free(auth_pkgname);
759                                         continue;
760                                 }
761                                 if (auth_pkgname != NULL)
762                                         free(auth_pkgname);
763
764                                 if (request != NULL && request->group == NULL) {
765                                         // if no group, update group.
766                                         request->group = group;
767                                 }
768
769                                 if (client_cmd.cmd == DP_CMD_DESTROY) {
770                                         if (request != NULL) {
771                                                 CLIENT_MUTEX_LOCK(&(request->mutex));
772                                                 // call download_cancel API
773                                                 if (request->agent_id > 0 &&
774                                                         dp_is_alive_download(request->agent_id)) {
775                                                         TRACE_INFO("[CANCEL-AGENT][%d] agent_id[%d]",
776                                                                 client_cmd.id, request->agent_id);
777                                                         if (dp_cancel_agent_download
778                                                                         (request->agent_id) < 0)
779                                                                 TRACE_INFO("[CANCEL FAILURE][%d]",
780                                                                         client_cmd.id);
781                                                         request->state = DP_STATE_CANCELED;
782                                                         if (dp_db_set_column
783                                                                         (request->id, DP_DB_TABLE_LOG,
784                                                                         DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
785                                                                         &request->state) < 0) {
786                                                                 TRACE_ERROR("[ERROR][%d][SQL] try [%s]",
787                                                                         client_cmd.id,
788                                                                         dp_print_state(request->state));
789                                                                 dp_db_remove_all(request->id);
790                                                         }
791                                                 }
792                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
793                                         }
794                                         // Always return GOOD
795                                         dp_ipc_send_errorcode
796                                                 (group->cmd_socket, DP_ERROR_NONE);
797                                         #if 0
798                                         // remove tmp file
799                                         char *tmp_path =
800                                                 dp_request_get_tmpsavedpath
801                                                         (client_cmd.id, &errorcode);
802                                         if ((tmp_path != NULL && strlen(tmp_path) > 0) &&
803                                                 dp_is_file_exist(tmp_path) == 0) {
804                                                 TRACE_INFO("[REMOVE][%d] TEMP FILE [%s]",
805                                                         client_cmd.id, tmp_path);
806                                                 if (unlink(tmp_path) != 0)
807                                                         TRACE_STRERROR("[ERROR][%d] remove file",
808                                                                 client_cmd.id);
809                                                 free(tmp_path);
810                                         }
811                                         // in DESTROY, clear all info
812                                         dp_db_remove_all(client_cmd.id);
813                                         #else
814                                         // in DESTROY, maintain DB logging
815                                         if (request != NULL) {
816                                                 CLIENT_MUTEX_LOCK(&(request->mutex));
817                                                 // change state to CANCELED.
818                                                 if (request->state == DP_STATE_NONE ||
819                                                         request->state == DP_STATE_READY ||
820                                                         request->state == DP_STATE_QUEUED ||
821                                                         request->state == DP_STATE_CONNECTING ||
822                                                         request->state == DP_STATE_DOWNLOADING ||
823                                                         request->state == DP_STATE_PAUSE_REQUESTED ||
824                                                         request->state == DP_STATE_PAUSED) {
825                                                         request->state = DP_STATE_CANCELED;
826                                                         if (dp_db_set_column
827                                                                         (request->id, DP_DB_TABLE_LOG,
828                                                                         DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
829                                                                         &request->state) < 0) {
830                                                                 TRACE_ERROR("[ERROR][%d][SQL] try [%s]",
831                                                                         client_cmd.id,
832                                                                         dp_print_state(request->state));
833                                                         }
834                                                 }
835                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
836                                         }
837                                         #endif
838                                 } else if (client_cmd.cmd == DP_CMD_FREE) {
839                                         // [destory]-[return]-[free]
840                                         // No return errorcode
841                                         if (request != NULL) {
842                                                 dp_request_free(request);
843                                                 privates->requests[index].request = NULL;
844                                         }
845                                 } else if (client_cmd.cmd == DP_CMD_START) {
846                                         if (request == NULL) { // Support Re-download
847                                                 index =
848                                                         __get_empty_request_index(privates->requests);
849                                                 if (index < 0) {
850                                                         TRACE_ERROR
851                                                                 ("[ERROR][%d] DP_ERROR_QUEUE_FULL",
852                                                                 client_cmd.id);
853                                                         // Busy, No Space in slot
854                                                         dp_ipc_send_errorcode(group->cmd_socket,
855                                                                 DP_ERROR_QUEUE_FULL);
856                                                         continue;
857                                                 }
858                                                 request = dp_request_load_from_log
859                                                                         (client_cmd.id, &errorcode);
860                                                 if (request == NULL) {
861                                                         TRACE_ERROR("[ERROR][%d] [%s]",
862                                                                 client_cmd.id,
863                                                                 dp_print_errorcode(errorcode));
864                                                         dp_ipc_send_errorcode
865                                                                 (group->cmd_socket, errorcode);
866                                                         continue;
867                                                 }
868                                                 // restore callback info
869                                                 request->state_cb = 
870                                                         dp_db_get_int_column(client_cmd.id,
871                                                                         DP_DB_TABLE_REQUEST_INFO,
872                                                                         DP_DB_COL_STATE_EVENT);
873                                                 request->progress_cb = 
874                                                         dp_db_get_int_column(client_cmd.id,
875                                                                         DP_DB_TABLE_REQUEST_INFO,
876                                                                         DP_DB_COL_PROGRESS_EVENT);
877                                                 privates->requests[index].request = request;
878                                         }
879                                         // Check URL
880                                         char *url = dp_request_get_url
881                                                         (client_cmd.id, request, &errorcode);
882                                         if (url == NULL) {
883                                                 TRACE_ERROR("[ERROR][%d] DP_ERROR_INVALID_URL",
884                                                         client_cmd.id);
885                                                 dp_ipc_send_errorcode
886                                                         (group->cmd_socket, DP_ERROR_INVALID_URL);
887                                                 continue;
888                                         } else {
889                                                 free(url);
890                                         }
891                                         if (request->state == DP_STATE_QUEUED ||
892                                                 request->state == DP_STATE_CONNECTING ||
893                                                 request->state == DP_STATE_DOWNLOADING ||
894                                                 request->state == DP_STATE_COMPLETED) {
895                                                 TRACE_ERROR
896                                                         ("[ERROR][%d] now [%s]", client_cmd.id,
897                                                         dp_print_state(request->state));
898                                                 dp_ipc_send_errorcode
899                                                         (group->cmd_socket, DP_ERROR_INVALID_STATE);
900                                                 continue;
901                                         }
902                                         dp_state_type state = DP_STATE_QUEUED;
903                                         if (dp_db_set_column
904                                                         (request->id, DP_DB_TABLE_LOG,
905                                                         DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
906                                                         &state) < 0) {
907                                                 TRACE_ERROR
908                                                         ("[ERROR][%d][SQL] try [%s]->[%s]",
909                                                         client_cmd.id,
910                                                         dp_print_state(request->state),
911                                                         dp_print_state(state));
912                                                 dp_ipc_send_errorcode
913                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
914                                                 continue;
915                                         }
916                                         group->queued_count++;
917                                         if (dp_db_update_date(request->id, DP_DB_TABLE_LOG,
918                                                         DP_DB_COL_ACCESS_TIME) < 0)
919                                                 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
920                                         request->start_time = (int)time(NULL);
921                                         request->pause_time = 0;
922                                         request->stop_time = 0;
923                                         request->state = state;
924                                         request->error = DP_ERROR_NONE;
925                                         // need to check how long take to come here.
926                                         dp_ipc_send_errorcode
927                                                 (group->cmd_socket, DP_ERROR_NONE);
928                                         //send signal to queue thread
929                                         dp_thread_queue_manager_wake_up();
930                                 } else if (client_cmd.cmd == DP_CMD_PAUSE) {
931                                         if (request == NULL) {
932                                                 TRACE_ERROR
933                                                         ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
934                                                         client_cmd.id);
935                                                 dp_ipc_send_errorcode(group->cmd_socket,
936                                                         DP_ERROR_ID_NOT_FOUND);
937                                                 continue;
938                                         }
939                                         if (dp_db_update_date(request->id, DP_DB_TABLE_LOG,
940                                                         DP_DB_COL_ACCESS_TIME) < 0)
941                                                 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
942
943                                         CLIENT_MUTEX_LOCK(&(request->mutex));
944                                         if (request->state > DP_STATE_DOWNLOADING) {
945                                                 TRACE_ERROR
946                                                         ("[ERROR][%d] now [%s]", client_cmd.id,
947                                                         dp_print_state(request->state));
948                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
949                                                 dp_ipc_send_errorcode(group->cmd_socket,
950                                                         DP_ERROR_INVALID_STATE);
951                                                 continue;
952                                         }
953                                         if (request->state <= DP_STATE_QUEUED) {
954                                                 request->state = DP_STATE_PAUSED;
955                                                 request->error = DP_ERROR_NONE;
956                                                 if (dp_db_set_column
957                                                                 (request->id, DP_DB_TABLE_LOG,
958                                                                 DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
959                                                                 &request->state) < 0) {
960                                                         TRACE_ERROR("[ERROR][%d][SQL] try [%s]",
961                                                                 client_cmd.id,
962                                                                 dp_print_state(request->state));
963                                                         dp_ipc_send_errorcode
964                                                                 (group->cmd_socket, DP_ERROR_IO_ERROR);
965                                                 } else {
966                                                         dp_ipc_send_errorcode
967                                                                 (group->cmd_socket, DP_ERROR_NONE);
968                                                 }
969                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
970                                                 continue;
971                                         }
972                                         if (dp_pause_agent_download(request->agent_id)
973                                                 < 0) {
974                                                 TRACE_ERROR
975                                                         ("[ERROR][%d][AGENT][ID:%d] now [%s]",
976                                                         client_cmd.id, request->agent_id,
977                                                         dp_print_state(request->state));
978                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
979                                                 dp_ipc_send_errorcode(group->cmd_socket,
980                                                         DP_ERROR_INVALID_STATE);
981                                                 continue;
982                                         }
983                                         request->pause_time = (int)time(NULL);
984                                         request->state = DP_STATE_PAUSE_REQUESTED;
985                                         request->error = DP_ERROR_NONE;
986                                         if (dp_db_set_column
987                                                         (request->id, DP_DB_TABLE_LOG,
988                                                         DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
989                                                         &request->state) < 0) {
990                                                 TRACE_ERROR("[ERROR][%d][SQL] try [%s]",
991                                                                 client_cmd.id,
992                                                                 dp_print_state(request->state));
993                                                 dp_ipc_send_errorcode
994                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
995                                         } else {
996                                                 dp_ipc_send_errorcode
997                                                         (group->cmd_socket, DP_ERROR_NONE);
998                                         }
999                                         CLIENT_MUTEX_UNLOCK(&(request->mutex));
1000                                 } else if (client_cmd.cmd == DP_CMD_CANCEL) {
1001                                         if (request == NULL) {
1002                                                 // find id in DB.
1003                                                 dp_state_type state =
1004                                                         dp_db_get_int_column(client_cmd.id,
1005                                                                 DP_DB_TABLE_LOG, DP_DB_COL_STATE);
1006                                                 if (state > DP_STATE_NONE) {
1007                                                         // if exist & it is paused, change to canceled.
1008                                                         if (state == DP_STATE_PAUSED ||
1009                                                                 state == DP_STATE_PAUSE_REQUESTED) {
1010                                                                 // change state to canceled.
1011                                                                 state = DP_STATE_CANCELED;
1012                                                                 if (dp_db_set_column
1013                                                                                 (client_cmd.id,
1014                                                                                 DP_DB_TABLE_LOG,
1015                                                                                 DP_DB_COL_STATE,
1016                                                                                 DP_DB_COL_TYPE_INT,
1017                                                                                 &state) < 0) {
1018                                                                         TRACE_ERROR
1019                                                                                 ("[ERROR][%d][SQL] try [%s]",
1020                                                                                         client_cmd.id,
1021                                                                                         dp_print_state(state));
1022                                                                         dp_ipc_send_errorcode
1023                                                                                 (group->cmd_socket,
1024                                                                                 DP_ERROR_IO_ERROR);
1025                                                                 } else {
1026                                                                         dp_ipc_send_errorcode
1027                                                                                 (group->cmd_socket,
1028                                                                                 DP_ERROR_NONE);
1029                                                                 }
1030                                                         } else {
1031                                                                 TRACE_ERROR("[ERROR][%d] now [%s]",
1032                                                                                 client_cmd.id,
1033                                                                                 dp_print_state(state));
1034                                                                 dp_ipc_send_errorcode(group->cmd_socket,
1035                                                                         DP_ERROR_INVALID_STATE);
1036                                                         }
1037                                                         continue;
1038                                                 }
1039                                                 // if not match these conditions, invalied param
1040                                                 TRACE_ERROR
1041                                                         ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1042                                                         client_cmd.id);
1043                                                 dp_ipc_send_errorcode(group->cmd_socket,
1044                                                         DP_ERROR_ID_NOT_FOUND);
1045                                                 continue;
1046                                         }
1047                                         CLIENT_MUTEX_LOCK(&(request->mutex));
1048                                         if (request->state >= DP_STATE_COMPLETED) {
1049                                                 // already finished.
1050                                                 TRACE_ERROR("[ERROR][%d] now [%s]",
1051                                                                 client_cmd.id,
1052                                                                 dp_print_state(request->state));
1053                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1054                                                 dp_ipc_send_errorcode(group->cmd_socket,
1055                                                         DP_ERROR_INVALID_STATE);
1056                                                 continue;
1057                                         }
1058                                         if (request->state <= DP_STATE_QUEUED) {
1059                                                 request->state = DP_STATE_CANCELED;
1060                                                 request->error = DP_ERROR_NONE;
1061                                                 if (dp_db_set_column
1062                                                                 (request->id, DP_DB_TABLE_LOG,
1063                                                                 DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
1064                                                                 &request->state) < 0) {
1065                                                         TRACE_ERROR("[ERROR][%d][SQL] try [%s]",
1066                                                                 client_cmd.id,
1067                                                                 dp_print_state(request->state));
1068                                                         dp_ipc_send_errorcode
1069                                                                 (group->cmd_socket, DP_ERROR_IO_ERROR);
1070                                                 } else {
1071                                                         dp_ipc_send_errorcode
1072                                                                 (group->cmd_socket, DP_ERROR_NONE);
1073                                                 }
1074                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1075                                                 continue;
1076                                         }
1077                                         if (dp_db_update_date(request->id, DP_DB_TABLE_LOG,
1078                                                         DP_DB_COL_ACCESS_TIME) < 0)
1079                                                 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1080
1081                                         if (dp_cancel_agent_download(request->agent_id)
1082                                                 < 0) {
1083                                                 TRACE_ERROR("[ERROR][%d][AGENT][ID:%d] now [%s]",
1084                                                                 client_cmd.id,
1085                                                                 request->agent_id,
1086                                                                 dp_print_state(request->state));
1087                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1088                                                 dp_ipc_send_errorcode
1089                                                         (group->cmd_socket, DP_ERROR_INVALID_STATE);
1090                                                 continue;
1091                                         }
1092                                         // need to check how long take to come here.
1093                                         if (dp_db_set_column
1094                                                         (request->id, DP_DB_TABLE_LOG,
1095                                                         DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
1096                                                         &request->state) < 0) {
1097                                                 TRACE_ERROR("[ERROR][%d][SQL] try [%s]",
1098                                                                 client_cmd.id,
1099                                                                 dp_print_state(request->state));
1100                                                 dp_ipc_send_errorcode
1101                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1102                                         } else {
1103                                                 dp_ipc_send_errorcode
1104                                                         (group->cmd_socket, DP_ERROR_NONE);
1105                                         }
1106                                         CLIENT_MUTEX_UNLOCK(&(request->mutex));
1107                                 } else if (client_cmd.cmd == DP_CMD_SET_URL) {
1108                                         char *url = dp_ipc_read_string(group->cmd_socket);
1109                                         if (url == NULL) {
1110                                                 TRACE_ERROR("[ERROR][%d] DP_ERROR_INVALID_URL",
1111                                                         client_cmd.id);
1112                                                 dp_ipc_send_errorcode
1113                                                         (group->cmd_socket, DP_ERROR_INVALID_URL);
1114                                                 continue;
1115                                         }
1116                                         dp_error_type ret =
1117                                                 dp_request_set_url(client_cmd.id, request, url);
1118                                         TRACE_INFO("[SET_URL][%d][%s]", client_cmd.id, url);
1119                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1120                                         free(url);
1121                                         if (ret != DP_ERROR_NONE)
1122                                                 TRACE_ERROR("[ERROR][%d][%s]",
1123                                                         client_cmd.id, dp_print_errorcode(ret));
1124                                 } else if (client_cmd.cmd == DP_CMD_SET_DESTINATION) {
1125                                         char *dest = dp_ipc_read_string(group->cmd_socket);
1126                                         if (dest == NULL) {
1127                                                 TRACE_ERROR
1128                                                         ("[ERROR][%d] DP_ERROR_INVALID_DESTINATION",
1129                                                         client_cmd.id);
1130                                                 dp_ipc_send_errorcode(group->cmd_socket,
1131                                                         DP_ERROR_INVALID_DESTINATION);
1132                                                 continue;
1133                                         }
1134                                         dp_error_type ret =
1135                                                 dp_request_set_destination
1136                                                         (client_cmd.id, request, dest);
1137                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1138                                         TRACE_INFO("[SET_DEST][%d][%s]", client_cmd.id, dest);
1139                                         free(dest);
1140                                         if (ret != DP_ERROR_NONE)
1141                                                 TRACE_ERROR("[ERROR][%d][%s]",
1142                                                         client_cmd.id, dp_print_errorcode(ret));
1143                                 } else if (client_cmd.cmd == DP_CMD_SET_FILENAME) {
1144                                         char *fname = dp_ipc_read_string(group->cmd_socket);
1145                                         if (fname == NULL) {
1146                                                 TRACE_ERROR
1147                                                         ("[ERROR][%d] DP_ERROR_INVALID_PARAMETER",
1148                                                         client_cmd.id);
1149                                                 dp_ipc_send_errorcode(group->cmd_socket,
1150                                                         DP_ERROR_INVALID_PARAMETER);
1151                                                 continue;
1152                                         }
1153                                         dp_error_type ret =
1154                                                 dp_request_set_filename
1155                                                         (client_cmd.id, request, fname);
1156                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1157                                         TRACE_INFO
1158                                                 ("[SET_FILE][%d][%s]", client_cmd.id, fname);
1159                                         free(fname);
1160                                         if (ret != DP_ERROR_NONE)
1161                                                 TRACE_ERROR("[ERROR][%d][%s]",
1162                                                         client_cmd.id, dp_print_errorcode(ret));
1163                                 } else if (client_cmd.cmd == DP_CMD_SET_NOTIFICATION) {
1164                                         int value = 0;
1165                                         if (dp_ipc_read_custom_type(group->cmd_socket,
1166                                                 &value, sizeof(int)) < 0) {
1167                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1168                                                 client_cmd.id);
1169                                                 dp_ipc_send_errorcode(group->cmd_socket,
1170                                                         DP_ERROR_IO_ERROR);
1171                                                 continue;
1172                                         }
1173                                         dp_error_type ret =
1174                                                 dp_request_set_notification
1175                                                         (client_cmd.id, request, value);
1176                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1177                                         TRACE_INFO
1178                                                 ("[SET_NOTI][%d] [%d]", client_cmd.id, value);
1179                                         if (ret != DP_ERROR_NONE)
1180                                                 TRACE_ERROR("[ERROR][%d][%s]",
1181                                                         client_cmd.id, dp_print_errorcode(ret));
1182                                 } else if (client_cmd.cmd == DP_CMD_SET_STATE_CALLBACK) {
1183                                         int value = 0;
1184                                         if (dp_ipc_read_custom_type(group->cmd_socket,
1185                                                 &value, sizeof(int)) < 0) {
1186                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1187                                                         client_cmd.id);
1188                                                 dp_ipc_send_errorcode(group->cmd_socket,
1189                                                         DP_ERROR_IO_ERROR);
1190                                                 continue;
1191                                         }
1192                                         dp_error_type ret =
1193                                                 dp_request_set_state_event
1194                                                         (client_cmd.id, request, value);
1195                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1196                                         TRACE_INFO
1197                                                 ("[STATE-EVENT][%d][%d]", client_cmd.id, value);
1198                                         if (ret != DP_ERROR_NONE)
1199                                                 TRACE_ERROR("[ERROR][%d][%s]",
1200                                                         client_cmd.id, dp_print_errorcode(ret));
1201                                 } else if (client_cmd.cmd == DP_CMD_SET_PROGRESS_CALLBACK) {
1202                                         int value = 0;
1203                                         if (dp_ipc_read_custom_type(group->cmd_socket,
1204                                                 &value, sizeof(int)) < 0) {
1205                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1206                                                         client_cmd.id);
1207                                                 dp_ipc_send_errorcode(group->cmd_socket,
1208                                                         DP_ERROR_IO_ERROR);
1209                                                 continue;
1210                                         }
1211                                         dp_error_type ret =
1212                                                 dp_request_set_progress_event
1213                                                         (client_cmd.id, request, value);
1214                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1215                                         TRACE_INFO
1216                                                 ("[PROG-EVENT][%d][%d]", client_cmd.id, value);
1217                                         if (ret != DP_ERROR_NONE)
1218                                                 TRACE_ERROR("[ERROR][%d][%s]",
1219                                                         client_cmd.id, dp_print_errorcode(ret));
1220                                 } else if (client_cmd.cmd == DP_CMD_SET_AUTO_DOWNLOAD) {
1221                                         int value = 0;
1222                                         if (dp_ipc_read_custom_type(group->cmd_socket,
1223                                                 &value, sizeof(int)) < 0) {
1224                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1225                                                         client_cmd.id);
1226                                                 dp_ipc_send_errorcode(group->cmd_socket,
1227                                                         DP_ERROR_IO_ERROR);
1228                                                 continue;
1229                                         }
1230                                         dp_error_type ret =
1231                                                 dp_request_set_auto_download
1232                                                         (client_cmd.id, request, value);
1233                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1234                                         TRACE_INFO
1235                                                 ("[SET_AUTO][%d][%d]", client_cmd.id, value);
1236                                         if (ret != DP_ERROR_NONE)
1237                                                 TRACE_ERROR("[ERROR][%d][%s]",
1238                                                         client_cmd.id, dp_print_errorcode(ret));
1239                                 } else if (client_cmd.cmd == DP_CMD_SET_NETWORK_TYPE) {
1240                                         int value = 0;
1241                                         if (dp_ipc_read_custom_type(group->cmd_socket,
1242                                                 &value, sizeof(int)) < 0) {
1243                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1244                                                         client_cmd.id);
1245                                                 dp_ipc_send_errorcode(group->cmd_socket,
1246                                                         DP_ERROR_IO_ERROR);
1247                                                 continue;
1248                                         }
1249                                         dp_error_type ret =
1250                                                 dp_request_set_network_type
1251                                                         (client_cmd.id, request, value);
1252                                         dp_ipc_send_errorcode(group->cmd_socket, ret);
1253                                         TRACE_INFO
1254                                                 ("[SET_NETTYPE][%d][%d]", client_cmd.id, value);
1255                                         if (ret != DP_ERROR_NONE)
1256                                                 TRACE_ERROR("[ERROR][%d][%s]",
1257                                                         client_cmd.id, dp_print_errorcode(ret));
1258                                 } else if (client_cmd.cmd == DP_CMD_SET_EXTRA_PARAM) {
1259                                         char *key = dp_ipc_read_string(group->cmd_socket);
1260                                         if (key == NULL) {
1261                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1262                                                         client_cmd.id);
1263                                                 dp_ipc_send_errorcode
1264                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1265                                                 continue;
1266                                         }
1267                                         char *value = dp_ipc_read_string(group->cmd_socket);
1268                                         if (value == NULL) {
1269                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1270                                                         client_cmd.id);
1271                                                 dp_ipc_send_errorcode
1272                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1273                                                 free(key);
1274                                                 continue;
1275                                         }
1276
1277                                         TRACE_INFO("[EXTRA-PARAM][%d][%s][%s]",
1278                                                 client_cmd.id, key, value);
1279
1280                                         if (dp_db_replace_column
1281                                                         (client_cmd.id, DP_DB_TABLE_NOTIFICATION,
1282                                                         DP_DB_COL_EXTRA_KEY, DP_DB_COL_TYPE_TEXT,
1283                                                         key) < 0) {
1284                                                 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1285                                                 dp_ipc_send_errorcode
1286                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1287                                                 free(key);
1288                                                 free(value);
1289                                                 continue;
1290                                         }
1291                                         free(key);
1292                                         if (dp_db_set_column
1293                                                         (client_cmd.id, DP_DB_TABLE_NOTIFICATION,
1294                                                         DP_DB_COL_EXTRA_VALUE, DP_DB_COL_TYPE_TEXT,
1295                                                         value) < 0) {
1296                                                 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1297                                                 dp_ipc_send_errorcode
1298                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1299                                         } else {
1300                                                 dp_ipc_send_errorcode
1301                                                         (group->cmd_socket, DP_ERROR_NONE);
1302                                         }
1303                                         free(value);
1304                                 } else if (client_cmd.cmd == DP_CMD_SET_HTTP_HEADER) {
1305                                         char *field = dp_ipc_read_string(group->cmd_socket);
1306                                         if (field == NULL) {
1307                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1308                                                         client_cmd.id);
1309                                                 dp_ipc_send_errorcode
1310                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1311                                                 continue;
1312                                         }
1313                                         char *value = dp_ipc_read_string(group->cmd_socket);
1314                                         if (value == NULL) {
1315                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1316                                                         client_cmd.id);
1317                                                 dp_ipc_send_errorcode
1318                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1319                                                 free(field);
1320                                                 continue;
1321                                         }
1322                                         char *check_field = dp_db_cond_get_text_column
1323                                                 (client_cmd.id, DP_DB_TABLE_HTTP_HEADERS,
1324                                                 DP_DB_COL_HEADER_FIELD, DP_DB_COL_HEADER_FIELD,
1325                                                 DP_DB_COL_TYPE_TEXT, field);
1326                                         if (check_field == NULL) {
1327                                                 // INSERT New Field
1328                                                 if (dp_db_insert_column
1329                                                                 (client_cmd.id,
1330                                                                 DP_DB_TABLE_HTTP_HEADERS,
1331                                                                 DP_DB_COL_HEADER_FIELD,
1332                                                                 DP_DB_COL_TYPE_TEXT, field) < 0) {
1333                                                         TRACE_ERROR
1334                                                                 ("[ERROR][%d][SQL]", client_cmd.id);
1335                                                         free(field);
1336                                                         free(value);
1337                                                         dp_ipc_send_errorcode
1338                                                                 (group->cmd_socket, DP_ERROR_IO_ERROR);
1339                                                         continue;
1340                                                 }
1341                                         } else {
1342                                                 free(check_field);
1343                                         }
1344                                         // UPDATE Value for Field
1345                                         if (dp_db_cond_set_column(client_cmd.id,
1346                                                         DP_DB_TABLE_HTTP_HEADERS,
1347                                                         DP_DB_COL_HEADER_DATA,
1348                                                         DP_DB_COL_TYPE_TEXT, value,
1349                                                         DP_DB_COL_HEADER_FIELD, DP_DB_COL_TYPE_TEXT,
1350                                                         field) < 0) {
1351                                                 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1352                                                 dp_ipc_send_errorcode
1353                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1354                                         } else {
1355                                                 dp_ipc_send_errorcode
1356                                                         (group->cmd_socket, DP_ERROR_NONE);
1357                                         }
1358                                         free(field);
1359                                         free(value);
1360                                 } else if (client_cmd.cmd == DP_CMD_DEL_HTTP_HEADER) {
1361                                         char *field = dp_ipc_read_string(group->cmd_socket);
1362                                         if (field == NULL) {
1363                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1364                                                         client_cmd.id);
1365                                                 dp_ipc_send_errorcode
1366                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1367                                                 continue;
1368                                         }
1369                                         char *check_field = dp_db_cond_get_text_column
1370                                                 (client_cmd.id, DP_DB_TABLE_HTTP_HEADERS,
1371                                                 DP_DB_COL_HEADER_FIELD, DP_DB_COL_HEADER_FIELD,
1372                                                 DP_DB_COL_TYPE_TEXT, field);
1373                                         if (check_field == NULL) {
1374                                                 TRACE_ERROR
1375                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1376                                                         client_cmd.id);
1377                                                 dp_ipc_send_errorcode
1378                                                         (group->cmd_socket, DP_ERROR_NO_DATA);
1379                                                 free(field);
1380                                                 continue;
1381                                         }
1382                                         free(check_field);
1383                                         if (dp_db_cond_remove(client_cmd.id,
1384                                                         DP_DB_TABLE_HTTP_HEADERS,
1385                                                         DP_DB_COL_HEADER_FIELD, DP_DB_COL_TYPE_TEXT,
1386                                                         field) < 0) {
1387                                                 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1388                                                 dp_ipc_send_errorcode
1389                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1390                                         } else {
1391                                                 dp_ipc_send_errorcode
1392                                                         (group->cmd_socket, DP_ERROR_NONE);
1393                                         }
1394                                         free(field);
1395                                 } else if (client_cmd.cmd == DP_CMD_GET_HTTP_HEADER) {
1396                                         char *field = dp_ipc_read_string(group->cmd_socket);
1397                                         if (field == NULL) {
1398                                                 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1399                                                         client_cmd.id);
1400                                                 dp_ipc_send_errorcode
1401                                                         (group->cmd_socket, DP_ERROR_IO_ERROR);
1402                                                 continue;
1403                                         }
1404                                         char *value = dp_db_cond_get_text_column
1405                                                 (client_cmd.id, DP_DB_TABLE_HTTP_HEADERS,
1406                                                 DP_DB_COL_HEADER_DATA, DP_DB_COL_HEADER_FIELD,
1407                                                 DP_DB_COL_TYPE_TEXT, field);
1408                                         free(field);
1409                                         if (value == NULL) {
1410                                                 TRACE_ERROR
1411                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1412                                                         client_cmd.id);
1413                                                 dp_ipc_send_errorcode
1414                                                         (group->cmd_socket, DP_ERROR_NO_DATA);
1415                                         } else {
1416                                                 __send_return_string
1417                                                         (group->cmd_socket, DP_ERROR_NONE, value);
1418                                                 free(value);
1419                                         }
1420                                 } else if (client_cmd.cmd == DP_CMD_GET_EXTRA_PARAM) {
1421                                         char *key = dp_db_get_text_column
1422                                                         (client_cmd.id, DP_DB_TABLE_NOTIFICATION,
1423                                                         DP_DB_COL_EXTRA_KEY);
1424                                         if (key == NULL) {
1425                                                 TRACE_ERROR
1426                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1427                                                         client_cmd.id);
1428                                                 dp_ipc_send_errorcode
1429                                                         (group->cmd_socket, DP_ERROR_NO_DATA);
1430                                                 continue;
1431                                         }
1432                                         char *value = dp_db_get_text_column
1433                                                         (client_cmd.id, DP_DB_TABLE_NOTIFICATION,
1434                                                         DP_DB_COL_EXTRA_VALUE);
1435                                         if (value == NULL) {
1436                                                 TRACE_ERROR
1437                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1438                                                         client_cmd.id);
1439                                                 dp_ipc_send_errorcode
1440                                                         (group->cmd_socket, DP_ERROR_NO_DATA);
1441                                         } else {
1442                                                 __send_return_string
1443                                                         (group->cmd_socket, DP_ERROR_NONE, key);
1444                                                 dp_ipc_send_string(group->cmd_socket, value);
1445                                                 free(value);
1446                                         }
1447                                         free(key);
1448                                 } else if (client_cmd.cmd == DP_CMD_GET_URL) {
1449                                         char *url = NULL;
1450                                         errorcode = DP_ERROR_NONE;
1451                                         url = dp_request_get_url
1452                                                         (client_cmd.id, request, &errorcode);
1453                                         if (url == NULL) {
1454                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1455                                                         dp_print_errorcode(errorcode));
1456                                                 dp_ipc_send_errorcode
1457                                                         (group->cmd_socket, errorcode);
1458                                         } else {
1459                                                 __send_return_string
1460                                                         (group->cmd_socket, DP_ERROR_NONE, url);
1461                                                 free(url);
1462                                         }
1463                                 } else if (client_cmd.cmd == DP_CMD_GET_DESTINATION) {
1464                                         char *dest = NULL;
1465                                         errorcode = DP_ERROR_NONE;
1466                                         dest = dp_request_get_destination
1467                                                         (client_cmd.id, request, &errorcode);
1468                                         if (dest == NULL) {
1469                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1470                                                         dp_print_errorcode(errorcode));
1471                                                 dp_ipc_send_errorcode
1472                                                         (group->cmd_socket, errorcode);
1473                                         } else {
1474                                                 __send_return_string
1475                                                         (group->cmd_socket, DP_ERROR_NONE, dest);
1476                                                 free(dest);
1477                                         }
1478                                 } else if (client_cmd.cmd == DP_CMD_GET_FILENAME) {
1479                                         char *filename = NULL;
1480                                         errorcode = DP_ERROR_NONE;
1481                                         filename = dp_request_get_filename
1482                                                         (client_cmd.id, request, &errorcode);
1483                                         if (filename == NULL) {
1484                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1485                                                         dp_print_errorcode(errorcode));
1486                                                 dp_ipc_send_errorcode
1487                                                         (group->cmd_socket, errorcode);
1488                                         } else {
1489                                                 __send_return_string
1490                                                         (group->cmd_socket, DP_ERROR_NONE, filename);
1491                                                 free(filename);
1492                                         }
1493                                 } else if (client_cmd.cmd == DP_CMD_GET_NOTIFICATION) {
1494                                         int enable = 0;
1495                                         enable = dp_db_get_int_column(client_cmd.id,
1496                                                                         DP_DB_TABLE_NOTIFICATION,
1497                                                                         DP_DB_COL_NOTIFICATION_ENABLE);
1498                                         if (enable < 0) {
1499                                                 TRACE_ERROR
1500                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1501                                                         client_cmd.id);
1502                                                 dp_ipc_send_errorcode(group->cmd_socket,
1503                                                         DP_ERROR_NO_DATA);
1504                                         } else {
1505                                                 __send_return_custom_type
1506                                                         (group->cmd_socket, DP_ERROR_NONE,
1507                                                         &enable, sizeof(int));
1508                                         }
1509                                 } else if (client_cmd.cmd == DP_CMD_GET_AUTO_DOWNLOAD) {
1510                                         int enable = 0;
1511                                         enable = dp_db_get_int_column(client_cmd.id,
1512                                                                         DP_DB_TABLE_REQUEST_INFO,
1513                                                                         DP_DB_COL_AUTO_DOWNLOAD);
1514                                         if (enable < 0) {
1515                                                 TRACE_ERROR
1516                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1517                                                         client_cmd.id);
1518                                                 dp_ipc_send_errorcode(group->cmd_socket,
1519                                                         DP_ERROR_NO_DATA);
1520                                         } else {
1521                                                 __send_return_custom_type
1522                                                         (group->cmd_socket, DP_ERROR_NONE,
1523                                                         &enable, sizeof(int));
1524                                         }
1525                                 } else if (client_cmd.cmd == DP_CMD_GET_NETWORK_TYPE) {
1526                                         int type = 0;
1527                                         type = dp_db_get_int_column(client_cmd.id,
1528                                                                         DP_DB_TABLE_REQUEST_INFO,
1529                                                                         DP_DB_COL_NETWORK_TYPE);
1530                                         if (type < 0) {
1531                                                 TRACE_ERROR
1532                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1533                                                         client_cmd.id);
1534                                                 dp_ipc_send_errorcode(group->cmd_socket,
1535                                                         DP_ERROR_NO_DATA);
1536                                         } else {
1537                                                 __send_return_custom_type
1538                                                         (group->cmd_socket, DP_ERROR_NONE,
1539                                                         &type, sizeof(dp_network_type));
1540                                         }
1541                                 } else if (client_cmd.cmd == DP_CMD_GET_SAVED_PATH) {
1542                                         char *savedpath = NULL;
1543                                         errorcode = DP_ERROR_NONE;
1544                                         savedpath = dp_request_get_savedpath
1545                                                         (client_cmd.id, request, &errorcode);
1546                                         if (savedpath == NULL) {
1547                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1548                                                         dp_print_errorcode(errorcode));
1549                                                 dp_ipc_send_errorcode
1550                                                         (group->cmd_socket, errorcode);
1551                                         } else {
1552                                                 __send_return_string
1553                                                         (group->cmd_socket, DP_ERROR_NONE, savedpath);
1554                                                 free(savedpath);
1555                                         }
1556                                 } else if (client_cmd.cmd == DP_CMD_GET_TEMP_SAVED_PATH) {
1557                                         char *tmppath = NULL;
1558                                         errorcode = DP_ERROR_NONE;
1559                                         tmppath = dp_request_get_tmpsavedpath
1560                                                         (client_cmd.id, request, &errorcode);
1561                                         if (tmppath == NULL) {
1562                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1563                                                         dp_print_errorcode(errorcode));
1564                                                 dp_ipc_send_errorcode
1565                                                         (group->cmd_socket, errorcode);
1566                                         } else {
1567                                                 __send_return_string
1568                                                         (group->cmd_socket, DP_ERROR_NONE, tmppath);
1569                                                 free(tmppath);
1570                                         }
1571                                 } else if (client_cmd.cmd == DP_CMD_GET_MIME_TYPE) {
1572                                         char *mimetype = NULL;
1573                                         errorcode = DP_ERROR_NONE;
1574                                         mimetype = dp_request_get_mimetype
1575                                                         (client_cmd.id, request, &errorcode);
1576                                         if (mimetype == NULL) {
1577                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1578                                                         dp_print_errorcode(errorcode));
1579                                                 dp_ipc_send_errorcode
1580                                                         (group->cmd_socket, errorcode);
1581                                         } else {
1582                                                 __send_return_string
1583                                                         (group->cmd_socket, DP_ERROR_NONE, mimetype);
1584                                                 free(mimetype);
1585                                         }
1586                                 } else if (client_cmd.cmd == DP_CMD_GET_RECEIVED_SIZE) {
1587                                         if (request == NULL) {
1588                                                 TRACE_ERROR
1589                                                         ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1590                                                         client_cmd.id);
1591                                                 dp_ipc_send_errorcode(group->cmd_socket,
1592                                                         DP_ERROR_ID_NOT_FOUND);
1593                                         } else {
1594                                                 __send_return_custom_type
1595                                                         (group->cmd_socket, DP_ERROR_NONE,
1596                                                         &request->received_size,
1597                                                         sizeof(unsigned long long));
1598                                         }
1599                                 } else if (client_cmd.cmd == DP_CMD_GET_TOTAL_FILE_SIZE) {
1600                                         if (request != NULL) {
1601                                                 __send_return_custom_type(group->cmd_socket,
1602                                                         DP_ERROR_NONE, &request->file_size,
1603                                                         sizeof(unsigned long long));
1604                                                 continue;
1605                                         }
1606                                         long long file_size =
1607                                                 dp_db_get_int64_column(client_cmd.id,
1608                                                                         DP_DB_TABLE_DOWNLOAD_INFO,
1609                                                                         DP_DB_COL_CONTENT_SIZE);
1610                                         if (file_size < 0) {
1611                                                 TRACE_ERROR
1612                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1613                                                         client_cmd.id);
1614                                                 dp_ipc_send_errorcode(group->cmd_socket,
1615                                                         DP_ERROR_NO_DATA);
1616                                         } else {
1617                                                 // casting
1618                                                 unsigned long long total_file_size = file_size;
1619                                                 __send_return_custom_type
1620                                                         (group->cmd_socket, DP_ERROR_NONE,
1621                                                         &total_file_size, sizeof(total_file_size));
1622                                         }
1623                                 } else if (client_cmd.cmd == DP_CMD_GET_CONTENT_NAME) {
1624                                         char *content = NULL;
1625                                         errorcode = DP_ERROR_NONE;
1626                                         content = dp_request_get_contentname
1627                                                         (client_cmd.id, request, &errorcode);
1628                                         if (content == NULL) {
1629                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1630                                                         dp_print_errorcode(errorcode));
1631                                                 dp_ipc_send_errorcode
1632                                                         (group->cmd_socket, errorcode);
1633                                         } else {
1634                                                 __send_return_string
1635                                                         (group->cmd_socket, DP_ERROR_NONE, content);
1636                                                 free(content);
1637                                         }
1638                                 } else if (client_cmd.cmd == DP_CMD_GET_HTTP_STATUS) {
1639                                         int http_status = 0;
1640                                         http_status = dp_db_get_int_column(client_cmd.id,
1641                                                                         DP_DB_TABLE_DOWNLOAD_INFO,
1642                                                                         DP_DB_COL_HTTP_STATUS);
1643                                         if (http_status < 0) {
1644                                                 TRACE_ERROR
1645                                                         ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1646                                                         client_cmd.id);
1647                                                 dp_ipc_send_errorcode(group->cmd_socket,
1648                                                         DP_ERROR_NO_DATA);
1649                                         } else {
1650                                                 __send_return_custom_type
1651                                                         (group->cmd_socket, DP_ERROR_NONE,
1652                                                         &http_status, sizeof(int));
1653                                         }
1654                                 } else if (client_cmd.cmd == DP_CMD_GET_ETAG) {
1655                                         char *etag = NULL;
1656                                         errorcode = DP_ERROR_NONE;
1657                                         etag = dp_request_get_etag
1658                                                         (client_cmd.id, request, &errorcode);
1659                                         if (etag == NULL) {
1660                                                 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1661                                                         dp_print_errorcode(errorcode));
1662                                                 dp_ipc_send_errorcode
1663                                                         (group->cmd_socket, errorcode);
1664                                         } else {
1665                                                 __send_return_string
1666                                                         (group->cmd_socket, DP_ERROR_NONE, etag);
1667                                                 free(etag);
1668                                         }
1669                                 } else if (client_cmd.cmd == DP_CMD_GET_STATE) {
1670                                         dp_state_type download_state = DP_STATE_NONE;
1671                                         if (request == NULL) {
1672                                                 download_state =
1673                                                         dp_db_get_int_column(client_cmd.id,
1674                                                                                 DP_DB_TABLE_LOG,
1675                                                                                 DP_DB_COL_STATE);
1676                                                 if (download_state < 0) {
1677                                                         TRACE_ERROR
1678                                                         ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1679                                                         client_cmd.id);
1680                                                         dp_ipc_send_errorcode(group->cmd_socket,
1681                                                                 DP_ERROR_ID_NOT_FOUND);
1682                                                         continue;
1683                                                 }
1684                                         } else {
1685                                                 CLIENT_MUTEX_LOCK(&(request->mutex));
1686                                                 download_state = request->state;
1687                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1688                                         }
1689                                         __send_return_custom_type
1690                                                 (group->cmd_socket, DP_ERROR_NONE,
1691                                                 &download_state, sizeof(dp_state_type));
1692                                 } else if (client_cmd.cmd == DP_CMD_GET_ERROR) {
1693                                         errorcode = DP_ERROR_NONE;
1694                                         if (request == NULL) {
1695                                                 errorcode =
1696                                                         dp_db_get_int_column(client_cmd.id,
1697                                                                                 DP_DB_TABLE_LOG,
1698                                                                                 DP_DB_COL_ERRORCODE);
1699                                                 if (errorcode < 0) {
1700                                                         TRACE_ERROR
1701                                                         ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1702                                                         client_cmd.id);
1703                                                         dp_ipc_send_errorcode(group->cmd_socket,
1704                                                                 DP_ERROR_ID_NOT_FOUND);
1705                                                         continue;
1706                                                 }
1707                                         } else {
1708                                                 CLIENT_MUTEX_LOCK(&(request->mutex));
1709                                                 errorcode = request->error;
1710                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1711                                         }
1712                                         dp_ipc_send_errorcode
1713                                                 (group->cmd_socket, DP_ERROR_NONE);
1714                                         dp_ipc_send_errorcode
1715                                                 (group->cmd_socket, errorcode);
1716                                 } else {
1717                                         TRACE_INFO
1718                                                 ("[UNKNOWN] I [%d] PID [%d]", i,
1719                                                 privates->groups[i].group->credential.pid);
1720                                         dp_ipc_send_errorcode(group->cmd_socket,
1721                                                 DP_ERROR_INVALID_PARAMETER);
1722                                         // disconnect this group, bad client
1723                                         FD_CLR(group->cmd_socket, &listen_fdset);
1724                                         dp_client_group_free(group);
1725                                         privates->groups[i].group = NULL;
1726                                 }
1727                         } // FD_ISSET
1728                 } // DP_MAX_GROUP
1729
1730                 // timeout
1731                 if (is_timeout == 1) {
1732                         int now_timeout = (int)time(NULL);
1733                         TRACE_INFO("[TIMEOUT] prev %ld, now %ld, setted %ld sec",
1734                                 prev_timeout, now_timeout, flexible_timeout);
1735                         if (prev_timeout == 0) {
1736                                 prev_timeout = now_timeout;
1737                         } else {
1738                                 if ((now_timeout - prev_timeout) <
1739                                         DP_CARE_CLIENT_MIN_INTERVAL) {
1740                                         // this is error.
1741                                         // terminate Process
1742                                         TRACE_STRERROR
1743                                         ("[CRITICAL] Sock exception prev[%ld]now[%ld][%ld]",
1744                                         prev_timeout, now_timeout, flexible_timeout);
1745                                         break;
1746                                 }
1747                         }
1748
1749                         // get 48hour old request from log DB
1750                         // clear old request
1751                         dp_db_limit_rows(DP_LOG_DB_LIMIT_ROWS);
1752                         int old_request_count = dp_db_get_count_by_limit_time();
1753                         if (old_request_count > 0) {
1754                                 if (old_request_count > DP_LOG_DB_CLEAR_LIMIT_ONE_TIME)
1755                                         old_request_count = DP_LOG_DB_CLEAR_LIMIT_ONE_TIME;
1756
1757                                 TRACE_INFO
1758                                         ("[CLEAR] [%d] old reqeusts", old_request_count);
1759
1760                                 dp_request_slots *old_requests =
1761                                         dp_request_slots_new(old_request_count);
1762                                 if (old_requests) {
1763                                         int list_count = dp_db_get_list_by_limit_time
1764                                                                 (old_requests, old_request_count);
1765                                         if (list_count > 0) {
1766                                                 for (i = 0; i < list_count; i++) {
1767                                                         // search on slots by ID.
1768                                                         int index =
1769                                                                 __get_same_request_index
1770                                                                         (privates->requests,
1771                                                                         old_requests[i].request->id);
1772                                                         if (index >= 0) {
1773                                                                 dp_request *request =
1774                                                                         privates->requests[index].request;
1775                                                                 // if downloading..remain it.
1776                                                                 CLIENT_MUTEX_LOCK(&(request->mutex));
1777                                                                 if (request->state ==
1778                                                                         DP_STATE_CONNECTING ||
1779                                                                         request->state ==
1780                                                                         DP_STATE_DOWNLOADING) {
1781                                                                         CLIENT_MUTEX_UNLOCK
1782                                                                                 (&(request->mutex));
1783                                                                         continue;
1784                                                                 }
1785                                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1786                                                                 // unload from slots ( memory )
1787                                                                 dp_request_free(request);
1788                                                                 privates->requests[index].request = NULL;
1789                                                         }
1790                                                         // remove tmp file
1791                                                         char *tmp_path =
1792                                                                 dp_request_get_tmpsavedpath
1793                                                                         (old_requests[i].request->id,
1794                                                                         old_requests[i].request,
1795                                                                         &errorcode);
1796                                                         if ((tmp_path && strlen(tmp_path) > 0) &&
1797                                                                 dp_is_file_exist(tmp_path) == 0) {
1798                                                                 TRACE_INFO
1799                                                                         ("[REMOVE][%d] TEMP FILE [%s]",
1800                                                                         old_requests[i].request->id,
1801                                                                         tmp_path);
1802                                                                 if (unlink(tmp_path) != 0)
1803                                                                         TRACE_STRERROR
1804                                                                                 ("[ERROR][%d] remove file",
1805                                                                                 old_requests[i].request->id);
1806                                                                 free(tmp_path);
1807                                                         }
1808                                                         // remove from DB
1809                                                         dp_db_remove_all(old_requests[i].request->id);
1810                                                 }
1811                                         }
1812                                         dp_request_slots_free(old_requests, old_request_count);
1813                                 }
1814                         }
1815
1816                         // clean slots
1817                         int ready_requests = 0;
1818                         for (i = 0; i < DP_MAX_REQUEST; i++) {
1819                                 if (!privates->requests[i].request)
1820                                         continue;
1821                                 dp_request *request = privates->requests[i].request;
1822
1823                                 CLIENT_MUTEX_LOCK(&(request->mutex));
1824
1825                                 // If downloading is too slow ? how to deal this request?
1826                                 // can limit too slot download using starttime.(48 hours)
1827                                 if (request->state == DP_STATE_CONNECTING ||
1828                                         request->state == DP_STATE_DOWNLOADING) {
1829                                         CLIENT_MUTEX_UNLOCK(&(request->mutex));
1830                                         continue;
1831                                 }
1832
1833                                 // paused & agent_id not exist.... unload from memory.
1834                                 if (request->state == DP_STATE_PAUSED &&
1835                                         dp_is_alive_download(request->agent_id) == 0) {
1836                                         CLIENT_MUTEX_UNLOCK(&(request->mutex));
1837                                         TRACE_INFO
1838                                         ("[FREE] [%d] unavailable agent ID [%d]",
1839                                                 request->id, request->agent_id);
1840                                         dp_request_free(request);
1841                                         privates->requests[i].request = NULL;
1842                                         continue;
1843                                 }
1844
1845                                 // client should call START command in 60 sec
1846                                 // unload from memory
1847                                 if (request->start_time <= 0 &&
1848                                         (now_timeout - request->create_time) >
1849                                                 DP_CARE_CLIENT_MAX_INTERVAL) {
1850                                         int download_id = request->id;
1851                                         dp_state_type state = DP_STATE_FAILED;
1852                                         errorcode = DP_ERROR_RESPONSE_TIMEOUT;
1853                                         if (request->group
1854                                                 && request->group->event_socket >= 0
1855                                                 && request->state_cb)
1856                                                 dp_ipc_send_event
1857                                                         (request->group->event_socket,
1858                                                         download_id, state, errorcode, 0);
1859                                         CLIENT_MUTEX_UNLOCK(&(request->mutex));
1860                                         TRACE_INFO
1861                                         ("[FREE] no response ID[%d] last access [%ld]",
1862                                                 request->id, request->start_time);
1863                                         dp_request_free(request);
1864                                         privates->requests[i].request = NULL;
1865                                         // no problem although updating is failed.
1866                                         if (dp_db_set_column
1867                                                         (download_id, DP_DB_TABLE_LOG,
1868                                                         DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
1869                                                         &state) < 0) {
1870                                                 TRACE_ERROR("[ERROR][%d][SQL]", request->id);
1871                                         }
1872                                         if (dp_db_set_column
1873                                                         (download_id, DP_DB_TABLE_LOG,
1874                                                         DP_DB_COL_ERRORCODE, DP_DB_COL_TYPE_INT,
1875                                                         &errorcode) < 0) {
1876                                                 TRACE_ERROR("[ERROR][%d][SQL]", request->id);
1877                                         }
1878                                         continue;
1879                                 }
1880
1881                                 // client should call DESTROY command in 60 sec after finished
1882                                 if (request->stop_time > 0 &&
1883                                         (now_timeout - request->stop_time) >
1884                                         DP_CARE_CLIENT_MAX_INTERVAL) {
1885                                         // check state again. stop_time means it's stopped
1886                                         if (request->state == DP_STATE_COMPLETED ||
1887                                                 request->state == DP_STATE_FAILED ||
1888                                                 request->state == DP_STATE_CANCELED) {
1889                                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1890                                                 TRACE_INFO("[FREE] by timeout cleaner ID[%d]",
1891                                                         request->id);
1892                                                 dp_request_free(request);
1893                                                 privates->requests[i].request = NULL;
1894                                                 continue;
1895                                         }
1896                                 }
1897
1898                                 // check after clear
1899                                 if (request->state == DP_STATE_QUEUED)
1900                                         ready_requests++;
1901
1902                                 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1903                         }
1904
1905                         if (ready_requests > 0) {
1906                                 //send signal to queue thread will check queue.
1907                                 dp_thread_queue_manager_wake_up();
1908                         } else {
1909 #ifdef DP_SUPPORT_DBUS_ACTIVATION
1910                                 // if no request & timeout is bigger than 60 sec
1911                                 // terminate by self.
1912                                 if ((now_timeout - prev_timeout) >= flexible_timeout &&
1913                                         dp_get_request_count(privates->requests) <= 0) {
1914                                         TRACE_INFO("No Request. Terminate Daemon");
1915                                         break;
1916                                 }
1917 #endif
1918                         }
1919                         prev_timeout = now_timeout;
1920                 } // timeout
1921         }
1922         TRACE_INFO("terminate main thread ...");
1923         dp_terminate(SIGTERM);
1924         pthread_exit(NULL);
1925         return 0;
1926 }