Tizen 2.0 Release
[framework/system/oma-dm-agent.git] / src / agent / dm-engine / dl-manager / fw_downloader.c
1 /*
2  * oma-dm-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*lib*/
19 #include <glib.h>
20 #include <unistd.h>
21
22 /*sync-agent*/
23 #include <sync_agent.h>
24
25 /*dm-agent*/
26 #include "common/dm_common.h"
27 #include "common/util/util.h"
28 #include "dm-engine/dl-manager/fw_downloader.h"
29 #include "dm-engine/dl-manager/dd_parser.h"
30 #include "dm-engine/dl-manager/sa_fw_downloader.h"
31 #include "ipc_agent.h"
32
33 #ifndef OMADM_AGENT_LOG
34 #undef LOG_TAG
35 #define LOG_TAG "OMA_DM_DL"
36 #endif
37
38 static Data_Resume_Infomation *_alloc_data_resume_infomation();
39 static void _free_data_resume_information(Data_Resume_Infomation * data_resume_info);
40 static int _arrange_file(const char *download_folder, const char *file_name);
41 static char *_get_msg_for_status(DM_ERROR download_status);
42
43 DM_ERROR get_object_information(char *dd_server_uri, int *file_size, Download_Descriptor ** download_descriptor, DM_ERROR * download_status)
44 {
45         _EXTERN_FUNC_ENTER;
46
47         DM_ERROR ret = DM_OK;
48
49         retvm_if((dd_server_uri) == NULL, COMMON_ERR_IS_NULL, "dd_server_uri is NULL!!");
50
51         /* 1. construct HTTP msg */
52         /* 2. send msg to server (about dd_server_uri) */
53         /* 3. receive dd information from server */
54         GList *send_header = 0;
55         char *recvMsg = 0;
56         unsigned int recvMsg_size = 0;
57         GList *recv_header = 0;
58         ret = send_download_msg(DD_DOWNLOAD, dd_server_uri, "application/vnd.oma.dd+xml", send_header, 0, 0, &recv_header, &recvMsg, &recvMsg_size);
59         if (ret != DM_OK) {
60                 *download_status = DM_ERR_LOSS_OF_SERVICE;
61                 _DEBUG_INFO("send_DL_Msg() err [%d]\n", ret);
62                 goto error;
63         }
64
65         /* 4. realloc or alloc download descriptor object */
66
67         /* 5. parse the dd information xml data (convert dd xml to dd object) */
68         ret = convert_xml_to_DD_object(recvMsg, recvMsg_size, download_descriptor);
69         if (ret != DM_OK) {
70                 _DEBUG_INFO("send_DL_Msg() err [%d]\n", ret);
71                 *download_status = DM_ERR_INVALID_DESCRIPTOR;
72                 goto error;
73         }
74
75         if (*download_descriptor != NULL && (*download_descriptor)->object_uri != NULL) {
76                 *file_size = (*download_descriptor)->object_size;
77
78                 _DEBUG_INFO(" dd->object_uri = %s \n", (*download_descriptor)->object_uri);
79                 _DEBUG_INFO(" dd->size = %d \n", (*download_descriptor)->object_size);
80                 _DEBUG_INFO(" dd->object_description = %s \n", (*download_descriptor)->object_description);
81         } else {
82                 _DEBUG_INFO("dd obejct uri null");
83                 ret = DM_ERR_INVALID_DESCRIPTOR;
84                 *download_status = DM_ERR_INVALID_DESCRIPTOR;
85                 goto error;
86         }
87
88  error:
89
90         if (recvMsg != NULL)
91                 free(recvMsg);
92
93         if (recv_header != NULL)
94                 free_header_info(recv_header);
95
96         _EXTERN_FUNC_EXIT;
97         return ret;
98 }
99
100 DM_ERROR check_file_resume(const char *checked_download_folder, DOWNLOAD_FILE_STATUS * file_status, Download_Descriptor * download_descriptor, Data_Resume_Infomation ** data_resume_info)
101 {
102         _EXTERN_FUNC_ENTER;
103         DM_ERROR ret = DM_OK;
104
105         /* 1. validate download_folder variable */
106         retvm_if((checked_download_folder) == NULL, COMMON_ERR_IS_NULL, "checked_download_folder is NULL!!");
107
108         if (file_status != NULL) {
109                 _DEBUG_INFO("checked_download_folder == 0 && file_status != 0 ");
110                 ret = COMMON_ERR_IS_NULL;
111                 _EXTERN_FUNC_EXIT;
112                 return ret;
113         }
114
115         char *file_name = NULL;
116         char *file_path = NULL;
117
118         /* send_msg to server */
119         GList *send_header = 0;
120         char *recvMsg = 0;
121         unsigned int recvMsg_size = 0;
122         GList *recv_header = 0;
123         ret = send_download_msg(GET_FILE_NAME, download_descriptor->object_uri, download_descriptor->object_type, send_header, 0, 0, &recv_header, &recvMsg, &recvMsg_size);
124         if (ret != DM_OK) {
125                 _DEBUG_INFO("send_DL_Msg() err [%d]\n", ret);
126                 goto error;
127         }
128
129         /* get file_name for header info */
130         file_name = get_file_name(recv_header, download_descriptor->object_uri);
131         if (file_name == NULL) {
132                 _DEBUG_INFO("file_name is null");
133                 ret = COMMON_ERR_IS_NULL;
134                 goto error;
135         }
136
137         /* check file */
138         file_path = g_strdup_printf("%s/%s", checked_download_folder, file_name);
139
140         _DEBUG_INFO("Download_Folder = %s\n", checked_download_folder);
141         _DEBUG_INFO("Download_Folder_Path = %s\n", file_path);
142
143         unsigned long file_size = 0;
144         int err = sync_agent_get_file_size(file_path, &file_size);
145         if (err == 0) {
146                 _DEBUG_INFO("NOT_EXIST_FILE\n");
147                 *file_status = NOT_EXIST_FILE;
148                 goto return_part;
149         }
150
151         _DEBUG_INFO("Exist File Size = %d", file_size);
152         _DEBUG_INFO(" download_descriptor->object_size = %d", download_descriptor->object_size);
153         if (file_size >= download_descriptor->object_size) {
154                 _DEBUG_INFO("EXIST_COMPLETED_FILE\n");
155                 *file_status = EXIST_COMPLETED_FILE;
156                 goto arrange;
157         }
158
159  return_part:
160
161         (*data_resume_info) = _alloc_data_resume_infomation();
162         if ((*data_resume_info) == NULL) {
163                 _DEBUG_INFO("calloc failed !!");
164                 ret = COMMON_ERR_ALLOC;
165                 *file_status = NOT_EXIST_FILE;
166                 goto error;
167         }
168         (*data_resume_info)->file_path = g_strdup_printf("%s", file_path);
169         (*data_resume_info)->current_data_size = file_size;
170         (*data_resume_info)->total_data_size = download_descriptor->object_size;
171         *file_status = EXIST_PARTIAL_FILE;
172         _DEBUG_INFO("EXIST_PARTIAL_FILE\n");
173
174  arrange:
175         err = _arrange_file(checked_download_folder, file_name);
176         if (err != 1) {
177                 ret = COMMON_ERR_GENERIC;
178         }
179
180  error:
181         if (recvMsg != NULL)
182                 free(recvMsg);
183
184         if (recv_header != NULL)
185                 free_header_info(recv_header);
186
187         str_free(&file_name);
188         str_free(&file_path);
189
190         _DEBUG_INFO("END error : %d !!", ret);
191         _EXTERN_FUNC_EXIT;
192         return ret;
193 }
194
195 DM_ERROR download_object(const char *download_folder, char **object_downloaded_path, Data_Resume_Infomation * data_resume_info, int config, Download_Descriptor * download_descriptor, DM_ERROR * download_status)
196 {
197         _EXTERN_FUNC_ENTER;
198
199         DM_ERROR ret = DM_OK;
200
201         retvm_if((download_folder) == NULL, COMMON_ERR_IS_NULL, "download_folder is NULL!!");
202         retvm_if((data_resume_info) == NULL, COMMON_ERR_IS_NULL, "data_resume_info is NULL!!");
203         retvm_if((download_descriptor) == NULL, COMMON_ERR_IS_NULL, "download_descriptor is NULL!!");
204
205         if (data_resume_info->file_path == NULL) {
206                 ret = COMMON_ERR_INTERNAL_NOT_DEFINED;
207                 *download_status = DM_ERR_INVALID_DESCRIPTOR;
208                 _EXTERN_FUNC_EXIT;
209                 return ret;
210         }
211
212         _DEBUG_INFO(" data_resume_info = %p", data_resume_info);
213         _DEBUG_INFO("file path : %s ", data_resume_info->file_path);
214         _DEBUG_INFO("file size : %d ", data_resume_info->total_data_size);
215
216         if (!sync_agent_is_existing_fs(data_resume_info->file_path)) {
217                 _DEBUG_INFO("FILE IS NOT EXIST");
218                 FILE *fp = fopen(data_resume_info->file_path, "w");
219                 fclose(fp);
220
221         } else {
222                 //
223         }
224         _DEBUG_INFO("############################################################################");
225         /*noti to ui */
226         int noti_err = noti_send_download_info(data_resume_info->total_data_size, data_resume_info->file_path);
227         sleep(1);
228         _DEBUG_INFO("download info noti : %d", noti_err);
229         _DEBUG_INFO("############################################################################");
230         if (noti_err != 1) {
231                 ret = COMMON_ERR_IPC;
232                 *download_status = DM_ERR_USER_CANDELLED;
233                 goto error;
234         }
235         char *download_path = NULL;
236         int current_file_download_size = 0;
237         if (data_resume_info != NULL) {
238                 current_file_download_size = data_resume_info->current_data_size;
239         }
240
241         GList *send_header = 0;
242         ret = download_data(download_descriptor->object_uri, download_descriptor->object_type, send_header, current_file_download_size, (char *)download_folder, config, &download_path);
243         if (ret != DM_OK) {
244                 _DEBUG_INFO("send_DL_Msg() err [%d]\n", ret);
245                 *download_status = DM_ERR_USER_CANDELLED;
246                 goto error;
247         }
248
249         *object_downloaded_path = download_path;
250         *download_status = DM_DD_SUCCESS;
251
252  error:
253
254         if (data_resume_info != NULL) {
255                 _free_data_resume_information(data_resume_info);
256                 _DEBUG_INFO("__free_Data_Resume_Information() Success\n");
257         }
258
259         _DEBUG_INFO("END : %d !!", ret);
260         _EXTERN_FUNC_EXIT;
261         return ret;
262 }
263
264 DM_ERROR send_donwload_status(DM_ERROR download_status, Download_Descriptor * download_descriptor)
265 {
266         _EXTERN_FUNC_ENTER;
267         DM_ERROR ret = DM_OK;
268
269         retvm_if((download_descriptor) == NULL, COMMON_ERR_IS_NULL, "download_descriptor is NULL!!");
270
271         if ((download_descriptor == NULL) || (download_descriptor->install_notify_uri == NULL)) {
272                 _EXTERN_FUNC_EXIT;
273                 return COMMON_ERR_IS_NULL;
274         }
275
276         GList *send_header = 0;
277         char *send_msg = 0;
278         char *recvMsg = 0;
279         unsigned int recvMsg_size = 0;
280         GList *recv_header = 0;
281
282         send_msg = _get_msg_for_status(download_status);
283         if (send_msg != NULL) {
284                 ret = send_download_msg(SEND_DOWNLOAD_STATUS, download_descriptor->install_notify_uri, 0, send_header, send_msg, strlen(send_msg), &recv_header, &recvMsg, &recvMsg_size);
285                 if (ret != DM_OK) {
286                         _DEBUG_INFO("send_DL_Msg() err [%d]\n", ret);
287                         _EXTERN_FUNC_EXIT;
288                         return 1;
289                 }
290         }
291
292         if (recvMsg != NULL)
293                 free(recvMsg);
294
295         if (recv_header != NULL)
296                 free_header_info(recv_header);
297
298         _EXTERN_FUNC_EXIT;
299         return ret;
300 }
301
302 /* static function implementation*/
303
304 void free_Download_Descriptor(Download_Descriptor ** download_descriptor)
305 {
306         _EXTERN_FUNC_ENTER;
307
308         if (*download_descriptor != NULL) {
309
310                 if ((*download_descriptor)->object_name != NULL)
311                         free((*download_descriptor)->object_name);
312
313                 if ((*download_descriptor)->object_description != NULL)
314                         free((*download_descriptor)->object_description);
315
316                 if ((*download_descriptor)->object_uri != NULL)
317                         free((*download_descriptor)->object_uri);
318
319                 if ((*download_descriptor)->next_uri != NULL)
320                         free((*download_descriptor)->next_uri);
321
322                 if ((*download_descriptor)->install_notify_uri != NULL)
323                         free((*download_descriptor)->install_notify_uri);
324
325                 if ((*download_descriptor)->info_uri != NULL)
326                         free((*download_descriptor)->info_uri);
327
328                 if ((*download_descriptor)->icon_uri != NULL)
329                         free((*download_descriptor)->icon_uri);
330
331                 if ((*download_descriptor)->object_vender != NULL)
332                         free((*download_descriptor)->object_vender);
333
334                 if ((*download_descriptor)->DD_version != NULL)
335                         free((*download_descriptor)->DD_version);
336
337                 if ((*download_descriptor)->install_param != NULL)
338                         free((*download_descriptor)->install_param);
339
340                 free((*download_descriptor));
341         }
342
343         *download_descriptor = 0;
344
345         _EXTERN_FUNC_EXIT;
346 }
347
348 static Data_Resume_Infomation *_alloc_data_resume_infomation()
349 {
350         _INNER_FUNC_ENTER;
351
352         _INNER_FUNC_EXIT;
353         return (Data_Resume_Infomation *) calloc(1, sizeof(Data_Resume_Infomation));
354 }
355
356 static void _free_data_resume_information(Data_Resume_Infomation * data_resume_info)
357 {
358         _INNER_FUNC_ENTER;
359         if (data_resume_info != NULL) {
360
361                 if (data_resume_info->file_path != NULL)
362                         free(data_resume_info->file_path);
363
364                 free(data_resume_info);
365         }
366
367         data_resume_info = NULL;
368         _INNER_FUNC_EXIT;
369 }
370
371 static int _arrange_file(const char *download_folder, const char *file_name)
372 {
373         _INNER_FUNC_ENTER;
374
375         retvm_if((download_folder) == NULL, 0, "download_folder is NULL!!");
376         retvm_if((file_name) == NULL, 0, "file_name is NULL!!");
377
378         int err = 1;
379         GSList *fileList = 0;
380         err = sync_agent_get_file_list(download_folder, &fileList);
381         if (err != 1)
382                 goto error;
383
384         GSList *iter = 0;
385         char *temp_file_info = 0;
386         char *temp_file_name = 0;
387         char *temp_file_path = 0;
388         for (iter = fileList; iter != 0; iter = g_slist_next(iter)) {
389                 temp_file_info = (char *)(iter->data);
390                 _DEBUG_TRACE("temp_file_name = %s\n", temp_file_name);
391
392                 //
393                 temp_file_name = strtok(temp_file_info, ",");
394                 //
395
396                 if (strcmp(temp_file_name, file_name) != 0) {
397                         temp_file_path = g_strdup_printf("%s/%s", download_folder, temp_file_name);
398                         _DEBUG_TRACE("temp_file_path = %s\n", temp_file_path);
399                         err = sync_agent_delete_file(temp_file_path);
400                         _DEBUG_TRACE("delete file = %d\n", err);
401                         str_free(&temp_file_path);
402                 }
403         }
404
405  error:
406
407         _INNER_FUNC_EXIT;
408         return err;
409 }
410
411 static char *_get_msg_for_status(DM_ERROR download_status)
412 {
413         _INNER_FUNC_ENTER;
414
415         char *send_msg = 0;
416
417         switch (download_status) {
418         case DM_OK:
419                 send_msg = g_strdup_printf("%d Success", download_status);
420                 break;
421         case DM_ERR_INSUFFICIENT_MEMORY:
422                 send_msg = g_strdup_printf("%d Insufficient memory", download_status);
423                 break;
424         case DM_ERR_USER_CANDELLED:
425                 send_msg = g_strdup_printf("%d User Cancelled", download_status);
426                 break;
427         case DM_ERR_LOSS_OF_SERVICE:
428                 send_msg = g_strdup_printf("%d Loss of Service", download_status);
429                 break;
430         case DM_ERR_ATTR_MISMATCH:
431                 send_msg = g_strdup_printf("%d Attribute mismatch", download_status);
432                 break;
433         case DM_ERR_INVALID_DESCRIPTOR:
434                 send_msg = g_strdup_printf("%d Invalid descriptor", download_status);
435                 break;
436         case DM_ERR_INVALID_DDVERSION:
437                 send_msg = g_strdup_printf("%d Invalid DDVersion", download_status);
438                 break;
439         case DM_ERR_DEVICE_ABORTED:
440                 send_msg = g_strdup_printf("%d Device Aborted", download_status);
441                 break;
442         case DM_ERR_NON_ACCEPTABLE_CONTENT:
443                 send_msg = g_strdup_printf("%d Non-Acceptable Content", download_status);
444                 break;
445         case DM_ERR_LOADER_ERROR:
446                 send_msg = g_strdup_printf("%d Loader Error", download_status);
447                 break;
448         default:
449                 break;
450         }
451
452         _INNER_FUNC_EXIT;
453
454         return send_msg;
455 }