2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <sys/socket.h>
30 #include <app_manager.h>
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"
43 void dp_terminate(int signo);
45 static char *__print_command(dp_command_type cmd)
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";
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 :
125 case DP_CMD_GET_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";
134 return "UNKNOWN COMMAND";
137 /* compare two string */
138 static int __cmp_string(char *s1, char *s2)
144 TRACE_ERROR("[CHECK PARAM]");
150 TRACE_ERROR("[CHECK PARAM] len[%d]", s1_len);
156 TRACE_ERROR("[CHECK PARAM] len[%d]", s2_len);
160 if (s1_len != s2_len) {
161 TRACE_ERROR("[DIFF] len[%d:%d]", s1_len, s2_len);
165 if (strncmp(s1, s2, s1_len) != 0) {
166 TRACE_ERROR("[DIFF] cmp[%s:%s]", s1, s2);
173 //////////////////////////////////////////////////////////////////////////
174 /// @brief return index of empty slot
175 static int __get_empty_request_index(dp_request_slots *slots)
182 for (i = 0; i < DP_MAX_REQUEST; i++)
183 if (!slots[i].request)
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)
195 if (!slots || id < 0)
198 for (i = 0; i < DP_MAX_REQUEST; i++) {
199 if (slots[i].request) {
200 if (slots[i].request->id == id) {
208 //////////////////////////////////////////////////////////////////////////
209 /// @brief return string via IPC
210 static void __send_return_string(int fd, dp_error_type errcode, char* str)
214 dp_ipc_send_errorcode(fd, errcode);
215 dp_ipc_send_string(fd, str);
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)
222 dp_ipc_send_errorcode(fd, errcode);
223 dp_ipc_send_custom_type(fd, value, type_size);
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)
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;
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;
242 dp_privates *privates = (dp_privates*)arg;
243 if (!privates || !privates->groups) {
244 TRACE_ERROR("[CRITICAL] Invalid Address");
245 dp_terminate(SIGTERM);
250 listenfd = privates->listen_fd;
253 TRACE_INFO("Ready to listen [%d][%s]", listenfd, DP_IPC);
255 FD_ZERO(&listen_fdset);
256 FD_ZERO(&except_fdset);
257 FD_SET(listenfd, &listen_fdset);
258 FD_SET(listenfd, &except_fdset);
260 while (privates && privates->listen_fd) {
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;
275 if (select((maxfd + 1), &rset, 0, &eset, &timeout) < 0) {
276 TRACE_STRERROR("[CRITICAL] select");
281 TRACE_INFO("Terminate Thread");
285 if (FD_ISSET(listenfd, &eset) > 0) {
286 TRACE_ERROR("[CRITICAL] listenfd Exception of socket");
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
295 // Anyway accept client.
296 clientlen = sizeof(clientaddr);
297 clientfd = accept(listenfd,
298 (struct sockaddr*)&clientaddr,
301 TRACE_INFO("[New Connection]");
304 TRACE_ERROR("[CRITICAL] accept provider was crashed ?");
305 // provider need the time of refresh.
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");
316 if (connect_cmd <= 0) {
317 TRACE_ERROR("[CRITICAL] peer terminate ?");
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");
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) {
334 ("credential : pid=%d, uid=%d, gid=%d",
335 credential.pid, credential.uid, credential.gid);
337 #else // In case of not supported SO_PEERCRED
339 if (dp_ipc_read_custom_type(clientfd,
340 &client_pid, sizeof(int)) < 0) {
341 TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
345 if (client_pid <= 0) {
346 TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
350 credential.pid = client_pid;
351 credential.uid = 5000;
352 credential.gid = 5000;
355 struct timeval tv_timeo; // 2.5 sec
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");
364 if (setsockopt(clientfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo,
365 sizeof( tv_timeo ) ) < 0) {
366 TRACE_STRERROR("[CRITICAL] setsockopt SO_SNDTIMEO");
371 if (connect_cmd == DP_CMD_SET_COMMAND_SOCKET) {
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;
380 // getting the package name via pid
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);
387 TRACE_ERROR("[CRITICAL] app_manager_get_package");
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
395 || !privates->groups[i].group->pkgname) {
397 (privates->groups[i].group);
398 privates->groups[i].group = NULL;
402 (privates->groups[i].group->pkgname)
405 (privates->groups[i].group->pkgname,
406 client_pkgname, pkgname_length)
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
414 && privates->groups[i].group->cmd_socket
417 (privates->groups[i].group->cmd_socket,
420 (privates->groups[i].group->cmd_socket);
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;
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)
437 if (i >= DP_MAX_GROUP) {
438 TRACE_ERROR("[CRITICAL] No space in groups");
439 close(clientfd); // how to deal in url-download ?
441 free(client_pkgname);
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);
452 ("New Group : GI %d [%s] PID [%d] cmd_socket[%d]",
453 i, client_pkgname, credential.pid, clientfd);
456 privates->groups[i].group =
457 (dp_client_group *) calloc(1,
458 sizeof(dp_client_group));
459 if (!privates->groups[i].group) {
461 ("[CRITICAL] calloc, ignore this client");
464 free(client_pkgname);
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 =
475 privates->groups[i].group->credential.uid =
477 privates->groups[i].group->credential.gid =
479 FD_SET(privates->groups[i].group->cmd_socket,
481 if (privates->groups[i].group->cmd_socket > maxfd)
482 maxfd = privates->groups[i].group->cmd_socket;
484 ("Group : GI [%d] [%s] S [%d] Max [%d]",
486 privates->groups[i].group->cmd_socket, maxfd);
489 free(client_pkgname);
491 } else if (connect_cmd == DP_CMD_SET_EVENT_SOCKET) {
493 // search same pid in groups. have same life-cycle with cmd_socket
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) {
504 ("Found Group : I %d [%s] PID [%d] \
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;
513 ("Found Group : I %d PID [%d] \
515 i, credential.pid, clientfd);
520 if (i >= DP_MAX_GROUP) {
522 ("[CRITICAL] Not found group for PID [%d]",
530 // listen cmd_socket of all group
531 for (i = 0; i < DP_MAX_GROUP; i++) {
532 if (!privates->groups[i].group)
534 if (privates->groups[i].group->cmd_socket < 0) {
537 if (FD_ISSET(privates->groups[i].group->cmd_socket, &rset)
539 dp_client_group *group = privates->groups[i].group;
540 dp_command client_cmd;
544 client_cmd.cmd = DP_CMD_NONE;
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
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);
561 if (client_cmd.cmd == 0) { // Client meet some Error.
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)
569 if (!privates->requests[index].request->group)
571 if (privates->requests[index].request->id <= 0)
573 dp_request *request =
574 privates->requests[index].request;
576 CLIENT_MUTEX_LOCK(&request->mutex);
577 if (request->group != group ||
578 request->group->cmd_socket !=
580 CLIENT_MUTEX_UNLOCK(&request->mutex);
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);
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;
604 (request->id, DP_DB_TABLE_LOG,
607 &request->state) < 0) {
608 TRACE_ERROR("[ERROR][%d][SQL]",
610 dp_db_remove_all(request->id);
613 (request->id, DP_DB_TABLE_LOG,
616 &request->error) < 0) {
617 TRACE_ERROR("[ERROR][%d][SQL]",
622 CLIENT_MUTEX_UNLOCK(&request->mutex);
623 dp_request_free(request);
624 privates->requests[index].request = NULL;
626 // call cancel_agent after free.
628 dp_is_alive_download(agentid)) {
630 ("[CANCEL-AGENT][%d] state [%s]",
631 requestid, dp_print_state(state));
632 if (dp_cancel_agent_download(agentid) <
634 TRACE_INFO("[CANCEL FAILURE]");
641 TRACE_INFO("[DISCONNECT][%d] [%s] fd[%d]",
642 request->id, request->group->pkgname,
643 request->group->cmd_socket);
645 request->group = NULL;
646 request->state_cb = 0;
647 request->progress_cb = 0;
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) {
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;
664 CLIENT_MUTEX_UNLOCK(&(request->mutex));
667 FD_CLR(group->cmd_socket, &listen_fdset);
668 dp_client_group_free(group);
669 privates->groups[i].group = NULL;
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);
682 if (client_cmd.cmd == DP_CMD_CREATE) {
683 // search empty slot in privates->requests
684 index = __get_empty_request_index(privates->requests);
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);
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) {
696 ("[CREATE] GOOD ID[%d] SLOT[%d]",
697 privates->requests[index].request->id,
699 __send_return_custom_type(group->cmd_socket,
701 &privates->requests[index].request->id,
705 ("[ERROR][%s]", dp_print_errorcode(ret));
706 dp_ipc_send_errorcode
707 (group->cmd_socket, ret);
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;
726 // search id in requests slot
727 index = __get_same_request_index
728 (privates->requests, client_cmd.id);
730 dp_request *request = NULL;
732 request = privates->requests[index].request;
734 char *auth_pkgname = NULL;
735 if (request != NULL) {
736 auth_pkgname = dp_strdup(request->packagename);
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) {
742 ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
744 dp_ipc_send_errorcode
745 (group->cmd_socket, DP_ERROR_ID_NOT_FOUND);
752 (group->pkgname, auth_pkgname) < 0) {
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);
761 if (auth_pkgname != NULL)
764 if (request != NULL && request->group == NULL) {
765 // if no group, update group.
766 request->group = group;
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]",
781 request->state = DP_STATE_CANCELED;
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]",
788 dp_print_state(request->state));
789 dp_db_remove_all(request->id);
792 CLIENT_MUTEX_UNLOCK(&(request->mutex));
794 // Always return GOOD
795 dp_ipc_send_errorcode
796 (group->cmd_socket, DP_ERROR_NONE);
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",
811 // in DESTROY, clear all info
812 dp_db_remove_all(client_cmd.id);
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;
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]",
832 dp_print_state(request->state));
835 CLIENT_MUTEX_UNLOCK(&(request->mutex));
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;
845 } else if (client_cmd.cmd == DP_CMD_START) {
846 if (request == NULL) { // Support Re-download
848 __get_empty_request_index(privates->requests);
851 ("[ERROR][%d] DP_ERROR_QUEUE_FULL",
853 // Busy, No Space in slot
854 dp_ipc_send_errorcode(group->cmd_socket,
855 DP_ERROR_QUEUE_FULL);
858 request = dp_request_load_from_log
859 (client_cmd.id, &errorcode);
860 if (request == NULL) {
861 TRACE_ERROR("[ERROR][%d] [%s]",
863 dp_print_errorcode(errorcode));
864 dp_ipc_send_errorcode
865 (group->cmd_socket, errorcode);
868 // restore callback info
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;
880 char *url = dp_request_get_url
881 (client_cmd.id, request, &errorcode);
883 TRACE_ERROR("[ERROR][%d] DP_ERROR_INVALID_URL",
885 dp_ipc_send_errorcode
886 (group->cmd_socket, DP_ERROR_INVALID_URL);
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) {
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);
902 dp_state_type state = DP_STATE_QUEUED;
904 (request->id, DP_DB_TABLE_LOG,
905 DP_DB_COL_STATE, DP_DB_COL_TYPE_INT,
908 ("[ERROR][%d][SQL] try [%s]->[%s]",
910 dp_print_state(request->state),
911 dp_print_state(state));
912 dp_ipc_send_errorcode
913 (group->cmd_socket, DP_ERROR_IO_ERROR);
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) {
933 ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
935 dp_ipc_send_errorcode(group->cmd_socket,
936 DP_ERROR_ID_NOT_FOUND);
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);
943 CLIENT_MUTEX_LOCK(&(request->mutex));
944 if (request->state > DP_STATE_DOWNLOADING) {
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);
953 if (request->state <= DP_STATE_QUEUED) {
954 request->state = DP_STATE_PAUSED;
955 request->error = DP_ERROR_NONE;
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]",
962 dp_print_state(request->state));
963 dp_ipc_send_errorcode
964 (group->cmd_socket, DP_ERROR_IO_ERROR);
966 dp_ipc_send_errorcode
967 (group->cmd_socket, DP_ERROR_NONE);
969 CLIENT_MUTEX_UNLOCK(&(request->mutex));
972 if (dp_pause_agent_download(request->agent_id)
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);
983 request->pause_time = (int)time(NULL);
984 request->state = DP_STATE_PAUSE_REQUESTED;
985 request->error = DP_ERROR_NONE;
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]",
992 dp_print_state(request->state));
993 dp_ipc_send_errorcode
994 (group->cmd_socket, DP_ERROR_IO_ERROR);
996 dp_ipc_send_errorcode
997 (group->cmd_socket, DP_ERROR_NONE);
999 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1000 } else if (client_cmd.cmd == DP_CMD_CANCEL) {
1001 if (request == NULL) {
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
1019 ("[ERROR][%d][SQL] try [%s]",
1021 dp_print_state(state));
1022 dp_ipc_send_errorcode
1026 dp_ipc_send_errorcode
1031 TRACE_ERROR("[ERROR][%d] now [%s]",
1033 dp_print_state(state));
1034 dp_ipc_send_errorcode(group->cmd_socket,
1035 DP_ERROR_INVALID_STATE);
1039 // if not match these conditions, invalied param
1041 ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1043 dp_ipc_send_errorcode(group->cmd_socket,
1044 DP_ERROR_ID_NOT_FOUND);
1047 CLIENT_MUTEX_LOCK(&(request->mutex));
1048 if (request->state >= DP_STATE_COMPLETED) {
1049 // already finished.
1050 TRACE_ERROR("[ERROR][%d] now [%s]",
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);
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]",
1067 dp_print_state(request->state));
1068 dp_ipc_send_errorcode
1069 (group->cmd_socket, DP_ERROR_IO_ERROR);
1071 dp_ipc_send_errorcode
1072 (group->cmd_socket, DP_ERROR_NONE);
1074 CLIENT_MUTEX_UNLOCK(&(request->mutex));
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);
1081 if (dp_cancel_agent_download(request->agent_id)
1083 TRACE_ERROR("[ERROR][%d][AGENT][ID:%d] now [%s]",
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);
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]",
1099 dp_print_state(request->state));
1100 dp_ipc_send_errorcode
1101 (group->cmd_socket, DP_ERROR_IO_ERROR);
1103 dp_ipc_send_errorcode
1104 (group->cmd_socket, DP_ERROR_NONE);
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);
1110 TRACE_ERROR("[ERROR][%d] DP_ERROR_INVALID_URL",
1112 dp_ipc_send_errorcode
1113 (group->cmd_socket, DP_ERROR_INVALID_URL);
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);
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);
1128 ("[ERROR][%d] DP_ERROR_INVALID_DESTINATION",
1130 dp_ipc_send_errorcode(group->cmd_socket,
1131 DP_ERROR_INVALID_DESTINATION);
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);
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) {
1147 ("[ERROR][%d] DP_ERROR_INVALID_PARAMETER",
1149 dp_ipc_send_errorcode(group->cmd_socket,
1150 DP_ERROR_INVALID_PARAMETER);
1154 dp_request_set_filename
1155 (client_cmd.id, request, fname);
1156 dp_ipc_send_errorcode(group->cmd_socket, ret);
1158 ("[SET_FILE][%d][%s]", client_cmd.id, 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) {
1165 if (dp_ipc_read_custom_type(group->cmd_socket,
1166 &value, sizeof(int)) < 0) {
1167 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1169 dp_ipc_send_errorcode(group->cmd_socket,
1174 dp_request_set_notification
1175 (client_cmd.id, request, value);
1176 dp_ipc_send_errorcode(group->cmd_socket, ret);
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) {
1184 if (dp_ipc_read_custom_type(group->cmd_socket,
1185 &value, sizeof(int)) < 0) {
1186 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1188 dp_ipc_send_errorcode(group->cmd_socket,
1193 dp_request_set_state_event
1194 (client_cmd.id, request, value);
1195 dp_ipc_send_errorcode(group->cmd_socket, ret);
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) {
1203 if (dp_ipc_read_custom_type(group->cmd_socket,
1204 &value, sizeof(int)) < 0) {
1205 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1207 dp_ipc_send_errorcode(group->cmd_socket,
1212 dp_request_set_progress_event
1213 (client_cmd.id, request, value);
1214 dp_ipc_send_errorcode(group->cmd_socket, ret);
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) {
1222 if (dp_ipc_read_custom_type(group->cmd_socket,
1223 &value, sizeof(int)) < 0) {
1224 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1226 dp_ipc_send_errorcode(group->cmd_socket,
1231 dp_request_set_auto_download
1232 (client_cmd.id, request, value);
1233 dp_ipc_send_errorcode(group->cmd_socket, ret);
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) {
1241 if (dp_ipc_read_custom_type(group->cmd_socket,
1242 &value, sizeof(int)) < 0) {
1243 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1245 dp_ipc_send_errorcode(group->cmd_socket,
1250 dp_request_set_network_type
1251 (client_cmd.id, request, value);
1252 dp_ipc_send_errorcode(group->cmd_socket, ret);
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);
1261 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1263 dp_ipc_send_errorcode
1264 (group->cmd_socket, DP_ERROR_IO_ERROR);
1267 char *value = dp_ipc_read_string(group->cmd_socket);
1268 if (value == NULL) {
1269 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1271 dp_ipc_send_errorcode
1272 (group->cmd_socket, DP_ERROR_IO_ERROR);
1277 TRACE_INFO("[EXTRA-PARAM][%d][%s][%s]",
1278 client_cmd.id, key, value);
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,
1284 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1285 dp_ipc_send_errorcode
1286 (group->cmd_socket, DP_ERROR_IO_ERROR);
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,
1296 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1297 dp_ipc_send_errorcode
1298 (group->cmd_socket, DP_ERROR_IO_ERROR);
1300 dp_ipc_send_errorcode
1301 (group->cmd_socket, DP_ERROR_NONE);
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]",
1309 dp_ipc_send_errorcode
1310 (group->cmd_socket, DP_ERROR_IO_ERROR);
1313 char *value = dp_ipc_read_string(group->cmd_socket);
1314 if (value == NULL) {
1315 TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]",
1317 dp_ipc_send_errorcode
1318 (group->cmd_socket, DP_ERROR_IO_ERROR);
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) {
1328 if (dp_db_insert_column
1330 DP_DB_TABLE_HTTP_HEADERS,
1331 DP_DB_COL_HEADER_FIELD,
1332 DP_DB_COL_TYPE_TEXT, field) < 0) {
1334 ("[ERROR][%d][SQL]", client_cmd.id);
1337 dp_ipc_send_errorcode
1338 (group->cmd_socket, DP_ERROR_IO_ERROR);
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,
1351 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1352 dp_ipc_send_errorcode
1353 (group->cmd_socket, DP_ERROR_IO_ERROR);
1355 dp_ipc_send_errorcode
1356 (group->cmd_socket, DP_ERROR_NONE);
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]",
1365 dp_ipc_send_errorcode
1366 (group->cmd_socket, DP_ERROR_IO_ERROR);
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) {
1375 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1377 dp_ipc_send_errorcode
1378 (group->cmd_socket, DP_ERROR_NO_DATA);
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,
1387 TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id);
1388 dp_ipc_send_errorcode
1389 (group->cmd_socket, DP_ERROR_IO_ERROR);
1391 dp_ipc_send_errorcode
1392 (group->cmd_socket, DP_ERROR_NONE);
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]",
1400 dp_ipc_send_errorcode
1401 (group->cmd_socket, DP_ERROR_IO_ERROR);
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);
1409 if (value == NULL) {
1411 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1413 dp_ipc_send_errorcode
1414 (group->cmd_socket, DP_ERROR_NO_DATA);
1416 __send_return_string
1417 (group->cmd_socket, DP_ERROR_NONE, value);
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);
1426 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1428 dp_ipc_send_errorcode
1429 (group->cmd_socket, DP_ERROR_NO_DATA);
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) {
1437 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1439 dp_ipc_send_errorcode
1440 (group->cmd_socket, DP_ERROR_NO_DATA);
1442 __send_return_string
1443 (group->cmd_socket, DP_ERROR_NONE, key);
1444 dp_ipc_send_string(group->cmd_socket, value);
1448 } else if (client_cmd.cmd == DP_CMD_GET_URL) {
1450 errorcode = DP_ERROR_NONE;
1451 url = dp_request_get_url
1452 (client_cmd.id, request, &errorcode);
1454 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1455 dp_print_errorcode(errorcode));
1456 dp_ipc_send_errorcode
1457 (group->cmd_socket, errorcode);
1459 __send_return_string
1460 (group->cmd_socket, DP_ERROR_NONE, url);
1463 } else if (client_cmd.cmd == DP_CMD_GET_DESTINATION) {
1465 errorcode = DP_ERROR_NONE;
1466 dest = dp_request_get_destination
1467 (client_cmd.id, request, &errorcode);
1469 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1470 dp_print_errorcode(errorcode));
1471 dp_ipc_send_errorcode
1472 (group->cmd_socket, errorcode);
1474 __send_return_string
1475 (group->cmd_socket, DP_ERROR_NONE, dest);
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);
1489 __send_return_string
1490 (group->cmd_socket, DP_ERROR_NONE, filename);
1493 } else if (client_cmd.cmd == DP_CMD_GET_NOTIFICATION) {
1495 enable = dp_db_get_int_column(client_cmd.id,
1496 DP_DB_TABLE_NOTIFICATION,
1497 DP_DB_COL_NOTIFICATION_ENABLE);
1500 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1502 dp_ipc_send_errorcode(group->cmd_socket,
1505 __send_return_custom_type
1506 (group->cmd_socket, DP_ERROR_NONE,
1507 &enable, sizeof(int));
1509 } else if (client_cmd.cmd == DP_CMD_GET_AUTO_DOWNLOAD) {
1511 enable = dp_db_get_int_column(client_cmd.id,
1512 DP_DB_TABLE_REQUEST_INFO,
1513 DP_DB_COL_AUTO_DOWNLOAD);
1516 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1518 dp_ipc_send_errorcode(group->cmd_socket,
1521 __send_return_custom_type
1522 (group->cmd_socket, DP_ERROR_NONE,
1523 &enable, sizeof(int));
1525 } else if (client_cmd.cmd == DP_CMD_GET_NETWORK_TYPE) {
1527 type = dp_db_get_int_column(client_cmd.id,
1528 DP_DB_TABLE_REQUEST_INFO,
1529 DP_DB_COL_NETWORK_TYPE);
1532 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1534 dp_ipc_send_errorcode(group->cmd_socket,
1537 __send_return_custom_type
1538 (group->cmd_socket, DP_ERROR_NONE,
1539 &type, sizeof(dp_network_type));
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);
1552 __send_return_string
1553 (group->cmd_socket, DP_ERROR_NONE, savedpath);
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);
1567 __send_return_string
1568 (group->cmd_socket, DP_ERROR_NONE, tmppath);
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);
1582 __send_return_string
1583 (group->cmd_socket, DP_ERROR_NONE, mimetype);
1586 } else if (client_cmd.cmd == DP_CMD_GET_RECEIVED_SIZE) {
1587 if (request == NULL) {
1589 ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1591 dp_ipc_send_errorcode(group->cmd_socket,
1592 DP_ERROR_ID_NOT_FOUND);
1594 __send_return_custom_type
1595 (group->cmd_socket, DP_ERROR_NONE,
1596 &request->received_size,
1597 sizeof(unsigned long long));
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));
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) {
1612 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1614 dp_ipc_send_errorcode(group->cmd_socket,
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));
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);
1634 __send_return_string
1635 (group->cmd_socket, DP_ERROR_NONE, content);
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) {
1645 ("[ERROR][%d] [DP_ERROR_NO_DATA]",
1647 dp_ipc_send_errorcode(group->cmd_socket,
1650 __send_return_custom_type
1651 (group->cmd_socket, DP_ERROR_NONE,
1652 &http_status, sizeof(int));
1654 } else if (client_cmd.cmd == DP_CMD_GET_ETAG) {
1656 errorcode = DP_ERROR_NONE;
1657 etag = dp_request_get_etag
1658 (client_cmd.id, request, &errorcode);
1660 TRACE_ERROR("[ERROR][%d] [%s]", client_cmd.id,
1661 dp_print_errorcode(errorcode));
1662 dp_ipc_send_errorcode
1663 (group->cmd_socket, errorcode);
1665 __send_return_string
1666 (group->cmd_socket, DP_ERROR_NONE, etag);
1669 } else if (client_cmd.cmd == DP_CMD_GET_STATE) {
1670 dp_state_type download_state = DP_STATE_NONE;
1671 if (request == NULL) {
1673 dp_db_get_int_column(client_cmd.id,
1676 if (download_state < 0) {
1678 ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1680 dp_ipc_send_errorcode(group->cmd_socket,
1681 DP_ERROR_ID_NOT_FOUND);
1685 CLIENT_MUTEX_LOCK(&(request->mutex));
1686 download_state = request->state;
1687 CLIENT_MUTEX_UNLOCK(&(request->mutex));
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) {
1696 dp_db_get_int_column(client_cmd.id,
1698 DP_DB_COL_ERRORCODE);
1699 if (errorcode < 0) {
1701 ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]",
1703 dp_ipc_send_errorcode(group->cmd_socket,
1704 DP_ERROR_ID_NOT_FOUND);
1708 CLIENT_MUTEX_LOCK(&(request->mutex));
1709 errorcode = request->error;
1710 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1712 dp_ipc_send_errorcode
1713 (group->cmd_socket, DP_ERROR_NONE);
1714 dp_ipc_send_errorcode
1715 (group->cmd_socket, errorcode);
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;
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;
1738 if ((now_timeout - prev_timeout) <
1739 DP_CARE_CLIENT_MIN_INTERVAL) {
1741 // terminate Process
1743 ("[CRITICAL] Sock exception prev[%ld]now[%ld][%ld]",
1744 prev_timeout, now_timeout, flexible_timeout);
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;
1758 ("[CLEAR] [%d] old reqeusts", old_request_count);
1760 dp_request_slots *old_requests =
1761 dp_request_slots_new(old_request_count);
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.
1769 __get_same_request_index
1770 (privates->requests,
1771 old_requests[i].request->id);
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 ||
1780 DP_STATE_DOWNLOADING) {
1782 (&(request->mutex));
1785 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1786 // unload from slots ( memory )
1787 dp_request_free(request);
1788 privates->requests[index].request = NULL;
1792 dp_request_get_tmpsavedpath
1793 (old_requests[i].request->id,
1794 old_requests[i].request,
1796 if ((tmp_path && strlen(tmp_path) > 0) &&
1797 dp_is_file_exist(tmp_path) == 0) {
1799 ("[REMOVE][%d] TEMP FILE [%s]",
1800 old_requests[i].request->id,
1802 if (unlink(tmp_path) != 0)
1804 ("[ERROR][%d] remove file",
1805 old_requests[i].request->id);
1809 dp_db_remove_all(old_requests[i].request->id);
1812 dp_request_slots_free(old_requests, old_request_count);
1817 int ready_requests = 0;
1818 for (i = 0; i < DP_MAX_REQUEST; i++) {
1819 if (!privates->requests[i].request)
1821 dp_request *request = privates->requests[i].request;
1823 CLIENT_MUTEX_LOCK(&(request->mutex));
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));
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));
1838 ("[FREE] [%d] unavailable agent ID [%d]",
1839 request->id, request->agent_id);
1840 dp_request_free(request);
1841 privates->requests[i].request = NULL;
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;
1854 && request->group->event_socket >= 0
1855 && request->state_cb)
1857 (request->group->event_socket,
1858 download_id, state, errorcode, 0);
1859 CLIENT_MUTEX_UNLOCK(&(request->mutex));
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,
1870 TRACE_ERROR("[ERROR][%d][SQL]", request->id);
1872 if (dp_db_set_column
1873 (download_id, DP_DB_TABLE_LOG,
1874 DP_DB_COL_ERRORCODE, DP_DB_COL_TYPE_INT,
1876 TRACE_ERROR("[ERROR][%d][SQL]", request->id);
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]",
1892 dp_request_free(request);
1893 privates->requests[i].request = NULL;
1898 // check after clear
1899 if (request->state == DP_STATE_QUEUED)
1902 CLIENT_MUTEX_UNLOCK(&(request->mutex));
1905 if (ready_requests > 0) {
1906 //send signal to queue thread will check queue.
1907 dp_thread_queue_manager_wake_up();
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");
1919 prev_timeout = now_timeout;
1922 TRACE_INFO("terminate main thread ...");
1923 dp_terminate(SIGTERM);