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.
19 #include "download-agent-client-mgr.h"
20 #include "download-agent-dl-info-util.h"
21 #include "download-agent-debug.h"
22 #include "download-agent-utils.h"
23 #include "download-agent-file.h"
24 #include "download-agent-http-mgr.h"
25 #include "download-agent-plugin-conf.h"
27 pthread_mutex_t mutex_download_state[DA_MAX_DOWNLOAD_ID];
28 static pthread_mutex_t mutex_download_mgr = PTHREAD_MUTEX_INITIALIZER;
29 download_mgr_t download_mgr;
31 void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic);
32 void cleanup_req_dl_info_http(req_dl_info *http_download);
33 void destroy_file_info(file_info *file);
35 da_result_t init_download_mgr() {
36 da_result_t ret = DA_RESULT_OK;
39 DA_LOG_FUNC_START(Default);
41 _da_thread_mutex_lock(&mutex_download_mgr);
43 if (download_mgr.is_init == DA_FALSE) {
44 download_mgr.is_init = DA_TRUE;
46 for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
47 _da_thread_mutex_init(&mutex_download_state[i], DA_NULL);
48 init_download_info(i);
50 init_dl_id_history(&(download_mgr.dl_id_history));
53 _da_thread_mutex_unlock(&mutex_download_mgr);
58 da_result_t deinit_download_mgr(void) {
59 da_result_t ret = DA_RESULT_OK;
61 DA_LOG_FUNC_START(Default);
63 _da_thread_mutex_lock(&mutex_download_mgr);
64 if (download_mgr.is_init == DA_TRUE) {
66 dl_info_t *dl_info = DA_NULL;
67 void *t_return = NULL;
68 for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
69 dl_info = &(download_mgr.dl_info[i]);
70 if (dl_info && dl_info->is_using) {
71 request_to_abort_http_download(GET_DL_CURRENT_STAGE(i));
72 DA_LOG_CRITICAL(Thread, "===download id[%d] thread id[%lu] join===",i, GET_DL_THREAD_ID(i));
73 /* Because the download daemon can call the deinit function, the resources of pthread are not freed
74 FIXME later : It is needed to change the termination flow again.
75 if (pthread_join(GET_DL_THREAD_ID(i), &t_return) < 0) {
76 DA_LOG_ERR(Thread, "join client thread is failed!!!");
79 DA_LOG_CRITICAL(Thread, "===download id[%d] thread join return[%d]===",i, (char*)t_return);
82 download_mgr.is_init = DA_FALSE;
83 deinit_dl_id_history(&(download_mgr.dl_id_history));
85 _da_thread_mutex_unlock(&mutex_download_mgr);
89 void init_download_info(int slot_id)
91 dl_info_t *dl_info = DA_NULL;
93 // DA_LOG_FUNC_START(Default);
95 _da_thread_mutex_lock(&mutex_download_state[slot_id]);
96 // DA_LOG_VERBOSE(Default, "Init slot_id [%d] Info", slot_id);
97 dl_info = &(download_mgr.dl_info[slot_id]);
99 dl_info->is_using = DA_FALSE;
100 dl_info->state = DOWNLOAD_STATE_IDLE;
101 dl_info->download_stage_data = DA_NULL;
103 dl_info->http_status = 0;
104 dl_info->enable_pause_update = DA_FALSE;
105 dl_info->user_install_path = DA_NULL;
106 dl_info->user_file_name = DA_NULL;
107 dl_info->user_etag = DA_NULL;
108 dl_info->user_temp_file_path = DA_NULL;
109 dl_info->user_data = DA_NULL;
111 Q_init_queue(&(dl_info->queue));
113 DA_LOG_VERBOSE(Default, "Init slot_id [%d] Info END", slot_id);
114 _da_thread_mutex_unlock(&mutex_download_state[slot_id]);
119 void destroy_download_info(int slot_id)
121 dl_info_t *dl_info = DA_NULL;
123 DA_LOG_FUNC_START(Default);
125 DA_LOG(Default, "Destroying slot_id [%d] Info", slot_id);
127 if (slot_id == DA_INVALID_ID) {
128 DA_LOG_ERR(Default, "invalid slot_id");
132 dl_info = &(download_mgr.dl_info[slot_id]);
133 if (DA_FALSE == dl_info->is_using) {
134 /* DA_LOG_ERR(Default, "invalid slot_id"); */
138 _da_thread_mutex_lock (&mutex_download_state[slot_id]);
139 dl_info->state = DOWNLOAD_STATE_IDLE;
140 DA_LOG(Default, "Changed download_state to - [%d] ", dl_info->state);
142 dl_info->active_dl_thread_id = 0;
144 if (dl_info->download_stage_data != DA_NULL) {
145 remove_download_stage(slot_id, dl_info->download_stage_data);
146 dl_info->download_stage_data = DA_NULL;
149 dl_info->enable_pause_update = DA_FALSE;
150 if (dl_info->user_install_path) {
151 free(dl_info->user_install_path);
152 dl_info->user_install_path = DA_NULL;
155 if (dl_info->user_file_name) {
156 free(dl_info->user_file_name);
157 dl_info->user_file_name = DA_NULL;
160 if (dl_info->user_etag) {
161 free(dl_info->user_etag);
162 dl_info->user_etag = DA_NULL;
165 if (dl_info->user_temp_file_path ) {
166 free(dl_info->user_temp_file_path );
167 dl_info->user_temp_file_path = DA_NULL;
170 dl_info->user_data = DA_NULL;
172 Q_destroy_queue(&(dl_info->queue));
173 dl_info->http_status = 0;
175 dl_info->is_using = DA_FALSE;
177 DA_LOG(Default, "Destroying slot_id [%d] Info END", slot_id);
178 _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
182 void *Add_new_download_stage(int slot_id)
184 stage_info *download_stage_data = NULL;
185 stage_info *new_download_stage_data = NULL;
187 DA_LOG_FUNC_START(Default);
189 new_download_stage_data = (stage_info*)calloc(1, sizeof(stage_info));
190 if (!new_download_stage_data)
193 new_download_stage_data->dl_id = slot_id;
194 download_stage_data = GET_DL_CURRENT_STAGE(slot_id);
195 if (download_stage_data) {
196 while (download_stage_data->next_stage_info) {
198 = download_stage_data->next_stage_info;
200 download_stage_data->next_stage_info = new_download_stage_data;
202 GET_DL_CURRENT_STAGE(slot_id) = new_download_stage_data;
204 DA_LOG(Default, "NEW STAGE ADDED FOR DOWNLOAD ID[%d] new_stage[%p]", slot_id,new_download_stage_data);
207 return new_download_stage_data;
210 void remove_download_stage(int slot_id, stage_info *in_stage)
212 stage_info *stage = DA_NULL;
214 DA_LOG_FUNC_START(Default);
216 stage = GET_DL_CURRENT_STAGE(slot_id);
217 if (DA_NULL == stage) {
218 DA_LOG_VERBOSE(Default, "There is no stage field on slot_id = %d", slot_id);
222 if (DA_NULL == in_stage) {
223 DA_LOG_VERBOSE(Default, "There is no in_stage to remove.");
227 if (in_stage == stage) {
228 DA_LOG_VERBOSE(Default, "Base stage will be removed. in_stage[%p]",in_stage);
229 DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info);
230 GET_DL_CURRENT_STAGE(slot_id) = stage->next_stage_info;
231 empty_stage_info(in_stage);
235 while (in_stage != stage->next_stage_info) {
236 stage = stage->next_stage_info;
238 if (in_stage == stage->next_stage_info) {
239 stage->next_stage_info
240 = stage->next_stage_info->next_stage_info;
241 DA_LOG_VERBOSE(Default, "Stage will be removed. in_stage[%p]",in_stage);
242 DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info);
243 empty_stage_info(in_stage);
253 void empty_stage_info(stage_info *in_stage)
255 source_info_t *source_information = NULL;
256 req_dl_info *request_download_info = NULL;
257 file_info *file_information = NULL;
259 DA_LOG_FUNC_START(Default);
261 DA_LOG(Default, "Stage to Remove:[%p]", in_stage);
262 source_information = GET_STAGE_SOURCE_INFO(in_stage);
264 cleanup_source_info_basic_download(
265 GET_SOURCE_BASIC(source_information));
267 request_download_info = GET_STAGE_TRANSACTION_INFO(in_stage);
269 cleanup_req_dl_info_http(request_download_info);
271 file_information = GET_STAGE_CONTENT_STORE_INFO(in_stage);
272 destroy_file_info(file_information);
275 void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic)
277 if (NULL == source_info_basic)
280 DA_LOG_FUNC_START(Default);
282 if (NULL != source_info_basic->url) {
283 free(source_info_basic->url);
284 source_info_basic->url = DA_NULL;
292 void cleanup_req_dl_info_http(req_dl_info *http_download)
294 DA_LOG_FUNC_START(Default);
296 if (http_download->http_info.http_msg_request) {
297 http_msg_request_destroy(
298 &(http_download->http_info.http_msg_request));
301 if (http_download->http_info.http_msg_response) {
302 http_msg_response_destroy(
303 &(http_download->http_info.http_msg_response));
306 if (DA_NULL != http_download->location_url) {
307 free(http_download->location_url);
308 http_download->location_url = DA_NULL;
310 if (DA_NULL != http_download->content_type_from_header) {
311 free(http_download->content_type_from_header);
312 http_download->content_type_from_header = DA_NULL;
315 if (DA_NULL != http_download->etag_from_header) {
316 free(http_download->etag_from_header);
317 http_download->etag_from_header = DA_NULL;
320 http_download->invloved_transaction_id = DA_INVALID_ID;
321 http_download->content_len_from_header = 0;
322 http_download->downloaded_data_size = 0;
324 _da_thread_mutex_destroy(&(http_download->mutex_http_state));
329 void destroy_file_info(file_info *file_information)
331 // DA_LOG_FUNC_START(Default);
333 if (!file_information)
336 if (file_information->file_name_final) {
337 free(file_information->file_name_final);
338 file_information->file_name_final = NULL;
341 if (file_information->content_type) {
342 free(file_information->content_type);
343 file_information->content_type = NULL;
346 if (file_information->pure_file_name) {
347 free(file_information->pure_file_name);
348 file_information->pure_file_name = NULL;
351 if (file_information->extension) {
352 free(file_information->extension);
353 file_information->extension = NULL;
358 void clean_up_client_input_info(client_input_t *client_input)
360 DA_LOG_FUNC_START(Default);
363 client_input->user_data = NULL;
365 if (client_input->install_path) {
366 free(client_input->install_path);
367 client_input->install_path = DA_NULL;
370 if (client_input->file_name) {
371 free(client_input->file_name);
372 client_input->file_name = DA_NULL;
375 if (client_input->etag) {
376 free(client_input->etag);
377 client_input->etag = DA_NULL;
380 if (client_input->temp_file_path) {
381 free(client_input->temp_file_path);
382 client_input->temp_file_path = DA_NULL;
385 client_input_basic_t *client_input_basic =
386 &(client_input->client_input_basic);
388 if (client_input_basic && client_input_basic->req_url) {
389 free(client_input_basic->req_url);
390 client_input_basic->req_url = DA_NULL;
393 if (client_input_basic && client_input_basic->user_request_header) {
395 int count = client_input_basic->user_request_header_count;
396 for (i = 0; i < count; i++)
398 if (client_input_basic->user_request_header[i]) {
399 free(client_input_basic->user_request_header[i]);
400 client_input_basic->user_request_header[i] = DA_NULL;
404 free(client_input_basic->user_request_header);
405 client_input_basic->user_request_header = DA_NULL;
406 client_input_basic->user_request_header_count = 0;
409 DA_LOG_ERR(Default, "client_input is NULL.");
415 da_result_t get_slot_id_for_dl_id(
419 da_result_t ret = DA_ERR_INVALID_DL_REQ_ID;
423 DA_LOG_ERR(Default, "dl_id is less than 0 - %d", dl_id);
424 return DA_ERR_INVALID_DL_REQ_ID;
427 _da_thread_mutex_lock(&mutex_download_mgr);
428 for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
429 if (download_mgr.dl_info[iter].is_using == DA_TRUE) {
430 if (download_mgr.dl_info[iter].dl_id ==
438 _da_thread_mutex_unlock(&mutex_download_mgr);
444 da_result_t get_available_slot_id(int *available_id)
446 da_result_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
449 _da_thread_mutex_lock(&mutex_download_mgr);
450 for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
451 if (download_mgr.dl_info[i].is_using == DA_FALSE) {
452 init_download_info(i);
454 download_mgr.dl_info[i].is_using = DA_TRUE;
456 download_mgr.dl_info[i].dl_id
457 = get_available_dl_id(&(download_mgr.dl_id_history));
460 DA_LOG_CRITICAL(Default, "available download id = %d", *available_id);
466 _da_thread_mutex_unlock(&mutex_download_mgr);
471 da_bool_t is_valid_slot_id(int slot_id)
473 da_bool_t ret = DA_FALSE;
475 if (slot_id >= 0 && slot_id < DA_MAX_DOWNLOAD_ID) {
476 if (download_mgr.dl_info[slot_id].is_using == DA_TRUE)
483 void store_http_status(int dl_id, int status)
485 if (status < 100 || status > 599) {
486 DA_LOG_ERR(Default, "Invalid status code [%d]", status);
489 DA_LOG_VERBOSE(Default, "store_http_status id[%d]status[%d] ",dl_id, status);
490 download_mgr.dl_info[dl_id].http_status = status;
493 int get_http_status(int slot_id)
495 if (!download_mgr.dl_info[slot_id].is_using) {
496 DA_LOG_ERR(Default, "Invalid slot_id [%d]", slot_id);
499 return download_mgr.dl_info[slot_id].http_status;