3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <sync_agent.h>
22 #include "common/dm_common.h"
23 #include "common/util/util.h"
24 #include "dm-engine/dl-manager/sa_fw_downloader.h"
25 #include "dm-engine/dl-manager/na_fw_dl_binder.h"
27 #ifndef OMADM_AGENT_LOG
29 #define LOG_TAG "OMA_DM_DL"
32 #define DOWNLOAD_BODY_SIZE 66304
33 //#define DOWNLOAD_BODY_SIZE 3592624
36 static sync_agent_na_result_e _download_data(GList * header_info, int na_plugIn_id, unsigned char *download_folder, unsigned int download_start_size,
37 unsigned int download_body_size, unsigned char **out_download_path, sync_agent_na_send_type_e send_type, unsigned int session_id, int config);
38 static sync_agent_na_result_e __get_data_info(void *http_req_info, void *http_info, int *total_doanload_size, char **current_download_range, char **download_file_name);
39 static sync_agent_na_result_e __set_data_info(void *http_info, char *current_download_range);
41 void free_header_info(GList * header_info)
45 if (header_info != NULL) {
47 sync_agent_na_common_header_info_s *iter_data;
48 for (iter = header_info; iter != NULL;) {
50 iter_data = ((sync_agent_na_common_header_info_s *) (iter->data));
52 iter = g_list_next(iter);
53 header_info = g_list_remove(header_info, iter_data);
55 if (iter_data->key != NULL)
57 if (iter_data->value != NULL)
58 free(iter_data->value);
61 g_list_free(header_info);
67 char *get_file_name(GList * recv_header, char *url_file_name)
71 retvm_if((recv_header) == NULL, NULL, "recv_header is NULL!!");
72 retvm_if((url_file_name) == NULL, NULL, "url_file_name is NULL!!");
74 char *file_name = NULL;
75 file_name = get_file_name_from_http_header(recv_header);
77 /*gcf server not response Content-Disposition element */
78 if (file_name == NULL) {
79 char *temp_ptr = NULL;
80 _DEBUG_INFO("http content_disposition is null");
82 temp_ptr = strrchr(url_file_name, '/');
83 _DEBUG_INFO("result_file name : %s", temp_ptr);
85 if (temp_ptr != NULL) {
87 _DEBUG_INFO("remove '/' result_file name : %s", temp_ptr);
88 file_name = strdup(temp_ptr);
91 _DEBUG_INFO("dd object uri file name is null");
94 _DEBUG_INFO(" file name : %s", file_name);
101 char *get_file_name_from_http_header(GList * header_info)
104 /* pasing file name */
108 retvm_if((header_info) == NULL, NULL, "header_info is NULL!!");
110 int ret = sync_agent_get_header_info(1, header_info, "Content-Disposition", &value);
114 _DEBUG_INFO("Key = %s, Value = %s\n", "Content-Disposition", value);
115 char *ptr1 = strstr(value, "attachment;");
117 ptr1 = strstr(ptr1, "fileName=");
120 char *temp = strdup(ptr1);
123 char *temp_ptr = strtok(temp, del);
124 //temp_ptr = strtok(NULL, del);
126 file_name = strdup(temp_ptr);
127 _DEBUG_INFO("*download_file_name = %s\n", file_name);
140 DM_ERROR send_download_msg(DL_SEND_MSG_TYPE send_dl_type, char *local_uri, char *content_type, GList * header_info, char *sendMsg, unsigned int sendMsg_length, GList ** recv_header, char **recvMsg, unsigned int *recvMsg_length)
144 int transportType = 1;
146 sync_agent_na_result_e res = SYNC_AGENT_NA_SUCCESS;
147 DM_ERROR ret = DM_OK;
150 retvm_if((sendMsg) == NULL, COMMON_ERR_IS_NULL, "sendMsg is NULL!!");
152 //timeout : 30 seconds
153 res = sync_agent_open_connection(transportType, 30, (unsigned int *)(&(net_session_id)));
155 _DEBUG_INFO("res =%d\n", res);
157 if (res != SYNC_AGENT_NA_SUCCESS) {
158 ret = COMMON_ERR_INTERNAL_CONNECTION_ERROR;
163 switch (send_dl_type) {
166 add_header_info(&header_info, "Range", g_strdup_printf("bytes=0-%d", DOWNLOAD_BODY_SIZE - 1));
167 /* intentionally not used "break" */
171 add_header_info(&header_info, "method", "get");
172 add_header_info(&header_info, "uri", local_uri);
173 add_header_info(&header_info, "Connection", "Keep-Alive");
174 add_header_info(&header_info, "User-Agent", "Samsung electronics GT-I9500 SyncML_DM Client");
175 add_header_info(&header_info, "Accept", content_type);
176 add_header_info(&header_info, "Accept-Charset", "UTF-8");
177 add_header_info(&header_info, "Content-Type", content_type);
180 case SEND_DOWNLOAD_STATUS:
182 add_header_info(&header_info, "method", "post");
183 add_header_info(&header_info, "uri", local_uri);
184 add_header_info(&header_info, "Content-Length", g_strdup_printf("%d", sendMsg_length));
192 switch (send_dl_type) {
195 case SEND_DOWNLOAD_STATUS:
197 res = sync_agent_send_msg( /*acc_info (id, pw, uri, ...), */
198 header_info, transportType, sendMsg, sendMsg_length, recv_header, (unsigned char **)recvMsg, recvMsg_length, SYNC_AGENT_NA_SEND_TYPE_SEND_N_RECEIVE, net_session_id);
205 _DEBUG_INFO("res =%d\n", res);
207 if (res != SYNC_AGENT_NA_SUCCESS) {
208 ret = COMMON_ERR_INTERNAL_CONNECTION_ERROR;
212 res = sync_agent_close_connection(transportType, net_session_id);
214 _DEBUG_INFO("res =%d\n", res);
215 if (res != SYNC_AGENT_NA_SUCCESS) {
216 ret = COMMON_ERR_INTERNAL_CONNECTION_ERROR;
227 _DEBUG_INFO("returnerror = %d\n", ret);
229 res = sync_agent_close_connection(transportType, net_session_id);
231 _DEBUG_INFO("res =%d\n", res);
232 if (res != SYNC_AGENT_NA_SUCCESS) {
233 ret = COMMON_ERR_INTERNAL_CONNECTION_ERROR;
243 _DEBUG_INFO("error = %d\n", ret);
253 DM_ERROR download_data(char *local_uri, char *content_type, GList * header_info, int current_file_download_size, char *download_folder, int config, char **download_path)
257 sync_agent_na_result_e res = SYNC_AGENT_NA_SUCCESS;
258 DM_ERROR ret = DM_OK;
259 int transportType = 1;
261 int net_session_id = 0;
264 retvm_if((local_uri) == NULL, COMMON_ERR_IS_NULL, "local_uri is NULL!!");
265 retvm_if((header_info) == NULL, COMMON_ERR_IS_NULL, "header_info is NULL!!");
266 retvm_if((download_folder) == NULL, COMMON_ERR_IS_NULL, "download_folder is NULL!!");
268 //timeout : 30 seconds
269 res = sync_agent_open_connection(transportType, 30, (unsigned int *)(&(net_session_id)));
271 _DEBUG_INFO("res =%d\n", res);
272 if (res != SYNC_AGENT_NA_SUCCESS) {
273 ret = COMMON_ERR_INTERNAL_CONNECTION_ERROR;
277 add_header_info(&header_info, "method", "get");
278 add_header_info(&header_info, "uri", local_uri);
279 add_header_info(&header_info, "Connection", "Keep-Alive");
280 // add_header_info(&header_info, "User-Agent", "Samsung electronics GT-I9500 SyncML_DM Client");
281 add_header_info(&header_info, "Accept", content_type);
282 add_header_info(&header_info, "Accept-Charset", "UTF-8");
283 add_header_info(&header_info, "Content-Type", content_type);
284 add_header_info(&header_info, "Range", g_strdup_printf("bytes=%d-%d", current_file_download_size, current_file_download_size + DOWNLOAD_BODY_SIZE - 1));
286 sync_agent_register_cancel_callback(network_cancel_callback, &(net_session_id));
288 //check cancel flag (note that this can be called every where inside processing logic)
289 cancel_flag = sync_agent_check_cancel_flag();
290 if (cancel_flag != 0) {
291 ret = DM_ERR_USER_CANDELLED;
295 while (down_count < MAX_COUNT) {
297 res = _download_data( /*acc_info (id, pw, uri, ...), */
298 header_info, transportType, (unsigned char *)download_folder, current_file_download_size, DOWNLOAD_BODY_SIZE, (unsigned char **)download_path, SYNC_AGENT_NA_SEND_TYPE_SEND_N_RECEIVE, net_session_id, config);
301 _DEBUG_INFO("response download =%d\n", res);
303 if (res != SYNC_AGENT_NA_SUCCESS) {
304 if (res == SYNC_AGENT_NA_NETWORK_UNAVAILABLE) {
306 if (down_count == MAX_COUNT) {
307 _DEBUG_INFO("download data wifi only error");
308 ret = DM_WIFI_ONLY_ERROR;
311 _DEBUG_INFO("download data network retry : %d", down_count);
315 _DEBUG_INFO("download data error");
316 ret = COMMON_ERR_INTERNAL_CONNECTION_ERROR;
317 /*f(res == SYNC_AGENT_NA_SEND_MSG_CANCEL) {
321 _DEBUG_INFO("----------------------------------------download success-------------------------------------------\n");
322 down_count = MAX_COUNT;
328 sync_agent_unregister_cancel_callback(network_cancel_callback, &(net_session_id));
330 cancel_flag = sync_agent_check_cancel_flag();
331 if (cancel_flag != 0) {
332 _DEBUG_INFO("----------------------------------------task cancel flag is : %d-------------------------------------------\n", cancel_flag);
333 _DEBUG_INFO("----------------------------------------download cancel-------------------------------------------\n");
334 if (cancel_flag != 0) {
335 _DEBUG_INFO("download cancel flag");
336 ret = DM_ERR_USER_CANDELLED;
340 _DEBUG_INFO("returnerror = %d\n", ret);
341 res = sync_agent_close_connection(transportType, net_session_id);
343 _DEBUG_INFO("res =%d\n", res);
348 _DEBUG_INFO("error = %d\n", ret);
352 static sync_agent_na_result_e _download_data(GList * header_info, int na_plugIn_id, unsigned char *download_folder, unsigned int download_start_size,
353 unsigned int download_body_size, unsigned char **out_download_path, sync_agent_na_send_type_e send_type, unsigned int session_id, int config)
357 retvm_if((header_info) == NULL, COMMON_ERR_IS_NULL, "header_info is NULL!!");
358 retvm_if((download_folder) == NULL, COMMON_ERR_IS_NULL, "download_folder is NULL!!");
360 GList *recv_header_info = 0;
361 /* char *recvMsg = 0; */
362 unsigned char *recvMsg = NULL;
363 unsigned int recvMsg_size = 0;
365 unsigned int download_current_size = download_start_size;
366 /* unsigned int download_total_size = 0; */
367 int download_total_size = 0;
368 char *current_download_range = NULL;
369 char *download_file_name = NULL;
371 int count = 0; /* for test log */
372 sync_agent_na_result_e ret = SYNC_AGENT_NA_SUCCESS;
373 GList *free_list = NULL;
374 sync_agent_na_common_header_info_s *free_item = NULL;
375 GList *backup_send_head_info_list = NULL;
378 while (download_total_size == 0 || download_current_size < download_total_size - 1) {
380 _DEBUG_TRACE("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
381 _DEBUG_TRACE("############# %d th download", ++count);
382 _DEBUG_TRACE("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
384 /* back up the header list TODO */
385 /* GSList *backup_send_head_info_list = 0; */
386 backup_send_head_info_list = NULL;
388 for (iter = header_info; iter != NULL; iter = g_list_next(iter)) {
389 sync_agent_na_common_header_info_s *header_item_info = (sync_agent_na_common_header_info_s *) calloc(1, sizeof(sync_agent_na_common_header_info_s));
390 if (header_item_info == NULL) {
391 _DEBUG_TRACE("calloc failed !!");
392 ret = SYNC_AGENT_NA_DOWNLOAD_DATA_FAIL;
396 if (((sync_agent_na_common_header_info_s *) (iter->data))->key != NULL) {
397 header_item_info->key = strdup(((sync_agent_na_common_header_info_s *) (iter->data))->key);
399 if (((sync_agent_na_common_header_info_s *) (iter->data))->value != NULL) {
400 header_item_info->value = strdup(((sync_agent_na_common_header_info_s *) (iter->data))->value);
402 _DEBUG_TRACE("key : %s, value is NULL !!", header_item_info->key);
403 header_item_info->value = NULL;
406 backup_send_head_info_list = g_list_append(backup_send_head_info_list, header_item_info);
408 if (strcmp(((sync_agent_na_common_header_info_s *) (iter->data))->key, "Range") == 0) {
409 _DEBUG_TRACE("[Before] key : %s, value : %s", ((sync_agent_na_common_header_info_s *) (iter->data))->key, ((sync_agent_na_common_header_info_s *) (iter->data))->value);
413 _DEBUG_TRACE("key is NULL !!");
414 header_item_info->key = NULL;
415 header_item_info->value = NULL;
416 free(header_item_info);
417 header_item_info = NULL;
422 _DEBUG_TRACE("wifi only off mode download");
423 } else if (config == 1) {
424 ret = get_wifi_state();
425 _DEBUG_TRACE("wifi only mode : %d", ret);
426 if (ret != SYNC_AGENT_NA_SUCCESS) {
432 ret = sync_agent_send_msg(backup_send_head_info_list, na_plugIn_id, 0, 0, &recv_header_info, &recvMsg, &recvMsg_size, send_type, session_id);
433 if (ret != SYNC_AGENT_NA_SUCCESS) {
434 _DEBUG_TRACE("sync_agent_send_msg() fail");
435 ret = SYNC_AGENT_NA_DOWNLOAD_DATA_FAIL;
439 _DEBUG_TRACE("RecvMSg_Size = %d", recvMsg_size);
440 _DEBUG_TRACE("############# sync_agent_send_msg() success !!");
442 /* get download total size, download current range */
443 ret = __get_data_info(header_info, recv_header_info, &download_total_size, ¤t_download_range, &download_file_name);
444 if (ret != SYNC_AGENT_NA_SUCCESS) {
445 _DEBUG_TRACE("Get_Data_Down_Info() fail !!");
446 ret = SYNC_AGENT_NA_DOWNLOAD_DATA_FAIL;
450 _DEBUG_TRACE("############# Get_Data_Down_Info() success !!");
451 if (current_download_range == NULL || download_total_size == 0 || download_file_name == NULL) {
452 _DEBUG_TRACE("current_download_range == NULL || download_total_size == 0 || download_file_name == NULL");
453 ret = SYNC_AGENT_NA_DOWNLOAD_DATA_FAIL;
457 _DEBUG_TRACE("download_total_size = %d", download_total_size);
458 _DEBUG_TRACE("current_download_range = %s", current_download_range);
459 _DEBUG_TRACE("download_file_name = %s", download_file_name);
461 /* download path setting */
462 if (*out_download_path == NULL) {
463 *out_download_path = (unsigned char *)g_strdup_printf("%s/%s", download_folder, download_file_name);
464 _DEBUG_TRACE("*out_download_path = %s", *out_download_path);
467 /* increment download count */
469 /* int down_size = 0; */
470 char *ptr = strtok(current_download_range, del);
476 _DEBUG_TRACE("start_size = %s", ptr);
477 start_size = atoi(ptr);
479 ptr = strtok(NULL, del);
480 _DEBUG_TRACE("end_size = %s", ptr);
481 end_size = atoi(ptr);
483 _DEBUG_TRACE("prev download_current_size = %d", download_current_size);
484 _DEBUG_TRACE("Gap = %d", end_size - start_size);
486 download_current_size += (end_size - start_size + 1);
487 _DEBUG_TRACE("after download_current_size = %d", download_current_size);
490 bool isFinal = false;
491 if (download_current_size >= download_total_size - 1)
495 _DEBUG_TRACE("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RecvMSg_Size = %d", recvMsg_size);
496 ret = sync_agent_append_file((char *)(*out_download_path), (char *)recvMsg, recvMsg_size, false);
497 if (ret != SYNC_AGENT_NA_SUCCESS) {
498 _DEBUG_TRACE("sync_agent_write_file() fail !!");
499 ret = SYNC_AGENT_NA_DOWNLOAD_DATA_FAIL;
502 _DEBUG_TRACE("############# sync_agent_write_file() success !!");
505 /* set download total size, download current range */
506 char *new_download_range = g_strdup_printf("%d-%d", download_current_size, download_current_size + (download_body_size - 1));
507 ret = __set_data_info(header_info, new_download_range);
508 if (ret != SYNC_AGENT_NA_SUCCESS) {
509 _DEBUG_TRACE("Set_Data_Down_Info() fail !!");
510 ret = SYNC_AGENT_NA_DOWNLOAD_DATA_FAIL;
514 _DEBUG_TRACE("############# Set_Data_Down_Info() success !!");
516 if (backup_send_head_info_list != NULL) {
517 for (free_list = backup_send_head_info_list; free_list != NULL;) {
518 free_item = (sync_agent_na_common_header_info_s *) (free_list->data);
519 free_list = g_list_next(free_list);
521 sync_agent_free_na_common_header_info(free_item);
523 g_list_free(backup_send_head_info_list);
532 if (backup_send_head_info_list != NULL) {
533 for (free_list = backup_send_head_info_list; free_list != NULL;) {
534 free_item = (sync_agent_na_common_header_info_s *) (free_list->data);
535 free_list = g_list_next(free_list);
537 sync_agent_free_na_common_header_info(free_item);
539 g_list_free(backup_send_head_info_list);
546 static sync_agent_na_result_e __get_data_info(void *http_req_info, void *http_info, int *total_doanload_size, char **current_download_range, char **download_file_name)
550 sync_agent_na_result_e ret = SYNC_AGENT_NA_SUCCESS;
552 /* pasing file name */
553 char *temp_file_name = 0; /* strdup("attachment; fileName=\"FW-20110901-13121.bin\""); */
554 ret = sync_agent_get_header_info(1, (GList *) http_info, "Content-Disposition", &temp_file_name);
555 if (ret == SYNC_AGENT_NA_SUCCESS) {
556 _DEBUG_VERBOSE("success in sync_agent_get_header_info = %d", ret);
558 _DEBUG_VERBOSE("failed in sync_agent_get_header_info = %d", ret);
560 _DEBUG_VERBOSE("temp_file_name = %s\n", temp_file_name);
561 if (temp_file_name) {
562 char *ptr1 = strstr(temp_file_name, "attachment;");
564 ptr1 = strstr(ptr1, "fileName=");
567 char *temp = strdup(ptr1);
570 char *temp_ptr = strtok(temp, del);
571 _DEBUG_VERBOSE("1st token = %s", temp_ptr);
573 temp_ptr = strtok(NULL, del);
574 _DEBUG_VERBOSE("2nd token = %s", temp_ptr);
576 *download_file_name = strdup(temp_ptr);
577 _DEBUG_VERBOSE("*download_file_name = %s", *download_file_name);
584 char *result_name = NULL;
586 ret = sync_agent_get_header_info(1, (GList *) http_req_info, "uri", &temp_file_name);
587 if (ret == SYNC_AGENT_NA_SUCCESS) {
588 _DEBUG_VERBOSE("success in sync_agent_get_header_info = %d", ret);
590 _DEBUG_VERBOSE("failed in sync_agent_get_header_info = %d", ret);
592 _DEBUG_VERBOSE("temp_file_name = %s\n", temp_file_name);
593 if (temp_file_name != NULL) {
595 result_name = strrchr(temp_file_name, '/');
596 _DEBUG_VERBOSE("result_file name : %s", result_name);
598 if (result_name != NULL) {
600 _DEBUG_VERBOSE("remove '/' result_file name : %s", result_name);
602 *download_file_name = strdup(result_name);
603 _DEBUG_VERBOSE("*download_file_name = %s\n", *download_file_name);
607 /* parsing data range info */
608 char *temp_range_value = 0; /* strdup("bytes 0-66303/3192624"); */
609 ret = sync_agent_get_header_info(1, (GList *) http_info, "Content-Range", &temp_range_value);
610 if (ret == SYNC_AGENT_NA_SUCCESS) {
611 _DEBUG_VERBOSE("success in sync_agent_get_header_info = %d", ret);
613 _DEBUG_VERBOSE("failed in sync_agent_get_header_info = %d", ret);
615 if (temp_range_value != NULL) {
617 temp = strdup(temp_range_value + strlen("bytes "));
618 _DEBUG_VERBOSE("temp_range = %s\n", temp);
621 char *ptr2 = strtok(temp, del2);
623 _DEBUG_VERBOSE("[na_http_plugIn] range = %s\n", ptr2);
624 *current_download_range = strdup(ptr2);
626 ptr2 = strtok(NULL, del2);
627 _DEBUG_VERBOSE("[na_http_plugIn] total = %s\n", ptr2);
628 *total_doanload_size = atoi(ptr2);
637 static sync_agent_na_result_e __set_data_info(void *http_info, char *current_download_range)
641 sync_agent_na_result_e ret = SYNC_AGENT_NA_SUCCESS;
644 for (iter = (GList *) http_info; iter != NULL; iter = g_list_next(iter)) {
646 if (((sync_agent_na_common_header_info_s *) (iter->data))->key != 0 && !strcmp(((sync_agent_na_common_header_info_s *) (iter->data))->key, "Range")) {
648 char *value = ((sync_agent_na_common_header_info_s *) (iter->data))->value;
652 ((sync_agent_na_common_header_info_s *) (iter->data))->value = g_strdup_printf("bytes=%s", current_download_range);
653 _DEBUG_VERBOSE("[After] key : %s, value : %s\n", ((sync_agent_na_common_header_info_s *) (iter->data))->key, ((sync_agent_na_common_header_info_s *) (iter->data))->value);
656 _DEBUG_VERBOSE("[na_http_plugIn] value is NULL !! \n");
657 ret = SYNC_AGENT_NA_GET_HEADER_INFO_FAIL;