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.
23 #include "download-provider.h"
24 #include "download-provider-log.h"
26 #include "download-provider-slots.h"
27 #include "download-provider-socket.h"
28 #include "download-provider-db.h"
29 #include "download-provider-pthread.h"
32 ///////// below functions are called by main thread of thread-request.c
36 //////////////////////////////////////////////////////////////////////////
37 /// @brief create unique id as integer type
38 /// @return unique id combined local time and the special calculation
39 static int __get_download_request_id(void)
43 static int last_uniquetime = 0;
46 uniquetime = (int)time(NULL);
47 gettimeofday(&tval, NULL);
48 if (tval.tv_usec == 0)
49 uniquetime = uniquetime + (tval.tv_usec + 1) % 0xfffff;
51 uniquetime = uniquetime + tval.tv_usec;
52 TRACE_INFO("ID : %d", uniquetime);
53 } while (last_uniquetime == uniquetime);
54 last_uniquetime = uniquetime; // store
58 char *dp_print_state(dp_state_type state)
66 case DP_STATE_QUEUED :
68 case DP_STATE_CONNECTING :
70 case DP_STATE_DOWNLOADING :
72 case DP_STATE_PAUSE_REQUESTED :
73 return "PAUSE_REQUESTED";
74 case DP_STATE_PAUSED :
76 case DP_STATE_COMPLETED :
78 case DP_STATE_CANCELED :
80 case DP_STATE_FAILED :
88 char *dp_print_errorcode(dp_error_type errorcode)
94 case DP_ERROR_INVALID_PARAMETER :
95 return "INVALID_PARAMETER";
96 case DP_ERROR_OUT_OF_MEMORY :
97 return "OUT_OF_MEMORY";
98 case DP_ERROR_IO_ERROR :
100 case DP_ERROR_NETWORK_UNREACHABLE :
101 return "NETWORK_UNREACHABLE";
102 case DP_ERROR_CONNECTION_TIMED_OUT :
103 return "CONNECTION_TIMED_OUT";
104 case DP_ERROR_NO_SPACE :
106 case DP_ERROR_FIELD_NOT_FOUND :
107 return "FIELD_NOT_FOUND";
108 case DP_ERROR_INVALID_STATE :
109 return "INVALID_STATE";
110 case DP_ERROR_CONNECTION_FAILED :
111 return "CONNECTION_FAILED";
112 case DP_ERROR_INVALID_URL :
113 return "INVALID_URL";
114 case DP_ERROR_INVALID_DESTINATION :
115 return "INVALID_DESTINATION";
116 case DP_ERROR_QUEUE_FULL :
118 case DP_ERROR_ALREADY_COMPLETED :
119 return "ALREADY_COMPLETED";
120 case DP_ERROR_FILE_ALREADY_EXISTS :
121 return "FILE_ALREADY_EXISTS";
122 case DP_ERROR_TOO_MANY_DOWNLOADS :
123 return "TOO_MANY_DOWNLOADS";
124 case DP_ERROR_NO_DATA :
126 case DP_ERROR_UNHANDLED_HTTP_CODE :
127 return "UNHANDLED_HTTP_CODE";
128 case DP_ERROR_CANNOT_RESUME :
129 return "CANNOT_RESUME";
130 case DP_ERROR_RESPONSE_TIMEOUT :
131 return "RESPONSE_TIMEOUT";
132 case DP_ERROR_REQUEST_TIMEOUT :
133 return "REQUEST_TIMEOUT";
134 case DP_ERROR_SYSTEM_DOWN :
135 return "SYSTEM_DOWN";
136 case DP_ERROR_CLIENT_DOWN :
137 return "CLIENT_DOWN";
138 case DP_ERROR_ID_NOT_FOUND :
139 return "ID_NOT_FOUND";
146 char *dp_strdup(char *src)
152 TRACE_ERROR("[CHECK PARAM]");
156 src_len = strlen(src);
158 TRACE_ERROR("[CHECK PARAM] len[%d]", src_len);
162 dest = (char *)calloc(src_len + 1, sizeof(char));
164 TRACE_STRERROR("[CHECK] allocation");
167 memcpy(dest, src, src_len * sizeof(char));
168 dest[src_len] = '\0';
175 // fill info to new slot
177 // save info to QUEUE(DB)
178 dp_error_type dp_request_create(int id, dp_client_group *group, dp_request **empty_slot)
181 TRACE_ERROR("[CHECK PROTOCOL] ID not -1");
182 return DP_ERROR_INVALID_STATE;
184 if (!group || !empty_slot) {
185 TRACE_ERROR("[CHECK INTERNAL][%d]", id);
186 return DP_ERROR_IO_ERROR;
188 // New allocation Slot
189 dp_request *new_request = dp_request_new();
191 TRACE_STRERROR("[CHECK MEMORY][%d]", id);
192 return DP_ERROR_OUT_OF_MEMORY;
195 new_request->id = __get_download_request_id();
196 new_request->group = group;
197 if (group->pkgname && strlen(group->pkgname) > 1)
198 new_request->packagename = dp_strdup(group->pkgname);
199 new_request->credential = group->credential;
200 if (new_request->packagename == NULL) {
201 dp_request_free(new_request);
202 TRACE_ERROR("[ERROR][%d] OUT_OF_MEMORY [PACKAGENAME]", id);
203 return DP_ERROR_OUT_OF_MEMORY;
205 new_request->state = DP_STATE_READY;
206 new_request->error = DP_ERROR_NONE;
207 if (dp_db_insert_column
208 (new_request->id, DP_DB_TABLE_LOG, DP_DB_COL_STATE,
209 DP_DB_COL_TYPE_INT, &new_request->state) < 0) {
210 TRACE_ERROR("[CHECK SQL][%d]", id);
211 dp_request_free(new_request);
212 return DP_ERROR_OUT_OF_MEMORY;
215 (new_request->id, DP_DB_TABLE_LOG, DP_DB_COL_PACKAGENAME,
216 DP_DB_COL_TYPE_TEXT, new_request->packagename) < 0)
217 TRACE_ERROR("[CHECK SQL][%d]", id);
218 if (dp_db_update_date
219 (new_request->id, DP_DB_TABLE_LOG, DP_DB_COL_CREATE_TIME) < 0)
220 TRACE_ERROR("[CHECK SQL][%d]", id);
222 new_request->create_time = (int)time(NULL);
224 *empty_slot = new_request;
225 return DP_ERROR_NONE;
228 dp_error_type dp_request_set_url(int id, dp_request *request, char *url)
231 if (!url || (length = strlen(url)) <= 1)
232 return DP_ERROR_INVALID_URL;
234 if (request != NULL) {
235 if (request->state == DP_STATE_CONNECTING ||
236 request->state == DP_STATE_DOWNLOADING ||
237 request->state == DP_STATE_COMPLETED) {
239 ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
240 return DP_ERROR_INVALID_STATE;
243 // check id in logging table.
244 dp_state_type state =
245 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
247 if (state <= DP_STATE_NONE) {
248 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
249 return DP_ERROR_ID_NOT_FOUND;
251 // check again from logging table
252 if (state == DP_STATE_CONNECTING ||
253 state == DP_STATE_DOWNLOADING ||
254 state == DP_STATE_COMPLETED) {
255 TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
256 return DP_ERROR_INVALID_STATE;
260 if (dp_db_replace_column
261 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_URL,
262 DP_DB_COL_TYPE_TEXT, url) < 0) {
263 TRACE_ERROR("[CHECK SQL][%d]", id);
264 return DP_ERROR_IO_ERROR;
266 return DP_ERROR_NONE;
269 dp_error_type dp_request_set_destination(int id, dp_request *request, char *dest)
272 if (!dest || (length = strlen(dest)) <= 1)
273 return DP_ERROR_INVALID_DESTINATION;
275 if (request != NULL) {
276 if (request->state == DP_STATE_CONNECTING ||
277 request->state == DP_STATE_DOWNLOADING ||
278 request->state == DP_STATE_COMPLETED) {
280 ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
281 return DP_ERROR_INVALID_STATE;
284 // check id in logging table.
285 dp_state_type state =
286 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
288 if (state <= DP_STATE_NONE) {
289 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
290 return DP_ERROR_ID_NOT_FOUND;
292 // check again from logging table
293 if (state == DP_STATE_CONNECTING ||
294 state == DP_STATE_DOWNLOADING ||
295 state == DP_STATE_COMPLETED) {
296 TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
297 return DP_ERROR_INVALID_STATE;
301 if (dp_db_replace_column
302 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_DESTINATION,
303 DP_DB_COL_TYPE_TEXT, dest) < 0) {
304 TRACE_ERROR("[CHECK SQL][%d]", id);
305 return DP_ERROR_IO_ERROR;
307 return DP_ERROR_NONE;
310 dp_error_type dp_request_set_filename(int id, dp_request *request, char *filename)
313 if (!filename || (length = strlen(filename)) <= 1)
314 return DP_ERROR_INVALID_PARAMETER;
316 if (request != NULL) {
317 if (request->state == DP_STATE_CONNECTING ||
318 request->state == DP_STATE_DOWNLOADING ||
319 request->state == DP_STATE_COMPLETED) {
321 ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
322 return DP_ERROR_INVALID_STATE;
325 // check id in logging table.
326 dp_state_type state =
327 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
329 if (state <= DP_STATE_NONE) {
330 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
331 return DP_ERROR_ID_NOT_FOUND;
333 // check again from logging table
334 if (state == DP_STATE_CONNECTING ||
335 state == DP_STATE_DOWNLOADING ||
336 state == DP_STATE_COMPLETED) {
337 TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
338 return DP_ERROR_INVALID_STATE;
342 if (dp_db_replace_column
343 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_FILENAME,
344 DP_DB_COL_TYPE_TEXT, filename) < 0) {
345 TRACE_ERROR("[CHECK SQL][%d]", id);
346 return DP_ERROR_IO_ERROR;
349 TRACE_INFO("ID [%d] Filename[%s]", id, filename);
350 return DP_ERROR_NONE;
353 dp_error_type dp_request_set_notification(int id, dp_request *request, unsigned enable)
355 if (request != NULL) {
356 if (request->state == DP_STATE_COMPLETED) {
358 ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
359 return DP_ERROR_INVALID_STATE;
362 // check id in logging table.
363 dp_state_type state =
364 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
366 if (state <= DP_STATE_NONE) {
367 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
368 return DP_ERROR_ID_NOT_FOUND;
370 // check again from logging table
371 if (state == DP_STATE_COMPLETED) {
372 TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
373 return DP_ERROR_INVALID_STATE;
378 if (dp_db_replace_column
379 (id, DP_DB_TABLE_REQUEST_INFO,
380 DP_DB_COL_NOTIFICATION_ENABLE, DP_DB_COL_TYPE_INT,
382 TRACE_ERROR("[CHECK SQL][%d]", id);
383 return DP_ERROR_IO_ERROR;
387 request->auto_notification = enable;
388 return DP_ERROR_NONE;
391 dp_error_type dp_request_set_auto_download(int id, dp_request *request, unsigned enable)
393 if (request != NULL) {
394 if (request->state == DP_STATE_COMPLETED) {
396 ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
397 return DP_ERROR_INVALID_STATE;
400 // check id in logging table.
401 dp_state_type state =
402 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
404 if (state <= DP_STATE_NONE) {
405 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
406 return DP_ERROR_ID_NOT_FOUND;
408 // check again from logging table
409 if (state == DP_STATE_COMPLETED) {
410 TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
411 return DP_ERROR_INVALID_STATE;
416 if (dp_db_replace_column
417 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_AUTO_DOWNLOAD,
418 DP_DB_COL_TYPE_INT, &enable) < 0) {
419 TRACE_ERROR("[CHECK SQL][%d]", id);
420 return DP_ERROR_IO_ERROR;
422 return DP_ERROR_NONE;
425 dp_error_type dp_request_set_state_event(int id, dp_request *request, unsigned enable)
427 if (request == NULL) {
428 // check id in logging table.
429 dp_state_type state =
430 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
432 if (state <= DP_STATE_NONE) {
433 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
434 return DP_ERROR_ID_NOT_FOUND;
439 if (dp_db_replace_column
440 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_STATE_EVENT,
441 DP_DB_COL_TYPE_INT, &enable) < 0) {
442 TRACE_ERROR("[CHECK SQL][%d]", id);
443 return DP_ERROR_IO_ERROR;
447 request->state_cb = enable;
448 return DP_ERROR_NONE;
451 dp_error_type dp_request_set_progress_event(int id, dp_request *request, unsigned enable)
453 if (request == NULL) {
454 // check id in logging table.
455 dp_state_type state =
456 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
458 if (state <= DP_STATE_NONE) {
459 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
460 return DP_ERROR_ID_NOT_FOUND;
465 if (dp_db_replace_column
466 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_PROGRESS_EVENT,
467 DP_DB_COL_TYPE_INT, &enable) < 0) {
468 TRACE_ERROR("[CHECK SQL][%d]", id);
469 return DP_ERROR_IO_ERROR;
473 request->progress_cb = enable;
474 return DP_ERROR_NONE;
477 dp_error_type dp_request_set_network_type(int id, dp_request *request, int type)
479 if (request != NULL) {
480 if (request->state == DP_STATE_CONNECTING ||
481 request->state == DP_STATE_DOWNLOADING ||
482 request->state == DP_STATE_COMPLETED) {
484 ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
485 return DP_ERROR_INVALID_STATE;
488 // check id in logging table.
489 dp_state_type state =
490 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
492 if (state <= DP_STATE_NONE) {
493 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
494 return DP_ERROR_ID_NOT_FOUND;
496 // check again from logging table
497 if (state == DP_STATE_CONNECTING ||
498 state == DP_STATE_DOWNLOADING ||
499 state == DP_STATE_COMPLETED) {
500 TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
501 return DP_ERROR_INVALID_STATE;
506 if (dp_db_replace_column
507 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_NETWORK_TYPE,
508 DP_DB_COL_TYPE_INT, &type) < 0) {
509 TRACE_ERROR("[CHECK SQL][%d]", id);
510 return DP_ERROR_IO_ERROR;
514 request->network_type = type;
515 return DP_ERROR_NONE;
518 char *dp_request_get_url(int id, dp_request *request, dp_error_type *errorcode)
522 if (request == NULL) {
523 dp_state_type state =
524 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
526 if (state <= DP_STATE_NONE) {
527 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
528 *errorcode = DP_ERROR_ID_NOT_FOUND;
532 url = dp_db_get_text_column
533 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_URL);
535 *errorcode = DP_ERROR_NO_DATA;
541 char *dp_request_get_destination(int id, dp_request *request, dp_error_type *errorcode)
545 if (request == NULL) {
546 dp_state_type state =
547 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
549 if (state <= DP_STATE_NONE) {
550 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
551 *errorcode = DP_ERROR_ID_NOT_FOUND;
555 dest = dp_db_get_text_column
556 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_DESTINATION);
558 *errorcode = DP_ERROR_NO_DATA;
564 char *dp_request_get_filename(int id, dp_request *request, dp_error_type *errorcode)
566 char *filename = NULL;
568 if (request == NULL) {
569 dp_state_type state =
570 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
572 if (state <= DP_STATE_NONE) {
573 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
574 *errorcode = DP_ERROR_ID_NOT_FOUND;
578 filename = dp_db_get_text_column
579 (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_FILENAME);
580 if (filename == NULL) {
581 *errorcode = DP_ERROR_NO_DATA;
587 char *dp_request_get_contentname(int id, dp_request *request, dp_error_type *errorcode)
589 char *content = NULL;
591 if (request == NULL) {
592 dp_state_type state =
593 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
595 if (state <= DP_STATE_NONE) {
596 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
597 *errorcode = DP_ERROR_ID_NOT_FOUND;
601 content = dp_db_get_text_column
602 (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_CONTENT_NAME);
603 if (content == NULL) {
604 *errorcode = DP_ERROR_NO_DATA;
610 char *dp_request_get_etag(int id, dp_request *request, dp_error_type *errorcode)
614 if (request == NULL) {
615 dp_state_type state =
616 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
618 if (state <= DP_STATE_NONE) {
619 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
620 *errorcode = DP_ERROR_ID_NOT_FOUND;
624 etag = dp_db_get_text_column
625 (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_ETAG);
627 *errorcode = DP_ERROR_NO_DATA;
633 char *dp_request_get_savedpath(int id, dp_request *request, dp_error_type *errorcode)
635 char *savedpath = NULL;
637 if (request == NULL) {
638 dp_state_type state =
639 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
641 if (state <= DP_STATE_NONE) {
642 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
643 *errorcode = DP_ERROR_ID_NOT_FOUND;
647 savedpath = dp_db_get_text_column
648 (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_SAVED_PATH);
649 if (savedpath == NULL) {
650 *errorcode = DP_ERROR_NO_DATA;
656 char *dp_request_get_tmpsavedpath(int id, dp_request *request, dp_error_type *errorcode)
658 char *tmppath = NULL;
660 if (request == NULL) {
661 dp_state_type state =
662 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
664 if (state <= DP_STATE_NONE) {
665 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
666 *errorcode = DP_ERROR_ID_NOT_FOUND;
670 tmppath = dp_db_get_text_column
671 (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_TMP_SAVED_PATH);
672 if (tmppath == NULL) {
673 *errorcode = DP_ERROR_NO_DATA;
679 char *dp_request_get_mimetype(int id, dp_request *request, dp_error_type *errorcode)
681 char *mimetype = NULL;
683 if (request == NULL) {
684 dp_state_type state =
685 dp_db_get_int_column(id, DP_DB_TABLE_LOG, DP_DB_COL_STATE);
687 if (state <= DP_STATE_NONE) {
688 TRACE_ERROR("[ERROR][%d] state[%s]", id, dp_print_state(state));
689 *errorcode = DP_ERROR_ID_NOT_FOUND;
693 mimetype = dp_db_get_text_column
694 (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_MIMETYPE);
695 if (mimetype == NULL) {
696 *errorcode = DP_ERROR_NO_DATA;
702 dp_request *dp_request_load_from_log(int id, dp_error_type *errorcode)
704 dp_request *request = NULL;
706 request = dp_db_load_logging_request(id);
707 if (request == NULL) {
708 *errorcode = DP_ERROR_ID_NOT_FOUND;
711 if (request->state == DP_STATE_COMPLETED) {
713 ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
714 *errorcode = DP_ERROR_INVALID_STATE;
715 dp_request_free(request);