Tizen 2.1 base
[platform/framework/web/download-provider.git] / src / agent / download-agent-dl-info-util.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 <string.h>
18
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"
26
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;
30
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);
34
35 da_result_t init_download_mgr() {
36         da_result_t ret = DA_RESULT_OK;
37         int i = 0;
38
39         DA_LOG_FUNC_START(Default);
40
41         _da_thread_mutex_lock(&mutex_download_mgr);
42
43         if (download_mgr.is_init == DA_FALSE) {
44                 download_mgr.is_init = DA_TRUE;
45
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);
49                 }
50                 init_dl_id_history(&(download_mgr.dl_id_history));
51         }
52
53         _da_thread_mutex_unlock(&mutex_download_mgr);
54
55         return ret;
56 }
57
58 da_result_t deinit_download_mgr(void) {
59         da_result_t ret = DA_RESULT_OK;
60
61         DA_LOG_FUNC_START(Default);
62
63         _da_thread_mutex_lock(&mutex_download_mgr);
64         if (download_mgr.is_init == DA_TRUE) {
65                 int i = 0;
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!!!");
77                 }
78 */
79                 DA_LOG_CRITICAL(Thread, "===download id[%d] thread join return[%d]===",i, (char*)t_return);
80                         }
81                 }
82                 download_mgr.is_init = DA_FALSE;
83                 deinit_dl_id_history(&(download_mgr.dl_id_history));
84         }
85         _da_thread_mutex_unlock(&mutex_download_mgr);
86         return ret;
87 }
88
89 void init_download_info(int slot_id)
90 {
91         dl_info_t *dl_info = DA_NULL;
92
93 //      DA_LOG_FUNC_START(Default);
94
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]);
98
99         dl_info->is_using = DA_FALSE;
100         dl_info->state = DOWNLOAD_STATE_IDLE;
101         dl_info->download_stage_data = DA_NULL;
102         dl_info->dl_id = 0;
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;
110
111         Q_init_queue(&(dl_info->queue));
112
113         DA_LOG_VERBOSE(Default, "Init slot_id [%d] Info END", slot_id);
114         _da_thread_mutex_unlock(&mutex_download_state[slot_id]);
115
116         return;
117 }
118
119 void destroy_download_info(int slot_id)
120 {
121         dl_info_t *dl_info = DA_NULL;
122
123         DA_LOG_FUNC_START(Default);
124
125         DA_LOG(Default, "Destroying slot_id [%d] Info", slot_id);
126
127         if (slot_id == DA_INVALID_ID) {
128                 DA_LOG_ERR(Default, "invalid slot_id");
129                 return;
130         }
131
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"); */
135                 return;
136         }
137
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);
141
142         dl_info->active_dl_thread_id = 0;
143
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;
147         }
148         dl_info->dl_id = 0;
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;
153         }
154
155         if (dl_info->user_file_name) {
156                 free(dl_info->user_file_name);
157                 dl_info->user_file_name = DA_NULL;
158         }
159
160         if (dl_info->user_etag) {
161                 free(dl_info->user_etag);
162                 dl_info->user_etag = DA_NULL;
163         }
164
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;
168         }
169
170         dl_info->user_data = DA_NULL;
171
172         Q_destroy_queue(&(dl_info->queue));
173         dl_info->http_status = 0;
174
175         dl_info->is_using = DA_FALSE;
176
177         DA_LOG(Default, "Destroying slot_id [%d] Info END", slot_id);
178         _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
179         return;
180 }
181
182 void *Add_new_download_stage(int slot_id)
183 {
184         stage_info *download_stage_data = NULL;
185         stage_info *new_download_stage_data = NULL;
186
187         DA_LOG_FUNC_START(Default);
188
189         new_download_stage_data = (stage_info*)calloc(1, sizeof(stage_info));
190         if (!new_download_stage_data)
191                 goto ERR;
192
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) {
197                         download_stage_data
198                                         = download_stage_data->next_stage_info;
199                 };
200                 download_stage_data->next_stage_info = new_download_stage_data;
201         } else {
202                 GET_DL_CURRENT_STAGE(slot_id) = new_download_stage_data;
203         }
204         DA_LOG(Default, "NEW STAGE ADDED FOR DOWNLOAD ID[%d] new_stage[%p]", slot_id,new_download_stage_data);
205
206 ERR:
207         return new_download_stage_data;
208 }
209
210 void remove_download_stage(int slot_id, stage_info *in_stage)
211 {
212         stage_info *stage = DA_NULL;
213
214         DA_LOG_FUNC_START(Default);
215
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);
219                 goto ERR;
220         }
221
222         if (DA_NULL == in_stage) {
223                 DA_LOG_VERBOSE(Default, "There is no in_stage to remove.");
224                 goto ERR;
225         }
226
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);
232                 free(in_stage);
233                 in_stage = DA_NULL;
234         } else {
235                 while (in_stage != stage->next_stage_info) {
236                         stage = stage->next_stage_info;
237                 }
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);
244                         free(in_stage);
245                         in_stage = DA_NULL;
246                 }
247         }
248
249 ERR:
250         return;
251 }
252
253 void empty_stage_info(stage_info *in_stage)
254 {
255         source_info_t *source_information = NULL;
256         req_dl_info *request_download_info = NULL;
257         file_info *file_information = NULL;
258
259         DA_LOG_FUNC_START(Default);
260
261         DA_LOG(Default, "Stage to Remove:[%p]", in_stage);
262         source_information = GET_STAGE_SOURCE_INFO(in_stage);
263
264         cleanup_source_info_basic_download(
265                         GET_SOURCE_BASIC(source_information));
266
267         request_download_info = GET_STAGE_TRANSACTION_INFO(in_stage);
268
269         cleanup_req_dl_info_http(request_download_info);
270
271         file_information = GET_STAGE_CONTENT_STORE_INFO(in_stage);
272         destroy_file_info(file_information);
273 }
274
275 void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic)
276 {
277         if (NULL == source_info_basic)
278                 goto ERR;
279
280         DA_LOG_FUNC_START(Default);
281
282         if (NULL != source_info_basic->url) {
283                 free(source_info_basic->url);
284                 source_info_basic->url = DA_NULL;
285         }
286
287 ERR:
288         return;
289
290 }
291
292 void cleanup_req_dl_info_http(req_dl_info *http_download)
293 {
294         DA_LOG_FUNC_START(Default);
295
296         if (http_download->http_info.http_msg_request) {
297                 http_msg_request_destroy(
298                                 &(http_download->http_info.http_msg_request));
299         }
300
301         if (http_download->http_info.http_msg_response) {
302                 http_msg_response_destroy(
303                                 &(http_download->http_info.http_msg_response));
304         }
305
306         if (DA_NULL != http_download->location_url) {
307                 free(http_download->location_url);
308                 http_download->location_url = DA_NULL;
309         }
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;
313         }
314
315         if (DA_NULL != http_download->etag_from_header) {
316                 free(http_download->etag_from_header);
317                 http_download->etag_from_header = DA_NULL;
318         }
319
320         http_download->invloved_transaction_id = DA_INVALID_ID;
321         http_download->content_len_from_header = 0;
322         http_download->downloaded_data_size = 0;
323
324         _da_thread_mutex_destroy(&(http_download->mutex_http_state));
325
326         return;
327 }
328
329 void destroy_file_info(file_info *file_information)
330 {
331 //      DA_LOG_FUNC_START(Default);
332
333         if (!file_information)
334                 return;
335
336         if (file_information->file_name_final) {
337                 free(file_information->file_name_final);
338                 file_information->file_name_final = NULL;
339         }
340
341         if (file_information->content_type) {
342                 free(file_information->content_type);
343                 file_information->content_type = NULL;
344         }
345
346         if (file_information->pure_file_name) {
347                 free(file_information->pure_file_name);
348                 file_information->pure_file_name = NULL;
349         }
350
351         if (file_information->extension) {
352                 free(file_information->extension);
353                 file_information->extension = NULL;
354         }
355         return;
356 }
357
358 void clean_up_client_input_info(client_input_t *client_input)
359 {
360         DA_LOG_FUNC_START(Default);
361
362         if (client_input) {
363                 client_input->user_data = NULL;
364
365                 if (client_input->install_path) {
366                         free(client_input->install_path);
367                         client_input->install_path = DA_NULL;
368                 }
369
370                 if (client_input->file_name) {
371                         free(client_input->file_name);
372                         client_input->file_name = DA_NULL;
373                 }
374
375                 if (client_input->etag) {
376                         free(client_input->etag);
377                         client_input->etag = DA_NULL;
378                 }
379
380                 if (client_input->temp_file_path) {
381                         free(client_input->temp_file_path);
382                         client_input->temp_file_path = DA_NULL;
383                 }
384
385                 client_input_basic_t *client_input_basic =
386                                 &(client_input->client_input_basic);
387
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;
391                 }
392
393                 if (client_input_basic && client_input_basic->user_request_header) {
394                         int i = 0;
395                         int count = client_input_basic->user_request_header_count;
396                         for (i = 0; i < count; i++)
397                         {
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;
401                                 }
402                         }
403
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;
407                 }
408         } else {
409                 DA_LOG_ERR(Default, "client_input is NULL.");
410         }
411
412         return;
413 }
414
415 da_result_t get_slot_id_for_dl_id(
416         int dl_id,
417         int* slot_id)
418 {
419         da_result_t ret = DA_ERR_INVALID_DL_REQ_ID;
420         int iter = 0;
421
422         if (dl_id < 0) {
423                 DA_LOG_ERR(Default, "dl_id is less than 0 - %d", dl_id);
424                 return DA_ERR_INVALID_DL_REQ_ID;
425         }
426
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 ==
431                                 dl_id) {
432                                 *slot_id = iter;
433                                 ret = DA_RESULT_OK;
434                                 break;
435                         }
436                 }
437         }
438         _da_thread_mutex_unlock(&mutex_download_mgr);
439
440         return ret;
441 }
442
443
444 da_result_t get_available_slot_id(int *available_id)
445 {
446         da_result_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
447         int i;
448
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);
453
454                         download_mgr.dl_info[i].is_using = DA_TRUE;
455
456                         download_mgr.dl_info[i].dl_id
457                                 = get_available_dl_id(&(download_mgr.dl_id_history));
458
459                         *available_id = i;
460                         DA_LOG_CRITICAL(Default, "available download id = %d", *available_id);
461                         ret = DA_RESULT_OK;
462
463                         break;
464                 }
465         }
466         _da_thread_mutex_unlock(&mutex_download_mgr);
467
468         return ret;
469 }
470
471 da_bool_t is_valid_slot_id(int slot_id)
472 {
473         da_bool_t ret = DA_FALSE;
474
475         if (slot_id >= 0 && slot_id < DA_MAX_DOWNLOAD_ID) {
476                 if (download_mgr.dl_info[slot_id].is_using == DA_TRUE)
477                         ret = DA_TRUE;
478         }
479
480         return ret;
481 }
482
483 void store_http_status(int dl_id, int status)
484 {
485         if (status < 100 || status > 599) {
486                 DA_LOG_ERR(Default, "Invalid status code [%d]", status);
487                 return;
488         }
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;
491 }
492
493 int get_http_status(int slot_id)
494 {
495         if (!download_mgr.dl_info[slot_id].is_using) {
496                 DA_LOG_ERR(Default, "Invalid slot_id [%d]", slot_id);
497                 return 0;
498         }
499         return download_mgr.dl_info[slot_id].http_status;
500 }