From d7efab678d65d5ea8c470d328427f24f4d683af9 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Sun, 1 Feb 2015 14:10:33 +0900 Subject: tizen 2.3 release --- agent/CMakeLists.txt | 138 +- agent/download-agent-basic.c | 431 ---- agent/download-agent-client-mgr.c | 680 +---- agent/download-agent-debug.c | 205 -- agent/download-agent-dl-info-util.c | 498 ---- agent/download-agent-dl-info.c | 462 ++++ agent/download-agent-dl-mgr.c | 356 +-- agent/download-agent-encoding.c | 61 +- agent/download-agent-file.c | 1507 +++++------ agent/download-agent-http-mgr.c | 2624 +++++++++----------- agent/download-agent-http-misc.c | 64 - agent/download-agent-http-msg-handler.c | 552 ++-- agent/download-agent-http-queue.c | 390 --- agent/download-agent-interface.c | 224 +- agent/download-agent-mime-util.c | 112 +- agent/download-agent-plugin-conf.c | 65 +- agent/download-agent-plugin-drm.c | 124 + agent/download-agent-plugin-libcurl.c | 702 ++++++ agent/download-agent-plugin-libsoup.c | 1002 -------- agent/download-agent-utils-dl-id-history.c | 71 - agent/download-agent-utils.c | 285 --- agent/include/download-agent-basic.h | 29 - agent/include/download-agent-client-mgr.h | 77 +- agent/include/download-agent-debug.h | 109 +- agent/include/download-agent-defs.h | 32 +- agent/include/download-agent-dl-info-util.h | 257 -- agent/include/download-agent-dl-info.h | 197 ++ agent/include/download-agent-dl-mgr.h | 20 +- agent/include/download-agent-encoding.h | 2 +- agent/include/download-agent-file.h | 45 +- agent/include/download-agent-http-mgr.h | 25 +- agent/include/download-agent-http-misc.h | 47 - agent/include/download-agent-http-msg-handler.h | 101 +- agent/include/download-agent-http-queue.h | 126 - agent/include/download-agent-interface.h | 445 +--- agent/include/download-agent-mime-util.h | 10 +- agent/include/download-agent-plugin-conf.h | 7 +- agent/include/download-agent-plugin-drm.h | 25 + .../include/download-agent-plugin-http-interface.h | 51 - agent/include/download-agent-plugin-libcurl.h | 35 + agent/include/download-agent-plugin-libsoup.h | 75 - agent/include/download-agent-pthread.h | 243 +- agent/include/download-agent-type.h | 44 +- agent/include/download-agent-utils-dl-id-history.h | 35 - agent/include/download-agent-utils.h | 60 - 45 files changed, 4312 insertions(+), 8338 deletions(-) delete mode 100755 agent/download-agent-basic.c delete mode 100755 agent/download-agent-debug.c delete mode 100755 agent/download-agent-dl-info-util.c create mode 100644 agent/download-agent-dl-info.c delete mode 100755 agent/download-agent-http-misc.c delete mode 100755 agent/download-agent-http-queue.c create mode 100644 agent/download-agent-plugin-drm.c create mode 100644 agent/download-agent-plugin-libcurl.c delete mode 100755 agent/download-agent-plugin-libsoup.c delete mode 100755 agent/download-agent-utils-dl-id-history.c delete mode 100755 agent/download-agent-utils.c delete mode 100755 agent/include/download-agent-basic.h delete mode 100755 agent/include/download-agent-dl-info-util.h create mode 100644 agent/include/download-agent-dl-info.h delete mode 100755 agent/include/download-agent-http-misc.h delete mode 100755 agent/include/download-agent-http-queue.h create mode 100644 agent/include/download-agent-plugin-drm.h delete mode 100755 agent/include/download-agent-plugin-http-interface.h create mode 100644 agent/include/download-agent-plugin-libcurl.h delete mode 100755 agent/include/download-agent-plugin-libsoup.h delete mode 100755 agent/include/download-agent-utils-dl-id-history.h delete mode 100755 agent/include/download-agent-utils.h (limited to 'agent') diff --git a/agent/CMakeLists.txt b/agent/CMakeLists.txt index 26f2b34..c92fc48 100755 --- a/agent/CMakeLists.txt +++ b/agent/CMakeLists.txt @@ -1,67 +1,27 @@ PROJECT(downloadagent2 C) -IF("${CMAKE_BUILD_TYPE}" STREQUAL "") - SET(CMAKE_BUILD_TYPE "Debug") -ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") -MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") +SET(VERSION "0.1.0") -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(VERSION "0.0.1") FIND_PROGRAM(UNAME NAMES uname) EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH") - -#DA Engine Include Directory -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include) - -INCLUDE(FindPkgConfig) -pkg_check_modules(subpkgs REQUIRED - libsoup-2.4 - xdgmime - vconf - capi-network-connection - glib-2.0 - dlog -) - -FOREACH(flag ${subpkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") -SET(CMAKE_C_FLAGS_DEBUG "-O0 -Wall") - IF("${ARCH}" MATCHES "^arm.*") ADD_DEFINITIONS("-D_TARGET") SET(CMAKE_C_FLAGS_RELEASE "-mabi=aapcs-linux -msoft-float -O2") ENDIF("${ARCH}" MATCHES "^arm.*") -ADD_DEFINITIONS("-D_EFL_PLATFORM") -#allow to install widget, deb pkg and apk for testing -ADD_DEFINITIONS("-DDA_DEBUG_USING_DLOG") -#This should be removed when release a target -ADD_DEFINITIONS("-D_SAMSUNG_MIME_POLICY") - -############################################################################# -#+++++++++++++++++++++++++DA ENGINE+++++++++++++++++++++++++++++++++++++++++++ -############################################################################# +#DA Engine Include Directory +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include) SET(SRCS_PATH ".") -SET(SRCS_DA_ENGINE - ${SRCS_PATH}/download-agent-debug.c +SET(SRCS_DA ${SRCS_PATH}/download-agent-interface.c ${SRCS_PATH}/download-agent-client-mgr.c ${SRCS_PATH}/download-agent-dl-mgr.c - ${SRCS_PATH}/download-agent-dl-info-util.c - ${SRCS_PATH}/download-agent-http-queue.c - ${SRCS_PATH}/download-agent-http-misc.c + ${SRCS_PATH}/download-agent-dl-info.c ${SRCS_PATH}/download-agent-http-mgr.c ${SRCS_PATH}/download-agent-http-msg-handler.c ${SRCS_PATH}/download-agent-encoding.c - ${SRCS_PATH}/download-agent-utils.c - ${SRCS_PATH}/download-agent-utils-dl-id-history.c - ${SRCS_PATH}/download-agent-basic.c ${SRCS_PATH}/download-agent-file.c - ${SRCS_PATH}/download-agent-plugin-libsoup.c ${SRCS_PATH}/download-agent-plugin-conf.c ${SRCS_PATH}/download-agent-mime-util.c ) @@ -71,14 +31,86 @@ SET(HEADERS include/download-agent-interface.h ) -ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS_DA_ENGINE}) -#TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${subpkgs_LDFLAGS} "-ldl") -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${subpkgs_LDFLAGS}) -SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.0.1) +INCLUDE(FindPkgConfig) + +MESSAGE("SUPPORT_SYS_RESOURCE: ${SUPPORT_SYS_RESOURCE}") +IF (SUPPORT_SYS_RESOURCE) +pkg_check_modules(subpkgs REQUIRED + xdgmime + vconf + capi-network-connection + dlog + system-resource + storage +) +ELSE (SUPPORT_SYS_RESOURCE) +pkg_check_modules(subpkgs REQUIRED + xdgmime + vconf + capi-network-connection + dlog + storage +) +ENDIF (SUPPORT_SYS_RESOURCE) + +IF ("${HTTP_LIB}" MATCHES "libcurl") + MESSAGE("HTTP_LIB: ${HTTP_LIB}") + pkg_check_modules(httppkgs REQUIRED + libcurl + ) + LIST(APPEND SRCS_DA + ${SRCS_PATH}/download-agent-plugin-libcurl.c + ) +ENDIF ("${HTTP_LIB}" MATCHES "libcurl") -############################################################################# -#+++++++++++++++++++++++++INSTALLATION++++++++++++++++++++++++++++++++++++++++ -############################################################################# +IF (SUPPORT_OMA_DRM) + MESSAGE("SUPPORT_OMA_DRM: ${SUPPORT_OMA_DRM}") + ADD_DEFINITIONS("-D_ENABLE_OMA_DRM") + LIST(APPEND SRCS_DA + ${SRCS_PATH}/download-agent-plugin-drm.c + ) + pkg_check_modules(drmpkgs REQUIRED + drm-client + drm-trusted + ) +ENDIF (SUPPORT_OMA_DRM) -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) +IF (SUPPORT_SYS_RESOURCE) + ADD_DEFINITIONS("-D_ENABLE_SYS_RESOURCE") +ENDIF (SUPPORT_SYS_RESOURCE) + +IF (SUPPORT_DOWNLOAD_BOOSTER) + MESSAGE("SUPPORT_DOWNLOAD_BOOSTER:${SUPPORT_DOWNLOAD_BOOSTER}") + ADD_DEFINITIONS("-D_RAF_SUPPORT") + ADD_DEFINITIONS("-D_DOWNLOAD_BOOSTER_SUPPORT") +ENDIF (SUPPORT_DOWNLOAD_BOOSTER) +FOREACH(flag ${subpkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +FOREACH(flag ${httppkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +IF (SUPPORT_OMA_DRM) + FOREACH(flag ${drmpkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") + ENDFOREACH(flag) + #This is request of DRM Team. + ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64") +ENDIF (SUPPORT_OMA_DRM) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -Wall") + +ADD_DEFINITIONS("-D_ENABLE_DLOG") +#This should be removed when release a target +ADD_DEFINITIONS("-D_SAMSUNG_MIME_POLICY") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS_DA}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${subpkgs_LDFLAGS} ${httppkgs_LDFLAGS} ${drmpkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION}) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) diff --git a/agent/download-agent-basic.c b/agent/download-agent-basic.c deleted file mode 100755 index 73fc892..0000000 --- a/agent/download-agent-basic.c +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "download-agent-basic.h" -#include "download-agent-debug.h" -#include "download-agent-client-mgr.h" -#include "download-agent-utils.h" -#include "download-agent-http-mgr.h" -#include "download-agent-http-misc.h" -#include "download-agent-dl-mgr.h" -#include "download-agent-pthread.h" -#include "download-agent-file.h" - -static void* __thread_start_download(void* data); -void __thread_clean_up_handler_for_start_download(void *arg); - -static da_result_t __make_source_info_basic_download( - stage_info *stage, - client_input_t *client_input); -static da_result_t __download_content(stage_info *stage); - -da_result_t start_download(const char *url , int *dl_id) -{ - DA_LOG_FUNC_LOGD(Default); - return start_download_with_extension(url, dl_id, NULL); -} - -da_result_t start_download_with_extension( - const char *url, - int *dl_id, - extension_data_t *extension_data) -{ - da_result_t ret = DA_RESULT_OK; - int slot_id = 0; - const char **request_header = DA_NULL; - const char *install_path = DA_NULL; - const char *file_name = DA_NULL; - const char *etag = DA_NULL; - const char *temp_file_path = DA_NULL; - const char *pkg_name = DA_NULL; - int request_header_count = 0; - void *user_data = DA_NULL; - client_input_t *client_input = DA_NULL; - client_input_basic_t *client_input_basic = DA_NULL; - download_thread_input *thread_info = DA_NULL; - pthread_attr_t thread_attr; - - DA_LOG_FUNC_LOGV(Default); - - if (extension_data) { - request_header = extension_data->request_header; - if (extension_data->request_header_count) - request_header_count = extension_data->request_header_count; - install_path = extension_data->install_path; - file_name = extension_data->file_name; - user_data = extension_data->user_data; - etag = extension_data->etag; - temp_file_path = extension_data->temp_file_path; - pkg_name = extension_data->pkg_name; - } - - ret = get_available_slot_id(&slot_id); - if (DA_RESULT_OK != ret) - return ret; - - *dl_id = GET_DL_ID(slot_id); - - client_input = (client_input_t *)calloc(1, sizeof(client_input_t)); - if (!client_input) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } else { - client_input->user_data = user_data; - if (install_path) { - int install_path_len = strlen(install_path); - if (install_path[install_path_len-1] == '/') - install_path_len--; - - client_input->install_path = (char *)calloc(install_path_len+1, sizeof(char)); - if (client_input->install_path) - strncpy(client_input->install_path, install_path, install_path_len); - } - - if (file_name) { - client_input->file_name = (char *)calloc(strlen(file_name)+1, sizeof(char)); - if (client_input->file_name) - strncpy(client_input->file_name, file_name, strlen(file_name)); - } - - if (etag) { - client_input->etag = (char *)calloc(strlen(etag)+1, sizeof(char)); - if (client_input->etag) - strncpy(client_input->etag, etag, strlen(etag)); - - } - - if (temp_file_path) { - client_input->temp_file_path = (char *)calloc(strlen(temp_file_path)+1, sizeof(char)); - if (client_input->temp_file_path) - strncpy(client_input->temp_file_path, temp_file_path, strlen(temp_file_path)); - } - - if (pkg_name) { - client_input->pkg_name = (char *)calloc(strlen(pkg_name)+1, sizeof(char)); - if (client_input->pkg_name) - strncpy(client_input->pkg_name, pkg_name, strlen(pkg_name)); - } - client_input_basic = &(client_input->client_input_basic); - client_input_basic->req_url = (char *)calloc(strlen(url)+1, sizeof(char)); - if(DA_NULL == client_input_basic->req_url) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - strncpy(client_input_basic->req_url ,url,strlen(url)); - - if (request_header_count > 0) { - int i = 0; - client_input_basic->user_request_header = - (char **)calloc(1, sizeof(char *)*request_header_count); - if(DA_NULL == client_input_basic->user_request_header) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - for (i = 0; i < request_header_count; i++) - { - client_input_basic->user_request_header[i] = strdup(request_header[i]); - } - client_input_basic->user_request_header_count = request_header_count; - } - } - - thread_info = (download_thread_input *)calloc(1, sizeof(download_thread_input)); - if (!thread_info) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } else { - thread_info->slot_id = slot_id; - thread_info->client_input = client_input; - } - if (pthread_attr_init(&thread_attr) != 0) { - ret = DA_ERR_FAIL_TO_CREATE_THREAD; - goto ERR; - } - - if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) { - ret = DA_ERR_FAIL_TO_CREATE_THREAD; - goto ERR; - } - - if (pthread_create(&GET_DL_THREAD_ID(slot_id), &thread_attr, - __thread_start_download, thread_info) < 0) { - DA_LOG_ERR(Thread, "making thread failed.."); - ret = DA_ERR_FAIL_TO_CREATE_THREAD; - } else { - if (GET_DL_THREAD_ID(slot_id) < 1) { - DA_LOG_ERR(Thread, "The thread start is failed before calling this"); -// When http resource is leaked, the thread ID is initialized at error handling section of thread_start_download() -// Because the thread ID is initialized, the ptrhead_detach should not be called. This is something like timing issue between threads. -// thread info and basic_dl_input is freed at thread_start_download(). And it should not returns error code in this case. - goto ERR; - } - } - DA_LOG_DEBUG(Thread, "download thread create slot_id[%d] thread id[%lu]", - slot_id,GET_DL_THREAD_ID(slot_id)); - -ERR: - if (DA_RESULT_OK != ret) { - if (client_input) { - clean_up_client_input_info(client_input); - free(client_input); - client_input = DA_NULL; - } - if (thread_info) { - free(thread_info); - thread_info = DA_NULL; - } - destroy_download_info(slot_id); - } - return ret; -} - -da_result_t __make_source_info_basic_download( - stage_info *stage, - client_input_t *client_input) -{ - da_result_t ret = DA_RESULT_OK; - client_input_basic_t *client_input_basic = DA_NULL; - source_info_t *source_info = DA_NULL; - source_info_basic_t *source_info_basic = DA_NULL; - - DA_LOG_FUNC_LOGV(Default); - - if (!stage) { - DA_LOG_ERR(Default, "no stage; DA_ERR_INVALID_ARGUMENT"); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - client_input_basic = &(client_input->client_input_basic); - if (DA_NULL == client_input_basic->req_url) { - DA_LOG_ERR(Default, "DA_ERR_INVALID_URL"); - ret = DA_ERR_INVALID_URL; - goto ERR; - } - - source_info_basic = (source_info_basic_t*)calloc(1, sizeof(source_info_basic_t)); - if (DA_NULL == source_info_basic) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - - source_info_basic->url = client_input_basic->req_url; - client_input_basic->req_url = DA_NULL; - - if (client_input_basic->user_request_header) { - source_info_basic->user_request_header = - client_input_basic->user_request_header; - source_info_basic->user_request_header_count = - client_input_basic->user_request_header_count; - client_input_basic->user_request_header = DA_NULL; - client_input_basic->user_request_header_count = 0; - } - - source_info = GET_STAGE_SOURCE_INFO(stage); - memset(source_info, 0, sizeof(source_info_t)); - - source_info->source_info_type.source_info_basic = source_info_basic; - -// DA_SECURE_LOGI("BASIC HTTP STARTED: URL=%s", -// source_info->source_info_type.source_info_basic->url); -ERR: - return ret; -} - -void __thread_clean_up_handler_for_start_download(void *arg) -{ - DA_LOG_CRITICAL(Default, "cleanup for thread id = %d", pthread_self()); -} - -static void *__thread_start_download(void *data) -{ - da_result_t ret = DA_RESULT_OK; - download_thread_input *thread_info = DA_NULL; - client_input_t *client_input = DA_NULL; - stage_info *stage = DA_NULL; - download_state_t download_state = 0; - - int slot_id = DA_INVALID_ID; - - DA_LOG_FUNC_LOGV(Thread); - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL); - - thread_info = (download_thread_input*)data; - if (DA_NULL == thread_info) { - DA_LOG_ERR(Thread, "thread_info is NULL.."); - ret = DA_ERR_INVALID_ARGUMENT; - return DA_NULL; - } else { - slot_id = thread_info->slot_id; - client_input = thread_info->client_input; - - if(thread_info) { - free(thread_info); - thread_info = DA_NULL; - } - } - - pthread_cleanup_push(__thread_clean_up_handler_for_start_download, (void *)NULL); - - if (DA_FALSE == is_valid_slot_id(slot_id)) { - ret = DA_ERR_INVALID_ARGUMENT; - DA_LOG_ERR(Default, "Invalid Download ID"); - goto ERR; - } - - if (!client_input) { - ret = DA_ERR_INVALID_ARGUMENT; - DA_LOG_ERR(Default, "Invalid client_input"); - goto ERR; - } - - stage = Add_new_download_stage(slot_id); - if (!stage) { - ret = DA_ERR_FAIL_TO_MEMALLOC; - DA_LOG_ERR(Default, "STAGE ADDITION FAIL!"); - goto ERR; - } - DA_LOG_VERBOSE(Default, "new added Stage : %p", stage); - - GET_DL_USER_DATA(slot_id) = client_input->user_data; - client_input->user_data = DA_NULL; - GET_DL_USER_INSTALL_PATH(slot_id) = client_input->install_path; - client_input->install_path = DA_NULL; - GET_DL_USER_FILE_NAME(slot_id) = client_input->file_name; - client_input->file_name = DA_NULL; - GET_DL_USER_ETAG(slot_id) = client_input->etag; - client_input->etag = DA_NULL; - GET_DL_USER_TEMP_FILE_PATH(slot_id) = client_input->temp_file_path; - client_input->temp_file_path = DA_NULL; - - ret = __make_source_info_basic_download(stage, client_input); - - if (ret == DA_RESULT_OK) { - /* to save memory */ - if (client_input) { - clean_up_client_input_info(client_input); - free(client_input); - client_input = DA_NULL; - } - - ret = __download_content(stage); - if (stage != GET_DL_CURRENT_STAGE(slot_id)) { - DA_LOG_ERR(Default,"Playready download case. The next stage is present stage"); - stage = GET_DL_CURRENT_STAGE(slot_id); - } - } -ERR: - if (client_input) { - clean_up_client_input_info(client_input); - free(client_input); - client_input = DA_NULL; - } - - if (DA_RESULT_OK == ret) { - char *installed_path = NULL; - char *etag = DA_NULL; - req_dl_info *request_info = NULL; - file_info *file_storage = NULL; - DA_LOG_VERBOSE(Default, "Whole download flow is finished."); - _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(stage)]); - download_state = GET_DL_STATE_ON_STAGE(stage); - _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(stage)]); - if (download_state == DOWNLOAD_STATE_ABORTED) { - DA_LOG(Default, "Abort case. Do not call client callback"); -#ifdef PAUSE_EXIT - } else if (download_state == DOWNLOAD_STATE_PAUSED) { - DA_LOG(Default, "Finish case from paused state"); - destroy_download_info(slot_id); -#endif - } else { - request_info = GET_STAGE_TRANSACTION_INFO(stage); - etag = GET_REQUEST_HTTP_HDR_ETAG(request_info); - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - installed_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage); - send_user_noti_and_finish_download_flow(slot_id, installed_path, - etag); - } - } else { - char *etag = DA_NULL; - req_dl_info *request_info = NULL; - request_info = GET_STAGE_TRANSACTION_INFO(stage); - DA_LOG_CRITICAL(Default, "Download Failed -Return = %d", ret); - if (request_info) { - etag = GET_REQUEST_HTTP_HDR_ETAG(request_info); - send_client_finished_info(slot_id, GET_DL_ID(slot_id), - DA_NULL, etag, ret, get_http_status(slot_id)); - } - destroy_download_info(slot_id); - } - - pthread_cleanup_pop(0); - DA_LOG_CRITICAL(Thread, "==thread_start_download - EXIT=="); - pthread_exit((void *)NULL); - return DA_NULL; -} - -da_result_t __download_content(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - download_state_t download_state = 0; - da_bool_t isDownloadComplete = DA_FALSE; - int slot_id = DA_INVALID_ID; - - DA_LOG_FUNC_LOGV(Default); - - slot_id = GET_STAGE_DL_ID(stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD, stage); - - do { - stage = GET_DL_CURRENT_STAGE(slot_id); - _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(stage)]); - download_state = GET_DL_STATE_ON_STAGE(stage); - DA_LOG_VERBOSE(Default, "download_state to - [%d] ", download_state); - _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(stage)]); - - switch(download_state) { - case DOWNLOAD_STATE_NEW_DOWNLOAD: - ret = requesting_download(stage); - - _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(stage)]); - download_state = GET_DL_STATE_ON_STAGE(stage); - _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(stage)]); - if (download_state == DOWNLOAD_STATE_CANCELED || - download_state == DOWNLOAD_STATE_ABORTED || - download_state == DOWNLOAD_STATE_PAUSED) { - break; - } else { - if (DA_RESULT_OK == ret) { - ret = handle_after_download(stage); - } - } - break; - default: - isDownloadComplete = DA_TRUE; - break; - } - }while ((DA_RESULT_OK == ret) && (DA_FALSE == isDownloadComplete)); - - return ret; -} diff --git a/agent/download-agent-client-mgr.c b/agent/download-agent-client-mgr.c index b27a2d4..82dd516 100755 --- a/agent/download-agent-client-mgr.c +++ b/agent/download-agent-client-mgr.c @@ -14,618 +14,132 @@ * limitations under the License. */ -#include +#include #include "download-agent-client-mgr.h" -#include "download-agent-debug.h" -#include "download-agent-utils.h" -#include "download-agent-file.h" -#define IS_CLIENT_Q_HAVING_DATA(QUEUE) (QUEUE->having_data) - -static client_app_mgr_t client_app_mgr; - -static da_result_t __launch_client_thread(void); -static void *__thread_for_client_noti(void *data); -void __thread_clean_up_handler_for_client_thread(void *arg); -static void __pop_client_noti(client_noti_t **out_client_noti); - -void __client_q_goto_sleep_without_lock(void); -void __client_q_wake_up_without_lock(void); -void destroy_client_noti(client_noti_t *client_noti); - -da_result_t init_client_app_mgr() -{ - DA_LOG_FUNC_LOGV(ClientNoti); - - if(client_app_mgr.is_init) - return DA_RESULT_OK; - - client_app_mgr.is_init = DA_TRUE; - client_app_mgr.client_app_info.client_user_agent = DA_NULL; - client_app_mgr.is_thread_init = DA_FALSE; - client_app_mgr.thread_id = 0; - - return DA_RESULT_OK; -} - -da_bool_t is_client_app_mgr_init(void) -{ - return client_app_mgr.is_init; -} - -da_result_t reg_client_app( - da_client_cb_t *da_client_callback) -{ - da_result_t ret = DA_RESULT_OK; - client_queue_t *queue = DA_NULL; - client_noti_t *client_noti = DA_NULL; - - DA_LOG_FUNC_LOGD(ClientNoti); - - memset(&(client_app_mgr.client_app_info.client_callback), - 0, sizeof(da_client_cb_t)); - memcpy(&(client_app_mgr.client_app_info.client_callback), - da_client_callback, sizeof(da_client_cb_t)); - - _da_thread_mutex_init(&(client_app_mgr.mutex_client_mgr), DA_NULL); - - /* If some noti is existed at queue, delete all */ - do { - __pop_client_noti(&client_noti); - destroy_client_noti(client_noti); - } while(client_noti != DA_NULL); - - queue = &(client_app_mgr.client_queue); - DA_LOG_VERBOSE(ClientNoti, "client queue = %p", queue); - _da_thread_mutex_init(&(queue->mutex_client_queue), DA_NULL); - _da_thread_cond_init(&(queue->cond_client_queue), DA_NULL); - - ret = __launch_client_thread(); - - return ret; -} - -da_result_t dereg_client_app(void) +da_ret_t send_client_paused_info(da_info_t *da_info) { - client_noti_t *client_noti = DA_NULL; - - DA_LOG_FUNC_LOGV(ClientNoti); - - client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t)); - if (!client_noti) { - DA_LOG_ERR(ClientNoti, "calloc fail"); - return DA_ERR_FAIL_TO_MEMALLOC; - } - - client_noti->slot_id = DA_INVALID_ID; - client_noti->noti_type = Q_CLIENT_NOTI_TYPE_TERMINATE; - client_noti->next = DA_NULL; + req_info_t *req_info = DA_NULL; + NULL_CHECK_RET(da_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); - _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr)); - if (client_app_mgr.is_thread_init != DA_TRUE) { - DA_LOG_CRITICAL(ClientNoti, "try to cancel client mgr thread id[%lu]", - client_app_mgr.thread_id); - if (client_app_mgr.thread_id && - pthread_cancel(client_app_mgr.thread_id) < 0) { - DA_LOG_ERR(ClientNoti, "cancel thread is failed!!!"); - } - free(client_noti); + if (da_info->is_cb_update && da_info->cb_info.paused_cb) { + da_info->cb_info.paused_cb(da_info->da_id, + req_info->user_req_data, req_info->user_client_data); + DA_LOGV("id[%d]", da_info->da_id); } else { - void *t_return = NULL; - DA_LOG_VERBOSE(ClientNoti, "pushing Q_CLIENT_NOTI_TYPE_TERMINATE"); - push_client_noti(client_noti); - DA_LOG_DEBUG(Thread, "===try to join client mgr thread id[%lu]===", - client_app_mgr.thread_id); - if (client_app_mgr.thread_id && - pthread_join(client_app_mgr.thread_id, &t_return) < 0) { - DA_LOG_ERR(Thread, "join client thread is failed!!!"); - } - DA_LOG_DEBUG(Thread, "===thread join return[%d]===", (char*)t_return); + DA_LOGV("No CB:id[%d]", da_info->da_id); } - _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr)); - /* ToDo: This clean up should be done at the end of client_thread. */ - if(client_app_mgr.client_app_info.client_user_agent) { - free(client_app_mgr.client_app_info.client_user_agent); - client_app_mgr.client_app_info.client_user_agent = DA_NULL; - } - _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr)); - client_app_mgr.is_thread_init = DA_FALSE; - _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr)); - _da_thread_mutex_destroy(&(client_app_mgr.mutex_client_mgr)); return DA_RESULT_OK; } -da_result_t send_client_paused_info(int slot_id) +da_ret_t send_client_update_dl_info(da_info_t *da_info) { - client_noti_t *client_noti = DA_NULL; - user_paused_info_t *paused_info = DA_NULL; - download_state_t state = GET_DL_STATE_ON_ID(slot_id); - - DA_LOG_FUNC_LOGD(ClientNoti); - - if (!GET_DL_ENABLE_PAUSE_UPDATE(slot_id)) { - DA_LOG(ClientNoti, "Do not call pause cb"); - return DA_RESULT_OK; - } - if (!is_valid_slot_id(slot_id)) { - DA_LOG_ERR(ClientNoti, "Download ID is not valid"); - return DA_RESULT_OK; - } + download_info_t *info = DA_NULL; + file_info_t *file_info = DA_NULL; + http_info_t *http_info = DA_NULL; + req_info_t *req_info = DA_NULL; + NULL_CHECK_RET(da_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); - DA_LOG_VERBOSE(ClientNoti, "slot_id[%d]", slot_id); - if ((DOWNLOAD_STATE_PAUSED != state)) { - DA_LOG(ClientNoti, "The state is not paused. state:%d", state); - return DA_ERR_INVALID_STATE; - } - - client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t)); - if (!client_noti) { - DA_LOG_ERR(ClientNoti, "calloc fail"); - return DA_ERR_FAIL_TO_MEMALLOC; - } - - client_noti->slot_id = slot_id; - client_noti->user_data = GET_DL_USER_DATA(slot_id); - client_noti->noti_type = Q_CLIENT_NOTI_TYPE_PAUSED_INFO; - client_noti->next = DA_NULL; - - paused_info = (user_paused_info_t *)&(client_noti->type.paused_info); - paused_info->download_id= GET_DL_ID(slot_id); - DA_LOG(ClientNoti, "pushing paused info. slot_id=%d, dl_id=%d", - slot_id, GET_DL_ID(slot_id)); - - push_client_noti(client_noti); - - return DA_RESULT_OK; -} - -da_result_t send_client_update_progress_info ( - int slot_id, - int dl_id, - unsigned long int received_size - ) -{ - client_noti_t *client_noti = DA_NULL; - user_progress_info_t *progress_info = DA_NULL; - - DA_LOG_FUNC_LOGV(ClientNoti); - - if (!is_valid_slot_id(slot_id)) { - DA_LOG_ERR(ClientNoti, "Download ID is not valid"); - return DA_ERR_INVALID_DL_REQ_ID; - } - - client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t)); - if (!client_noti) { - DA_LOG_ERR(ClientNoti, "calloc fail"); - return DA_ERR_FAIL_TO_MEMALLOC; - } - - client_noti->slot_id = slot_id; - client_noti->user_data = GET_DL_USER_DATA(slot_id); - client_noti->noti_type = Q_CLIENT_NOTI_TYPE_PROGRESS_INFO; - client_noti->next = DA_NULL; - - progress_info = (user_progress_info_t *)&(client_noti->type.update_progress_info); - progress_info->download_id= dl_id; - progress_info->received_size = received_size; - - DA_LOG_VERBOSE(ClientNoti, "pushing received_size=%lu, slot_id=%d, dl_id=%d", - received_size, slot_id, dl_id); - - push_client_noti(client_noti); - - return DA_RESULT_OK; -} - -da_result_t send_client_update_dl_info ( - int slot_id, - int dl_id, - char *file_type, - unsigned long int file_size, - char *tmp_saved_path, - char *pure_file_name, - char *etag, - char *extension) -{ - client_noti_t *client_noti = DA_NULL; - user_download_info_t *update_dl_info = DA_NULL; - int len = 0; - - DA_LOG_FUNC_LOGV(ClientNoti); - - if (!is_valid_slot_id(slot_id)) { - DA_LOG_ERR(ClientNoti, "Download ID is not valid"); - return DA_ERR_INVALID_DL_REQ_ID; - } - - client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t)); - if (!client_noti) { - DA_LOG_ERR(ClientNoti, "calloc fail"); - return DA_ERR_FAIL_TO_MEMALLOC; - } - - client_noti->slot_id = slot_id; - client_noti->user_data = GET_DL_USER_DATA(slot_id); - client_noti->noti_type = Q_CLIENT_NOTI_TYPE_STARTED_INFO; - client_noti->next = DA_NULL; - - update_dl_info = (user_download_info_t *)&(client_noti->type.update_dl_info); - update_dl_info->download_id = dl_id; - update_dl_info->file_size = file_size; - if (pure_file_name && extension) { - len = strlen(pure_file_name) + strlen(extension) + 1; - update_dl_info->content_name = (char *)calloc(len + 1, sizeof(char)); - if (!update_dl_info->content_name) { - free(client_noti); + if (da_info->is_cb_update && da_info->cb_info.download_info_cb) { + info = (download_info_t *)calloc(1, sizeof(download_info_t)); + if (!info) return DA_ERR_FAIL_TO_MEMALLOC; + info->download_id = da_info->da_id; + info->file_size = http_info->content_len_from_header; + if (http_info->content_type_from_header) + info->file_type = strdup(http_info->content_type_from_header); + if (file_info->file_path) + info->tmp_saved_path = strdup(file_info->file_path); + if (file_info->pure_file_name) + info->content_name = strdup(file_info->pure_file_name); + if (http_info->etag_from_header) { + info->etag = strdup(http_info->etag_from_header); + //DA_SECURE_LOGI("etag[%s]", info->etag); } - snprintf(update_dl_info->content_name, len + 1, "%s.%s", - pure_file_name, extension); - } - - /* These strings MUST be copied to detach __thread_for_client_noti from download_info */ - if (file_type) - update_dl_info->file_type = strdup(file_type); - - if (tmp_saved_path) - update_dl_info->tmp_saved_path = strdup(tmp_saved_path); - - if (etag) - update_dl_info->etag = strdup(etag); - DA_LOG_DEBUG(ClientNoti, "pushing slot_id=%d, dl_id=%d", slot_id, dl_id); - - push_client_noti(client_noti); - - return DA_RESULT_OK; -} - -da_result_t send_client_finished_info ( - int slot_id, - int dl_id, - char *saved_path, - char *etag, - int error, - int http_status - ) -{ - client_noti_t *client_noti = DA_NULL; - user_finished_info_t *finished_info = DA_NULL; - - DA_LOG_FUNC_LOGV(ClientNoti); - - if (!is_valid_slot_id(slot_id)) { - DA_LOG_ERR(ClientNoti, "Download ID is not valid"); - return DA_ERR_INVALID_DL_REQ_ID; - } - - client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t)); - if (!client_noti) { - DA_LOG_ERR(ClientNoti, "calloc fail"); - return DA_ERR_FAIL_TO_MEMALLOC; - } - - client_noti->slot_id = slot_id; - client_noti->user_data = GET_DL_USER_DATA(slot_id); - client_noti->noti_type = Q_CLIENT_NOTI_TYPE_FINISHED_INFO; - client_noti->next = DA_NULL; - - finished_info = (user_finished_info_t *)&(client_noti->type.finished_info); - finished_info->download_id = dl_id; - finished_info->err = error; - finished_info->http_status = http_status; - - if (saved_path) { - finished_info->saved_path = strdup(saved_path); - DA_SECURE_LOGD("saved path=%s", saved_path); - } - if (etag) { - finished_info->etag = strdup(etag); - DA_SECURE_LOGD("pushing finished info. etag[%s]", etag); - } - DA_LOG_VERBOSE(ClientNoti, "user_data=%p", client_noti->user_data); - DA_LOG_VERBOSE(ClientNoti, "http_status=%d", http_status); - DA_LOG(ClientNoti, "pushing slot_id=%d, dl_id=%d err=%d", slot_id, dl_id, error); - - push_client_noti(client_noti); - - return DA_RESULT_OK; -} - -da_result_t __launch_client_thread(void) -{ - pthread_t thread_id = 0; - - DA_LOG_FUNC_LOGV(Thread); - - if (pthread_create(&thread_id, DA_NULL, - __thread_for_client_noti,DA_NULL) < 0) { - DA_LOG_ERR(Thread, "making thread failed.."); - return DA_ERR_FAIL_TO_CREATE_THREAD; + da_info->cb_info.download_info_cb(info, + req_info->user_req_data, req_info->user_client_data); + DA_LOGD("id[%d]", info->download_id); + //DA_LOGI("id[%d]total_size[%lu]", info->download_id, info->file_size); + //if (http_info->content_type_from_header) + //DA_SECURE_LOGI("mime_type[%s]", http_info->content_type_from_header); + } else { + DA_LOGI("No CB:id[%d]", da_info->da_id); } - DA_LOG_VERBOSE(Thread, "client mgr thread id[%d]", thread_id); - client_app_mgr.thread_id = thread_id; return DA_RESULT_OK; } -void destroy_client_noti(client_noti_t *client_noti) -{ - if (client_noti) { - if (client_noti->noti_type == Q_CLIENT_NOTI_TYPE_STARTED_INFO) { - user_download_info_t *update_dl_info = DA_NULL; - update_dl_info = (user_download_info_t*)&(client_noti->type.update_dl_info); - if (update_dl_info->file_type) { - free(update_dl_info->file_type); - update_dl_info->file_type = DA_NULL; - } - if (update_dl_info->tmp_saved_path) { - free(update_dl_info->tmp_saved_path); - update_dl_info->tmp_saved_path = DA_NULL; - } - if (update_dl_info->etag) { - free(update_dl_info->etag); - update_dl_info->etag = DA_NULL; - } - } else if (client_noti->noti_type == - Q_CLIENT_NOTI_TYPE_FINISHED_INFO) { - user_finished_info_t *finished_info = DA_NULL; - finished_info = (user_finished_info_t*) - &(client_noti->type.finished_info); - if (finished_info->saved_path) { - free(finished_info->saved_path); - finished_info->saved_path = DA_NULL; - } - if (finished_info->etag) { - free(finished_info->etag); - finished_info->etag = DA_NULL; - } - } - free(client_noti); - } -} - - -void push_client_noti(client_noti_t *client_noti) +da_ret_t send_client_update_progress_info(da_info_t *da_info) { - client_queue_t *queue = DA_NULL; - client_noti_t *head = DA_NULL; - client_noti_t *pre = DA_NULL; - client_noti_t *cur = DA_NULL; - - queue = &(client_app_mgr.client_queue); - _da_thread_mutex_lock (&(queue->mutex_client_queue)); + file_info_t *file_info = DA_NULL; + req_info_t *req_info = DA_NULL; + NULL_CHECK_RET(da_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); - head = queue->client_q_head; - if (!head) { - queue->client_q_head = client_noti; - } else { - cur = head; - while (cur->next) { - pre = cur; - cur = pre->next; - } -#if 0 - if (cur->noti_type == Q_CLIENT_NOTI_TYPE_PROGRESS_INFO) { - /* For UI performance. If the update noti info is existed at queue, - replace it with new update noti info */ - if (cur->slot_id == client_noti->slot_id) { - /* DA_LOG(ClientNoti, "exchange queue's tail and pushing item"); */ - if (pre == DA_NULL) - queue->client_q_head = client_noti; - else - pre->next = client_noti; - destroy_client_noti(cur); - } else { - cur->next = client_noti; - } - } else { - cur->next = client_noti; - } -#else - cur->next = client_noti; -#endif - } - - queue->having_data = DA_TRUE; + if (!file_info->is_updated) + return DA_RESULT_OK; - __client_q_wake_up_without_lock(); - if (queue->client_q_head->next) { - DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti[%p]", - queue->client_q_head, queue->client_q_head->next); + if (da_info->is_cb_update && da_info->cb_info.progress_cb) { + da_info->cb_info.progress_cb(da_info->da_id, + file_info->bytes_written_to_file, + req_info->user_req_data, req_info->user_client_data); + DA_LOGV("id[%d],size[%llu]", da_info->da_id, + file_info->bytes_written_to_file); } else { - DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti is NULL", - queue->client_q_head); + DA_LOGI("No CB:id[%d]", da_info->da_id); } - - _da_thread_mutex_unlock (&(queue->mutex_client_queue)); + file_info->is_updated = DA_FALSE; + return DA_RESULT_OK; } -void __pop_client_noti(client_noti_t **out_client_noti) +da_ret_t send_client_finished_info(da_info_t *da_info, int err) { - client_queue_t *queue = DA_NULL; - - queue = &(client_app_mgr.client_queue); + finished_info_t *info = DA_NULL; + file_info_t *file_info = DA_NULL; + http_info_t *http_info = DA_NULL; + req_info_t *req_info = DA_NULL; + NULL_CHECK_RET(da_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); - _da_thread_mutex_lock (&(queue->mutex_client_queue)); - - if (queue->client_q_head) { - *out_client_noti = queue->client_q_head; - queue->client_q_head = queue->client_q_head->next; - if (queue->client_q_head) { - DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti[%p]", - *out_client_noti, queue->client_q_head); - } else { - DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti is NULL", - *out_client_noti); - } + if (da_info->is_cb_update && da_info->cb_info.finished_cb) { + info = (finished_info_t *)calloc(1, sizeof(finished_info_t)); + if (!info) + return DA_ERR_FAIL_TO_MEMALLOC; + info->download_id = da_info->da_id; + if (http_info->http_msg_response) + info->http_status = http_info->http_msg_response->status_code; + else + DA_LOGE("http_msg_response is NULL"); + if (file_info->file_path) + info->saved_path = strdup(file_info->file_path); + if (http_info->etag_from_header) + info->etag = strdup(http_info->etag_from_header); + info->err = err; + da_info->cb_info.finished_cb(info, + req_info->user_req_data, req_info->user_client_data); + DA_LOGD("id[%d]", info->download_id); + //DA_LOGI("id[%d],err[%d], http_status[%d]", info->download_id, + //info->err, info->http_status); } else { - *out_client_noti = DA_NULL; - } - - if (queue->client_q_head == DA_NULL) { - queue->having_data = DA_FALSE; + DA_LOGI("No CB:id[%d]", da_info->da_id); } - - _da_thread_mutex_unlock (&(queue->mutex_client_queue)); -} - -void __client_q_goto_sleep_without_lock(void) -{ - client_queue_t *queue = DA_NULL; - queue = &(client_app_mgr.client_queue); - _da_thread_cond_wait(&(queue->cond_client_queue), &(queue->mutex_client_queue)); -} - -void __client_q_wake_up_without_lock(void) -{ - client_queue_t *queue = DA_NULL; - queue = &(client_app_mgr.client_queue); - _da_thread_cond_signal(&(queue->cond_client_queue)); -} - -void __thread_clean_up_handler_for_client_thread(void *arg) -{ - DA_LOG_CRITICAL(Thread, "cleanup for thread id = %d", pthread_self()); -} - -static void *__thread_for_client_noti(void *data) -{ - da_result_t ret = DA_RESULT_OK; - da_bool_t need_wait = DA_TRUE; - client_queue_t *queue = DA_NULL; - client_noti_t *client_noti = DA_NULL; - - DA_LOG_FUNC_LOGV(Thread); - - _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr)); - client_app_mgr.is_thread_init = DA_TRUE; - _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr)); - - queue = &(client_app_mgr.client_queue); - DA_LOG_VERBOSE(ClientNoti, "client queue = %p", queue); - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL); - pthread_cleanup_push(__thread_clean_up_handler_for_client_thread, (void *)DA_NULL); - - do { - _da_thread_mutex_lock(&(queue->mutex_client_queue)); - if (DA_FALSE == IS_CLIENT_Q_HAVING_DATA(queue)) { - DA_LOG_VERBOSE(Thread, "Sleep @ thread_for_client_noti!"); - __client_q_goto_sleep_without_lock(); - DA_LOG_VERBOSE(Thread, "Woke up @ thread_for_client_noti"); - } - _da_thread_mutex_unlock(&(queue->mutex_client_queue)); - - do { - __pop_client_noti(&client_noti); - if (client_noti == DA_NULL) { - DA_LOG_ERR(ClientNoti, "There is no data on client queue!"); - ret = DA_ERR_INVALID_STATE; - need_wait = DA_FALSE; - } else { - DA_LOG_VERBOSE(ClientNoti, "noti type[%d]", - client_noti->noti_type); - switch (client_noti->noti_type) { - case Q_CLIENT_NOTI_TYPE_STARTED_INFO: - { - user_download_info_t *update_dl_info = DA_NULL;; - update_dl_info = (user_download_info_t*)(&(client_noti->type.update_dl_info)); - if (client_app_mgr.client_app_info.client_callback.update_dl_info_cb) { - client_app_mgr.client_app_info.client_callback.update_dl_info_cb(update_dl_info, client_noti->user_data); - if (update_dl_info->etag) - DA_SECURE_LOGD("Etag:[%s]", update_dl_info->etag); - DA_SECURE_LOGD("file size=%lu", update_dl_info->file_size); - DA_LOG(ClientNoti, "Update download info for slot_id=%d, dl_id=%d- DONE", - client_noti->slot_id, - update_dl_info->download_id - ); - } - } - break; - case Q_CLIENT_NOTI_TYPE_PROGRESS_INFO: - { - user_progress_info_t *progress_info = DA_NULL;; - progress_info = (user_progress_info_t*)(&(client_noti->type.update_progress_info)); - if (client_app_mgr.client_app_info.client_callback.update_progress_info_cb) { - client_app_mgr.client_app_info.client_callback.update_progress_info_cb(progress_info, client_noti->user_data); - DA_LOG_VERBOSE(ClientNoti, "Update downloading info for slot_id=%d, dl_id=%d, received size=%lu - DONE", - client_noti->slot_id, - progress_info->download_id, - progress_info->received_size); - } - } - break; - case Q_CLIENT_NOTI_TYPE_FINISHED_INFO: - { - user_finished_info_t *finished_info = DA_NULL;; - finished_info = (user_finished_info_t*)(&(client_noti->type.finished_info)); - if (client_app_mgr.client_app_info.client_callback.finished_info_cb) { - client_app_mgr.client_app_info.client_callback.finished_info_cb( - finished_info, client_noti->user_data); - DA_LOG(ClientNoti, "Completed info for slot_id=%d, dl_id=%d, err=%d http_state=%d user_data=%p- DONE", - client_noti->slot_id, - finished_info->download_id, - finished_info->err, - finished_info->http_status, - client_noti->user_data); - if (finished_info->etag) - DA_SECURE_LOGD("Completed info for etag=%s - DONE", - finished_info->etag); - - } - } - break; - case Q_CLIENT_NOTI_TYPE_PAUSED_INFO: - { - user_paused_info_t *da_paused_info = DA_NULL; - da_paused_info = (user_paused_info_t *)(&(client_noti->type.paused_info)); - - if (client_app_mgr.client_app_info.client_callback.paused_info_cb) { - DA_LOG(ClientNoti, "User Paused info for slot_id=%d, dl_id=%d - Done", - client_noti->slot_id, - da_paused_info->download_id); - client_app_mgr.client_app_info.client_callback.paused_info_cb( - da_paused_info, client_noti->user_data); - } - } - break; - case Q_CLIENT_NOTI_TYPE_TERMINATE: - DA_LOG_VERBOSE(ClientNoti, "Q_CLIENT_NOTI_TYPE_TERMINATE"); - need_wait = DA_FALSE; - break; - } - destroy_client_noti(client_noti); - } - - if(DA_TRUE == need_wait) { - _da_thread_mutex_lock(&(queue->mutex_client_queue)); - if (DA_FALSE == IS_CLIENT_Q_HAVING_DATA(queue)) { - _da_thread_mutex_unlock (&(queue->mutex_client_queue)); - break; - } else { - _da_thread_mutex_unlock (&(queue->mutex_client_queue)); - } - } else { - break; - } - } while (1); - } while (DA_TRUE == need_wait); - - _da_thread_mutex_destroy(&(queue->mutex_client_queue)); - _da_thread_cond_destroy(&(queue->cond_client_queue)); - - pthread_cleanup_pop(0); - DA_LOG_DEBUG(Thread, "=====thread_for_client_noti- EXIT====="); - pthread_exit((void *)NULL); - return DA_NULL; + return DA_RESULT_OK; } -char *get_client_user_agent_string(void) -{ - if (!client_app_mgr.is_init) - return DA_NULL; - - return client_app_mgr.client_app_info.client_user_agent; -} diff --git a/agent/download-agent-debug.c b/agent/download-agent-debug.c deleted file mode 100755 index 07078b3..0000000 --- a/agent/download-agent-debug.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "download-agent-debug.h" -#include "download-agent-utils.h" - -#define STRING_IT(x) #x -#define TURN_ON_LOG(channel) (DALogBitMap |= (0x1<<(channel))) - -int DALogBitMap; - -char *__get_log_env(void); -char **__parsing_log_env(char *in_log_env); -char *__copying_str(char *source, int length); -char *__get_channel_name_from_enum(da_log_channel channel_enum); - -da_result_t init_log_mgr(void) { - da_result_t ret = DA_RESULT_OK; - static da_bool_t did_log_mgr_init = DA_FALSE; - char *log_env = DA_NULL; - char **parsed_log_env = DA_NULL; - char **cur_parsed_log_env = DA_NULL; - int i = 0; - - if (did_log_mgr_init) - return ret; - - did_log_mgr_init = DA_TRUE; - - log_env = __get_log_env(); - if (!log_env) { - /* If no environment values are found, do behave like all logs are turned on except for Soup log */ - DALogBitMap = ~(0x1 << Soup); - return ret; - } - - TURN_ON_LOG(Default); - - parsed_log_env = __parsing_log_env(log_env); - if (parsed_log_env) { - char *channel_keyward = DA_NULL; - for (cur_parsed_log_env = parsed_log_env; *cur_parsed_log_env; cur_parsed_log_env++) { - if (!*cur_parsed_log_env) - break; - for (i = 0; i < DA_LOG_CHANNEL_MAX; i++) { - channel_keyward = __get_channel_name_from_enum(i); - if (channel_keyward && !strcmp(*cur_parsed_log_env, - channel_keyward)) { - TURN_ON_LOG(i); - break; - } - } - free(*cur_parsed_log_env); - } - free(parsed_log_env); - } - - if (log_env) - free(log_env); - - return ret; -} - -char *__get_log_env(void) { - char *log_env = DA_NULL; - - /* environment value has higher priority than configure file */ - log_env = getenv(DA_DEBUG_ENV_KEY); - if (log_env && strlen(log_env)) - return strdup(log_env); - - if (read_data_from_file(DA_DEBUG_CONFIG_FILE_PATH, &log_env)) - return log_env; - - return DA_NULL; -} - -char **__parsing_log_env(char *in_log_env) { - char **out_parsed_result = DA_NULL; - - char **temp_result_array = DA_NULL; - char **cur_temp_result_array = DA_NULL; - int how_many_item = 0; - int how_many_delimeter = 0; - - char delimiter = ','; - - char *org_str = in_log_env; - char *cur_char = org_str; - char *start = org_str; - char *end = org_str; - int target_len = 0; - - if (!org_str) - return DA_NULL; - - /* counting delimiter to know how many items should be memory allocated. - * This causes two round of loop (counting delimiter and real operation). - * But I think it is tolerable, because input parameter is from console. - * And it is also a reason why we should not use fixed length array. - * Users are hard to input very long environment, but it is possible. */ - for (cur_char = org_str; *cur_char; cur_char++) { - if (*cur_char == delimiter) - how_many_delimeter++; - } - how_many_item = how_many_delimeter + 1; - temp_result_array = (char**) calloc(1, how_many_item + 1); - if (!(temp_result_array)) - goto ERR; - - cur_temp_result_array = temp_result_array; - cur_char = org_str; - while (1) { - if (*cur_char == delimiter) { - end = cur_char; - target_len = (int) (end - start); - *cur_temp_result_array++ = __copying_str(start, - target_len); - start = ++cur_char; - continue; - } else if (!(*cur_char)) { - end = cur_char; - target_len = (int) (end - start); - *cur_temp_result_array++ = __copying_str(start, - target_len); - *cur_temp_result_array = DA_NULL; - break; - } else { - cur_char++; - } - } - out_parsed_result = temp_result_array; -ERR: - return out_parsed_result; -} - -char *__copying_str(char *source, int length) { - char *copied_str = DA_NULL; - char *cur_pos = DA_NULL; - char white_space = ' '; - char end_of_line = 10; /* ASCII for LF */ - int i = 0; - - if (!source || !(length > 0)) - return DA_NULL; - - copied_str = (char*) calloc(1, length + 1); - if (copied_str) { - cur_pos = copied_str; - for (i = 0; i < length; i++) { - if ((source[i] != white_space) && (source[i] - != end_of_line)) - *cur_pos++ = source[i]; - } - } - - return copied_str; -} - -char *__get_channel_name_from_enum(da_log_channel channel_enum) { - switch (channel_enum) { - case Soup: - return STRING_IT(Soup); - case HTTPManager: - return STRING_IT(HTTPManager); - case FileManager: - return STRING_IT(FileManager); - case DRMManager: - return STRING_IT(DRMManager); - case DownloadManager: - return STRING_IT(DownloadManager); - case ClientNoti: - return STRING_IT(ClientNoti); - case HTTPMessageHandler: - return STRING_IT(HTTPMessageHandler); - case Encoding: - return STRING_IT(Encoding); - case QueueManager: - return STRING_IT(QueueManager); - case Parsing: - return STRING_IT(Parsing); - case Thread: - return STRING_IT(Thread); - case Default: - return STRING_IT(Default); - default: - return DA_NULL; - } -} diff --git a/agent/download-agent-dl-info-util.c b/agent/download-agent-dl-info-util.c deleted file mode 100755 index 2b66357..0000000 --- a/agent/download-agent-dl-info-util.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "download-agent-client-mgr.h" -#include "download-agent-dl-info-util.h" -#include "download-agent-debug.h" -#include "download-agent-utils.h" -#include "download-agent-file.h" -#include "download-agent-http-mgr.h" -#include "download-agent-plugin-conf.h" - -pthread_mutex_t mutex_download_state[DA_MAX_DOWNLOAD_ID]; -static pthread_mutex_t mutex_download_mgr = PTHREAD_MUTEX_INITIALIZER; -download_mgr_t download_mgr; - -void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic); -void cleanup_req_dl_info_http(req_dl_info *http_download); -void destroy_file_info(file_info *file); - -da_result_t init_download_mgr() { - da_result_t ret = DA_RESULT_OK; - int i = 0; - - DA_LOG_FUNC_LOGV(Default); - - _da_thread_mutex_lock(&mutex_download_mgr); - - if (download_mgr.is_init == DA_FALSE) { - download_mgr.is_init = DA_TRUE; - - for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) { - _da_thread_mutex_init(&mutex_download_state[i], DA_NULL); - init_download_info(i); - } - init_dl_id_history(&(download_mgr.dl_id_history)); - } - - _da_thread_mutex_unlock(&mutex_download_mgr); - - return ret; -} - -da_result_t deinit_download_mgr(void) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGV(Default); - - _da_thread_mutex_lock(&mutex_download_mgr); - if (download_mgr.is_init == DA_TRUE) { - int i = 0; - dl_info_t *dl_info = DA_NULL; - void *t_return = NULL; - for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) { - dl_info = &(download_mgr.dl_info[i]); - if (dl_info && dl_info->is_using) { - request_to_abort_http_download(GET_DL_CURRENT_STAGE(i)); - DA_LOG_CRITICAL(Thread, "===download id[%d] thread id[%lu] join===",i, GET_DL_THREAD_ID(i)); -/* Because the download daemon can call the deinit function, the resources of pthread are not freed - FIXME later : It is needed to change the termination flow again. - if (pthread_join(GET_DL_THREAD_ID(i), &t_return) < 0) { - DA_LOG_ERR(Thread, "join client thread is failed!!!"); - } -*/ - DA_LOG_CRITICAL(Thread, "===download id[%d] thread join return[%d]===",i, (char*)t_return); - } - } - download_mgr.is_init = DA_FALSE; - deinit_dl_id_history(&(download_mgr.dl_id_history)); - } - _da_thread_mutex_unlock(&mutex_download_mgr); - return ret; -} - -void init_download_info(int slot_id) -{ - dl_info_t *dl_info = DA_NULL; - - DA_LOG_FUNC_LOGV(Default); - - _da_thread_mutex_lock(&mutex_download_state[slot_id]); - dl_info = &(download_mgr.dl_info[slot_id]); - dl_info->is_using = DA_FALSE; - dl_info->state = DOWNLOAD_STATE_IDLE; - dl_info->download_stage_data = DA_NULL; - dl_info->dl_id = 0; - dl_info->http_status = 0; - dl_info->enable_pause_update = DA_FALSE; - dl_info->user_install_path = DA_NULL; - dl_info->user_file_name = DA_NULL; - dl_info->user_etag = DA_NULL; - dl_info->user_temp_file_path = DA_NULL; - dl_info->user_data = DA_NULL; - - Q_init_queue(&(dl_info->queue)); - - DA_LOG_VERBOSE(Default, "Init slot_id [%d] Info END", slot_id); - _da_thread_mutex_unlock(&mutex_download_state[slot_id]); - - return; -} - -void destroy_download_info(int slot_id) -{ - dl_info_t *dl_info = DA_NULL; - - DA_LOG_VERBOSE(Default, "Destroying slot_id [%d] Info", slot_id); - - if (slot_id == DA_INVALID_ID) { - DA_LOG_ERR(Default, "invalid slot_id"); - return; - } - - dl_info = &(download_mgr.dl_info[slot_id]); - if (DA_FALSE == dl_info->is_using) { - return; - } - - _da_thread_mutex_lock (&mutex_download_state[slot_id]); - dl_info->state = DOWNLOAD_STATE_IDLE; - dl_info->active_dl_thread_id = 0; - - if (dl_info->download_stage_data != DA_NULL) { - remove_download_stage(slot_id, dl_info->download_stage_data); - dl_info->download_stage_data = DA_NULL; - } - dl_info->dl_id = 0; - dl_info->enable_pause_update = DA_FALSE; - if (dl_info->user_install_path) { - free(dl_info->user_install_path); - dl_info->user_install_path = DA_NULL; - } - - if (dl_info->user_file_name) { - free(dl_info->user_file_name); - dl_info->user_file_name = DA_NULL; - } - - if (dl_info->user_etag) { - free(dl_info->user_etag); - dl_info->user_etag = DA_NULL; - } - - if (dl_info->user_temp_file_path) { - free(dl_info->user_temp_file_path); - dl_info->user_temp_file_path = DA_NULL; - } - - dl_info->user_data = DA_NULL; - - Q_destroy_queue(&(dl_info->queue)); - dl_info->http_status = 0; - - dl_info->is_using = DA_FALSE; - - DA_LOG_DEBUG(Default, "Destroying slot_id [%d] Info END", slot_id); - _da_thread_mutex_unlock (&mutex_download_state[slot_id]); - return; -} - -void *Add_new_download_stage(int slot_id) -{ - stage_info *download_stage_data = NULL; - stage_info *new_download_stage_data = NULL; - - DA_LOG_FUNC_LOGV(Default); - - new_download_stage_data = (stage_info*)calloc(1, sizeof(stage_info)); - if (!new_download_stage_data) - goto ERR; - - new_download_stage_data->dl_id = slot_id; - download_stage_data = GET_DL_CURRENT_STAGE(slot_id); - if (download_stage_data) { - while (download_stage_data->next_stage_info) { - download_stage_data - = download_stage_data->next_stage_info; - }; - download_stage_data->next_stage_info = new_download_stage_data; - } else { - GET_DL_CURRENT_STAGE(slot_id) = new_download_stage_data; - } - DA_LOG_VERBOSE(Default, "NEW STAGE ADDED FOR DOWNLOAD ID[%d] new_stage[%p]", slot_id,new_download_stage_data); - -ERR: - return new_download_stage_data; -} - -void remove_download_stage(int slot_id, stage_info *in_stage) -{ - stage_info *stage = DA_NULL; - - DA_LOG_FUNC_LOGV(Default); - - stage = GET_DL_CURRENT_STAGE(slot_id); - if (DA_NULL == stage) { - DA_LOG_VERBOSE(Default, "There is no stage field on slot_id = %d", slot_id); - goto ERR; - } - - if (DA_NULL == in_stage) { - DA_LOG_VERBOSE(Default, "There is no in_stage to remove."); - goto ERR; - } - - if (in_stage == stage) { - DA_LOG_VERBOSE(Default, "Base stage will be removed. in_stage[%p]",in_stage); - DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info); - GET_DL_CURRENT_STAGE(slot_id) = stage->next_stage_info; - empty_stage_info(in_stage); - free(in_stage); - in_stage = DA_NULL; - } else { - while (in_stage != stage->next_stage_info) { - stage = stage->next_stage_info; - } - if (in_stage == stage->next_stage_info) { - stage->next_stage_info - = stage->next_stage_info->next_stage_info; - DA_LOG_VERBOSE(Default, "Stage will be removed. in_stage[%p]",in_stage); - DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info); - empty_stage_info(in_stage); - free(in_stage); - in_stage = DA_NULL; - } - } - -ERR: - return; -} - -void empty_stage_info(stage_info *in_stage) -{ - source_info_t *source_information = NULL; - req_dl_info *request_download_info = NULL; - file_info *file_information = NULL; - - DA_LOG_VERBOSE(Default, "Stage to Remove:[%p]", in_stage); - source_information = GET_STAGE_SOURCE_INFO(in_stage); - - cleanup_source_info_basic_download( - GET_SOURCE_BASIC(source_information)); - - request_download_info = GET_STAGE_TRANSACTION_INFO(in_stage); - - cleanup_req_dl_info_http(request_download_info); - - file_information = GET_STAGE_CONTENT_STORE_INFO(in_stage); - destroy_file_info(file_information); -} - -void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic) -{ - if (NULL == source_info_basic) - goto ERR; - - DA_LOG_FUNC_LOGV(Default); - - if (NULL != source_info_basic->url) { - free(source_info_basic->url); - source_info_basic->url = DA_NULL; - } - -ERR: - return; - -} - -void cleanup_req_dl_info_http(req_dl_info *http_download) -{ - DA_LOG_FUNC_LOGV(Default); - - if (http_download->http_info.http_msg_request) { - http_msg_request_destroy( - &(http_download->http_info.http_msg_request)); - http_download->http_info.http_msg_request = DA_NULL; - } - - if (http_download->http_info.http_msg_response) { - http_msg_response_destroy( - &(http_download->http_info.http_msg_response)); - http_download->http_info.http_msg_response = DA_NULL; - } - - if (DA_NULL != http_download->location_url) { - free(http_download->location_url); - http_download->location_url = DA_NULL; - } - if (DA_NULL != http_download->content_type_from_header) { - free(http_download->content_type_from_header); - http_download->content_type_from_header = DA_NULL; - } - - if (DA_NULL != http_download->etag_from_header) { - free(http_download->etag_from_header); - http_download->etag_from_header = DA_NULL; - } - - http_download->invloved_transaction_id = DA_INVALID_ID; - http_download->content_len_from_header = 0; - http_download->downloaded_data_size = 0; - - _da_thread_mutex_destroy(&(http_download->mutex_http_state)); - - return; -} - -void destroy_file_info(file_info *file_information) -{ - DA_LOG_FUNC_LOGV(Default); - - if (!file_information) - return; - - if (file_information->file_name_final) { - free(file_information->file_name_final); - file_information->file_name_final = NULL; - } - - if (file_information->content_type) { - free(file_information->content_type); - file_information->content_type = NULL; - } - - if (file_information->pure_file_name) { - free(file_information->pure_file_name); - file_information->pure_file_name = NULL; - } - - if (file_information->extension) { - free(file_information->extension); - file_information->extension = NULL; - } - return; -} - -void clean_up_client_input_info(client_input_t *client_input) -{ - DA_LOG_FUNC_LOGV(Default); - - if (client_input) { - client_input->user_data = NULL; - - if (client_input->install_path) { - free(client_input->install_path); - client_input->install_path = DA_NULL; - } - - if (client_input->file_name) { - free(client_input->file_name); - client_input->file_name = DA_NULL; - } - - if (client_input->etag) { - free(client_input->etag); - client_input->etag = DA_NULL; - } - - if (client_input->temp_file_path) { - free(client_input->temp_file_path); - client_input->temp_file_path = DA_NULL; - } - - if (client_input->pkg_name) { - free(client_input->pkg_name); - client_input->pkg_name = DA_NULL; - } - - client_input_basic_t *client_input_basic = - &(client_input->client_input_basic); - - if (client_input_basic && client_input_basic->req_url) { - free(client_input_basic->req_url); - client_input_basic->req_url = DA_NULL; - } - - if (client_input_basic && client_input_basic->user_request_header) { - int i = 0; - int count = client_input_basic->user_request_header_count; - for (i = 0; i < count; i++) - { - if (client_input_basic->user_request_header[i]) { - free(client_input_basic->user_request_header[i]); - client_input_basic->user_request_header[i] = DA_NULL; - } - } - - free(client_input_basic->user_request_header); - client_input_basic->user_request_header = DA_NULL; - client_input_basic->user_request_header_count = 0; - } - } else { - DA_LOG_ERR(Default, "client_input is NULL."); - } - - return; -} - -da_result_t get_slot_id_for_dl_id( - int dl_id, - int* slot_id) -{ - da_result_t ret = DA_ERR_INVALID_DL_REQ_ID; - int iter = 0; - - if (dl_id < 0) { - DA_LOG_ERR(Default, "dl_id is less than 0 - %d", dl_id); - return DA_ERR_INVALID_DL_REQ_ID; - } - - _da_thread_mutex_lock(&mutex_download_mgr); - for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) { - if (download_mgr.dl_info[iter].is_using == DA_TRUE) { - if (download_mgr.dl_info[iter].dl_id == - dl_id) { - *slot_id = iter; - ret = DA_RESULT_OK; - break; - } - } - } - _da_thread_mutex_unlock(&mutex_download_mgr); - - return ret; -} - - -da_result_t get_available_slot_id(int *available_id) -{ - da_result_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD; - int i; - - _da_thread_mutex_lock(&mutex_download_mgr); - for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) { - if (download_mgr.dl_info[i].is_using == DA_FALSE) { - init_download_info(i); - - download_mgr.dl_info[i].is_using = DA_TRUE; - - download_mgr.dl_info[i].dl_id - = get_available_dl_id(&(download_mgr.dl_id_history)); - - *available_id = i; - DA_LOG_VERBOSE(Default, "available download id = %d", *available_id); - ret = DA_RESULT_OK; - - break; - } - } - _da_thread_mutex_unlock(&mutex_download_mgr); - - return ret; -} - -da_bool_t is_valid_slot_id(int slot_id) -{ - da_bool_t ret = DA_FALSE; - - if (slot_id >= 0 && slot_id < DA_MAX_DOWNLOAD_ID) { - if (download_mgr.dl_info[slot_id].is_using == DA_TRUE) - ret = DA_TRUE; - } - - return ret; -} - -void store_http_status(int dl_id, int status) -{ - if (status < 100 || status > 599) { - DA_LOG_ERR(Default, "Invalid status code [%d]", status); - return; - } - DA_LOG_VERBOSE(Default, "store_http_status id[%d]status[%d] ",dl_id, status); - download_mgr.dl_info[dl_id].http_status = status; -} - -int get_http_status(int slot_id) -{ - if (!download_mgr.dl_info[slot_id].is_using) { - DA_LOG_ERR(Default, "Invalid slot_id [%d]", slot_id); - return 0; - } - return download_mgr.dl_info[slot_id].http_status; -} diff --git a/agent/download-agent-dl-info.c b/agent/download-agent-dl-info.c new file mode 100644 index 0000000..6e49145 --- /dev/null +++ b/agent/download-agent-dl-info.c @@ -0,0 +1,462 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "download-agent-dl-info.h" +#include "download-agent-http-mgr.h" +#include "download-agent-http-msg-handler.h" + +static pthread_mutex_t mutex_da_info_list = PTHREAD_MUTEX_INITIALIZER; + +static void __init_da_info(int id) +{ + da_info_t *da_info = DA_NULL; + file_info_t *file_info = DA_NULL; + http_info_t *http_info = DA_NULL; + req_info_t *req_info = DA_NULL; + + da_info = (da_info_t *)calloc(1, sizeof(da_info_t)); + if (!da_info) { + DA_LOGE("Fail to calloc. id[%d]",id); + da_info_list[id] = DA_NULL; + return; + } + file_info = (file_info_t *)calloc(1, sizeof(file_info_t)); + if (!file_info) { + DA_LOGE("Fail to calloc. id[%d]",id); + free(da_info); + da_info_list[id] = DA_NULL; + return; + } + http_info = (http_info_t *)calloc(1, sizeof(http_info_t)); + if (!http_info) { + DA_LOGE("Fail to calloc. id[%d]",id); + free(da_info); + free(file_info); + da_info_list[id] = DA_NULL; + return; + } + req_info = (req_info_t *)calloc(1, sizeof(req_info_t)); + if (!req_info) { + DA_LOGE("Fail to calloc. id[%d]",id); + free(da_info); + free(file_info); + free(http_info); + da_info_list[id] = DA_NULL; + return; + } + + da_info->da_id = DA_INVALID_ID; + da_info->tid = DA_INVALID_ID; + memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t)); + da_info->is_cb_update = DA_FALSE; + da_info->http_info = http_info; + da_info->file_info = file_info; + da_info->req_info = req_info; + da_info->update_time = 0; + da_info_list[id] = da_info; +} + +da_ret_t init_http_msg_t(http_msg_t **http_msg) +{ + da_ret_t ret = DA_RESULT_OK; + http_msg_t *temp = DA_NULL; + temp = (http_msg_t *)calloc(1, sizeof(http_msg_t)); + if (!temp) { + DA_LOGE("Fail to calloc. id"); + return DA_ERR_FAIL_TO_MEMALLOC; + } + *http_msg = temp; + return ret; +} + +void destroy_http_msg_t(http_msg_t *http_msg) +{ + if (http_msg) + free(http_msg); + http_msg = DA_NULL; + return; +} + +da_ret_t get_available_da_id(int *available_id) +{ + da_ret_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD; + int i = 0; + + DA_MUTEX_LOCK(&mutex_da_info_list); + for (i = 0; i < DA_MAX_ID; i++) { + if (da_info_list[i] == DA_NULL) { + *available_id = i; + DA_LOGV("available download id[%d]", *available_id); + __init_da_info(i); + ret = DA_RESULT_OK; + break; + } + } + DA_MUTEX_UNLOCK(&mutex_da_info_list); + + return ret; +} + +da_ret_t get_da_info_with_da_id(int id, da_info_t **out_info) +{ + da_ret_t ret = DA_ERR_INVALID_ARGUMENT; + int i = 0; + + DA_MUTEX_LOCK(&mutex_da_info_list); + for (i = 0; i < DA_MAX_ID; i++) { + if (DA_NULL != da_info_list[i] && da_info_list[i]->da_id == id) { + *out_info = da_info_list[i]; + ret = DA_RESULT_OK; + break; + } + } + DA_MUTEX_UNLOCK(&mutex_da_info_list); + + return ret; +} + +da_ret_t __is_supporting_protocol(const char *url) +{ + da_ret_t ret = DA_RESULT_OK; + int wanted_str_len = 0; + char *protocol = NULL; + char *wanted_str_start = NULL; + char *wanted_str_end = NULL; + + if (DA_NULL == url || strlen(url) < 1) + return DA_ERR_INVALID_URL; + + wanted_str_start = (char*)url; + wanted_str_end = strstr(url, "://"); + if (!wanted_str_end) { + DA_LOGE("No protocol on this url"); + return DA_ERR_INVALID_URL; + } + + wanted_str_len = wanted_str_end - wanted_str_start; + protocol = (char*)calloc(1, wanted_str_len + 1); + if (!protocol) { + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); + return DA_ERR_FAIL_TO_MEMALLOC; + } + strncpy(protocol, wanted_str_start, wanted_str_len); + + if (strlen(protocol) < 1) + ret = DA_ERR_UNSUPPORTED_PROTOCAL; + else if (strcasecmp(protocol, "http") != 0 && + strcasecmp(protocol, "https") != 0) + ret = DA_ERR_UNSUPPORTED_PROTOCAL; + + free(protocol); + return ret; +} + +da_ret_t copy_user_input_data(da_info_t *da_info, const char *url, + req_data_t *ext_data, da_cb_t *da_cb_data) +{ + da_ret_t ret = DA_RESULT_OK; + + if (!url || !da_info) { + DA_LOGE("Invalid Param"); + return DA_ERR_INVALID_ARGUMENT; + } + + ret = __is_supporting_protocol(url); + if (ret != DA_RESULT_OK) { + DA_SECURE_LOGE("url[%s]", url); + return ret; + } + + if (ext_data) { + req_info_t *req_info = da_info->req_info; + + if (ext_data->request_header_count > 0) { + int i = 0; + int count = ext_data->request_header_count; + req_info->req_header = (char **)calloc(count, sizeof(char *)); + if(DA_NULL == req_info->req_header) { + DA_LOGE("Fail to calloc"); + free(req_info); + da_info->req_info = DA_NULL; + return DA_ERR_FAIL_TO_MEMALLOC; + } + for (i = 0; i < count; i++) { + if (ext_data->request_header[i]) + req_info->req_header[i] = + strdup(ext_data->request_header[i]); + } + req_info->req_header_count = count; + } + + if (url) + req_info->url = strdup(url); + if (ext_data->install_path) + req_info->install_path = strdup(ext_data->install_path); + if (ext_data->file_name) + req_info->file_name = strdup(ext_data->file_name); + if (ext_data->etag) + req_info->etag = strdup(ext_data->etag); + if (ext_data->temp_file_path) + req_info->temp_file_path = strdup(ext_data->temp_file_path); + if (ext_data->pkg_name) + req_info->pkg_name = strdup(ext_data->pkg_name); + req_info->network_bonding = ext_data->network_bonding; + if (ext_data->user_req_data) + req_info->user_req_data = ext_data->user_req_data; + if (ext_data->user_client_data) + req_info->user_client_data = ext_data->user_client_data; + da_info->req_info = req_info; + } + if (da_cb_data) { + da_info->is_cb_update = DA_TRUE; + memcpy(&(da_info->cb_info), da_cb_data, sizeof(da_cb_t)); + } + return ret; +} + +static void __destroy_http_msg(http_msg_t *msg) +{ + msg->curl = DA_NULL; + free(msg); +} + +static void __destroy_http_msg_request(http_msg_request_t *msg) +{ + if (msg) { + http_msg_request_destroy(&msg); + free(msg); + } +} + +static void __destroy_http_msg_response(http_msg_response_t *msg) +{ + if (msg) { + http_msg_response_destroy(&msg); + free(msg); + } +} + +static void __destroy_req_info(req_info_t *req_info) +{ + if (req_info) { + free(req_info->url); + if (req_info->req_header && req_info->req_header_count > 0) { + int i = 0; + int count = req_info->req_header_count; + for (i = 0; i < count; i++) { + free(req_info->req_header[i]); + req_info->req_header[i] = DA_NULL; + } + free(req_info->req_header); + req_info->req_header = DA_NULL; + req_info->req_header_count = 0; + } + free(req_info->install_path); + free(req_info->file_name); + free(req_info->etag); + free(req_info->temp_file_path); + free(req_info->pkg_name); + req_info->user_req_data = DA_NULL; + req_info->user_client_data = DA_NULL; + free(req_info); + } +} + +void destroy_http_info(http_info_t *http_info) +{ + if (http_info) { + DA_LOGI("[TEST] location_url[%p]",http_info->location_url); + free(http_info->location_url); + free(http_info->proxy_addr); + free(http_info->content_type_from_header); + free(http_info->etag_from_header); + free(http_info->file_name_from_header); + if (http_info->http_msg_request) { + __destroy_http_msg_request(http_info->http_msg_request); + http_info->http_msg_request = DA_NULL; + } + if (http_info->http_msg_response) { + __destroy_http_msg_response(http_info->http_msg_response); + http_info->http_msg_response = DA_NULL; + } + if (http_info->http_msg) { + __destroy_http_msg(http_info->http_msg); + http_info->http_msg = DA_NULL; + } + DA_MUTEX_DESTROY(&(http_info->mutex_state)); + DA_MUTEX_DESTROY(&(http_info->mutex_http)); + DA_COND_DESTROY(&(http_info->cond_http)); + http_info->state = HTTP_STATE_READY_TO_DOWNLOAD; + http_info->http_method = HTTP_METHOD_GET; + http_info->content_len_from_header = 0; + http_info->total_size = 0; + http_info->error_code = 0; + free(http_info); + } +} + +void destroy_file_info(file_info_t *file_info) +{ + if (file_info) { + file_info->file_handle = DA_NULL; + free(file_info->pure_file_name); + free(file_info->extension); + free(file_info->file_path); + free(file_info->mime_type); + free(file_info->buffer); + file_info->buffer_len = 0; + file_info->file_size = 0; +#ifdef _RAF_SUPPORT + file_info->file_size_of_temp_file = 0; +#endif + file_info->bytes_written_to_file = 0; + file_info->is_updated = DA_FALSE; + free(file_info); + } +} + +// For pause and resume case +void reset_http_info_for_resume(http_info_t *http_info) +{ + if (http_info) { + DA_LOGI("[TEST] location_url[%p]",http_info->location_url); + free(http_info->location_url); + http_info->location_url = DA_NULL; + free(http_info->proxy_addr); + http_info->proxy_addr = DA_NULL; + free(http_info->content_type_from_header); + http_info->content_type_from_header = DA_NULL; + if (http_info->http_msg_response) { + __destroy_http_msg_response(http_info->http_msg_response); + http_info->http_msg_response = DA_NULL; + } + if (http_info->http_msg) { + __destroy_http_msg(http_info->http_msg); + http_info->http_msg = DA_NULL; + } + http_info->http_method = HTTP_METHOD_GET; + http_info->content_len_from_header = 0; + http_info->total_size = 0; + } +} + +void reset_http_info(http_info_t *http_info) +{ + if (http_info) { + DA_LOGI("[TEST] location_url[%p]",http_info->location_url); + free(http_info->location_url); + http_info->location_url = DA_NULL; + free(http_info->proxy_addr); + http_info->proxy_addr = DA_NULL; + free(http_info->content_type_from_header); + http_info->content_type_from_header = DA_NULL; + if (http_info->http_msg_request) { + __destroy_http_msg_request(http_info->http_msg_request); + http_info->http_msg_request = DA_NULL; + } + if (http_info->http_msg_response) { + __destroy_http_msg_response(http_info->http_msg_response); + http_info->http_msg_response = DA_NULL; + } + if (http_info->http_msg) { + __destroy_http_msg(http_info->http_msg); + http_info->http_msg = DA_NULL; + } + http_info->http_method = HTTP_METHOD_GET; + http_info->content_len_from_header = 0; + http_info->total_size = 0; + } +} + +da_bool_t is_valid_download_id(int download_id) +{ + da_ret_t ret = DA_RESULT_OK; + + DA_LOGV(""); + DA_MUTEX_LOCK(&mutex_da_info_list); + if (DA_NULL == da_info_list[download_id]) { + DA_MUTEX_UNLOCK(&mutex_da_info_list); + return DA_FALSE; + } + if (is_stopped_state(da_info_list[download_id])) { + DA_MUTEX_UNLOCK(&mutex_da_info_list); + return DA_TRUE; + } + if (da_info_list[download_id]->da_id != DA_INVALID_ID) { + DA_MUTEX_UNLOCK(&mutex_da_info_list); + return DA_TRUE; + } else { + DA_MUTEX_UNLOCK(&mutex_da_info_list); + return DA_FALSE; + } + DA_MUTEX_UNLOCK(&mutex_da_info_list); + return ret; +} + +void destroy_da_info_list() +{ + int i = 0; + DA_MUTEX_LOCK(&mutex_da_info_list); + for (i = 0; i < DA_MAX_ID; i++) { + if(DA_NULL != da_info_list[i]) { + if (da_info_list[i]->req_info) { + __destroy_req_info(da_info_list[i]->req_info); + da_info_list[i]->req_info = DA_NULL; + } + if (da_info_list[i]->http_info) { + destroy_http_info(da_info_list[i]->http_info); + da_info_list[i]->http_info = DA_NULL; + } + if (da_info_list[i]->file_info) { + destroy_file_info(da_info_list[i]->file_info); + da_info_list[i]->file_info = DA_NULL; + } + free(da_info_list[i]); + da_info_list[i] = DA_NULL; + } + } + DA_MUTEX_UNLOCK(&mutex_da_info_list); +} + +void destroy_da_info(int id) +{ + da_info_t *da_info = DA_NULL; + DA_MUTEX_LOCK(&mutex_da_info_list); + da_info = da_info_list[id]; + if (da_info) { + if (da_info->req_info) { + __destroy_req_info(da_info->req_info); + da_info->req_info = DA_NULL; + } + if (da_info->http_info) { + destroy_http_info(da_info->http_info); + da_info->http_info = DA_NULL; + } + if (da_info->file_info) { + destroy_file_info(da_info->file_info); + da_info->file_info = DA_NULL; + } + da_info->da_id = DA_INVALID_ID; + da_info->tid = DA_INVALID_ID; + memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t)); + free(da_info); + da_info_list[id] = DA_NULL; + } + DA_MUTEX_UNLOCK(&mutex_da_info_list); +} diff --git a/agent/download-agent-dl-mgr.c b/agent/download-agent-dl-mgr.c index 7a2ce0d..e57f3f3 100755 --- a/agent/download-agent-dl-mgr.c +++ b/agent/download-agent-dl-mgr.c @@ -14,301 +14,173 @@ * limitations under the License. */ -#include "download-agent-client-mgr.h" -#include "download-agent-debug.h" -#include "download-agent-dl-mgr.h" -#include "download-agent-utils.h" -#include "download-agent-http-mgr.h" -#include "download-agent-file.h" -#include "download-agent-plugin-conf.h" +#include +#include +#include +#ifdef _ENABLE_SYS_RESOURCE +#include "resourced.h" +#endif -static da_result_t __cancel_download_with_slot_id(int slot_id); -static da_result_t __suspend_download_with_slot_id(int slot_id); - +#include "download-agent-dl-mgr.h" +#include "download-agent-dl-info.h" +#include "download-agent-http-mgr.h" -da_result_t requesting_download(stage_info *stage) +void __thread_clean_up_handler_for_start_download(void *arg) { - da_result_t ret = DA_RESULT_OK; - req_dl_info *request_session = DA_NULL; + DA_LOGI("cleanup for thread id[%lu]", pthread_self()); +} - DA_LOG_FUNC_LOGV(Default); +da_ret_t __download_content(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; - if (!stage) { - DA_LOG_ERR(Default, "stage is null.."); + DA_LOGV(""); + if (!da_info) { + DA_LOGE("NULL CHECK!: da_info"); ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; + return ret; } - ret = make_req_dl_info_http(stage, GET_STAGE_TRANSACTION_INFO(stage)); - if (ret != DA_RESULT_OK) - goto ERR; - - request_session = GET_STAGE_TRANSACTION_INFO(stage); - ret = request_http_download(stage); - if (DA_RESULT_OK == ret) { - DA_LOG_VERBOSE(Default, "Http download is complete."); - } else { - DA_LOG_ERR(Default, "Http download is failed. ret = %d", ret); - goto ERR; - } -ERR: + ret = request_http_download(da_info); return ret; } -da_result_t handle_after_download(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - da_mime_type_id_t mime_type = DA_MIME_TYPE_NONE; - - DA_LOG_FUNC_LOGV(Default); - mime_type = get_mime_type_id( - GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage))); - - switch (mime_type) { - case DA_MIME_TYPE_NONE: - DA_LOG(Default, "DA_MIME_TYPE_NONE"); - ret = DA_ERR_MISMATCH_CONTENT_TYPE; - break; - default: - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_FINISH, stage); - break; - } /* end of switch */ - - return ret; -} - -static da_result_t __cancel_download_with_slot_id(int slot_id) +static void *__thread_start_download(void *data) { - da_result_t ret = DA_RESULT_OK; - download_state_t download_state; - stage_info *stage = DA_NULL; - - DA_LOG_FUNC_LOGD(Default); - - _da_thread_mutex_lock (&mutex_download_state[slot_id]); - download_state = GET_DL_STATE_ON_ID(slot_id); - DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id)); - - if (download_state == DOWNLOAD_STATE_FINISH || - download_state == DOWNLOAD_STATE_CANCELED) { - DA_LOG_CRITICAL(Default, "Already download is finished. Do not send cancel request"); - _da_thread_mutex_unlock (&mutex_download_state[slot_id]); - return ret; + da_info_t *da_info = DA_NULL; + req_info_t *req_info = DA_NULL; + int da_id = DA_INVALID_ID; + +// DA_LOGV(""); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL); + + da_info = (da_info_t *)data; + NULL_CHECK_RET_OPT(da_info, DA_NULL); + req_info = da_info->req_info; + NULL_CHECK_RET_OPT(req_info, DA_NULL); + + da_id = da_info->da_id; + pthread_cleanup_push(__thread_clean_up_handler_for_start_download, DA_NULL); +#ifdef _ENABLE_SYS_RESOURCE + if (req_info->pkg_name) { + pid_t tid = (pid_t) syscall(SYS_gettid); + da_info->tid = (pid_t) syscall(SYS_gettid); + DA_SECURE_LOGI("pkg_name[%s] threadid[%lu]", + req_info->pkg_name,pthread_self()); + if (join_app_performance(req_info->pkg_name, tid) != + RESOURCED_ERROR_OK) { + DA_LOGE("Can not put app to network performance id[%d]", da_id); + } } - _da_thread_mutex_unlock (&mutex_download_state[slot_id]); - - stage = GET_DL_CURRENT_STAGE(slot_id); - if (!stage) - return DA_RESULT_OK; - - ret = request_to_cancel_http_download(stage); - if (ret != DA_RESULT_OK) - goto ERR; - DA_LOG(Default, "Download cancel Successful for download id - %d", slot_id); -ERR: - return ret; +#endif + __download_content(da_info); + destroy_da_info(da_id); + pthread_cleanup_pop(0); + DA_LOGI("=====EXIT thread : da_id[%d]=====", da_id); + pthread_exit((void *)DA_NULL); + return DA_NULL; } -da_result_t cancel_download(int dl_id) +da_ret_t start_download(da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; - - int slot_id = DA_INVALID_ID; - - DA_LOG_FUNC_LOGD(Default); - - ret = get_slot_id_for_dl_id(dl_id, &slot_id); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(Default, "dl req ID is not Valid"); + da_ret_t ret = DA_RESULT_OK; + pthread_attr_t thread_attr; + pthread_t tid; + if (pthread_attr_init(&thread_attr) != 0) { + ret = DA_ERR_FAIL_TO_CREATE_THREAD; goto ERR; } - if (DA_FALSE == is_valid_slot_id(slot_id)) { - DA_LOG_ERR(Default, "Download ID is not Valid"); - ret = DA_ERR_INVALID_ARGUMENT; + if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) { + ret = DA_ERR_FAIL_TO_CREATE_THREAD; goto ERR; } - ret = __cancel_download_with_slot_id(slot_id); - -ERR: - return ret; - -} - -static da_result_t __suspend_download_with_slot_id(int slot_id) -{ - da_result_t ret = DA_RESULT_OK; - download_state_t download_state; - stage_info *stage = DA_NULL; - - DA_LOG_FUNC_LOGD(Default); - - _da_thread_mutex_lock (&mutex_download_state[slot_id]); - download_state = GET_DL_STATE_ON_ID(slot_id); - DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id)); - _da_thread_mutex_unlock (&mutex_download_state[slot_id]); - - stage = GET_DL_CURRENT_STAGE(slot_id); - if (!stage) - return DA_ERR_CANNOT_SUSPEND; - - ret = request_to_suspend_http_download(stage); - if (ret != DA_RESULT_OK) - goto ERR; - DA_LOG(Default, "Download Suspend Successful for download id-%d", slot_id); -ERR: - return ret; -} - -da_result_t suspend_download(int dl_id, da_bool_t is_enable_cb) -{ - da_result_t ret = DA_RESULT_OK; - int slot_id = DA_INVALID_ID; - - DA_LOG_FUNC_LOGD(Default); - - ret = get_slot_id_for_dl_id(dl_id, &slot_id); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(Default, "dl req ID is not Valid"); - goto ERR; - } - GET_DL_ENABLE_PAUSE_UPDATE(slot_id) = is_enable_cb; - if (DA_FALSE == is_valid_slot_id(slot_id)) { - DA_LOG_ERR(Default, "Download ID is not Valid"); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; + if (pthread_create(&(tid), &thread_attr, + __thread_start_download, da_info) < 0) { + DA_LOGE("Fail to make thread:id[%d]", da_info->da_id); + ret = DA_ERR_FAIL_TO_CREATE_THREAD; + } else { + if (tid < 1) { + DA_LOGE("The thread start is failed before calling this"); +// When http resource is leaked, the thread ID is initialized at error handling section of thread_start_download() +// Because the thread ID is initialized, the ptrhead_detach should not be called. This is something like timing issue between threads. +// thread info and basic_dl_input is freed at thread_start_download(). And it should not returns error code in this case. + ret = DA_ERR_FAIL_TO_CREATE_THREAD; + goto ERR; + } } - - ret = __suspend_download_with_slot_id(slot_id); - + da_info->thread_id = tid; + DA_LOGI("Thread create:thread id[%lu]", da_info->thread_id); ERR: + if (DA_RESULT_OK != ret) { + destroy_da_info(da_info->da_id); + } return ret; - } -static da_result_t __resume_download_with_slot_id(int slot_id) +da_ret_t cancel_download(int dl_id, da_bool_t is_enable_cb) { - da_result_t ret = DA_RESULT_OK; - download_state_t download_state; - stage_info *stage = DA_NULL; - - DA_LOG_FUNC_LOGD(Default); + da_ret_t ret = DA_RESULT_OK; + da_info_t *da_info = DA_NULL; - _da_thread_mutex_lock (&mutex_download_state[slot_id]); - download_state = GET_DL_STATE_ON_ID(slot_id); - DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id)); - _da_thread_mutex_unlock (&mutex_download_state[slot_id]); + DA_LOGV(""); - stage = GET_DL_CURRENT_STAGE(slot_id); - - ret = request_to_resume_http_download(stage); + ret = get_da_info_with_da_id(dl_id, &da_info); + if (ret != DA_RESULT_OK || !da_info) { + return DA_ERR_INVALID_ARGUMENT; + } + da_info->is_cb_update = is_enable_cb; + ret = request_to_cancel_http_download(da_info); if (ret != DA_RESULT_OK) goto ERR; - DA_LOG(Default, "Download Resume Successful for download id-%d", slot_id); + DA_LOGI("Download cancel Successful for download id[%d]", da_info->da_id); + ERR: return ret; } -da_result_t resume_download(int dl_id) +da_ret_t suspend_download(int dl_id, da_bool_t is_enable_cb) { - da_result_t ret = DA_RESULT_OK; - int slot_id = DA_INVALID_ID; + da_ret_t ret = DA_RESULT_OK; + da_info_t *da_info = DA_NULL; - DA_LOG_FUNC_LOGD(Default); + DA_LOGV(""); - ret = get_slot_id_for_dl_id(dl_id, &slot_id); + ret = get_da_info_with_da_id(dl_id, &da_info); + if (ret != DA_RESULT_OK || !da_info) { + return DA_ERR_INVALID_ARGUMENT; + } + da_info->is_cb_update = is_enable_cb; + ret = request_to_suspend_http_download(da_info); if (ret != DA_RESULT_OK) goto ERR; - - if (DA_FALSE == is_valid_slot_id(slot_id)) { - DA_LOG_ERR(Default, "Download ID is not Valid"); - ret = DA_ERR_INVALID_DL_REQ_ID; - goto ERR; - } - - ret = __resume_download_with_slot_id(slot_id); - + DA_LOGV("Download Suspend Successful for download id[%d]", da_info->da_id); ERR: return ret; -} - -da_result_t send_user_noti_and_finish_download_flow( - int slot_id, char *installed_path, char *etag) -{ - da_result_t ret = DA_RESULT_OK; - download_state_t download_state = HTTP_STATE_READY_TO_DOWNLOAD; - da_bool_t need_destroy_download_info = DA_FALSE; - - DA_LOG_FUNC_LOGV(Default); - _da_thread_mutex_lock (&mutex_download_state[slot_id]); - download_state = GET_DL_STATE_ON_ID(slot_id); - DA_LOG_DEBUG(Default, "state = %d", download_state); - _da_thread_mutex_unlock (&mutex_download_state[slot_id]); - - switch (download_state) { - case DOWNLOAD_STATE_FINISH: - send_client_finished_info(slot_id, GET_DL_ID(slot_id), - installed_path, DA_NULL, DA_RESULT_OK, - get_http_status(slot_id)); - need_destroy_download_info = DA_TRUE; - break; - case DOWNLOAD_STATE_CANCELED: - send_client_finished_info(slot_id, GET_DL_ID(slot_id), - installed_path, etag, DA_RESULT_USER_CANCELED, - get_http_status(slot_id)); - need_destroy_download_info = DA_TRUE; - break; -#ifdef PAUSE_EXIT - case DOWNLOAD_STATE_PAUSED: - need_destroy_download_info = DA_TRUE; - break; -#endif - default: - DA_LOG(Default, "download state = %d", download_state); - break; - } - - if (need_destroy_download_info == DA_TRUE) { - destroy_download_info(slot_id); - } else { - DA_LOG_CRITICAL(Default, "download info is not destroyed"); - } - - return ret; } -da_bool_t is_valid_download_id(int dl_id) +da_ret_t resume_download(int dl_id) { + da_ret_t ret = DA_RESULT_OK; + da_info_t *da_info = DA_NULL; - da_bool_t ret = DA_TRUE; - int slot_id = DA_INVALID_ID; - - DA_LOG_VERBOSE(Default, "[is_valid_download_id]download_id : %d", dl_id); - - ret = get_slot_id_for_dl_id(dl_id, &slot_id); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(Default, "dl req ID is not Valid"); - ret = DA_FALSE; - goto ERR; - } else { - ret = DA_TRUE; - } + DA_LOGV(""); - if (DA_FALSE == is_valid_slot_id(slot_id)) { - DA_LOG_ERR(Default, "Download ID is not Valid"); - ret = DA_FALSE; - goto ERR; + ret = get_da_info_with_da_id(dl_id, &da_info); + if (ret != DA_RESULT_OK || !da_info) { + return DA_ERR_INVALID_ARGUMENT; } - if (GET_DL_THREAD_ID(slot_id) < 1) { - DA_LOG_ERR(Default, "Download thread is not alive"); - ret = DA_FALSE; + da_info->is_cb_update = DA_TRUE; + ret = request_to_resume_http_download(da_info); + if (ret != DA_RESULT_OK) goto ERR; - } - + DA_LOGV("Download Resume Successful for download id[%d]", da_info->da_id); ERR: return ret; } + diff --git a/agent/download-agent-encoding.c b/agent/download-agent-encoding.c index 1955fcd..3f14fca 100755 --- a/agent/download-agent-encoding.c +++ b/agent/download-agent-encoding.c @@ -16,12 +16,12 @@ #include #include -#include +#include "glib.h" -#include "download-agent-encoding.h" #include "download-agent-debug.h" +#include "download-agent-encoding.h" -da_result_t _parsing_base64_encoded_str(const char *in_encoded_str, +da_ret_t _parsing_base64_encoded_str(const char *in_encoded_str, char **out_charset_type, char *out_encoding_type, char **out_raw_encoded_str); @@ -34,7 +34,7 @@ da_bool_t is_base64_encoded_word(const char *in_str) char *found_str = DA_NULL; if (!in_str) { - DA_LOG_ERR(Default, "input string is NULL"); + DA_LOGE("input string is NULL"); return DA_FALSE; } @@ -47,14 +47,10 @@ da_bool_t is_base64_encoded_word(const char *in_str) snprintf(second_needle, sizeof(second_needle), "%s", "?="); // ?= } -// DA_SECURE_LOGD("needle = [%s], haystack = [%s]", first_needle, haystack); - found_str = strstr(haystack, first_needle); if (found_str) { if (found_str == haystack) { -// DA_SECURE_LOGD("Input string is starting with %s", needle); haystack = haystack + strlen(haystack) - strlen(second_needle); -// DA_SECURE_LOGD("second haystack is [%s]", haystack); if(!strcmp(haystack, second_needle)) return DA_TRUE; } @@ -62,11 +58,10 @@ da_bool_t is_base64_encoded_word(const char *in_str) return DA_FALSE; } -da_result_t decode_base64_encoded_str(const char *in_encoded_str, +da_ret_t decode_base64_encoded_str(const char *in_encoded_str, char **out_decoded_ascii_str) { - da_result_t ret = DA_RESULT_OK; - + da_ret_t ret = DA_RESULT_OK; const char *org_str = DA_NULL; char *charset_type = NULL; char encoding_type = '\0'; @@ -80,7 +75,7 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str, org_str = in_encoded_str; if(!org_str) { - DA_LOG_ERR(Default, "Input string is NULL"); + DA_LOGE("Input string is NULL"); ret = DA_ERR_INVALID_ARGUMENT; goto ERR; } @@ -91,10 +86,8 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str, goto ERR; } -// DA_SECURE_LOGD("charset = [%s], encoding = [%c], raw = [%s]", charset_type, encoding_type, raw_encoded_str); - if(encoding_type != 'B') { - DA_LOG_ERR(Default, "Encoded Word is not encoded with Base64, but %c. We can only handle Base64.", encoding_type); + DA_LOGE("Encoded Word is not encoded with Base64, but %c. We can only handle Base64.", encoding_type); ret = DA_ERR_INVALID_ARGUMENT; goto ERR; } @@ -112,7 +105,7 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str, DA_SECURE_LOGD("g_decoded_text = [%s]", g_decoded_text); decoded_str = (char*)calloc(1, g_decoded_text_len+1); if(!decoded_str) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); ret = DA_ERR_FAIL_TO_MEMALLOC; goto ERR; } else { @@ -123,40 +116,32 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str, ERR: *out_decoded_ascii_str = decoded_str; - if(charset_type) { free(charset_type); charset_type = NULL; } - if(raw_encoded_str) { free(raw_encoded_str); raw_encoded_str = NULL; } - if(g_decoded_text) { g_free(g_decoded_text); } - return ret; } - -da_result_t _parsing_base64_encoded_str(const char *in_encoded_str, +da_ret_t _parsing_base64_encoded_str(const char *in_encoded_str, char **out_charset_type, char *out_encoding_type, char **out_raw_encoded_str) { - da_result_t ret = DA_RESULT_OK; - + da_ret_t ret = DA_RESULT_OK; const char *org_str = DA_NULL; // e.g. =?UTF-8?B?7Jew7JWE7JmA7IKs7J6QLmpwZw==?= char *charset_type = NULL; // e.g. UTF-8 char encoding_type = '\0'; // e.g. B (means Base64) char *raw_encoded_str = NULL; // e.g. 7Jew7JWE7JmA7IKs7J6QLmpwZw== - char *haystack = DA_NULL; char needle[8] = {0,}; - char *wanted_str = DA_NULL; int wanted_str_len = 0; char *wanted_str_start = DA_NULL; @@ -164,7 +149,7 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str, org_str = in_encoded_str; if (!org_str) { - DA_LOG_ERR(Default, "Input string is NULL"); + DA_LOGE("Input string is NULL"); ret = DA_ERR_INVALID_ARGUMENT; goto ERR; } @@ -174,12 +159,11 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str, snprintf(needle, sizeof(needle), "=?"); wanted_str_end = strstr(haystack, needle); if (!wanted_str_end) { - DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("DA_ERR_INVALID_ARGUMENT"); ret = DA_ERR_INVALID_ARGUMENT; goto ERR; } else { wanted_str = wanted_str_end + strlen(needle); - DA_SECURE_LOGD("strip [%s]", wanted_str); } // for charset @@ -187,14 +171,14 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str, needle[0] = '?'; wanted_str_end = strchr(haystack, needle[0]); if (!wanted_str_end) { - DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("DA_ERR_INVALID_ARGUMENT"); ret = DA_ERR_INVALID_ARGUMENT; goto ERR; } else { wanted_str_len = wanted_str_end - wanted_str_start + 1; wanted_str = (char*)calloc(1, wanted_str_len+1); if (!wanted_str) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); ret = DA_ERR_FAIL_TO_MEMALLOC; goto ERR; } else { @@ -203,27 +187,26 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str, wanted_str = DA_NULL; } - DA_LOG(Default, "charset [%s]", charset_type); + DA_LOGV("charset [%s]", charset_type); } - // for encoding encoding_type = *(++wanted_str_end); - DA_LOG(Default, "encoding [%c]", encoding_type); + DA_LOGV("encoding [%c]", encoding_type); // for raw encoded str haystack = wanted_str_start = wanted_str_end + 1; snprintf(needle, sizeof(needle), "?="); wanted_str_end = strstr(haystack, needle); if (!wanted_str_end) { - DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("DA_ERR_INVALID_ARGUMENT"); ret = DA_ERR_INVALID_ARGUMENT; goto ERR; } else { wanted_str_len = wanted_str_end - wanted_str_start + 1; wanted_str = (char*)calloc(1, wanted_str_len+1); if (!wanted_str) { - DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); ret = DA_ERR_FAIL_TO_MEMALLOC; goto ERR; } else { @@ -234,7 +217,6 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str, DA_SECURE_LOGD("raw encoded str [%s]", raw_encoded_str); } - ERR: if (ret != DA_RESULT_OK) { if (charset_type) { @@ -242,17 +224,15 @@ ERR: charset_type = NULL; } } - *out_charset_type = charset_type; *out_encoding_type = encoding_type; *out_raw_encoded_str = raw_encoded_str; - return ret; } void decode_url_encoded_str(const char *in_encoded_str, char **out_str) { - char *in = NULL; + char *in = NULL; char *out = NULL; *out_str = calloc(1, strlen(in_encoded_str) + 1); if (*out_str == NULL) @@ -279,4 +259,3 @@ void decode_url_encoded_str(const char *in_encoded_str, char **out_str) out++; } } - diff --git a/agent/download-agent-file.c b/agent/download-agent-file.c index 0da5445..ea901e2 100755 --- a/agent/download-agent-file.c +++ b/agent/download-agent-file.c @@ -14,1178 +14,895 @@ * limitations under the License. */ -#include +#include #include #include +#include +#include #include #include -#include "download-agent-client-mgr.h" + #include "download-agent-debug.h" -#include "download-agent-utils.h" -#include "download-agent-dl-mgr.h" #include "download-agent-file.h" #include "download-agent-mime-util.h" -#include "download-agent-http-mgr.h" +/* FIXME Later */ +#include "download-agent-http-msg-handler.h" +#include "download-agent-plugin-drm.h" #include "download-agent-plugin-conf.h" +#include + #define NO_NAME_TEMP_STR "No name" +#define MAX_SUFFIX_COUNT 1000000000 -static da_result_t __set_file_size(stage_info *stage); -static da_result_t __saved_file_open(stage_info *stage); - -static char *__derive_extension(stage_info *stage); -static da_result_t __divide_file_name_into_pure_name_N_extesion( - const char *in_file_name, - char **out_pure_file_name, - char **out_extension); -static da_result_t __get_candidate_file_name(stage_info *stage, - char **out_pure_file_name, char **out_extension); - -static da_result_t __file_write_buf_make_buf(file_info *file_storage); -static da_result_t __file_write_buf_destroy_buf(file_info *file_storage); -static da_result_t __file_write_buf_flush_buf(stage_info *stage, - file_info *file_storage); -static da_result_t __file_write_buf_copy_to_buf(file_info *file_storage, - char *body, int body_len); -static da_result_t __file_write_buf_directly_write(stage_info *stage, - file_info *file_storage, char *body, int body_len); - -da_result_t clean_files_from_dir(char *dir_path) +da_ret_t __saved_file_open(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - struct dirent *d = DA_NULL; - DIR *dir; - char file_path[DA_MAX_FULL_PATH_LEN] = { 0, }; + da_ret_t ret = DA_RESULT_OK; + char *actual_file_path = DA_NULL; + void *fd = DA_NULL; - DA_LOG_FUNC_LOGD(FileManager); + DA_LOGV(""); - if (dir_path == DA_NULL) + actual_file_path = file_info->file_path; + if (!actual_file_path) return DA_ERR_INVALID_ARGUMENT; - if (is_dir_exist(dir_path)) { - dir = opendir(dir_path); - if (DA_NULL == dir) { - DA_LOG_ERR(FileManager, "opendir() is failed."); - ret = DA_ERR_INVALID_INSTALL_PATH; - } else { - while (DA_NULL != (d = readdir(dir))) { - DA_SECURE_LOGD("%s",d->d_name); - if (0 == strncmp(d->d_name, ".", strlen(".")) - || 0 == strncmp(d->d_name, - "..", - strlen(".."))) { - continue; - } - - memset(file_path, 0x00, DA_MAX_FULL_PATH_LEN); - snprintf(file_path, DA_MAX_FULL_PATH_LEN, - "%s/%s", dir_path, d->d_name); - if (remove(file_path) < 0) { - DA_LOG_ERR(FileManager, "fail to remove file"); - } - } + fd = fopen(actual_file_path, "a+"); // for resume + if (fd == DA_NULL) { + DA_LOGE("File open failed"); + if (errno == ENOSPC) + ret = DA_ERR_DISK_FULL; + else + ret = DA_ERR_FAIL_TO_ACCESS_FILE; + goto ERR; + } - closedir(dir); - if (remove(dir_path) < 0) { - DA_LOG_ERR(FileManager, "fail to remove dir"); - } - } + file_info->file_handle = fd; + //DA_SECURE_LOGD("file path for saving[%s]", file_info->file_path); + +ERR: + if (DA_RESULT_OK != ret) { + file_info->file_handle = DA_NULL; } return ret; } -/* Priority to obtain MIME Type - * 1. HTTP response header's field - * 2. from OMA descriptor file's attribute (mandatory field) - * 3. Otherwise, leave blank for MIME Type - */ -da_result_t get_mime_type(stage_info *stage, char **out_mime_type) +da_ret_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_name, char **out_pure_file_name, char **out_extension) { - char *mime_type = DA_NULL; + char *file_name = DA_NULL; + char *tmp_ptr = DA_NULL; + char temp_file[DA_MAX_FILE_PATH_LEN] = {0,}; + char tmp_ext[DA_MAX_STR_LEN] = {0,}; + int len = 0; + da_ret_t ret = DA_RESULT_OK; - if (!GET_STAGE_SOURCE_INFO(stage)) + DA_LOGV(""); + + if (!in_file_name) return DA_ERR_INVALID_ARGUMENT; - /* Priority 1 */ - if (GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage))) { - mime_type = GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage)); -// DA_SECURE_LOGI("content type from HTTP response header [%s]", mime_type); + file_name = (char *)in_file_name; + tmp_ptr = strrchr(file_name, '.'); + if (tmp_ptr) + tmp_ptr++; + if (tmp_ptr && out_extension) { + strncpy((char*) tmp_ext, tmp_ptr, sizeof(tmp_ext) - 1); + *out_extension = strdup((const char*) tmp_ext); + DA_SECURE_LOGD("extension [%s]", *out_extension); } - if (!mime_type) { - DA_LOG(FileManager, "no content type derived"); - return DA_RESULT_OK; + if (!out_pure_file_name) + return ret; + + if (tmp_ptr) + len = tmp_ptr - file_name - 1; + else + len = strlen(file_name); + + if (len >= DA_MAX_FILE_PATH_LEN) { + strncpy((char*) temp_file, file_name, + DA_MAX_FILE_PATH_LEN - 1); + } else { + strncpy((char*) temp_file, file_name, len); } - /* FIXME really need memory allocation? */ - *out_mime_type = (char *)calloc(1, strlen(mime_type) + 1); - if (*out_mime_type) { - strncpy(*out_mime_type, mime_type, strlen(mime_type)); -// DA_SECURE_LOGD("out_mime_type str[%s] ptr[%p] len[%d]", -// *out_mime_type,*out_mime_type,strlen(*out_mime_type)); + delete_prohibited_char((char*) temp_file, + strlen((char*) temp_file)); + if (strlen(temp_file) < 1) { + *out_pure_file_name = strdup(NO_NAME_TEMP_STR); } else { - DA_LOG_ERR(FileManager, "fail to allocate memory"); - return DA_ERR_FAIL_TO_MEMALLOC; + *out_pure_file_name = strdup( + (const char*) temp_file); } -// DA_SECURE_LOGD("mime type = %s", *out_mime_type); - return DA_RESULT_OK; + DA_LOGV( "pure file name [%s]", *out_pure_file_name); + return ret; } -da_bool_t is_file_exist(const char *file_path) +da_ret_t __file_write_buf_make_buf(file_info_t *file_info) { - struct stat dir_state; - int stat_ret; - - if (file_path == DA_NULL) { - DA_LOG_ERR(FileManager, "file path is DA_NULL"); - return DA_FALSE; - } - - stat_ret = stat(file_path, &dir_state); + da_ret_t ret = DA_RESULT_OK; + char *buffer = DA_NULL; - if (stat_ret == 0) { - if (dir_state.st_mode & S_IFREG) { - DA_SECURE_LOGD("Exist! %s is a regular file & its size = %lu", file_path, dir_state.st_size); - return DA_TRUE; - } + DA_LOGV(""); - return DA_FALSE; + buffer = (char*) calloc(1, DA_FILE_BUF_SIZE); + if (DA_NULL == buffer) { + DA_LOGE("Calloc failure "); + ret = DA_ERR_FAIL_TO_MEMALLOC; + } else { + file_info->buffer_len = 0; + file_info->buffer = buffer; } - return DA_FALSE; + return ret; } -da_bool_t is_dir_exist(const char *file_path) +da_ret_t __file_write_buf_destroy_buf(file_info_t *file_info) { - struct stat dir_state; - int stat_ret; - - if (file_path == DA_NULL) { - DA_LOG_ERR(FileManager, "file path is DA_NULL"); - return DA_FALSE; - } + da_ret_t ret = DA_RESULT_OK; - stat_ret = stat(file_path, &dir_state); + DA_LOGV(""); + NULL_CHECK_RET(file_info); - if (stat_ret == 0) { - if (dir_state.st_mode & S_IFDIR) { - DA_LOG_VERBOSE(FileManager, "Existed directory."); - return DA_TRUE; - } + free(file_info->buffer); + file_info->buffer = DA_NULL; + file_info->buffer_len = 0; - return DA_FALSE; - } - return DA_FALSE; + return ret; } -void get_file_size(char *file_path, unsigned long long *out_file_size) +da_ret_t __file_write_buf_flush_buf(file_info_t *file_info) { - struct stat dir_state; - int stat_ret; + da_ret_t ret = DA_RESULT_OK; + char *buffer = DA_NULL; + int buffer_size = 0; + int write_success_len = 0; + void *fd = DA_NULL; - *out_file_size = -1; + // DA_LOGV(""); - if (file_path == DA_NULL) { - DA_LOG_ERR(FileManager, "file path is DA_NULL"); - return; - } + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; - /* Please do not use ftell() to obtain file size, use stat instead. - * This is a guide from www.securecoding.cert.org - * : FIO19-C. Do not use fseek() and ftell() to compute the size of a file - */ - stat_ret = stat(file_path, &dir_state); - if (stat_ret == 0) { - if (dir_state.st_mode & S_IFREG) { - DA_LOG(FileManager, "size = %lu", dir_state.st_size); - *out_file_size = dir_state.st_size; - } + if (buffer_size == 0) { + DA_LOGE("no data on buffer.."); + return ret; } - return; -} - -da_result_t __saved_file_open(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; - char *actual_file_path = DA_NULL; - void *fd = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) - return DA_ERR_INVALID_ARGUMENT; + fd = file_info->file_handle; + if (DA_NULL == fd) { + DA_LOGE("There is no file handle."); - actual_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage); - if (!actual_file_path) - return DA_ERR_INVALID_ARGUMENT; + ret = DA_ERR_FAIL_TO_ACCESS_FILE; + goto ERR; + } - fd = fopen(actual_file_path, "a+"); // for resume - if (fd == DA_NULL) { - DA_LOG_ERR(FileManager, "File open failed"); + write_success_len = fwrite(buffer, sizeof(char), buffer_size, + (FILE *) fd); + /* FIXME : This can be necessary later due to progressive download. + * The solution for reducing fflush is needed */ + //fflush((FILE *) fd); + if (write_success_len != buffer_size) { + DA_LOGE("write fails "); if (errno == ENOSPC) ret = DA_ERR_DISK_FULL; else ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = fd; + file_info->bytes_written_to_file += write_success_len; + file_info->is_updated = DA_TRUE; + file_info->buffer_len = 0; +ERR: + return ret; +} -// DA_SECURE_LOGD("file path for saving = %s", -// GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage)); +da_ret_t __file_write_buf_copy_to_buf(file_info_t *file_info, char *body, + int body_len) +{ + da_ret_t ret = DA_RESULT_OK; + char *buffer = DA_NULL; + int buffer_size = 0; + + DA_LOGV(""); + + NULL_CHECK_RET(file_info->buffer); + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; + + memcpy(buffer + buffer_size, body, body_len); + file_info->buffer_len += body_len; -ERR: - if (DA_RESULT_OK != ret) { - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL; - } return ret; } -da_result_t __set_file_size(stage_info *stage) +da_ret_t __file_write_buf_directly_write(file_info_t *file_info, + char *body, int body_len) { - da_result_t ret = DA_RESULT_OK; - req_dl_info *stage_req_info = DA_NULL; - file_info *file_storage = DA_NULL; + da_ret_t ret = DA_RESULT_OK; + size_t write_success_len = 0; + void *fd = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); + // DA_LOGV(""); - if (!stage) { - ret = DA_ERR_INVALID_ARGUMENT; + fd = file_info->file_handle; + if (DA_NULL == fd) { + DA_LOGE("There is no file handle."); + ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } - stage_req_info = GET_STAGE_TRANSACTION_INFO(stage); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) + write_success_len = fwrite(body, sizeof(char), (size_t)body_len, + (FILE *) fd); + /* FIXME : This can be necessary later due to progressive download. + * The solution for reducing fflush is needed */ + //fflush((FILE *) fd); + if (write_success_len != (size_t)body_len) { + DA_LOGE("write fails "); + if (errno == ENOSPC) + ret = DA_ERR_DISK_FULL; + else + ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; - - if (GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info) != 0) { - GET_CONTENT_STORE_FILE_SIZE(file_storage) - = GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info); - } else { - GET_CONTENT_STORE_FILE_SIZE(file_storage) = 0; } - DA_LOG_VERBOSE(FileManager, "file size = %d", GET_CONTENT_STORE_FILE_SIZE(file_storage)); + file_info->bytes_written_to_file += write_success_len; + DA_LOGV( "write %llu bytes", write_success_len); + file_info->is_updated = DA_TRUE; + ERR: return ret; - } /* Priority to derive extension - * 1. according to MIME-Type - * 2. if MIME-Type is ambiguous or blank, - * 2-1. derived from field's "filename" attribute - * 2-2. derived from url - * 3. if url does not have extension, leave blank for extension + * 1. extension name which client set + * 2. according to MIME-Type + * 3. if MIME-Type is ambiguous or blank, + * 3-1. derived from field's "filename" attribute + * 3-2. derived from url + * 4. if url does not have extension, leave blank for extension */ -char *__derive_extension(stage_info *stage) +char *__get_extension_name(char *mime_type, + char *file_name_from_header, char *url) { - if (!stage) - return DA_NULL; - - source_info_t *source_info = GET_STAGE_SOURCE_INFO(stage); - req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage); - file_info *file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); char *extension = DA_NULL; - char *url = DA_NULL; /* Priority 1 */ - char *mime_type = DA_NULL; - mime_type = GET_CONTENT_STORE_CONTENT_TYPE(file_info_data); if (mime_type && !is_ambiguous_MIME_Type(mime_type)) { char *extension = DA_NULL; - da_result_t ret = get_extension_from_mime_type(mime_type, &extension); + da_ret_t ret = get_extension_from_mime_type(mime_type, &extension); if (ret == DA_RESULT_OK && extension) return extension; } - /* Priority 2-1 */ - http_msg_response_t *http_msg_response = DA_NULL; - http_msg_response = request_info->http_info.http_msg_response; - if (http_msg_response) { - char *file_name = DA_NULL; - da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response, - DA_NULL, &file_name); - if (b_ret && file_name) { - char *extension = DA_NULL; - DA_SECURE_LOGD("Name from Content-Disposition :[%s]", file_name); - __divide_file_name_into_pure_name_N_extesion(file_name, DA_NULL, &extension); - if (file_name) { - free(file_name); - file_name = DA_NULL; - } - if (extension) - return extension; - } + if (file_name_from_header) { + char *extension = DA_NULL; + DA_SECURE_LOGI("Content-Disposition :[%s]", file_name_from_header); + __divide_file_name_into_pure_name_N_extesion(file_name_from_header, + DA_NULL, &extension); + if (extension) + return extension; } /* Priority 2-2 */ - /* If there is location url from response header in case of redirection, - * it try to parse the extention name from the location url */ - if (GET_REQUEST_HTTP_REQ_LOCATION(request_info)) - url = GET_REQUEST_HTTP_REQ_LOCATION(request_info); - else - url = GET_SOURCE_BASIC_URL(source_info); if (url) { - DA_SECURE_LOGD("url:[%s]", url); + DA_LOGV("Get extension from url"); da_bool_t b_ret = da_get_extension_name_from_url(url, &extension); if (b_ret && extension) return extension; } - return DA_NULL; } /** Priority for deciding file name - * 1. what client wants, which is conveyed by DA_FEATURE_FILE_NAME + * 1. file name which client set * 2. 'filename' option on HTTP response header's Content-Disposition field * 3. requesting URL * 4. Otherwise, define it as "No name" */ -da_result_t __get_candidate_file_name(stage_info *stage, char **out_pure_file_name, char **out_extension) +da_ret_t __get_candidate_file_name(char *user_file_name, char *url, + char *file_name_from_header, + char **out_pure_file_name, char **out_extension) { - da_result_t ret = DA_RESULT_OK; - source_info_t *source_info = DA_NULL; - char *pure_file_name = DA_NULL; - char *extension = DA_NULL; + da_ret_t ret = DA_RESULT_OK; - DA_LOG_FUNC_LOGV(FileManager); - - if (!stage || !out_pure_file_name) - return DA_ERR_INVALID_ARGUMENT; - - source_info = GET_STAGE_SOURCE_INFO(stage); - if (!source_info) - return DA_ERR_INVALID_ARGUMENT; + DA_LOGV(""); /* Priority 1 */ - if (!pure_file_name && GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage))) { + if (user_file_name) { __divide_file_name_into_pure_name_N_extesion( - GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage)), - &pure_file_name, &extension); + user_file_name, out_pure_file_name, out_extension); } - + if (*out_pure_file_name) + return ret; /* Priority 2 */ - if (!pure_file_name) { - req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage); - http_msg_response_t *http_msg_response = DA_NULL; - http_msg_response = request_info->http_info.http_msg_response; - if (http_msg_response) { - char *file_name = DA_NULL; - da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response, - DA_NULL, &file_name); - if (b_ret && file_name) { - DA_SECURE_LOGD("Name from Content-Disposition :[%s]", file_name); - __divide_file_name_into_pure_name_N_extesion(file_name, &pure_file_name, &extension); - if (file_name) { - free(file_name); - file_name = DA_NULL; - } - } - } + if (file_name_from_header) { + DA_SECURE_LOGI("Content-Disposition:[%s]", file_name_from_header); + __divide_file_name_into_pure_name_N_extesion(file_name_from_header, + out_pure_file_name, DA_NULL); } - + if (*out_pure_file_name) + return ret ; /* Priority 3 */ - if (!pure_file_name) { - char *url = DA_NULL; - req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage); - /* If there is location url from response header in case of redirection, - * it try to parse the file name from the location url */ - if (GET_REQUEST_HTTP_REQ_LOCATION(request_info)) - url = GET_REQUEST_HTTP_REQ_LOCATION(request_info); - else - url = GET_SOURCE_BASIC_URL(source_info); - if (url) { - DA_SECURE_LOGD("url: [%s]", url); - da_get_file_name_from_url(url, &pure_file_name); - } + if (url) { + DA_LOGV("Get file name from url"); + da_get_file_name_from_url(url, out_pure_file_name); } - + if (*out_pure_file_name) + return ret ; /* Priority 4 */ - if (!pure_file_name) { - pure_file_name = strdup(NO_NAME_TEMP_STR); - if (!pure_file_name) { - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - } - - *out_pure_file_name = pure_file_name; - pure_file_name = DA_NULL; - DA_SECURE_LOGD("candidate file name [%s]", *out_pure_file_name); - - if (out_extension) { - if (extension) { - *out_extension = extension; - extension = DA_NULL; - } else { - *out_extension = __derive_extension(stage); - DA_SECURE_LOGD("candidate extension [%s]", *out_extension); - } - } - - if (extension) - free(extension); - - return DA_RESULT_OK; - -ERR: - if (extension) - free(extension); - + *out_pure_file_name = strdup(NO_NAME_TEMP_STR); + if (*out_pure_file_name == DA_NULL) + ret = DA_ERR_FAIL_TO_MEMALLOC; return ret; } -da_result_t __decide_file_path(stage_info *stage) +da_ret_t __decide_file_path(da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; - char *temp_dir = DA_NULL; + da_ret_t ret = DA_RESULT_OK; char *extension = DA_NULL; - char *file_name_without_extension = DA_NULL; + char *file_name = DA_NULL; char *tmp_file_path = DA_NULL; - char *user_install_path = DA_NULL; - file_info *file_info_data = DA_NULL; - int len = 0; - DA_LOG_FUNC_LOGV(FileManager); - - file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_info_data) - return DA_ERR_INVALID_ARGUMENT; - + char *install_dir = DA_DEFAULT_INSTALL_PATH_FOR_PHONE; + char *user_file_name = DA_NULL; + char *file_name_from_header = DA_NULL; + char *url = DA_NULL; + file_info_t *file_info = DA_NULL; + req_info_t *req_info = DA_NULL; + http_info_t *http_info = DA_NULL; + + DA_LOGV(""); + + NULL_CHECK_RET(da_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + + if (req_info->install_path) + install_dir = req_info->install_path; + user_file_name = req_info->file_name; + /* If there is location url from response header in case of redirection, + * it try to parse the file name from the location url */ + if (http_info->location_url) { + url = http_info->location_url; + DA_LOGI("[TEST] location_url[%s][%p]",http_info->location_url, http_info->location_url); + } else + url = req_info->url; + + file_name_from_header = http_info->file_name_from_header; + + /* extension is extracted only if User set specific name */ + ret = __get_candidate_file_name(user_file_name, url, file_name_from_header, + &file_name, &extension); + if (ret != DA_RESULT_OK) + goto ERR; - /* If the installed path which user want is set, the temporary directory is same to the installation directory. - * Otherwise, the default temporary directory is used. - */ - user_install_path = GET_DL_USER_INSTALL_PATH(GET_STAGE_DL_ID(stage)); - if (user_install_path) { - len = strlen(user_install_path); - temp_dir = (char *)calloc(len + 1, sizeof(char)); - if (!temp_dir) { + if (file_name && strpbrk(file_name, DA_INVALID_PATH_STRING) != NULL) { + DA_LOGI("Invalid string at file name"); + free(file_name); + file_name = strdup(NO_NAME_TEMP_STR); + if (!file_name) { ret = DA_ERR_FAIL_TO_MEMALLOC; goto ERR; } - memcpy(temp_dir, user_install_path, len); - temp_dir[len] = '\0'; - } else { - ret = get_default_install_dir(&temp_dir); - if (DA_RESULT_OK != ret || DA_NULL == temp_dir) { - goto ERR; - } } - ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension); - if (ret != DA_RESULT_OK) - goto ERR; + DA_SECURE_LOGI("candidate file name [%s]", file_name); + + if (!extension) { + extension = __get_extension_name(file_info->mime_type, + file_name_from_header, url); + } + if (file_name && !file_info->pure_file_name) { + file_info->pure_file_name = file_name; + file_name = DA_NULL; + } + if (extension && !file_info->extension) { + DA_LOGV("candidate extension [%s]", extension); + file_info->extension = extension; + extension = DA_NULL; + } // for resume - tmp_file_path = get_full_path_avoided_duplication(temp_dir, file_name_without_extension, extension); + tmp_file_path = get_full_path_avoided_duplication(install_dir, + file_info->pure_file_name, file_info->extension); if (tmp_file_path) { - GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)) - = tmp_file_path; + file_info->file_path = tmp_file_path; tmp_file_path = DA_NULL; } else { ret = DA_ERR_FAIL_TO_ACCESS_FILE; goto ERR; } - if (file_name_without_extension && !GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data)) { - GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data) = file_name_without_extension; - file_name_without_extension = DA_NULL; - } +ERR: + DA_SECURE_LOGI("decided file path [%s]", file_info->file_path); + free(file_name); + free(extension); + return ret; +} - if (extension && !GET_CONTENT_STORE_EXTENSION(file_info_data)) { - GET_CONTENT_STORE_EXTENSION(file_info_data) = extension; - extension = DA_NULL; +// for resume with new download request +da_ret_t __decide_file_path_for_resume(file_info_t *file_info) +{ + da_ret_t ret = DA_RESULT_OK; + char *extension = DA_NULL; + char *file_name = DA_NULL; + char *file_path = DA_NULL; + char *ptr = DA_NULL; + char *ptr2 = DA_NULL; + + DA_LOGV(""); + + NULL_CHECK_RET(file_info); + + file_path = file_info->file_path; + ptr = strrchr(file_path, '/'); + if (ptr) { + ptr++; + ptr2 = strrchr(ptr, '.'); + if (ptr2) { + int len = 0; + len = ptr2 - ptr; + ptr2++; + extension = strdup(ptr2); + file_name = calloc(1, len + 1); + if (file_name) + snprintf(file_name, len + 1, "%s", ptr); + } else { + file_name = strdup(ptr); + } } -ERR: - DA_SECURE_LOGI("decided file path = %s", GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data)); - if (temp_dir) { - free(temp_dir); - temp_dir = DA_NULL; - } - if (file_name_without_extension) { - free(file_name_without_extension); - file_name_without_extension = DA_NULL; + if (file_name && !file_info->pure_file_name) { + file_info->pure_file_name = file_name; + file_name = DA_NULL; + } else { + free(file_name); } - if (extension) { - free(extension); + if (extension && !file_info->extension) { + DA_LOGV( "candidate extension [%s]", extension); + file_info->extension = extension; extension = DA_NULL; + } else { + free(extension); } return ret; } -char *get_full_path_avoided_duplication(char *in_dir, char *in_candidate_file_name, char *in_extension) +da_ret_t start_file_writing(da_info_t *da_info) { - char *dir = in_dir; - char *file_name = in_candidate_file_name; - char *extension = in_extension; - char *final_path = DA_NULL; - - int final_path_len = 0; - int extension_len = 0; + da_ret_t ret = DA_RESULT_OK; + file_info_t *file_info = DA_NULL; + req_info_t *req_info = DA_NULL; + + DA_LOGV(""); + + NULL_CHECK_RET(da_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + + /* resume case */ + if (req_info->etag || req_info->temp_file_path) { + char *file_path = DA_NULL; + char *origin_path = DA_NULL; + file_path = req_info->temp_file_path; + if (!file_path) + return DA_ERR_INVALID_ARGUMENT; + origin_path = file_info->file_path; + file_info->file_path = strdup(file_path); + free(origin_path); + ret = __decide_file_path_for_resume(file_info); + } else { + ret = __decide_file_path(da_info); + } - int suffix_count = 0; /* means suffix on file name. up to "_1000000000" */ - const int max_suffix_count = 1000000000; - int suffix_len = (int)log10(max_suffix_count+1) + 1; /* 1 means "_" */ + if (ret != DA_RESULT_OK) + goto ERR; - if (!in_dir || !in_candidate_file_name) - return DA_NULL; - -// DA_SECURE_LOGD("in_candidate_file_name=[%s], in_extension=[%s]", in_candidate_file_name, in_extension); - - if (extension) - extension_len = strlen(extension); - - /* first 1 for "/", second 1 for ".", last 1 for DA_NULL */ - final_path_len = strlen(dir) + 1 + strlen(file_name) + 1 - + suffix_len + extension_len + 1; - - final_path = (char*)calloc(1, final_path_len); - if (!final_path) { - DA_LOG_ERR(FileManager, "DA_ERR_FAIL_TO_MEMALLOC"); - return DA_NULL; - } - - do { - /* e.g) /tmp/abc.jpg - * if there is no extension name, just make a file name without extension */ - if (0 == extension_len) { - if (suffix_count == 0) { - snprintf(final_path, final_path_len, - "%s/%s", dir, file_name); - } else { - snprintf(final_path, final_path_len, - "%s/%s_%d", dir, file_name, suffix_count); - } - } else { - if (suffix_count == 0) { - snprintf(final_path, final_path_len, - "%s/%s.%s", dir, file_name, extension); - } else { - snprintf(final_path, final_path_len, - "%s/%s_%d.%s", - dir, file_name, suffix_count, extension); - } - } - - if (is_file_exist(final_path)) { - suffix_count++; - if (suffix_count > max_suffix_count) { - free(final_path); - final_path = DA_NULL; - break; - } else { - memset(final_path, 0x00, final_path_len); - continue; - } - } - - break; - } while (1); - -// DA_SECURE_LOGD("decided path = [%s]", final_path); - return final_path; -} - -da_result_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_name, char **out_pure_file_name, char **out_extension) -{ - char *file_name = DA_NULL; - char *tmp_ptr = DA_NULL; - char temp_file[DA_MAX_FILE_PATH_LEN] = {0,}; - char tmp_ext[DA_MAX_STR_LEN] = {0,}; - int len = 0; - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGD(FileManager); - - if (!in_file_name) - return DA_ERR_INVALID_ARGUMENT; - - file_name = (char *)in_file_name; - tmp_ptr = strrchr(file_name, '.'); - if (tmp_ptr) - tmp_ptr++; - if (tmp_ptr && out_extension) { - strncpy((char*) tmp_ext, tmp_ptr, sizeof(tmp_ext) - 1); - *out_extension = strdup((const char*) tmp_ext); - DA_SECURE_LOGD("extension [%s]", *out_extension); - } - - if (!out_pure_file_name) - return ret; - - if (tmp_ptr) - len = tmp_ptr - file_name - 1; - else - len = strlen(file_name); - - if (len >= DA_MAX_FILE_PATH_LEN) { - strncpy((char*) temp_file, file_name, - DA_MAX_FILE_PATH_LEN - 1); - } else { - strncpy((char*) temp_file, file_name, len); - } - - delete_prohibited_char((char*) temp_file, - strlen((char*) temp_file)); - if (strlen(temp_file) < 1) { - *out_pure_file_name = strdup(NO_NAME_TEMP_STR); - } else { - *out_pure_file_name = strdup( - (const char*) temp_file); - } - - DA_SECURE_LOGD("pure file name [%s]", *out_pure_file_name); - return ret; -} - -da_result_t __file_write_buf_make_buf(file_info *file_storage) -{ - da_result_t ret = DA_RESULT_OK; - char *buffer = DA_NULL; - - DA_LOG_FUNC_LOGV(FileManager); - - buffer = (char*) calloc(DOWNLOAD_NOTIFY_LIMIT, 1); - if (DA_NULL == buffer) { - DA_LOG_ERR(FileManager, "Calloc failure "); - ret = DA_ERR_FAIL_TO_MEMALLOC; + if (req_info->etag || req_info->temp_file_path) { + da_size_t file_size = 0; + get_file_size(req_info->temp_file_path, &file_size); + if (file_size < 1) + goto ERR; +#ifdef _RAF_SUPPORT + file_info->file_size_of_temp_file = file_size; +#endif + file_info->bytes_written_to_file = file_size; } else { - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; - GET_CONTENT_STORE_FILE_BUFFER(file_storage) = buffer; + file_info->bytes_written_to_file = 0; } - - return ret; -} - -da_result_t __file_write_buf_destroy_buf(file_info *file_storage) -{ - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGV(FileManager); - - if (GET_CONTENT_STORE_FILE_BUFFER(file_storage)) - free(GET_CONTENT_STORE_FILE_BUFFER(file_storage)); - - GET_CONTENT_STORE_FILE_BUFFER(file_storage) = DA_NULL; - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; - - return ret; -} - -da_result_t __file_write_buf_flush_buf(stage_info *stage, file_info *file_storage) -{ - da_result_t ret = DA_RESULT_OK; - char *buffer = DA_NULL; - int buffer_size = 0; - int write_success_len = 0; - void *fd = DA_NULL; - - DA_LOG_FUNC_LOGV(FileManager); - - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); - - if (buffer_size == 0) { - DA_LOG_ERR(FileManager, "no data on buffer.."); - return ret; - } - - fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage); - if (DA_NULL == fd) { - DA_LOG_ERR(FileManager, "There is no file handle."); - - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; - } - write_success_len = fwrite(buffer, sizeof(char), buffer_size, - (FILE *) fd); - /* FIXME : This can be necessary later due to progressive download. - * The solution for reducing fflush is needed */ - //fflush((FILE *) fd); - if (write_success_len != buffer_size) { - DA_LOG_ERR(FileManager, "write fails "); - if (errno == ENOSPC) - ret = DA_ERR_DISK_FULL; - else - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; - } - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - += write_success_len; - DA_LOG_VERBOSE(FileManager, "write %d bytes", write_success_len); - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE; - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; - + ret = __saved_file_open(file_info); ERR: return ret; } -da_result_t __file_write_buf_copy_to_buf(file_info *file_storage, char *body, - int body_len) -{ - da_result_t ret = DA_RESULT_OK; - char *buffer = DA_NULL; - int buffer_size = 0; - - DA_LOG_FUNC_LOGV(FileManager); - - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); - - memcpy(buffer + buffer_size, body, body_len); - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) += body_len; - - return ret; -} - -da_result_t __file_write_buf_directly_write(stage_info *stage, - file_info *file_storage, char *body, int body_len) +da_ret_t start_file_append(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - int write_success_len = 0; - void *fd = DA_NULL; - - DA_LOG_FUNC_LOGV(FileManager); + da_ret_t ret = DA_RESULT_OK; - fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage); - if (DA_NULL == fd) { - DA_LOG_ERR(FileManager, "There is no file handle."); + DA_LOGV(""); - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; - } - write_success_len = fwrite(body, sizeof(char), body_len, - (FILE *) fd); - /* FIXME : This can be necessary later due to progressive download. - * The solution for reducing fflush is needed */ - //fflush((FILE *) fd); - if (write_success_len != body_len) { - DA_LOG_ERR(FileManager, "write fails "); - if (errno == ENOSPC) - ret = DA_ERR_DISK_FULL; - else - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; - } - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - += write_success_len; - DA_LOG(FileManager, "write %d bytes", write_success_len); - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE; + NULL_CHECK_RET(file_info); -ERR: + ret = __saved_file_open(file_info); return ret; } -da_result_t file_write_ongoing(stage_info *stage, char *body, int body_len) +da_ret_t file_write_ongoing(file_info_t *file_info, char *body, int body_len) { - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; + da_ret_t ret = DA_RESULT_OK; int buffer_size = 0; char *buffer = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) { - DA_LOG_ERR(FileManager, "file_info is empty."); - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; - } + DA_LOGV(""); - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_FALSE; + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; if (DA_NULL == buffer) { - if (body_len < DOWNLOAD_NOTIFY_LIMIT) { - ret = __file_write_buf_make_buf(file_storage); + if (body_len < DA_FILE_BUF_SIZE) { + ret = __file_write_buf_make_buf(file_info); if (ret != DA_RESULT_OK) goto ERR; - - __file_write_buf_copy_to_buf(file_storage, body, body_len); + __file_write_buf_copy_to_buf(file_info, body, body_len); } else { - ret = __file_write_buf_directly_write(stage, - file_storage, body, body_len); + ret = __file_write_buf_directly_write(file_info, + body, body_len); if (ret != DA_RESULT_OK) goto ERR; } } else { - if (DOWNLOAD_NOTIFY_LIMIT <= body_len) { - ret = __file_write_buf_flush_buf(stage, file_storage); + if (DA_FILE_BUF_SIZE <= body_len) { + ret = __file_write_buf_flush_buf(file_info); if (ret != DA_RESULT_OK) goto ERR; - - ret = __file_write_buf_directly_write(stage, - file_storage, body, body_len); + ret = __file_write_buf_directly_write(file_info, + body, body_len); if (ret != DA_RESULT_OK) goto ERR; - - } else if ((DOWNLOAD_NOTIFY_LIMIT - buffer_size) <= body_len) { - ret = __file_write_buf_flush_buf(stage, file_storage); + } else if ((DA_FILE_BUF_SIZE - buffer_size) <= body_len) { + ret = __file_write_buf_flush_buf(file_info); if (ret != DA_RESULT_OK) goto ERR; - - __file_write_buf_copy_to_buf(file_storage, body, body_len); + __file_write_buf_copy_to_buf(file_info, body, body_len); } else { - __file_write_buf_copy_to_buf(file_storage, body, body_len); + __file_write_buf_copy_to_buf(file_info, body, body_len); } } - ERR: if (ret != DA_RESULT_OK) { - if (file_storage) { - GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0; - if (GET_CONTENT_STORE_FILE_BUFFER(file_storage)) { - free( - GET_CONTENT_STORE_FILE_BUFFER(file_storage)); - GET_CONTENT_STORE_FILE_BUFFER(file_storage) - = DA_NULL; - } - } + file_info->buffer_len = 0; + free(file_info->buffer); + file_info->buffer = DA_NULL; } return ret; } -da_result_t file_write_complete(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - file_info*file_storage = DA_NULL; +#ifdef _RAF_SUPPORT +da_ret_t file_write_complete_for_raf(file_info_t *file_info) { + da_ret_t ret = DA_RESULT_OK; char *buffer = DA_NULL; - unsigned int buffer_size = 0; + da_size_t wrriten_size = 0; + da_size_t file_size = 0; void *fd = DA_NULL; - DA_LOG_FUNC_LOGV(FileManager); + DA_LOGV(""); + fd = file_info->file_handle; - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) { - DA_LOG_ERR(FileManager, "file_info is DA_NULL."); - ret = DA_ERR_FAIL_TO_ACCESS_FILE; - goto ERR; + wrriten_size = file_info->bytes_written_to_file; + // test code + get_file_size(file_info->file_path, &file_size); + DA_LOGI("wrriten_size:%llu file_size:%llu file[%s]", + wrriten_size, file_size, file_info->file_path); + if (fd) { + fclose(fd); + fd = DA_NULL; + } + file_info->file_handle = DA_NULL; + if (wrriten_size < file_size) { + DA_LOGD("Try truncate"); + if (truncate(file_info->file_path, wrriten_size) < 0) { + DA_LOGE("Fail to ftruncate: errno[%d,%s]", errno, strerror(errno)); + } + DA_LOGD("Try truncate done"); } - buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage); - buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage); + ERR: + return ret; +} +#endif + +da_ret_t file_write_complete(file_info_t *file_info) +{ + da_ret_t ret = DA_RESULT_OK; + char *buffer = DA_NULL; + unsigned int buffer_size = 0; + void *fd = DA_NULL; + + DA_LOGV(""); + + buffer = file_info->buffer; + buffer_size = file_info->buffer_len; if (DA_NULL == buffer) { - DA_LOG_ERR(FileManager, "file buffer is DA_NULL"); + DA_LOGE("file buffer is NULL"); } else { if (buffer_size != 0) { - ret = __file_write_buf_flush_buf(stage, file_storage); + ret = __file_write_buf_flush_buf(file_info); if (ret != DA_RESULT_OK) goto ERR; } - __file_write_buf_destroy_buf(file_storage); + __file_write_buf_destroy_buf(file_info); } - fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage); + fd = file_info->file_handle; if (fd) { fclose(fd); fd = DA_NULL; } - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL; + file_info->file_handle = DA_NULL; ERR: return ret; } -da_result_t start_file_writing(stage_info *stage) +da_ret_t discard_download(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - file_info *file_info_data = DA_NULL; - - DA_LOG_FUNC_LOGV(FileManager); - - file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); - ret = get_mime_type(stage, - &GET_CONTENT_STORE_CONTENT_TYPE(file_info_data)); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = __decide_file_path(stage); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = __set_file_size(stage); - if (DA_RESULT_OK != ret) - goto ERR; - - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - = 0; + da_ret_t ret = DA_RESULT_OK; + FILE *f_handle = DA_NULL; - ret = __saved_file_open(stage); + DA_LOGV(""); -ERR: + f_handle = file_info->file_handle; + if (f_handle) { + fclose(f_handle); + file_info->file_handle = DA_NULL; + } return ret; } - -da_result_t start_file_writing_append(stage_info *stage) +void clean_paused_file(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; + char *paused_file_path = DA_NULL; + FILE *fd = DA_NULL; - DA_LOG_FUNC_LOGD(FileManager); + DA_LOGV(""); + + fd = file_info->file_handle; + if (fd) { + fclose(fd); + file_info->file_handle = DA_NULL; + } - ret = __saved_file_open(stage); + paused_file_path = file_info->file_path; + file_info->bytes_written_to_file = 0; // Ignore resume flow after failed or cancled. + remove_file((const char*) paused_file_path); - return ret; + return; } -// for resume with new download request -da_result_t start_file_writing_append_with_new_download(stage_info *stage) +da_bool_t is_file_exist(const char *file_path) { - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; - char *original_file_path = DA_NULL; - char *temp_file_path = DA_NULL; - char *extension = DA_NULL; - char *file_name_without_extension = DA_NULL; - req_dl_info *request_info = DA_NULL; - unsigned long long temp_file_size = 0; - - DA_LOG_FUNC_LOGD(FileManager); - - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); - if (!file_storage) - return DA_ERR_INVALID_ARGUMENT; - request_info = GET_STAGE_TRANSACTION_INFO(stage); - if (!request_info) - return DA_ERR_INVALID_ARGUMENT; - temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(request_info); - if (!temp_file_path) - return DA_ERR_INVALID_ARGUMENT; - original_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage); - - GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage) = strdup(temp_file_path); - - if (original_file_path) - free(original_file_path); - - ret = get_mime_type(stage, - &GET_CONTENT_STORE_CONTENT_TYPE(file_storage)); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension); - if (ret != DA_RESULT_OK) - goto ERR; + struct stat dir_state; + int stat_ret; - if (file_name_without_extension) { - if (!GET_CONTENT_STORE_PURE_FILE_NAME(file_storage)) { - GET_CONTENT_STORE_PURE_FILE_NAME(file_storage) = file_name_without_extension; - file_name_without_extension = DA_NULL; - } else { - free(file_name_without_extension); - file_name_without_extension = DA_NULL; - } + if (file_path == DA_NULL) { + DA_LOGE("file path is DA_NULL"); + return DA_FALSE; } - - if (extension) { - if (!GET_CONTENT_STORE_EXTENSION(file_storage)) { - GET_CONTENT_STORE_EXTENSION(file_storage) = extension; - extension = DA_NULL; - } else { - free(extension); - extension = DA_NULL; + stat_ret = stat(file_path, &dir_state); + if (stat_ret == 0) { + if (dir_state.st_mode & S_IFREG) { + //DA_SECURE_LOGD("Exist! %s is a regular file & its size = %lu", file_path, dir_state.st_size); + return DA_TRUE; } - } - - ret = __set_file_size(stage); - if (DA_RESULT_OK != ret) - goto ERR; - get_file_size(temp_file_path, &temp_file_size); - if (temp_file_size < 1) - goto ERR; - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - = temp_file_size; - - ret = __saved_file_open(stage); - return ret; -ERR: - if (file_name_without_extension) { - free(file_name_without_extension); - file_name_without_extension = DA_NULL; + return DA_FALSE; } + return DA_FALSE; - if (extension) { - free(extension); - extension = DA_NULL; - } - return ret; } -da_result_t discard_download(stage_info *stage) +void get_file_size(char *file_path, da_size_t *out_file_size) { - da_result_t ret = DA_RESULT_OK; - file_info *file_storage = DA_NULL; - FILE *f_handle = DA_NULL; - - DA_LOG_FUNC_LOGD(FileManager); + struct stat dir_state; + int stat_ret; - file_storage = GET_STAGE_CONTENT_STORE_INFO(stage); + *out_file_size = -1; - f_handle = GET_CONTENT_STORE_FILE_HANDLE(file_storage); - if (f_handle) { - fclose(f_handle); - GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL; + if (file_path == DA_NULL) { + DA_LOGE("file path is DA_NULL"); + return; } - return ret; + /* Please do not use ftell() to obtain file size, use stat instead. + * This is a guide from www.securecoding.cert.org + * : FIO19-C. Do not use fseek() and ftell() to compute the size of a file + */ + stat_ret = stat(file_path, &dir_state); + if (stat_ret == 0) { + if (dir_state.st_mode & S_IFREG) { + DA_LOGV( "size = %lu", dir_state.st_size); + *out_file_size = dir_state.st_size; + } + } + return; } -void clean_paused_file(stage_info *stage) +char *get_full_path_avoided_duplication(char *in_dir, + char *in_candidate_file_name, char *in_extension) { - file_info *file_info_data = DA_NULL; - char *paused_file_path = DA_NULL; - FILE *fd = DA_NULL; - - DA_LOG_FUNC_LOGD(FileManager); - - file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); + char *dir = in_dir; + char *file_name = in_candidate_file_name; + char *extension = in_extension; + char *final_path = DA_NULL; - fd = GET_CONTENT_STORE_FILE_HANDLE(file_info_data); - if (fd) { - fclose(fd); - GET_CONTENT_STORE_FILE_HANDLE(file_info_data) = DA_NULL; - } + int dir_path_len = 0; + int final_path_len = 0; + int extension_len = 0; - paused_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data); - remove_file((const char*) paused_file_path); + int suffix_count = 0; /* means suffix on file name. up to "_99" */ + int suffix_len = (int)log10(MAX_SUFFIX_COUNT + 1) + 1; /* 1 means "_" */ - return; -} + if (!in_dir || !in_candidate_file_name) + return DA_NULL; -da_result_t replace_content_file_in_stage(stage_info *stage, - const char *dest_dd_file_path) -{ - da_result_t ret = DA_RESULT_OK; - char *dd_file_path = DA_NULL; - int len; + //DA_SECURE_LOGI("in_candidate_file_name=[%s],in_extension=[%s]", + //in_candidate_file_name, in_extension); - DA_LOG_FUNC_LOGD(FileManager); + if (extension) + extension_len = strlen(extension); - if (!dest_dd_file_path - && (DA_FALSE == is_file_exist(dest_dd_file_path))) { - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; + // to remove trailing slash from dir path + dir_path_len = strlen(dir); + if (dir[dir_path_len - 1] == '/') { + dir[dir_path_len - 1] = '\0'; + --dir_path_len; } - dd_file_path - =GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)); + /* first 1 for "/", second 1 for ".", last 1 for DA_NULL */ + final_path_len = dir_path_len + 1 + strlen(file_name) + 1 + + suffix_len + extension_len + 1; - if (DA_NULL != dd_file_path) { - remove_file((const char*) dd_file_path); - free(dd_file_path); - } - len = strlen(dest_dd_file_path); - dd_file_path = calloc(1, len + 1); - if (!dd_file_path) { - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; + final_path = (char*)calloc(1, final_path_len); + if (!final_path) { + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); + return DA_NULL; } - strncpy(dd_file_path, dest_dd_file_path, len); - GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)) - = dd_file_path; -ERR: - return ret; + do { + /* e.g) /tmp/abc.jpg + * if there is no extension name, just make a file name without extension */ + if (0 == extension_len) { + if (suffix_count == 0) { + snprintf(final_path, final_path_len, + "%s/%s", dir, file_name); + } else { + snprintf(final_path, final_path_len, + "%s/%s_%d", dir, file_name, suffix_count); + } + } else { + if (suffix_count == 0) { + snprintf(final_path, final_path_len, + "%s/%s.%s", dir, file_name, extension); + } else { + snprintf(final_path, final_path_len, + "%s/%s_%d.%s", + dir, file_name, suffix_count, extension); + } + } + if (is_file_exist(final_path)) { + suffix_count++; + if (suffix_count > MAX_SUFFIX_COUNT) { + free(final_path); + final_path = DA_NULL; + break; + } else { + memset(final_path, 0x00, final_path_len); + continue; + } + } + break; + } while (1); + //DA_SECURE_LOGD("decided path = [%s]", final_path); + return final_path; } -da_result_t copy_file(const char *src, const char *dest) -{ - FILE *fs = DA_NULL; - FILE *fd = DA_NULL; - int freadnum = 0; - int fwritenum = 0; - char buff[4096] = { 0, }; - DA_LOG_FUNC_LOGD(FileManager); +da_ret_t check_drm_convert(file_info_t *file_info) +{ + da_ret_t ret = DA_RESULT_OK; + da_bool_t ret_b = DA_TRUE; - /* open files to copy */ - fs = fopen(src, "rb"); - if (!fs) { - DA_LOG_ERR(FileManager, "Fail to open src file"); - return DA_ERR_FAIL_TO_ACCESS_FILE; - } + DA_LOGD(""); - fd = fopen(dest, "wb"); - if (!fd) { - DA_LOG_ERR(FileManager, "Fail to open dest file"); + NULL_CHECK_RET(file_info); - fclose(fs); - return DA_ERR_FAIL_TO_ACCESS_FILE; - } +#ifdef _ENABLE_OMA_DRM - /* actual copy */ - while (!feof(fs)) { - memset(buff, 0x00, 4096); - freadnum = fread(buff, sizeof(char), sizeof(buff), fs); - if (freadnum > 0) { - fwritenum = fwrite(buff, sizeof(char), freadnum, fd); - if (fwritenum <= 0) { - DA_LOG(FileManager, "written = %d",fwritenum); - break; - } - } else { - DA_LOG(FileManager, "read = %d",freadnum); - break; - } + /* In case of OMA DRM 1.0 SD, it is not necessary to call DRM convert API. + * Because it is already converted itself. + * And, the case will return fail because The SD is not supported now. + */ + if (is_content_drm_dcf(file_info->mime_type)) { + DA_LOGI("DRM SD case"); + unlink(file_info->file_path); + free(file_info->file_path); + file_info->file_path = DA_NULL; + return DA_ERR_DRM_FAIL; + } + if (is_content_drm_dm(file_info->mime_type)) { + char *actual_file_path = DA_NULL; + char *out_file_path = DA_NULL; + + actual_file_path = file_info->file_path; + DA_SECURE_LOGD("actual_file_path = %s", actual_file_path); + if (!actual_file_path) + return DA_ERR_INVALID_ARGUMENT; + ret_b = EDRM_convert(actual_file_path, &out_file_path); + unlink(actual_file_path); + free(actual_file_path); + if (!ret_b) + ret = DA_ERR_DRM_FAIL; + file_info->file_path = out_file_path; + } else { + return ret; } +#endif - fclose(fd); - fclose(fs); - - return DA_RESULT_OK; + return ret; } -da_result_t create_dir(const char *install_dir) +void remove_file(const char *file_path) { - da_result_t ret = DA_RESULT_OK; - /* read/write/search permissions for owner and group, - * and with read/search permissions for others. */ - if (mkdir(install_dir, S_IRWXU | S_IRWXG | S_IRWXO)) { - DA_LOG_ERR(FileManager, "Fail to creaate directory"); - ret = DA_ERR_FAIL_TO_ACCESS_STORAGE; - } else { - DA_SECURE_LOGD("[%s] is created!", install_dir); - if (chown(install_dir, 5000, 5000) < 0) { - DA_LOG_ERR(FileManager, "Fail to chown"); - ret = DA_ERR_FAIL_TO_ACCESS_STORAGE; + DA_LOGV(""); + + if (file_path && is_file_exist(file_path)) { + DA_SECURE_LOGD("remove file [%s]", file_path); + if (unlink(file_path) < 0) { + DA_LOGE("file removing failed."); } } - return ret; } -da_result_t get_default_install_dir(char **out_path) +da_ret_t get_available_memory(char *dir_path, da_size_t len) { - char *default_path = DA_NULL; - da_result_t ret = DA_RESULT_OK; - int len = 0; + da_ret_t ret = DA_RESULT_OK; + int fs_ret = 0; + //struct statfs filesys_info = {0, }; + struct statvfs filesys_info; - if (!out_path) { - DA_LOG_ERR(ClientNoti, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } + DA_LOGV(""); + + if (!dir_path) + return DA_ERR_INVALID_INSTALL_PATH; - len = strlen(DA_DEFAULT_INSTALL_PATH_FOR_PHONE); + //fs_ret = statfs(dir_path, &filesys_info); + // Using this as it considers FOTA memory while returning available memory + fs_ret = storage_get_internal_memory_size(&filesys_info); - default_path = calloc(len + 1, sizeof(char)); - if (!default_path) { - return DA_ERR_FAIL_TO_MEMALLOC; + if (fs_ret != 0) { + // DA_LOGE("statfs error[%s]", strerror(errno)); + return DA_ERR_INVALID_ARGUMENT; + // return DA_ERR_INVALID_INSTALL_PATH; } - memcpy(default_path, DA_DEFAULT_INSTALL_PATH_FOR_PHONE, len); - default_path[len] = '\0'; + double available_size = (double)filesys_info.f_bsize * filesys_info.f_bavail; + double total_size = (double)filesys_info.f_frsize * filesys_info.f_blocks; + DA_SECURE_LOGI(" total = %lf ", total_size); + DA_SECURE_LOGI(" available = %lf ",available_size); - *out_path = default_path; + DA_LOGV("Available Memory(f_bavail) : %lu", filesys_info.f_bavail); + DA_LOGV("Available Memory(f_bsize) : %d", filesys_info.f_bsize); + DA_LOGD("Available Memory(kbytes) : %d", (filesys_info.f_bavail/1024)*filesys_info.f_bsize); + DA_LOGV("Content: %llu", len); + if (available_size < (len + + SAVE_FILE_BUFFERING_SIZE_50KB)) /* 50KB buffering */ + ret = DA_ERR_DISK_FULL; - if (!is_dir_exist(default_path)) { - ret = create_dir(default_path); - } - DA_SECURE_LOGD("default temp path = [%s]", *out_path); - return DA_RESULT_OK; + return ret; } diff --git a/agent/download-agent-http-mgr.c b/agent/download-agent-http-mgr.c index bbc69f0..3a2feb9 100755 --- a/agent/download-agent-http-mgr.c +++ b/agent/download-agent-http-mgr.c @@ -14,376 +14,200 @@ * limitations under the License. */ -#include "download-agent-utils.h" -#include "download-agent-debug.h" +#include +#include +#include +#include + +#include "download-agent-dl-info.h" +#include "download-agent-file.h" +#include "download-agent-mime-util.h" #include "download-agent-client-mgr.h" -#include "download-agent-http-mgr.h" -#include "download-agent-http-misc.h" #include "download-agent-http-msg-handler.h" -#include "download-agent-file.h" #include "download-agent-plugin-conf.h" -#include "download-agent-plugin-http-interface.h" - -da_result_t make_default_http_request_hdr(const char *url, - char **user_request_header, - int user_request_heaer_count, - http_msg_request_t **out_http_msg_request, - char *user_request_etag, - char *user_request_temp_file_path); -da_result_t create_resume_http_request_hdr(stage_info *stage, - http_msg_request_t **out_resume_request); - -da_result_t start_new_transaction(stage_info *stage); -da_result_t set_http_request_hdr(stage_info *stage); -da_result_t make_transaction_info_and_start_transaction(stage_info *stage); - -da_result_t pause_for_flow_control(stage_info *stage); -da_result_t unpause_for_flow_control(stage_info *stage); - -da_result_t handle_any_input(stage_info *stage); -da_result_t handle_event_control(stage_info *stage, q_event_t *event); -da_result_t handle_event_http(stage_info *stage, q_event_t *event); -da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event); -da_result_t handle_event_http_final(stage_info *stage, q_event_t *event); -da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event); - -da_result_t exchange_url_from_header_for_redirection(stage_info *stage, - http_msg_response_t *http_msg_response); - -da_result_t handle_event_abort(stage_info *stage); -da_result_t handle_event_cancel(stage_info *stage); -da_result_t handle_event_suspend(stage_info *stage); -da_result_t handle_event_resume(stage_info *stage); -da_result_t handle_http_hdr(stage_info *stage, - http_msg_response_t *http_msg_response, int http_status); -da_result_t handle_http_status_code(stage_info *stage, - http_msg_response_t *http_msg_response, int http_status); -da_result_t handle_http_body(stage_info *stage, char *body, int body_len); - -da_result_t set_hdr_fields_on_download_info(stage_info *stage); - -da_result_t _check_content_type_is_matched(stage_info *stage); -da_result_t _check_enough_memory_for_this_download(stage_info *stage); -da_result_t _check_downloaded_file_size_is_same_with_header_content_size( - stage_info *stage); - -da_result_t _check_resume_download_is_available(stage_info *stage, - http_msg_response_t *new_http_msg_response); -da_result_t _check_this_partial_download_is_available(stage_info *stage, - http_msg_response_t *new_http_msg_response); - -da_result_t _cancel_transaction(stage_info *stage); -da_result_t _disconnect_transaction(stage_info *stage); - -void __parsing_user_request_header(char *user_request_header, - char **out_field, char **out_value); - -http_mgr_t http_mgr; - -da_result_t init_http_mgr(void) -{ - da_result_t ret = DA_RESULT_OK; +#include "download-agent-plugin-drm.h" +#include "download-agent-plugin-libcurl.h" - DA_LOG_FUNC_LOGV(HTTPManager); +void __http_update_cb(http_raw_data_t *data, void *user_param); - if (http_mgr.is_http_init == DA_FALSE) { - http_mgr.is_http_init = DA_TRUE; - ret = PI_http_init(); - } - - return ret; -} +#define CONVERT_STR(NAME) (#NAME) - -da_result_t request_to_abort_http_download(stage_info *stage) +static const char *__get_state_str(http_state_t state) { - da_result_t ret = DA_RESULT_OK; - q_event_t *q_event = DA_NULL; - - DA_LOG_FUNC_LOGD(HTTPManager); - if (!stage) { - DA_LOG_ERR(HTTPManager, "Stage is NULL. download info is already destroyed"); - return DA_ERR_INVALID_ARGUMENT; - } - - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT"); - ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_ABORT, &q_event); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(HTTPManager, "fail to make q_control_event"); - goto ERR; - } else { - DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage))); - Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), q_event); + char *str = NULL; + switch(state) { + case HTTP_STATE_READY_TO_DOWNLOAD: + str = CONVERT_STR(HTTP_STATE_READY_TO_DOWNLOAD); + break; + case HTTP_STATE_REDIRECTED: + str = CONVERT_STR(HTTP_STATE_REDIRECTED); + break; + case HTTP_STATE_DOWNLOAD_REQUESTED: + str = CONVERT_STR(HTTP_STATE_DOWNLOAD_REQUESTED); + break; + case HTTP_STATE_DOWNLOAD_STARTED: + str = CONVERT_STR(HTTP_STATE_DOWNLOAD_STARTED); + break; + case HTTP_STATE_DOWNLOADING: + str = CONVERT_STR(HTTP_STATE_DOWNLOADING); + break; + case HTTP_STATE_DOWNLOAD_FINISH: + str = CONVERT_STR(HTTP_STATE_DOWNLOAD_FINISH); + break; + case HTTP_STATE_REQUEST_CANCEL: + str = CONVERT_STR(HTTP_STATE_REQUEST_CANCEL); + break; + case HTTP_STATE_REQUEST_PAUSE: + str = CONVERT_STR(HTTP_STATE_REQUEST_PAUSE); + break; + case HTTP_STATE_REQUEST_RESUME: + str = CONVERT_STR(HTTP_STATE_REQUEST_RESUME); + break; + case HTTP_STATE_CANCELED: + str = CONVERT_STR(HTTP_STATE_CANCELED); + break; + case HTTP_STATE_FAILED: + str = CONVERT_STR(HTTP_STATE_FAILED); + break; + case HTTP_STATE_PAUSED: + str = CONVERT_STR(HTTP_STATE_PAUSED); + break; + case HTTP_STATE_RESUMED: + str = CONVERT_STR(HTTP_STATE_RESUMED); + break; + case HTTP_STATE_ABORTED: + str = CONVERT_STR(HTTP_STATE_ABORTED); + break; + case HTTP_STATE_WAIT_FOR_NET_ERR: + str = CONVERT_STR(HTTP_STATE_WAIT_FOR_NET_ERR); + break; + default: + str = "Unknown State"; + break; } - -ERR: - return ret; + return str; } -void deinit_http_mgr(void) +void __init_http_info(http_info_t *http_info) { - DA_LOG_FUNC_LOGV(HTTPManager); - - if (http_mgr.is_http_init == DA_TRUE) { - http_mgr.is_http_init = DA_FALSE; - PI_http_deinit(); - } + DA_LOGV(""); - return; + http_info->state = HTTP_STATE_READY_TO_DOWNLOAD; + http_info->update_cb = __http_update_cb; + DA_MUTEX_INIT(&(http_info->mutex_state), DA_NULL); + DA_MUTEX_INIT(&(http_info->mutex_http), DA_NULL); + DA_COND_INIT(&(http_info->cond_http), DA_NULL); } -da_result_t request_http_download(stage_info *stage) +void __parsing_user_request_header(char *user_request_header, + char **out_field, char **out_value) { - da_result_t ret = DA_RESULT_OK; - - int slot_id = DA_INVALID_ID; - http_state_t http_state = 0; - da_bool_t need_wait = DA_TRUE; - - queue_t *queue = DA_NULL; - req_dl_info *req_info = DA_NULL; - - slot_id = GET_STAGE_DL_ID(stage); - queue = GET_DL_QUEUE(slot_id); - req_info = GET_STAGE_TRANSACTION_INFO(stage); - - DA_LOG_VERBOSE(HTTPManager, "queue = %p", GET_DL_QUEUE(slot_id)); - - CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD, stage); - - do { - ret = handle_any_input(stage); - if (ret != DA_RESULT_OK) { - if (DA_RESULT_OK == GET_REQUEST_HTTP_RESULT(req_info)) { - GET_REQUEST_HTTP_RESULT(req_info) = ret; - DA_LOG_CRITICAL(HTTPManager, "setting internal error [%d]", ret); - } - _cancel_transaction(stage); - } - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG_VERBOSE(HTTPManager, "http_state = %d", http_state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - switch (http_state) { - case HTTP_STATE_READY_TO_DOWNLOAD: - ret = start_new_transaction(stage); - if (ret != DA_RESULT_OK) { - if (DA_RESULT_OK == GET_REQUEST_HTTP_RESULT(req_info)) { - GET_REQUEST_HTTP_RESULT(req_info) = ret; - DA_LOG_CRITICAL(HTTPManager, "setting internal error [%d]", ret); - } - DA_LOG(HTTPManager, "exiting with error..."); - need_wait = DA_FALSE; - break; - } + int len = 0; + char *pos = NULL; + char *temp_pos = NULL; + char *field = NULL; + char *value = NULL; - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_REQUESTED, stage); - break; + DA_LOGV(""); - case HTTP_STATE_CANCELED: - case HTTP_STATE_DOWNLOAD_FINISH: - case HTTP_STATE_ABORTED: -#ifdef PAUSE_EXIT - case HTTP_STATE_PAUSED: -#endif - DA_LOG_VERBOSE(HTTPManager, "exiting..."); - need_wait = DA_FALSE; - break; + if (!user_request_header) { + DA_LOGE("NULL CHECK!: user_request_header"); + goto ERR; + } - default: + pos = strchr(user_request_header, ':'); + if (!pos) { + DA_LOGE("Fail to parse"); + goto ERR; + } + temp_pos = (char *)user_request_header; + while (*temp_pos) + { + if (temp_pos == pos || *temp_pos == ' ') { + len = temp_pos - user_request_header; break; } - - if (need_wait == DA_TRUE) { - _da_thread_mutex_lock(&(queue->mutex_queue)); - if (DA_FALSE == GET_IS_Q_HAVING_DATA(queue)) { - unpause_for_flow_control(stage); - -// DA_LOG_VERBOSE(HTTPManager, "Waiting for input"); - Q_goto_sleep(queue); -// DA_LOG_VERBOSE(HTTPManager, "Woke up to receive new packet or control event"); - } - _da_thread_mutex_unlock (&(queue->mutex_queue)); - - } - - } while (need_wait == DA_TRUE); - - ret = GET_REQUEST_HTTP_RESULT(req_info); - DA_LOG_DEBUG(HTTPManager, "Exit request_http_download! ret[%d]slot_id[%d]", - ret, slot_id); - return ret; -} - -da_result_t request_to_cancel_http_download(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - q_event_t *q_event = DA_NULL; - - DA_LOG_FUNC_LOGD(HTTPManager); - - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL"); - ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_CANCEL, &q_event); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(HTTPManager, "fail to make q_control_event"); + temp_pos++; + } + if (len < 1) { + DA_LOGE("Wrong field name"); goto ERR; - } else { - DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage))); - Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), q_event); } - -ERR: - return ret; -} - -da_result_t request_to_suspend_http_download(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - http_state_t http_state = 0; - q_event_t *q_event = DA_NULL; - - DA_LOG_FUNC_LOGD(HTTPManager); - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG(HTTPManager, "http_state = %d", http_state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - switch (http_state) { - case HTTP_STATE_PAUSED: - case HTTP_STATE_REQUEST_PAUSE: - DA_LOG_CRITICAL(HTTPManager, "Already paused. http_state = %d", http_state); - ret = DA_ERR_ALREADY_SUSPENDED; - break; - - default: - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND"); - ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_SUSPEND, - &q_event); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(HTTPManager, "fail to make q_control_event"); - goto ERR; - } else { - DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage))); - Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), - q_event); - } - - break; + field = (char *)calloc(1, len + 1); + if (!field) { + DA_LOGE("Fail to calloc"); + goto ERR; } - -ERR: - return ret; -} - -da_result_t request_to_resume_http_download(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - http_state_t http_state = 0; - q_event_t *q_event = DA_NULL; - - DA_LOG_FUNC_LOGD(HTTPManager); - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG(HTTPManager, "[%d] http_state = %d", GET_STAGE_DL_ID(stage), http_state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - switch (http_state) { - case HTTP_STATE_PAUSED: - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME"); - ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_RESUME, - &q_event); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(HTTPManager, "fail to make q_control_event"); - goto ERR; - } else { - DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage))); - Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), - q_event); - } - - break; - - case HTTP_STATE_REQUEST_PAUSE: - DA_LOG_ERR(HTTPManager, "[%d] Fail to resume. Previous pause is not finished. http_state = %d", GET_STAGE_DL_ID(stage), http_state); - ret = DA_ERR_INVALID_STATE; - - break; - - case HTTP_STATE_RESUMED: - ret = DA_ERR_ALREADY_RESUMED; - - break; - - default: - DA_LOG_ERR(HTTPManager, "[%d] Fail to resume. This is not a paused ID. http_state = %d", GET_STAGE_DL_ID(stage), http_state); - ret = DA_ERR_INVALID_STATE; - - break; + strncpy(field, user_request_header, len); + pos++; + while (*pos) + { + if (*pos != ' ') + break; + pos++; + } + len = strlen(pos) + 1; + value = (char *)calloc(1, len + 1); + if (!value) { + DA_LOGE("Fail to calloc"); + goto ERR; } + strncpy(value, pos, len); + *out_field = field; + *out_value = value; + DA_SECURE_LOGD("field[%s], value[%s]", field, value); + return; ERR: - return ret; + if (field) { + free(field); + field = NULL; + } + return; } -da_result_t start_new_transaction(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - - ret = set_http_request_hdr(stage); - if (ret != DA_RESULT_OK) - return ret; - - ret = make_transaction_info_and_start_transaction(stage); - return ret; -} -da_result_t make_default_http_request_hdr(const char *url, - char **user_request_header, - int user_request_header_count, - http_msg_request_t **out_http_msg_request, - char *user_request_etag, - char *user_request_temp_file_path) +da_ret_t __set_http_request_hdr(req_info_t *req_info, http_info_t *http_info, file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - + da_ret_t ret = DA_RESULT_OK; http_msg_request_t *http_msg_request = NULL; char *user_agent = NULL; + int count = 0; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); - if (!url) { - DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL"); - ret = DA_ERR_INVALID_URL; - goto ERR; - } + NULL_CHECK_RET(req_info); + NULL_CHECK_RET(http_info); + NULL_CHECK_RET(file_info); + NULL_CHECK_RET_OPT(req_info->url, DA_ERR_INVALID_URL); + count = req_info->req_header_count; ret = http_msg_request_create(&http_msg_request); if (ret != DA_RESULT_OK) goto ERR; - ret = http_msg_request_set_url(http_msg_request, url); + ret = http_msg_request_set_url(http_msg_request, req_info->url); if (ret != DA_RESULT_OK) goto ERR; - user_agent = get_user_agent(); - if (user_agent) - http_msg_request_add_field(http_msg_request, HTTP_FIELD_UAGENT, - user_agent); + ret = get_user_agent_string(&user_agent); + if (user_agent && ret == DA_RESULT_OK) + http_msg_request_add_field(http_msg_request, + HTTP_FIELD_UAGENT, user_agent); + - http_msg_request_add_field(http_msg_request, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); - http_msg_request_add_field(http_msg_request, HTTP_FIELD_ACCEPT_CHARSET, "utf-8"); + http_msg_request_add_field(http_msg_request, + HTTP_FIELD_ACCEPT_LANGUAGE, "en"); + http_msg_request_add_field(http_msg_request, + HTTP_FIELD_ACCEPT_CHARSET, "utf-8"); - if (user_request_header && user_request_header_count > 0) { + if (req_info->req_header && count > 0) { int i = 0; - for (i = 0; i < user_request_header_count; i++) - { + for (i = 0; i < count; i++) { char *field = NULL; char *value = NULL; - __parsing_user_request_header(user_request_header[i], - &field, &value); + __parsing_user_request_header(req_info->req_header[i], + &field, &value); if (field && value) { http_msg_request_add_field(http_msg_request, field, value); if (field) { @@ -403,204 +227,348 @@ da_result_t make_default_http_request_hdr(const char *url, free(value); value= NULL; } - DA_LOG_ERR(HTTPManager, "Fail to parse user request header"); + DA_LOGE("Fail to parse user request header"); } } - } else - DA_LOG(HTTPManager, "no user reqeust header inserted"); - - if (user_request_etag) { + } + if (req_info->etag) { char buff[64] = {0,}; - unsigned long long size = 0; + da_size_t size = 0; http_msg_request_add_field(http_msg_request, - HTTP_FIELD_IF_RANGE, user_request_etag); - get_file_size(user_request_temp_file_path, &size); + HTTP_FIELD_IF_RANGE, req_info->etag); + get_file_size(req_info->temp_file_path, &size); +#ifdef _RAF_SUPPORT + file_info->file_size_of_temp_file = size; +#endif snprintf(buff, sizeof(buff)-1, "bytes=%llu-", size); http_msg_request_add_field(http_msg_request, - HTTP_FIELD_RANGE, buff); + HTTP_FIELD_RANGE, buff); } - *out_http_msg_request = http_msg_request; - + http_info->http_msg_request = http_msg_request; + free(user_agent); + return ret; ERR: - if (ret != DA_RESULT_OK) + if (http_msg_request) http_msg_request_destroy(&http_msg_request); - if (user_agent) - free(user_agent); + return ret; + } -da_result_t set_http_request_hdr(stage_info *stage) +da_ret_t __create_http_resume_hdr(req_info_t *req_info, http_info_t *http_info, + file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - req_dl_info *request_info = DA_NULL; - - char *url = DA_NULL; - char **user_request_header = DA_NULL; - int user_request_header_count = 0; - char *user_request_etag = DA_NULL; - char *user_request_temp_file_path = DA_NULL; - http_msg_request_t* http_msg_request = NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); + da_ret_t ret = DA_RESULT_OK; + da_bool_t b_ret = DA_FALSE; + char *value = NULL; + char temp_size_str[32] = { 0, }; + char *etag_from_response = NULL; + char *date_from_response = NULL; + http_msg_response_t *first_response = NULL; + http_msg_request_t *resume_request = NULL; + http_msg_request_t *old_request = NULL; - request_info = GET_STAGE_TRANSACTION_INFO(stage); + DA_LOGV(""); - if (DA_NULL == - (url = GET_REQUEST_HTTP_REQ_URL(request_info))) { - DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL"); - ret = DA_ERR_INVALID_URL; + first_response = http_info->http_msg_response; + if (first_response) { + b_ret = http_msg_response_get_ETag(first_response, &value); + if (b_ret) { + etag_from_response = value; + value = NULL; + DA_SECURE_LOGD("[ETag][%s]", etag_from_response); + } + b_ret = http_msg_response_get_date(first_response, &value); + if (b_ret) { + date_from_response = value; + value = NULL; + DA_LOGV("[Date][%s]", date_from_response); + } + DA_SECURE_LOGD("downloaded_size[%u]", file_info->bytes_written_to_file); + snprintf(temp_size_str, sizeof(temp_size_str), "bytes=%llu-", + file_info->bytes_written_to_file); + DA_SECURE_LOGD("size str[%s]", temp_size_str); + free(first_response); + http_info->http_msg_response = DA_NULL; + } + old_request = http_info->http_msg_request; + free(old_request); + http_info->http_msg_request = DA_NULL; + + ret = __set_http_request_hdr(req_info, http_info, file_info); + if (ret != DA_RESULT_OK) goto ERR; - } - user_request_header = GET_REQUEST_HTTP_USER_REQUEST_HEADER( - request_info); - user_request_header_count = GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT( - request_info); - user_request_etag = GET_REQUEST_HTTP_USER_REQUEST_ETAG( - request_info); - user_request_temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH( - request_info); - if (user_request_etag) { - DA_SECURE_LOGD("user_request_etag[%s]",user_request_etag); + resume_request = http_info->http_msg_request; + if (etag_from_response) { + http_msg_request_add_field(resume_request, HTTP_FIELD_IF_RANGE, + etag_from_response); } else { - DA_LOG_VERBOSE(HTTPManager, "user_request_etag is NULL"); + if (date_from_response) { + http_msg_request_add_field(resume_request, + HTTP_FIELD_IF_RANGE, date_from_response); + } } - ret = make_default_http_request_hdr(url, user_request_header, - user_request_header_count, &http_msg_request, - user_request_etag, user_request_temp_file_path); - if (ret == DA_RESULT_OK) - request_info->http_info.http_msg_request = http_msg_request; -ERR: - return ret; + if (strlen(temp_size_str) > 0) + http_msg_request_add_field(resume_request, HTTP_FIELD_RANGE, + temp_size_str); +ERR: + if (etag_from_response) { + free(etag_from_response); + etag_from_response = NULL; + } + if (date_from_response) { + free(date_from_response); + date_from_response = NULL; + } + return ret; } -da_result_t make_transaction_info_and_start_transaction(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - int slot_id = DA_INVALID_ID; - req_dl_info *request_info = DA_NULL; +da_ret_t __start_transaction(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; + http_info_t *http_info; + DA_LOGV(""); - input_for_tranx_t *input_for_tranx = DA_NULL; + if (!da_info) { + DA_LOGE("NULL CHECK!: da_info"); + return DA_ERR_INVALID_ARGUMENT; + } + http_info = da_info->http_info; + if (!http_info) { + DA_LOGE("NULL CHECK!: http_info"); + return DA_ERR_INVALID_ARGUMENT; + } + http_info->http_method = HTTP_METHOD_GET; + http_info->proxy_addr = get_proxy_address(); - DA_LOG_FUNC_LOGV(HTTPManager); + ret = PI_http_start(da_info); - slot_id = GET_STAGE_DL_ID(stage); + return ret; +} - request_info = GET_STAGE_TRANSACTION_INFO(stage); +da_ret_t __start_resume_transaction(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; + http_info_t *http_info = DA_NULL; + file_info_t *file_info = DA_NULL; + req_info_t *req_info = DA_NULL; + + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + + ret = __create_http_resume_hdr(req_info, http_info, + file_info); + if (ret != DA_RESULT_OK) + return ret; - if (GET_REQUEST_HTTP_REQ_URL(request_info) == DA_NULL) { - DA_LOG_ERR(HTTPManager, "url is NULL"); - ret = DA_ERR_INVALID_URL; - goto ERR; + reset_http_info_for_resume(http_info); + if (file_info->file_path) { + req_info->temp_file_path = strdup(file_info->file_path); + } else { + DA_LOGE("file_path cannot be NULL in resume case"); + return DA_ERR_INVALID_ARGUMENT; } + ret = __start_transaction(da_info); + return ret; +} - input_for_tranx = (input_for_tranx_t*) calloc(1, - sizeof(input_for_tranx_t)); - if (input_for_tranx == DA_NULL) { - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } else { - input_for_tranx->proxy_addr = get_proxy_address(); - input_for_tranx->queue = GET_DL_QUEUE(slot_id); - input_for_tranx->http_method = PI_HTTP_METHOD_GET; - input_for_tranx->http_msg_request - = request_info->http_info.http_msg_request; +da_ret_t __start_new_transaction(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; + + if (!da_info) { + DA_LOGE("NULL CHECK!: da_info"); + return DA_ERR_INVALID_ARGUMENT; } - ret = PI_http_start_transaction(input_for_tranx, - &(GET_REQUEST_HTTP_TRANS_ID(request_info))); + ret = __set_http_request_hdr(da_info->req_info, da_info->http_info, da_info->file_info); if (ret != DA_RESULT_OK) - goto ERR; - -ERR: - if (input_for_tranx) { - free(input_for_tranx); - input_for_tranx = DA_NULL; - } + return ret; + ret = __start_transaction(da_info); return ret; } -da_result_t make_req_dl_info_http(stage_info *stage, req_dl_info *out_info) +int __check_wait_for_auto_retry(http_info_t *http_info) { - char *url = DA_NULL; - char **user_request_header = DA_NULL; - int user_request_header_count = 0; - char *user_request_etag = DA_NULL; - char *user_request_temp_file_path = DA_NULL; - int dl_id = -1; - source_info_t *source_info = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!stage) { - DA_LOG_ERR(HTTPManager, "stage is NULL"); - return DA_ERR_INVALID_ARGUMENT; - } - - source_info = GET_STAGE_SOURCE_INFO(stage); - - url = source_info->source_info_type.source_info_basic->url; - user_request_header = - source_info->source_info_type.source_info_basic->user_request_header; - user_request_header_count = - source_info->source_info_type.source_info_basic->user_request_header_count; - dl_id = source_info->source_info_type.source_info_basic->dl_id; - user_request_etag = GET_DL_USER_ETAG(GET_STAGE_DL_ID(stage)); - user_request_temp_file_path = GET_DL_USER_TEMP_FILE_PATH(GET_STAGE_DL_ID(stage)); - - DA_SECURE_LOGD("url [%s]", url); - - if (url) { - GET_REQUEST_HTTP_REQ_URL(out_info) = url; - GET_REQUEST_HTTP_USER_REQUEST_HEADER(out_info) = user_request_header; - GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(out_info) = - user_request_header_count; - GET_REQUEST_HTTP_USER_REQUEST_ETAG(out_info) = - user_request_etag; - GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(out_info) = - user_request_temp_file_path; + da_ret_t ret = DA_RESULT_OK; + struct timespec ts; + struct timeval tp; + NULL_CHECK_RET_OPT(http_info, 0); + gettimeofday(&tp, NULL); + ts.tv_sec = tp.tv_sec + DA_MAX_TIME_OUT; + ts.tv_nsec = tp.tv_usec * 1000; + DA_LOGI("Network Fail case, wait for a while"); + + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_WAIT_FOR_NET_ERR; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_MUTEX_LOCK(&(http_info->mutex_http)); + ret = pthread_cond_timedwait(&(http_info->cond_http), + &(http_info->mutex_http), &ts); + DA_MUTEX_UNLOCK(&(http_info->mutex_http)); + if (ret == ETIMEDOUT) { + DA_LOGI("Waiting is done by timeout"); + } else if (ret != 0) { + DA_LOGE("fail to pthread_cond_waittime[%d][%s]",ret, strerror(ret)); } else { - DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL"); - return DA_ERR_INVALID_URL; + DA_LOGI("Waiting is done by control"); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + DA_LOGI("http_state[%s]", __get_state_str(http_info->state)); + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + return 1; } - _da_thread_mutex_init(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)), NULL); - - return DA_RESULT_OK; + return 0; } -da_result_t pause_for_flow_control(stage_info *stage) +// In download thread +da_ret_t request_http_download(da_info_t *da_info) { - return DA_RESULT_OK; -} + da_ret_t ret = DA_RESULT_OK; + req_info_t *req_info = DA_NULL; + http_info_t *http_info = DA_NULL; + http_state_t http_state = 0; + da_bool_t need_wait = DA_TRUE; -da_result_t unpause_for_flow_control(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; + DA_LOGV(""); - DA_LOG_FUNC_LOGV(HTTPManager); + NULL_CHECK_RET(da_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + __init_http_info(http_info); + + do { + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("http_state[%s][%d]",__get_state_str(http_info->state), da_info->da_id); + switch (http_state) { + case HTTP_STATE_READY_TO_DOWNLOAD: + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_REQUESTED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + ret = __start_new_transaction(da_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_LOGD("http_state[%s][%d]",__get_state_str(http_info->state), da_info->da_id); + http_info->error_code = ret; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + if (ret == DA_ERR_NETWORK_FAIL && http_state != HTTP_STATE_PAUSED) { + DA_LOGE("Network failed"); + if (__check_wait_for_auto_retry(http_info) == 1) + need_wait = DA_TRUE; + else + need_wait = DA_FALSE; + } + break; + case HTTP_STATE_REDIRECTED: + case HTTP_STATE_DOWNLOAD_REQUESTED: + case HTTP_STATE_DOWNLOAD_STARTED: + case HTTP_STATE_DOWNLOADING: + case HTTP_STATE_REQUEST_PAUSE: + DA_LOGE("Cannot enter here:[%s][id]", + __get_state_str(http_info->state), da_info->da_id); + break; + case HTTP_STATE_REQUEST_CANCEL: + break; + case HTTP_STATE_REQUEST_RESUME: + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_READY_TO_DOWNLOAD; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + need_wait = DA_TRUE; + break; + case HTTP_STATE_CANCELED: + need_wait = DA_FALSE; + ret = DA_RESULT_USER_CANCELED; + break; + case HTTP_STATE_PAUSED: + DA_LOGD("error_code[%d]", http_info->error_code); + send_client_paused_info(da_info); + DA_LOGD("Waiting thread for paused state"); + DA_MUTEX_LOCK(&(http_info->mutex_http)); + pthread_cond_wait(&(http_info->cond_http),&(http_info->mutex_http)); + DA_MUTEX_UNLOCK(&(http_info->mutex_http)); + DA_LOGD("Wake up thread due to resume"); + break; + case HTTP_STATE_RESUMED: + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_REQUESTED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + ret = __start_resume_transaction(da_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + if (ret == DA_ERR_NETWORK_FAIL && http_state != HTTP_STATE_PAUSED) { + DA_LOGE("Network failed"); + if (__check_wait_for_auto_retry(http_info) == 1) + need_wait = DA_TRUE; + else + need_wait = DA_FALSE; + } + break; + case HTTP_STATE_DOWNLOAD_FINISH: + need_wait = DA_FALSE; + if (ret == DA_RESULT_OK) + ret = check_drm_convert(da_info->file_info); + break; + case HTTP_STATE_FAILED: + if (ret == DA_ERR_NETWORK_FAIL) { + if (__check_wait_for_auto_retry(http_info) == 1) + need_wait = DA_TRUE; + else + need_wait = DA_FALSE; + } else { + need_wait = DA_FALSE; + } + break; + case HTTP_STATE_ABORTED: + need_wait = DA_FALSE; + break; + default: + break; + } + } while (need_wait == DA_TRUE); + DA_LOGD("Final http_state[%s][%d] err[%d]",__get_state_str(http_info->state), da_info->da_id, ret); + if (http_info->state != HTTP_STATE_PAUSED) + send_client_finished_info(da_info ,ret); + DA_LOGI("=== Exiting http_download ret[%d] ===", ret); + return ret; +} - PI_http_unpause_transaction( - GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage))); +da_ret_t __disconnect_transaction(http_info_t *http_info) +{ + da_ret_t ret = DA_RESULT_OK; + DA_LOGD(""); + ret = PI_http_disconnect(http_info); return ret; } -da_result_t handle_event_abort(stage_info *stage) + +da_ret_t __handle_event_abort(http_info_t *http_info) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; http_state_t state = 0; - DA_LOG_FUNC_LOGD(HTTPManager); + DA_LOGD(""); + + DA_MUTEX_LOCK(&(http_info->mutex_state)); + state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGV("http_state[%s]", __get_state_str(state)); - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG(HTTPManager, "http_state = %d", state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); switch (state) { case HTTP_STATE_READY_TO_DOWNLOAD: case HTTP_STATE_REDIRECTED: @@ -614,1200 +582,938 @@ da_result_t handle_event_abort(stage_info *stage) case HTTP_STATE_PAUSED: case HTTP_STATE_RESUMED: case HTTP_STATE_ABORTED: + case HTTP_STATE_WAIT_FOR_NET_ERR: /* IF the network session is terminated due to some error, * the state can be aborted.(data aborted case) */ - CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_ABORTED, stage); - _disconnect_transaction(stage); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_ABORTED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + __disconnect_transaction(http_info); break; case HTTP_STATE_DOWNLOAD_FINISH: break; default: - DA_LOG_ERR(HTTPManager, "have to check the flow for this case"); + DA_LOGE("Cannot enter here"); break; } return ret; } -da_result_t handle_event_cancel(stage_info *stage) +da_ret_t __check_enough_memory(http_info_t *http_info, char *user_install_path) { - da_result_t ret = DA_RESULT_OK; - http_state_t state = 0; + da_ret_t ret = DA_RESULT_OK; + da_size_t cont_len = 0; + char *dir_path = DA_DEFAULT_INSTALL_PATH_FOR_PHONE; + + DA_LOGV(""); + NULL_CHECK_RET(http_info); + cont_len = http_info->content_len_from_header; + if (cont_len > 0) { + if (user_install_path) + dir_path = user_install_path; + ret = get_available_memory(dir_path, cont_len); + } + return ret; +} - DA_LOG_FUNC_LOGD(HTTPManager); +da_ret_t request_to_abort_http_download(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; + ret = __handle_event_abort(da_info->http_info); + return ret; +} - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG(HTTPManager, "http_state = %d", state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - switch (state) { +da_ret_t request_to_cancel_http_download(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; + http_info_t *http_info = DA_NULL; + http_state_t http_state = 0; + DA_LOGV(""); + + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("http_state[%s]", __get_state_str(http_state)); + switch (http_state) { case HTTP_STATE_READY_TO_DOWNLOAD: - CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage); + ret = PI_http_cancel(http_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_CANCELED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + if (da_info->thread_id > 0) { + if (pthread_cancel(da_info->thread_id) != 0) { + DA_LOGE("Fail to cancel thread id[%d] err[%s]", + da_info->thread_id, strerror(errno)); + } else { + DA_LOGI("====Exit thread with cancel:da_id[%d]===", + da_info->da_id); + } + } + break; + case HTTP_STATE_WAIT_FOR_NET_ERR: + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_CANCELED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_MUTEX_LOCK(&(http_info->mutex_http)); + DA_COND_SIGNAL(&(http_info->cond_http)); + DA_MUTEX_UNLOCK(&(http_info->mutex_http)); break; - case HTTP_STATE_PAUSED: - discard_download(stage); - CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage); + reset_http_info(http_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_CANCELED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); break; - case HTTP_STATE_DOWNLOAD_REQUESTED: case HTTP_STATE_DOWNLOAD_STARTED: case HTTP_STATE_DOWNLOADING: case HTTP_STATE_REQUEST_RESUME: case HTTP_STATE_RESUMED: - _cancel_transaction(stage); - CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_CANCEL, stage); + ret = PI_http_cancel(http_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_REQUEST_CANCEL; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); break; - case HTTP_STATE_DOWNLOAD_FINISH: + ret = DA_ERR_INVALID_STATE; break; - case HTTP_STATE_REQUEST_CANCEL: - DA_LOG(HTTPManager, "HTTP_STATE_REQUEST_CANCEL : cancel is already in progress... "); + DA_LOGV("cancel is already in progress... "); + ret = DA_ERR_INVALID_STATE; break; - default: - DA_LOG_ERR(HTTPManager, "have to check the flow for this case"); + ret = DA_ERR_INVALID_STATE; + DA_LOGE("Cannot enter here"); break; } - return ret; } -da_result_t handle_event_suspend(stage_info *stage) +da_ret_t request_to_suspend_http_download(da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; + + da_ret_t ret = DA_RESULT_OK; + http_info_t *http_info = DA_NULL; http_state_t http_state = 0; - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); + DA_LOGV(""); + + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("http_state[%s]", __get_state_str(http_state)); switch (http_state) { + case HTTP_STATE_PAUSED: case HTTP_STATE_REQUEST_PAUSE: - DA_LOG(HTTPManager, "already requested to pause! do nothing"); + DA_LOGI("Already paused. http_state[%s]", __get_state_str(http_state)); + ret = DA_ERR_ALREADY_SUSPENDED; break; - case HTTP_STATE_READY_TO_DOWNLOAD: - CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage); - send_client_paused_info(GET_STAGE_DL_ID(stage)); + DA_LOGE("Download has not been started yet"); + ret = DA_ERR_INVALID_STATE; + break; + case HTTP_STATE_WAIT_FOR_NET_ERR: + DA_LOGD("error_code[%d]", http_info->error_code); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_PAUSED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_MUTEX_LOCK(&(http_info->mutex_http)); + DA_COND_SIGNAL(&(http_info->cond_http)); + DA_MUTEX_UNLOCK(&(http_info->mutex_http)); break; - default: - //send_client_paused_info(GET_STAGE_DL_ID(stage)); - _cancel_transaction(stage); - GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)) = DA_RESULT_OK; - DA_LOG_CRITICAL(HTTPManager, "[%d] cleanup internal error", GET_STAGE_DL_ID(stage)); - CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_PAUSE,stage); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_REQUEST_PAUSE; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("error_code[%d]", http_info->error_code); + if (http_info->error_code != DA_ERR_NETWORK_FAIL) + ret = PI_http_pause(http_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_PAUSED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + break; } - return ret; } -da_result_t handle_event_resume(stage_info *stage) +da_ret_t request_to_resume_http_download(da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; - http_msg_request_t *resume_request = NULL; - + da_ret_t ret = DA_RESULT_OK; + http_info_t *http_info = DA_NULL; http_state_t http_state = 0; + int retry_count = 0; - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - if (http_state != HTTP_STATE_PAUSED) { - DA_LOG_ERR(HTTPManager, "Not HTTP_STATE_PAUSED! http_state = %d", http_state); - ret = DA_ERR_INVALID_STATE; - goto ERR; - } - - GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)) = DA_RESULT_OK; - DA_LOG_CRITICAL(HTTPManager, "[%d] cleanup internal error", GET_STAGE_DL_ID(stage)); - - CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_RESUME,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); + DA_LOGV(""); - ret = create_resume_http_request_hdr(stage, &resume_request); - if (ret != DA_RESULT_OK) - goto ERR; + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); - if (GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request) - free(GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("http_state[%s]", __get_state_str(http_state)); - GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request - = resume_request; - - make_transaction_info_and_start_transaction(stage); + switch (http_state) { + case HTTP_STATE_PAUSED: + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_RESUMED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("Wake up thread for paused state"); + DA_MUTEX_LOCK(&(http_info->mutex_http)); + DA_COND_SIGNAL(&(http_info->cond_http)); + DA_MUTEX_UNLOCK(&(http_info->mutex_http)); + DA_LOGD("error_code[%d]", http_info->error_code); + if (http_info->error_code != DA_ERR_NETWORK_FAIL) { + ret = PI_http_unpause(http_info); + if (ret != DA_RESULT_OK) + PI_http_cancel(http_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOADING; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); -ERR: + } + break; + case HTTP_STATE_REQUEST_PAUSE: + DA_LOGD("Waiting to handle pause request"); + do { + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + if (http_state == HTTP_STATE_PAUSED) { + DA_LOGD("Change to paused state"); + ret = PI_http_unpause(http_info); + break; + } + retry_count++; + } while(retry_count < 10000); + if (ret != DA_RESULT_OK || retry_count >= 10000) + PI_http_cancel(http_info); + break; + case HTTP_STATE_RESUMED: + ret = DA_ERR_ALREADY_RESUMED; + break; + default: + DA_LOGE("Fail to resume. Invalid state check. http_state[%s]", + __get_state_str(http_state)); + ret = DA_ERR_INVALID_STATE; + // If resume is failed due to invalid state, the previous pause should be canceled. + PI_http_cancel(http_info); + break; + } return ret; - } -da_result_t create_resume_http_request_hdr(stage_info *stage, - http_msg_request_t **out_resume_request) +da_ret_t __check_resume_download_is_available( + req_info_t *req_info, http_info_t *http_info, file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; da_bool_t b_ret = DA_FALSE; - - req_dl_info *request_info = NULL; - - http_msg_response_t *first_response = NULL; - http_msg_request_t *resume_request = NULL; - + char *origin_ETag = NULL; + char *new_ETag = NULL; + da_size_t remained_content_len = 0; char *value = NULL; - char *url = NULL; - unsigned int downloaded_data_size = 0; - char downloaded_data_size_to_str[32] = { 0, }; + da_size_t size = 0; + char *temp_file_path = DA_NULL; + char *dir_path = DA_DEFAULT_INSTALL_PATH_FOR_PHONE; - char *etag_from_response = NULL; - char *date_from_response = NULL; + DA_LOGV(""); + + origin_ETag = req_info->etag; - DA_LOG_FUNC_LOGD(HTTPManager); + b_ret = http_msg_response_get_content_length(http_info->http_msg_response, + &size); + if (b_ret) { + remained_content_len = size; + size = 0; + DA_SECURE_LOGD("remained_content_len[%llu]", remained_content_len); + } - request_info = GET_STAGE_TRANSACTION_INFO(stage); + b_ret = http_msg_response_get_ETag(http_info->http_msg_response, &value); + if (b_ret) { + new_ETag = value; + value = NULL; + DA_SECURE_LOGD("new ETag[%s]", new_ETag); + } else { + goto ERR; + } - if (!(url = GET_REQUEST_HTTP_REQ_URL(GET_STAGE_TRANSACTION_INFO(stage)))) { - DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL"); - ret = DA_ERR_INVALID_URL; + if (origin_ETag && new_ETag && + 0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) { + DA_LOGE("ETag is not identical! revoke!"); + /* FIXME Later : Need to detail error exception handling */ + ret = DA_ERR_NETWORK_FAIL; + /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */ goto ERR; } - first_response = request_info->http_info.http_msg_response; - if (first_response) { - b_ret = http_msg_response_get_ETag(first_response, &value); - if (b_ret) { - etag_from_response = value; - value = NULL; - DA_SECURE_LOGD("[ETag][%s]", etag_from_response); - } + if (remained_content_len > 0) { + if (req_info->install_path) + dir_path = req_info->install_path; + ret = get_available_memory(dir_path, remained_content_len); + if (ret != DA_RESULT_OK) + goto ERR; + } - b_ret = http_msg_response_get_date(first_response, &value); + if (!http_info->content_type_from_header) { + b_ret = http_msg_response_get_content_type(http_info->http_msg_response, + &value); if (b_ret) { - date_from_response = value; + http_info->content_type_from_header = value; value = NULL; - DA_SECURE_LOGD("[Date][%s]", date_from_response); + DA_SECURE_LOGD("Content-Type[%s]", + http_info->content_type_from_header); } - - downloaded_data_size - = GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)); - DA_LOG(HTTPManager, "downloaded_data_size = %u", downloaded_data_size); - snprintf(downloaded_data_size_to_str, sizeof(downloaded_data_size_to_str), "bytes=%u-", - downloaded_data_size); - DA_LOG(HTTPManager, "downloaded_data_size_to_str = %s", downloaded_data_size_to_str); } - - ret = make_default_http_request_hdr(url, NULL, 0, &resume_request, NULL, NULL); - if (ret != DA_RESULT_OK) + temp_file_path = req_info->temp_file_path; + if (!temp_file_path) { + DA_LOGE("Temporary file path cannot be NULL"); + ret = DA_ERR_INVALID_ARGUMENT; goto ERR; - - if (etag_from_response) { - http_msg_request_add_field(resume_request, HTTP_FIELD_IF_RANGE, - etag_from_response); - } else { - if (date_from_response) { - http_msg_request_add_field(resume_request, - HTTP_FIELD_IF_RANGE, date_from_response); - } } - - if (strlen(downloaded_data_size_to_str) > 0) - http_msg_request_add_field(resume_request, HTTP_FIELD_RANGE, - downloaded_data_size_to_str); - - *out_resume_request = resume_request; - + get_file_size(temp_file_path, &size); + http_info->content_len_from_header = remained_content_len + size; + DA_SECURE_LOGD("Content-Length[%llu]", http_info->content_len_from_header); ERR: - if (etag_from_response) { - free(etag_from_response); - etag_from_response = NULL; - } - - if (date_from_response) { - free(date_from_response); - date_from_response = NULL; + if (new_ETag) { + free(new_ETag); + new_ETag = DA_NULL; } - return ret; } -da_result_t handle_any_input(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - - int slot_id = GET_STAGE_DL_ID(stage); - queue_t *queue = DA_NULL; - q_event_t *event = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); +da_ret_t __check_content_type_is_matched(http_info_t *http_info) +{ + da_ret_t ret = DA_RESULT_OK; + char *content_type_from_server = DA_NULL; - queue = GET_DL_QUEUE(slot_id); + DA_LOGV(""); - Q_pop_event(queue, &event); - if (event == DA_NULL) { - DA_LOG_DEBUG(HTTPManager, "There is no data on the queue!"); + content_type_from_server = http_info->content_type_from_header; + if (content_type_from_server == DA_NULL) { + DA_LOGV("http header has no Content-Type field, no need to compare"); return DA_RESULT_OK; } - - switch (event->event_type) { - case Q_EVENT_TYPE_CONTROL: - ret = handle_event_control(stage, event); - break; - - case Q_EVENT_TYPE_DATA_HTTP: - ret = handle_event_http(stage, event); - break; - - case Q_EVENT_TYPE_DATA_DRM: - break; - - default: - break; - } - Q_destroy_q_event(&event); - return ret; } -da_result_t handle_event_control(stage_info *stage, q_event_t *event) +da_ret_t __handle_http_status_code(http_info_t *http_info, + file_info_t *file_info, req_info_t *req_info) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGD(HTTPManager); - - if (event->event_type == Q_EVENT_TYPE_CONTROL) { - switch (event->type.q_event_control.control_type) { - case Q_EVENT_TYPE_CONTROL_CANCEL: - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL"); - ret = handle_event_cancel(stage); - break; - - case Q_EVENT_TYPE_CONTROL_SUSPEND: - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND"); - ret = handle_event_suspend(stage); - break; + da_ret_t ret = DA_RESULT_OK; + http_state_t http_state = 0; + http_msg_response_t *http_msg_response = DA_NULL; + char *location = DA_NULL; + char *if_range_str = DA_NULL; + char *range_str = DA_NULL; + int http_status = 0; - case Q_EVENT_TYPE_CONTROL_RESUME: - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME"); - ret = handle_event_resume(stage); - break; - case Q_EVENT_TYPE_CONTROL_ABORT: - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT"); - ret = handle_event_abort(stage); - break; - /* Fixme: need to think how we use this type. For now, this type is not used. */ - case Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED: - DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED"); - break; - case Q_EVENT_TYPE_CONTROL_NONE: - default: - DA_LOG_ERR(HTTPManager, "Cannot enter here"); - break; + NULL_CHECK_RET(http_info); + NULL_CHECK_RET(file_info); + NULL_CHECK_RET(req_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("http_state[%s]", __get_state_str(http_state)); + http_msg_response = http_info->http_msg_response; + NULL_CHECK_RET(http_msg_response); + http_status = http_msg_response->status_code; + switch (http_status) { + case 200: + case 201: + case 202: + case 203: +// Although expecting 206, 200 response is received. Remove temporary file and reset file info + if (http_info->http_msg_request && + http_msg_request_get_if_range(http_info->http_msg_request, &if_range_str) == DA_TRUE && + http_msg_request_get_range(http_info->http_msg_request, &range_str) == DA_TRUE) { + DA_LOGI("Server do not support if-range option"); + clean_paused_file(file_info); } - } + free(if_range_str); + free(range_str); + if (http_state == HTTP_STATE_REQUEST_RESUME) + clean_paused_file(file_info); + ret = __check_content_type_is_matched(http_info); + if (ret != DA_RESULT_OK) + goto ERR; + ret = __check_enough_memory(http_info, req_info->install_path); + if (ret != DA_RESULT_OK) + goto ERR; + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_STARTED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + break; - return ret; -} - -da_result_t handle_event_http(stage_info *stage, q_event_t *event) -{ - da_result_t ret = DA_RESULT_OK; - q_event_data_http_t *q_event_data_http = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if (event->event_type == Q_EVENT_TYPE_DATA_HTTP) { - q_event_data_http = &(event->type.q_event_data_http); - switch (q_event_data_http->data_type) { - case Q_EVENT_TYPE_DATA_PACKET: - ret = handle_event_http_packet(stage, event); - break; - case Q_EVENT_TYPE_DATA_FINAL: - DA_LOG_VERBOSE(HTTPManager, "Q_EVENT_TYPE_DATA_FINAL"); - ret = handle_event_http_final(stage, event); - break; - case Q_EVENT_TYPE_DATA_ABORT: - DA_LOG_VERBOSE(HTTPManager, "Q_EVENT_TYPE_DATA_ABORT"); - ret = handle_event_http_abort(stage, event); - break; - } - } - return ret; -} - -da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event) -{ - da_result_t ret = DA_RESULT_OK; - da_bool_t is_handle_hdr_success = DA_TRUE; - q_event_data_http_t *received_data = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - received_data = &(event->type.q_event_data_http); - - if (received_data->http_response_msg) { - ret = handle_http_hdr(stage, received_data->http_response_msg, - received_data->http_response_msg->status_code); - if (DA_RESULT_OK != ret) { - is_handle_hdr_success = DA_FALSE; - } - - received_data->http_response_msg = NULL; - } - - if (received_data->body_len > 0) { - if (is_handle_hdr_success == DA_TRUE) { - ret = handle_http_body(stage, received_data->body_data, - received_data->body_len); - } - /*For all cases body_data should be deleted*/ - free(received_data->body_data); - received_data->body_data = DA_NULL; - } - return ret; -} - -da_result_t handle_event_http_final(stage_info *stage, q_event_t *event) -{ - da_result_t ret = DA_RESULT_OK; - http_state_t http_state = 0; - int slot_id = DA_INVALID_ID; - int http_status = 0; - q_event_data_http_t *received_data = DA_NULL; - - - DA_LOG_FUNC_LOGV(HTTPManager); - - slot_id = GET_STAGE_DL_ID(stage); - _disconnect_transaction(stage); - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG(HTTPManager, "http_state = %d", http_state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - switch (http_state) { - case HTTP_STATE_REDIRECTED: - CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD,stage); - break; - - case HTTP_STATE_DOWNLOAD_REQUESTED: - DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOAD_REQUESTED"); - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage); - /* Most of http status is decided when got headers. - * But it is ignored for credential url when got headers in case of 401 status code. - * So, when the download is finished, it means unauthorized error if the status code has still 401. - */ - received_data = &(event->type.q_event_data_http); - http_status = received_data->status_code; - if (http_status == 401) { - store_http_status(slot_id, http_status); - ret = DA_ERR_NETWORK_FAIL; - } - break; + case 206: + DA_LOGV("HTTP Status is %d - Partial download for resume!", http_status); + /* The resume can be started with start API. + * So the state should be not HTTP_STATE_RESUME_REQUESTED but HTTP_STATE_DOWNLOAD_REQUESTED*/ + if (http_state == HTTP_STATE_DOWNLOAD_REQUESTED) { + ret = __check_resume_download_is_available(req_info, http_info, file_info); + if (ret != DA_RESULT_OK) + goto ERR; + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_STARTED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); - case HTTP_STATE_DOWNLOADING: - DA_LOG_VERBOSE(HTTPManager, "case HTTP_STATE_DOWNLOADING"); - ret = file_write_complete(stage); - if (ret != DA_RESULT_OK) { - discard_download(stage); - goto ERR; - } - /* Sometimes, the server can send "0" byte package data although whole data are not sent. - * At that case, the libsoup call finished callback function with 200 Ok. - * Only if the DA know content size form response header, it can check the error or not - */ - ret = _check_downloaded_file_size_is_same_with_header_content_size(stage); - if(ret != DA_RESULT_OK) { - discard_download(stage) ; + } else if (http_state == HTTP_STATE_REQUEST_RESUME) { + ///FIXME later : how get previous response header + ///ret = __check_this_partial_download_is_available(http_info, + /// previous_ http_msg_response); + //if (ret != DA_RESULT_OK) + //goto ERR; + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_RESUMED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + } else { + DA_LOGE("This download is not resumed, revoke"); + ret = DA_ERR_INVALID_STATE; goto ERR; } - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage); - send_client_update_progress_info( - slot_id, - GET_DL_ID(slot_id), - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - ); break; - case HTTP_STATE_REQUEST_PAUSE: - if (GET_CONTENT_STORE_FILE_HANDLE(GET_STAGE_CONTENT_STORE_INFO(stage))) { - ret = file_write_complete(stage); - - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage)) - = DA_FALSE; - - send_client_update_progress_info( - slot_id, - GET_DL_ID(slot_id), - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - ); - + case 300: + case 301: + case 302: + case 303: + case 305: + case 306: + case 307: + DA_LOGV("HTTP Status is %d - redirection!",http_status); + if (http_msg_response_get_location(http_msg_response, &location)) { + DA_SECURE_LOGD("location = %s\n", location); + http_info->location_url = location; + DA_LOGI("[TEST] location_url[%p]",http_info->location_url); } - CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage); - send_client_paused_info(GET_STAGE_DL_ID(stage)); - DA_LOG(HTTPManager, "Server Notification code is set to NULL"); - break; - - case HTTP_STATE_ABORTED: - case HTTP_STATE_CANCELED: - discard_download(stage); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_REDIRECTED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + http_msg_response_destroy(&http_msg_response); + http_info->http_msg_response = DA_NULL; break; - case HTTP_STATE_REQUEST_CANCEL: - ret = file_write_complete(stage); - if (ret != DA_RESULT_OK) - goto ERR; - discard_download(stage); - CHANGE_HTTP_STATE(HTTP_STATE_CANCELED, stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage); + case 100: + case 101: + case 102: + case 204: + case 304: + DA_LOGV("HTTP Status is %d - 204 server got the request, \ + but no content to reply back, \ + 304 means not modified!", http_status); + ret = DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT; break; + case 416: // Requested range not satisfiable + case 503: + case 504: default: - ret = file_write_complete(stage); - if (ret != DA_RESULT_OK) - goto ERR; - discard_download(stage); - CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage); +/// GET_REQUEST_HTTP_RESULT(request_info) +/// = DA_ERR_UNREACHABLE_SERVER; + DA_LOGI("set internal error code : DA_ERR_UNREACHABLE_SERVER"); break; } ERR: - /* When file complete is failed */ - if (DA_RESULT_OK != ret) { - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage); - } return ret; } -da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event) +da_ret_t __check_before_downloading(da_info_t *da_info, http_state_t state) { - da_result_t ret = DA_RESULT_OK; - http_state_t http_state = 0; - DA_LOG_FUNC_LOGD(HTTPManager); - - GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)) - = event->type.q_event_data_http.error_type; - DA_LOG_CRITICAL(HTTPManager, "set internal error code : [%d]", GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))); - _disconnect_transaction(stage); - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG(HTTPManager, "http_state = %d", http_state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - switch (http_state) { - case HTTP_STATE_REQUEST_PAUSE: - CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage); - send_client_paused_info(GET_STAGE_DL_ID(stage)); - ret = file_write_complete(stage); - if (ret != DA_RESULT_OK) - goto ERR; - break; + da_ret_t ret = DA_RESULT_OK; + http_info_t *http_info = DA_NULL; + req_info_t *req_info = DA_NULL; + file_info_t *file_info = DA_NULL; + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + DA_LOGD("state:%s",__get_state_str(state)); + // resume case + if (req_info->temp_file_path && file_info->bytes_written_to_file > 0) { + ret = start_file_append(file_info); + } else if (state == HTTP_STATE_DOWNLOAD_STARTED) { + ret = start_file_writing(da_info); + } else { + DA_LOGE("Cannot enter here!"); + ret = DA_ERR_INVALID_ARGUMENT; + goto ERR; + } + if (DA_RESULT_OK != ret) + goto ERR; - case HTTP_STATE_REQUEST_CANCEL: - CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage); - ret = file_write_complete(stage); - if (ret != DA_RESULT_OK) - goto ERR; - discard_download(stage); - break; + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOADING; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); - default: - CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage); - ret = file_write_complete(stage); - if (ret != DA_RESULT_OK) - goto ERR; - discard_download(stage); - break; - } + ret = send_client_update_dl_info(da_info); ERR: return ret; } -da_result_t handle_http_hdr(stage_info *stage, - http_msg_response_t *http_msg_response, int http_status) +da_ret_t __handle_event_http_header(http_raw_data_t *raw_data, da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; - int slot_id = DA_INVALID_ID; + da_ret_t ret = DA_RESULT_OK; http_state_t http_state = 0; - - DA_LOG_FUNC_LOGV(HTTPManager); - - slot_id = GET_STAGE_DL_ID(stage); - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG_DEBUG(HTTPManager, "http_state = %d", http_state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - + http_info_t *http_info = DA_NULL; + file_info_t *file_info = DA_NULL; + req_info_t *req_info = DA_NULL; + http_msg_response_t *http_msg_response = DA_NULL; + da_size_t size = 0; + char *mime_type = DA_NULL; + char *etag = DA_NULL; + char *file_name = DA_NULL; + + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + req_info = da_info->req_info; + NULL_CHECK_RET(req_info); + NULL_CHECK_RET(raw_data); + + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGV("http_state[%s]", __get_state_str(http_state)); + http_msg_response = http_info->http_msg_response; switch (http_state) { case HTTP_STATE_DOWNLOAD_REQUESTED: case HTTP_STATE_REQUEST_PAUSE: case HTTP_STATE_REQUEST_RESUME: case HTTP_STATE_REDIRECTED: - ret = handle_http_status_code(stage, http_msg_response, - http_status); - if (ret != DA_RESULT_OK) + http_msg_response_get_content_length(http_msg_response, &size); + http_info->content_len_from_header = size; + http_msg_response_get_content_type(http_msg_response, &mime_type); + http_info->content_type_from_header = mime_type; + if (mime_type) + file_info->mime_type = strdup(mime_type); + http_msg_response_get_ETag(http_msg_response, &etag); + http_info->etag_from_header = etag; + http_msg_response_get_content_disposition( + http_msg_response, DA_NULL, &file_name); + http_info->file_name_from_header = file_name; + ret = __handle_http_status_code(http_info, file_info, req_info); + if (ret != DA_RESULT_OK) { + DA_LOGE("Fail to handle http status code"); goto ERR; + } +#ifdef _RAF_SUPPORT + char *val = NULL; + http_msg_response_get_RAF_mode(http_msg_response, &val); + if (!val) { + DA_LOGE("Fail to raf mode value from response header"); + } else { + DA_LOGI("[RAF] val[%s:%s]", HTTP_FIELD_RAF_MODE, val); + if (strncmp(val, "yes", strlen("yes")) == 0) { + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_STARTED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + ret = __check_before_downloading(da_info, http_info->state); + if (ret != DA_RESULT_OK) { + free(val); + goto ERR; + } + http_info->is_raf_mode_confirmed = DA_TRUE; + ret = PI_http_set_file_name_to_curl(http_info->http_msg, file_info->file_path); + if (ret != DA_RESULT_OK) { + DA_LOGE("Fail to set file name to curl"); + free(val); + goto ERR; + } + } + free(val); + } +#endif break; - case HTTP_STATE_REQUEST_CANCEL: - DA_LOG(HTTPManager, "Cancel is in progress.. http_state = %d", http_state); + DA_LOGV("Cancel is in progress.. http_state[%s]", + __get_state_str(http_state)); break; default: - DA_LOG_ERR(HTTPManager, "http_state = %d", http_state); + DA_LOGE("http_state[%s]", __get_state_str(http_state)); goto ERR; } ERR: + if (ret != DA_RESULT_OK) { + DA_LOGE("Request to cancel due to error[%d]", ret); + PI_http_cancel(http_info); + http_info->error_code = ret; + discard_download(file_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_FAILED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + } + free(raw_data); return ret; } -da_result_t handle_http_status_code(stage_info *stage, - http_msg_response_t *http_msg_response, int http_status) +da_ret_t __handle_event_http_packet(http_raw_data_t *raw_data, da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; - - int slot_id = DA_INVALID_ID; - req_dl_info *request_info = DA_NULL; + da_ret_t ret = DA_RESULT_OK; http_state_t http_state = 0; + http_info_t *http_info = DA_NULL; + file_info_t *file_info = DA_NULL; + time_t t; + struct tm *lc_time; + DA_LOGV(""); + + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + NULL_CHECK_RET(raw_data); + + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); - DA_LOG_FUNC_LOGV(HTTPManager); - - slot_id = GET_STAGE_DL_ID(stage); - request_info = GET_STAGE_TRANSACTION_INFO(stage); - - GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_response - = http_msg_response; - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - DA_LOG_VERBOSE(HTTPManager, "http_state = %d", http_state); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - store_http_status(slot_id, http_status); - - switch (http_status) { - case 200: - case 201: - case 202: - case 203: - if (http_state == HTTP_STATE_REQUEST_RESUME) - clean_paused_file(stage); - ret = set_hdr_fields_on_download_info(stage); - if (ret != DA_RESULT_OK) - goto ERR; - ret = _check_content_type_is_matched(stage); + switch (http_state) { + case HTTP_STATE_DOWNLOAD_STARTED: +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_FALSE) { +#endif + ret = __check_before_downloading(da_info, http_state); if (ret != DA_RESULT_OK) goto ERR; - ret = _check_enough_memory_for_this_download(stage); + ret = file_write_ongoing(file_info, + raw_data->body, raw_data->body_len); if (ret != DA_RESULT_OK) goto ERR; - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage); - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); // ? - break; - - case 206: - DA_LOG(HTTPManager, "HTTP Status is %d - Partial download for resume!",http_status); - /* The resume can be started with start API. - * So the state should be not HTTP_STATE_RESUME_REQUESTED but HTTP_STATE_DOWNLOAD_REQUESTED*/ - if (http_state == HTTP_STATE_DOWNLOAD_REQUESTED) { - ret = _check_resume_download_is_available(stage, - http_msg_response); - if (ret != DA_RESULT_OK) - goto ERR; - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage); - - } else if (http_state == HTTP_STATE_REQUEST_RESUME) { - ret = _check_this_partial_download_is_available(stage, - http_msg_response); - if (ret != DA_RESULT_OK) - goto ERR; - CHANGE_HTTP_STATE(HTTP_STATE_RESUMED,stage); +#ifdef _RAF_SUPPORT } else { - DA_LOG_ERR(HTTPManager, "This download is not resumed, revoke"); - ret = DA_ERR_INVALID_STATE; - goto ERR; + file_info->bytes_written_to_file = + raw_data->received_len + file_info->file_size_of_temp_file; + file_info->is_updated = DA_TRUE; } - CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); +#endif + ret = send_client_update_progress_info(da_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = HTTP_STATE_DOWNLOADING; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); break; - - case 300: - case 301: - case 302: - case 303: - case 305: - case 306: - case 307: - DA_LOG(HTTPManager, "HTTP Status is %d - redirection!",http_status); - ret = exchange_url_from_header_for_redirection(stage, http_msg_response); + case HTTP_STATE_RESUMED: +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_FALSE) { +#endif + __check_before_downloading(da_info, http_state); + ret = file_write_ongoing(file_info, + raw_data->body, raw_data->body_len); if (ret != DA_RESULT_OK) goto ERR; - CHANGE_HTTP_STATE(HTTP_STATE_REDIRECTED,stage); - http_msg_response_destroy(&http_msg_response); - request_info->http_info.http_msg_response = DA_NULL; - break; - - case 100: - case 101: - case 102: - case 204: - case 304: - DA_LOG(HTTPManager, "HTTP Status is %d - 204 means server got the request, but no content to reply back, 304 means not modified!",http_status); - ret = DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT; - break; - - case 416: // Requested range not satisfiable - case 503: - case 504: - default: - GET_REQUEST_HTTP_RESULT(request_info) - = DA_ERR_UNREACHABLE_SERVER; - DA_LOG_CRITICAL(HTTPManager, "set internal error code : DA_ERR_UNREACHABLE_SERVER [%d]", DA_ERR_UNREACHABLE_SERVER); +#ifdef _RAF_SUPPORT + } else { + file_info->bytes_written_to_file = + raw_data->received_len + file_info->file_size_of_temp_file; + file_info->is_updated = DA_TRUE; + } +#endif + ret = send_client_update_progress_info(da_info); break; - } - -ERR: - return ret; -} - -da_result_t exchange_url_from_header_for_redirection(stage_info *stage, - http_msg_response_t *http_msg_response) -{ - da_result_t ret = DA_RESULT_OK; - char *location = DA_NULL; - - DA_LOG_FUNC_LOGD(HTTPManager); - - if (http_msg_response_get_location(http_msg_response, &location)) { - DA_SECURE_LOGD("location = %s\n", location); - GET_REQUEST_HTTP_REQ_LOCATION(GET_STAGE_TRANSACTION_INFO(stage)) = location; - } - - return ret; -} - -da_result_t handle_http_body(stage_info *stage, char *body, int body_len) -{ - da_result_t ret = DA_RESULT_OK; - http_state_t http_state = 0; - int slot_id = DA_INVALID_ID; - - DA_LOG_FUNC_LOGV(HTTPManager); - - slot_id = GET_STAGE_DL_ID(stage); - - if (DA_RESULT_OK - != GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))) { - DA_LOG_CRITICAL(HTTPManager, "ignore because internal error code is set with [%d]", - GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))); - return ret; - } - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - if (http_state == HTTP_STATE_DOWNLOAD_STARTED) { - // resume case - if (GET_REQUEST_HTTP_USER_REQUEST_ETAG(GET_STAGE_TRANSACTION_INFO(stage))) - ret = start_file_writing_append_with_new_download(stage); - else - ret = start_file_writing(stage); - if (DA_RESULT_OK != ret) - goto ERR; - - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING, stage); - send_client_update_dl_info( - slot_id, - GET_DL_ID(slot_id), - GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_CONTENT_STORE_PURE_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage)), - GET_CONTENT_STORE_EXTENSION(GET_STAGE_CONTENT_STORE_INFO(stage)) - ); - } else if (http_state == HTTP_STATE_RESUMED) { - ret = start_file_writing_append(stage); - if (DA_RESULT_OK != ret) - goto ERR; - - CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING,stage); - send_client_update_dl_info( - slot_id, - GET_DL_ID(slot_id), - GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_CONTENT_STORE_PURE_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)), - GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage)), - GET_CONTENT_STORE_EXTENSION(GET_STAGE_CONTENT_STORE_INFO(stage)) - ); - } - - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - http_state = GET_HTTP_STATE_ON_STAGE(stage); - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - - switch (http_state) { case HTTP_STATE_REDIRECTED: - DA_LOG(HTTPManager, "Just ignore http body, because this body is not for redirection one."); + DA_LOGV("http_state[%s]", __get_state_str(http_state)); break; - case HTTP_STATE_DOWNLOADING: +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_FALSE) { +#endif /* Should this function before updating download info * Because it extract mime type at once only if first download updating at client */ - ret = file_write_ongoing(stage, body, body_len); + ret = file_write_ongoing(file_info, + raw_data->body, raw_data->body_len); if (ret != DA_RESULT_OK) goto ERR; - if ((DA_TRUE == - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage)))) { - - IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage)) - = DA_FALSE; - send_client_update_progress_info( - slot_id, - GET_DL_ID(slot_id), - GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)) - ); - +#ifdef _RAF_SUPPORT + } else { + file_info->bytes_written_to_file = + raw_data->received_len + file_info->file_size_of_temp_file; + file_info->is_updated = DA_TRUE; + } +#endif + // send event every 1 second. + if ((t = time(DA_NULL)) > 0) { + if ((lc_time = localtime(&t)) != DA_NULL) { + if (da_info->update_time != lc_time->tm_sec) { + da_info->update_time = lc_time->tm_sec; + ret = send_client_update_progress_info(da_info); + } + } else { + DA_LOGE("Fail to call localtime[%s]",strerror(errno)); + ret = send_client_update_progress_info(da_info); + } + } else { + DA_LOGE("Fail to call time[%s]",strerror(errno)); + ret = send_client_update_progress_info(da_info); } break; - case HTTP_STATE_REQUEST_PAUSE: - ret = file_write_ongoing(stage, body, body_len); +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_FALSE) { +#endif + DA_LOGV("http_state[%s]", __get_state_str(http_state)); + ret = file_write_ongoing(file_info, + raw_data->body, raw_data->body_len); if (ret != DA_RESULT_OK) goto ERR; - break; +#ifdef _RAF_SUPPORT + } else { + file_info->bytes_written_to_file = + raw_data->received_len + file_info->file_size_of_temp_file; + file_info->is_updated = DA_TRUE; + } +#endif + break; default: - DA_LOG(HTTPManager, "Do nothing! http_state is in case %d", http_state); - + DA_LOGE("Do nothing! http_state is in case[%s]", + __get_state_str(http_state)); goto ERR; } - -ERR: - return ret; -} - -/* Function should be renamed , as it is actually not setting the header fields in download info */ -da_result_t set_hdr_fields_on_download_info(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - da_bool_t b_ret = DA_FALSE; - - req_dl_info *request_info = DA_NULL; - http_msg_response_t *http_msg_response = NULL; - - char *value = NULL; - unsigned long long size = 0; - - DA_LOG_FUNC_LOGV(HTTPManager); - - request_info = GET_STAGE_TRANSACTION_INFO(stage); - - http_msg_response - = request_info->http_info.http_msg_response; - if (!http_msg_response) { - DA_LOG_ERR(HTTPManager, "There is no header data!!"); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - b_ret = http_msg_response_get_content_type(http_msg_response, &value); - if (b_ret) { - GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value; - value = NULL; -// DA_SECURE_LOGD("[Content-Type][%s] - stored", GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info)); - } - - b_ret = http_msg_response_get_content_length(http_msg_response, - &size); - if (b_ret) { - GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = size; - size = 0; - } - - b_ret = http_msg_response_get_ETag(http_msg_response, &value); - if (b_ret) { - GET_REQUEST_HTTP_HDR_ETAG(request_info) = value; - value = NULL; - DA_SECURE_LOGD("[ETag][%s] - stored ", GET_REQUEST_HTTP_HDR_ETAG(request_info)); - } - ERR: + if (ret != DA_RESULT_OK) { + DA_LOGE("Request to cancel due to error[%d]", ret); + PI_http_cancel(http_info); + http_info->error_code = ret; + discard_download(da_info->file_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_FAILED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + } + if (raw_data->body) + free(raw_data->body); + free(raw_data); return ret; } -da_result_t _check_content_type_is_matched(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - req_dl_info *request_info = DA_NULL; - source_info_t *source_info = DA_NULL; - char *content_type_from_server = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - request_info = GET_STAGE_TRANSACTION_INFO(stage); - source_info = GET_STAGE_SOURCE_INFO(stage); - - content_type_from_server = GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info); - if (content_type_from_server == DA_NULL) { - DA_LOG(HTTPManager, "http header has no Content-Type field, no need to compare"); - return DA_RESULT_OK; - } - - return ret; -} - -da_result_t _check_enough_memory_for_this_download(stage_info *stage) +da_ret_t __check_file_size_with_header_content_size(file_info_t *file_info) { - da_result_t ret = DA_RESULT_OK; - - req_dl_info *request_info = DA_NULL; + da_ret_t ret = DA_RESULT_OK; + unsigned long long tmp_file_size = 0; - unsigned long long cont_len = 0; - da_storage_size_t memory; + DA_LOGV(""); - DA_LOG_FUNC_LOGV(HTTPManager); + if (file_info->file_size > 0) { - memset(&memory, 0x00, sizeof(da_storage_size_t)); - request_info = GET_STAGE_TRANSACTION_INFO(stage); - - cont_len = (unsigned long long) GET_REQUEST_HTTP_HDR_CONT_LEN(request_info); - if (cont_len) { - ret = get_available_memory(&memory); - if (DA_RESULT_OK == ret) { - DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu", - memory.b_available,memory.b_size, cont_len); - if (memory.b_available < ((cont_len - + (unsigned long long)SAVE_FILE_BUFFERING_SIZE_50KB) - / (unsigned long long)memory.b_size)) /* 50KB buffering */ - { - ret = DA_ERR_DISK_FULL; - goto ERR; - } +#ifdef _ENABLE_OMA_DRM + if (is_content_drm_dm(file_info->mime_type)) { + /* FIXME Later : How can get the file size of DRM file. */ + return ret; } - } - -ERR: - return ret; -} - -da_result_t _check_this_partial_download_is_available(stage_info *stage, - http_msg_response_t *new_http_msg_response) -{ - da_result_t ret = DA_RESULT_OK; - da_bool_t b_ret = DA_FALSE; - char *origin_ETag = NULL; - char *new_ETag = NULL; - unsigned long long remained_content_len = 0; - da_storage_size_t memory; - char *value = NULL; - unsigned long long size = 0; - - DA_LOG_FUNC_LOGD(HTTPManager); - - origin_ETag - = GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage)); - - b_ret = http_msg_response_get_content_length(new_http_msg_response, - &size); - if (b_ret) { - remained_content_len = size; - size = 0; - DA_LOG(HTTPManager, "[remained_content_len][%lu]", remained_content_len); - } - - b_ret = http_msg_response_get_ETag(new_http_msg_response, &value); - if (b_ret) { - new_ETag = value; - value = NULL; - DA_SECURE_LOGD("[new ETag][%s]", new_ETag); - } else { - goto ERR; - } +#endif - if (origin_ETag && new_ETag && - 0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) { - DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!"); - /* FIXME Later : Need to detail error exception handling */ - ret = DA_ERR_NETWORK_FAIL; - /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */ - goto ERR; - } + get_file_size(file_info->file_path, &tmp_file_size); - if (remained_content_len) { - ret = get_available_memory(&memory); - if (DA_RESULT_OK == ret) { - DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu", - memory.b_available,memory.b_size, remained_content_len); - if (memory.b_available < ((remained_content_len - + SAVE_FILE_BUFFERING_SIZE_50KB) - / memory.b_size)) /* 50KB buffering */ - { - ret = DA_ERR_DISK_FULL; - goto ERR; - } + if (tmp_file_size != file_info->file_size) { + DA_SECURE_LOGE("Real file size[%llu], MISMATCH CONTENT SIZE", + tmp_file_size); + ret = DA_ERR_MISMATCH_CONTENT_SIZE; } } - -ERR: - if (new_ETag) { - free(new_ETag); - new_ETag = DA_NULL; - } - return ret; } -da_result_t _check_resume_download_is_available(stage_info *stage, - http_msg_response_t *new_http_msg_response) +da_ret_t __handle_event_http_final(http_raw_data_t *raw_data, da_info_t *da_info) { - da_result_t ret = DA_RESULT_OK; - da_bool_t b_ret = DA_FALSE; - char *origin_ETag = NULL; - char *new_ETag = NULL; - unsigned long long remained_content_len = 0; - da_storage_size_t memory; - char *value = NULL; - unsigned long long size = 0; - char *temp_file_path = DA_NULL; - req_dl_info *request_info = DA_NULL; - - DA_LOG_FUNC_LOGD(HTTPManager); - - request_info = GET_STAGE_TRANSACTION_INFO(stage); - origin_ETag - = GET_REQUEST_HTTP_USER_REQUEST_ETAG(request_info); + da_ret_t ret = DA_RESULT_OK; + http_state_t http_state = 0; + http_info_t *http_info = DA_NULL; + file_info_t *file_info = DA_NULL; - b_ret = http_msg_response_get_content_length(new_http_msg_response, - &size); - if (b_ret) { - remained_content_len = size; - size = 0; - DA_LOG(HTTPManager, "[remained_content_len][%lu]", remained_content_len); - } + DA_LOGV(""); - b_ret = http_msg_response_get_ETag(new_http_msg_response, &value); - if (b_ret) { - new_ETag = value; - value = NULL; - DA_SECURE_LOGD("[new ETag][%s]", new_ETag); - } else { - goto ERR; - } + NULL_CHECK_RET(da_info); + http_info = da_info->http_info; + NULL_CHECK_RET(http_info); + file_info = da_info->file_info; + NULL_CHECK_RET(file_info); + NULL_CHECK_RET(raw_data); - if (origin_ETag && new_ETag && - 0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) { - DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!"); - /* FIXME Later : Need to detail error exception handling */ - ret = DA_ERR_NETWORK_FAIL; - /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */ - goto ERR; - } + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGD("http_state[%s]", __get_state_str(http_state)); - if (remained_content_len) { - ret = get_available_memory(&memory); - if (DA_RESULT_OK == ret) { - DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu", - memory.b_available,memory.b_size, remained_content_len); - if (memory.b_available < ((remained_content_len - + SAVE_FILE_BUFFERING_SIZE_50KB) - / memory.b_size)) /* 50KB buffering */ - { - ret = DA_ERR_DISK_FULL; - goto ERR; - } + switch (http_state) { + case HTTP_STATE_REDIRECTED: + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_READY_TO_DOWNLOAD; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + break; + case HTTP_STATE_DOWNLOAD_REQUESTED: + DA_LOGV("case HTTP_STATE_DOWNLOAD_REQUESTED"); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_FINISH; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + break; + case HTTP_STATE_DOWNLOADING: + DA_LOGD("case HTTP_STATE_DOWNLOADING"); +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_TRUE) { + ret = file_write_complete_for_raf(file_info); + } else { + ret = file_write_complete(file_info); } - } - b_ret = http_msg_response_get_content_type(new_http_msg_response, &value); - if (b_ret) { - GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value; - value = NULL; - DA_SECURE_LOGD("[Content-Type][%s]", - GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info)); - } - temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(request_info); - get_file_size(temp_file_path, &size); - GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = remained_content_len + size; - DA_SECURE_LOGD("[Content-Length][%llu]", - GET_REQUEST_HTTP_HDR_CONT_LEN(request_info)); - - -ERR: - if (new_ETag) { - free(new_ETag); - new_ETag = DA_NULL; - } - - return ret; -} - - -da_result_t _check_downloaded_file_size_is_same_with_header_content_size( - stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - - req_dl_info *request_info = DA_NULL; - file_info *file_info_data = DA_NULL; - - char *real_file_path = DA_NULL; - unsigned long long content_size_from_real_file = 0; - unsigned long long content_size_from_http_header = 0; - - DA_LOG_FUNC_LOGD(HTTPManager); - - request_info = GET_STAGE_TRANSACTION_INFO(stage); - file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage); - - content_size_from_http_header - = GET_CONTENT_STORE_FILE_SIZE(file_info_data); - - if (content_size_from_http_header > 0) { - real_file_path - = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data); - - get_file_size(real_file_path, - &content_size_from_real_file); - - if (content_size_from_real_file - != content_size_from_http_header) { - DA_SECURE_LOGE("size from header = %llu, real size = %llu,\ - DA_ERR_MISMATCH_CONTENT_SIZE", - content_size_from_http_header, content_size_from_real_file); - ret = DA_ERR_MISMATCH_CONTENT_SIZE; +#else + ret = file_write_complete(file_info); +#endif + if (ret != DA_RESULT_OK) { + discard_download(file_info); + goto ERR; + } + ret = __check_file_size_with_header_content_size(file_info); + if(ret != DA_RESULT_OK) { + discard_download(file_info) ; + goto ERR; + } + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_FINISH; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + ret = send_client_update_progress_info(da_info); + break; + case HTTP_STATE_REQUEST_PAUSE: +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_TRUE) { + if (file_info->file_handle) + ret = file_write_complete_for_raf(file_info); + } else { + ret = file_write_complete(file_info); + } +#else + if (file_info->file_handle) { + ret = file_write_complete(file_info); +// send_client_update_progress_info(da_info); + } +#endif + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_PAUSED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + DA_LOGV("Server Notification code is set to NULL"); + break; + case HTTP_STATE_ABORTED: + case HTTP_STATE_CANCELED: + discard_download(file_info); + break; + case HTTP_STATE_REQUEST_CANCEL: +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_TRUE) { + ret = file_write_complete_for_raf(file_info); + } else { + ret = file_write_complete(file_info); + } +#else + ret = file_write_complete(file_info); +#endif + if (ret != DA_RESULT_OK) + goto ERR; + discard_download(file_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_CANCELED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + break; + case HTTP_STATE_PAUSED: + DA_LOGD("Remain paused stated"); + break; + default: +#ifdef _RAF_SUPPORT + if (http_info->is_raf_mode_confirmed == DA_TRUE) { + ret = file_write_complete_for_raf(file_info); + } else { + ret = file_write_complete(file_info); } +#else + ret = file_write_complete(file_info); +#endif + if (ret != DA_RESULT_OK) + goto ERR; + discard_download(file_info); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_FAILED; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + break; } - return ret; -} - -da_result_t _disconnect_transaction(stage_info *stage) -{ - da_result_t ret = DA_RESULT_OK; - int transaction_id = DA_INVALID_ID; - - DA_LOG_FUNC_LOGV(HTTPManager); - - transaction_id - = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage)); - - DA_LOG(HTTPManager, "transaction_id = %d slot_id = %d", transaction_id, GET_STAGE_DL_ID(stage)); - - if (transaction_id != DA_INVALID_ID) { - ret = PI_http_disconnect_transaction(transaction_id); - GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage)) - = DA_INVALID_ID; +ERR: + /* When file complete is failed */ + if (DA_RESULT_OK != ret) { + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_info->state = HTTP_STATE_DOWNLOAD_FINISH; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); } - + if (raw_data->body) + free(raw_data->body); + free(raw_data); return ret; } -da_result_t _cancel_transaction(stage_info *stage) +void __http_update_cb(http_raw_data_t *data, void *user_param) { - da_result_t ret = DA_RESULT_OK; - int transaction_id = DA_INVALID_ID; - - DA_LOG_FUNC_LOGD(HTTPManager); - - transaction_id - = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage)); - - DA_LOG(HTTPManager, "transaction_id = %d", transaction_id); - - if (transaction_id != DA_INVALID_ID) { - http_state_t state = 0; - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - state = GET_HTTP_STATE_ON_STAGE(stage); - if (state <= HTTP_STATE_DOWNLOAD_REQUESTED) { - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - ret = PI_http_cancel_transaction(transaction_id, DA_TRUE); - } else { - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage))); - ret = PI_http_cancel_transaction(transaction_id, DA_FALSE); - } - + http_raw_data_t *raw_data = DA_NULL; + da_info_t *da_info = DA_NULL; + if (!data || !user_param) { + DA_LOGE("NULL CHECK!: data, user_param"); + return; + } + DA_LOGV(""); + raw_data = data; + da_info = (da_info_t *)user_param; + + switch(data->type) { + case HTTP_EVENT_GOT_HEADER: + __handle_event_http_header(raw_data, da_info); + break; + case HTTP_EVENT_GOT_PACKET: + __handle_event_http_packet(raw_data, da_info); + break; + case HTTP_EVENT_FINAL: + __handle_event_http_final(raw_data, da_info); + break; +/* + case HTTP_EVENT_ABORT: + ret = __handle_event_http_abort(raw_data, da_info); + break; +*/ } - return ret; } -void __parsing_user_request_header(char *user_request_header, - char **out_field, char **out_value) +da_bool_t is_stopped_state(da_info_t *da_info) { - int len = 0; - char *pos = NULL; - char *temp_pos = NULL; - char *field = NULL; - char *value = NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!user_request_header) { - DA_LOG_ERR(HTTPManager, "user_request_header is NULL"); - goto ERR; - } - - pos = strchr(user_request_header, ':'); - if (!pos) { - DA_LOG_ERR(HTTPManager, "Fail to parse"); - goto ERR; - } - temp_pos = (char *)user_request_header; - while (*temp_pos) - { - if (temp_pos == pos || *temp_pos == ' ') { - len = temp_pos - user_request_header; - break; - } - temp_pos++; - } - if (len < 1) { - DA_LOG_ERR(HTTPManager, "Wrong field name"); - goto ERR; - } - field = (char *)calloc(1, len + 1); - if (!field) { - DA_LOG_ERR(HTTPManager, "Fail to calloc"); - goto ERR; - } - strncpy(field, user_request_header, len); - pos++; - while (*pos) - { - if (*pos != ' ') - break; - pos++; - } - len = strlen(pos) + 1; - value = (char *)calloc(1, len + 1); - if (!value) { - DA_LOG_ERR(HTTPManager, "Fail to calloc"); - goto ERR; - } - strncpy(value, pos, len); - *out_field = field; - *out_value = value; - DA_SECURE_LOGD("field[%s], value[%s]", field, value); - - return; -ERR: - if (field) { - free(field); - field = NULL; + http_info_t *http_info = DA_NULL; + http_state_t http_state; + NULL_CHECK_RET_OPT(da_info, DA_FALSE); + http_info = da_info->http_info; + NULL_CHECK_RET_OPT(http_info, DA_FALSE); + DA_MUTEX_LOCK(&(http_info->mutex_state)); + http_state = http_info->state; + DA_MUTEX_UNLOCK(&(http_info->mutex_state)); + switch (http_state) { + case HTTP_STATE_REQUEST_CANCEL: + case HTTP_STATE_CANCELED: + case HTTP_STATE_FAILED: + case HTTP_STATE_ABORTED: + //case HTTP_STATE_REQUEST_PAUSE: + //case HTTP_STATE_REQUEST_RESUME: + //case HTTP_STATE_WAIT_FOR_NET_ERR: + return DA_TRUE; + default: + return DA_FALSE; } - return; + return DA_FALSE; } - diff --git a/agent/download-agent-http-misc.c b/agent/download-agent-http-misc.c deleted file mode 100755 index 08cd8ec..0000000 --- a/agent/download-agent-http-misc.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "download-agent-http-misc.h" -#include "download-agent-debug.h" -#include "download-agent-dl-mgr.h" -#include "download-agent-plugin-conf.h" -#include "download-agent-client-mgr.h" - -#define DEFAULT_HTTP_ACCEPT_HEADERS \ - "Accept-Language: en\r\n" \ - "Accept-Charset: utf-8\r\n" \ - - -char *get_user_agent() -{ - char *uagent_str = DA_NULL; - - DA_LOG_FUNC_LOGV(Default); - - uagent_str = get_client_user_agent_string(); - if (!uagent_str) { - da_result_t ret = DA_RESULT_OK; - ret = get_user_agent_string(&uagent_str); - if (ret != DA_RESULT_OK) - return NULL; - } - return uagent_str; -} - -da_bool_t is_supporting_protocol(const char *protocol) -{ - if((protocol == NULL) || (1 > strlen(protocol))) - { - return DA_FALSE; - } - - if(!strcasecmp(protocol, "http")) - { - return DA_TRUE; - } - else if(!strcasecmp(protocol, "https")) - { - return DA_TRUE; - } - else - { - return DA_FALSE; - } - -} diff --git a/agent/download-agent-http-msg-handler.c b/agent/download-agent-http-msg-handler.c index 6064c37..231a61d 100755 --- a/agent/download-agent-http-msg-handler.c +++ b/agent/download-agent-http-msg-handler.c @@ -20,20 +20,19 @@ #include "download-agent-http-msg-handler.h" #include "download-agent-debug.h" -#include "download-agent-http-misc.h" #include "download-agent-encoding.h" // '.' and ';' are request from Vodafone -#define IS_TERMINATING_CHAR(c) ( ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) ) -#define IS_TERMINATING_CHAR_EX(c) ( ((c) == '"') || ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) ) -#define IS_URI_TERMINATING_CHAR(c) ( ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) ) +#define IS_TERMINATING_CHAR(c) ( ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) ) +#define IS_TERMINATING_CHAR_EX(c) ( ((c) == '"') || ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) ) +#define IS_URI_TERMINATING_CHAR(c) ( ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) ) enum parsing_type { WITH_PARSING_OPTION, WITHOUT_PARSING_OPTION }; -static da_result_t __http_header_add_field(http_header_t **head, +static da_ret_t __http_header_add_field(http_header_t **head, const char *field, const char *value, enum parsing_type type); static void __http_header_destroy_all_field(http_header_t **head); static da_bool_t __get_http_header_for_field( @@ -41,29 +40,27 @@ static da_bool_t __get_http_header_for_field( http_header_t **out_header); static void __exchange_header_value(http_header_t *header, const char *in_raw_value); - static http_header_options_t *__create_http_header_option(const char *field, const char *value); static void __http_header_destroy_all_option(http_header_options_t **head); static da_bool_t __get_http_header_option_for_field( http_header_options_t *header_option, const char *in_field, char **out_value); - static http_header_options_t *__parsing_N_create_option_str(char *org_str); static http_header_options_t *__parsing_options(char *org_str); static void __parsing_raw_value(http_header_t *http_header); -da_result_t http_msg_request_create(http_msg_request_t **http_msg_request) +da_ret_t http_msg_request_create(http_msg_request_t **http_msg_request) { http_msg_request_t *temp_http_msg_request = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); +// DA_LOGV(""); temp_http_msg_request = (http_msg_request_t *)calloc(1, sizeof(http_msg_request_t)); if (!temp_http_msg_request) { *http_msg_request = NULL; - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); return DA_ERR_FAIL_TO_MEMALLOC; } @@ -73,7 +70,7 @@ da_result_t http_msg_request_create(http_msg_request_t **http_msg_request) temp_http_msg_request->http_body = NULL; *http_msg_request = temp_http_msg_request; - DA_LOG_DEBUG(HTTPManager, "http_msg_request: %x", (unsigned int)(*http_msg_request)); + DA_LOGV( "http_msg_request: %x", (unsigned int)(*http_msg_request)); return DA_RESULT_OK; } @@ -82,99 +79,54 @@ void http_msg_request_destroy(http_msg_request_t **http_msg_request) { http_msg_request_t *temp_http_msg_request = *http_msg_request; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (temp_http_msg_request) { if (temp_http_msg_request->http_method) { free(temp_http_msg_request->http_method); temp_http_msg_request->http_method = NULL; } - if (temp_http_msg_request->url) { free(temp_http_msg_request->url); temp_http_msg_request->url = NULL; } - if (temp_http_msg_request->http_body) { free(temp_http_msg_request->http_body); temp_http_msg_request->http_body = NULL; } - __http_header_destroy_all_field(&(temp_http_msg_request->head)); - free(temp_http_msg_request); *http_msg_request = NULL; } - -} - -da_result_t http_msg_request_set_method(http_msg_request_t *http_msg_request, - const char *method) -{ - DA_LOG_FUNC_LOGD(HTTPManager); - - if (!http_msg_request || !method) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } - - // ToDo: check method is valid - - http_msg_request->http_method = strdup(method); - - DA_LOG(HTTPManager, "http method : %s", http_msg_request->http_method); - - return DA_RESULT_OK; -} - -da_result_t http_msg_request_get_method(http_msg_request_t *http_msg_request, - const char **method) -{ - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!http_msg_request) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } - - if (http_msg_request->http_method) { - *method = http_msg_request->http_method; - return DA_RESULT_OK; - } else { - *method = DA_NULL; - return DA_ERR_INVALID_ARGUMENT; - } } -da_result_t http_msg_request_set_url(http_msg_request_t *http_msg_request, +da_ret_t http_msg_request_set_url(http_msg_request_t *http_msg_request, const char *url) { - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (!http_msg_request) { - DA_LOG_ERR(HTTPManager, "http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT"); return DA_ERR_INVALID_ARGUMENT; } if (!url) { - DA_LOG_ERR(HTTPManager, "url is NULL; DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("url is NULL; DA_ERR_INVALID_ARGUMENT"); return DA_ERR_INVALID_URL; } http_msg_request->url = strdup(url); - - //DA_SECURE_LOGD("http url : %s", http_msg_request->url); - + DA_SECURE_LOGI("http url[%s]", http_msg_request->url); return DA_RESULT_OK; } -da_result_t http_msg_request_get_url(http_msg_request_t *http_msg_request, +da_ret_t http_msg_request_get_url(http_msg_request_t *http_msg_request, const char **url) { - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (!http_msg_request) { - DA_LOG_ERR(HTTPManager, "http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT"); return DA_ERR_INVALID_ARGUMENT; } @@ -187,76 +139,34 @@ da_result_t http_msg_request_get_url(http_msg_request_t *http_msg_request, } } -da_result_t http_msg_request_set_body(http_msg_request_t *http_msg_request, - const char *body) -{ - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!http_msg_request) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } - - if (!body) - return DA_RESULT_OK; - - http_msg_request->http_body = strdup(body); - - DA_SECURE_LOGD("http body : %s", http_msg_request->http_body); - - return DA_RESULT_OK; -} - -da_result_t http_msg_request_get_body(http_msg_request_t *http_msg_request, - const char **body) -{ - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!http_msg_request) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } - - if (http_msg_request->http_body) { - *body = http_msg_request->http_body; - return DA_RESULT_OK; - } else { - *body = DA_NULL; - return DA_ERR_INVALID_ARGUMENT; - } -} - -/* FIXME later : check to free filed and value after this API is called */ -da_result_t http_msg_request_add_field(http_msg_request_t *http_msg_request, +da_ret_t http_msg_request_add_field(http_msg_request_t *http_msg_request, const char *field, const char *value) { - DA_LOG_FUNC_LOGV(HTTPManager); + // DA_LOGV(""); if (!http_msg_request) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("Check NULL! : http_msg_request"); return DA_ERR_INVALID_ARGUMENT; } return __http_header_add_field(&(http_msg_request->head), field, value, WITHOUT_PARSING_OPTION); } -da_result_t http_msg_response_create(http_msg_response_t **http_msg_response) +da_ret_t http_msg_response_create(http_msg_response_t **http_msg_response) { http_msg_response_t *temp_http_msg_response = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); temp_http_msg_response = (http_msg_response_t *)calloc(1, sizeof(http_msg_response_t)); if (!temp_http_msg_response) { - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); return DA_ERR_FAIL_TO_MEMALLOC; } else { temp_http_msg_response->status_code = 0; temp_http_msg_response->head = NULL; - *http_msg_response = temp_http_msg_response; - return DA_RESULT_OK; } } @@ -265,59 +175,27 @@ void http_msg_response_destroy(http_msg_response_t **http_msg_response) { http_msg_response_t *temp_http_msg_response = *http_msg_response; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (temp_http_msg_response) { __http_header_destroy_all_field(&(temp_http_msg_response->head)); - free(temp_http_msg_response); *http_msg_response = DA_NULL; } } -da_result_t http_msg_response_set_status_code( - http_msg_response_t *http_msg_response, int status_code) -{ - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!http_msg_response) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } - - http_msg_response->status_code = status_code; - - return DA_RESULT_OK; -} - -da_result_t http_msg_response_get_status_code( - http_msg_response_t *http_msg_response, int *status_code) -{ - DA_LOG_FUNC_LOGD(HTTPManager); - - if (!http_msg_response) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } - - *status_code = http_msg_response->status_code; - - return DA_RESULT_OK; -} - -da_result_t http_msg_response_add_field(http_msg_response_t *http_msg_response, +da_ret_t http_msg_response_add_field(http_msg_response_t *http_msg_response, const char *field, const char *value) { - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (!http_msg_response) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("DA_ERR_INVALID_ARGUMENT"); return DA_ERR_INVALID_ARGUMENT; } - return __http_header_add_field(&(http_msg_response->head), field, value, WITH_PARSING_OPTION); } -da_result_t __http_header_add_field(http_header_t **head, +da_ret_t __http_header_add_field(http_header_t **head, const char *field, const char *value, enum parsing_type type) { http_header_t *pre = NULL; @@ -365,7 +243,7 @@ da_result_t __http_header_add_field(http_header_t **head, else *head = cur; } else { - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); return DA_ERR_FAIL_TO_MEMALLOC; } @@ -377,8 +255,6 @@ void __http_header_destroy_all_field(http_header_t **head) http_header_t *pre = NULL; http_header_t *cur = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); - cur = *head; while (cur) { @@ -386,25 +262,21 @@ void __http_header_destroy_all_field(http_header_t **head) free(cur->field); cur->field = DA_NULL; } - if (cur->value) { free(cur->value); cur->value = DA_NULL; } - if (cur->raw_value) { free(cur->raw_value); cur->raw_value = DA_NULL; } - __http_header_destroy_all_option(&(cur->options)); - + free(cur->options); + cur->options = DA_NULL; pre = cur; cur = cur->next; - free(pre); } - *head = DA_NULL; } @@ -418,13 +290,10 @@ http_header_options_t *__create_http_header_option(const char *field, if (option) { if (field) option->field = strdup(field); - if (value) option->value = strdup(value); - option->next = NULL; } - return option; } @@ -433,38 +302,34 @@ void __http_header_destroy_all_option(http_header_options_t **head) http_header_options_t *pre = NULL; http_header_options_t *cur = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + // DA_LOGV(""); cur = *head; while (cur) { if (cur->field) { - DA_LOG_VERBOSE("field= %s", cur->field); + DA_SECURE_LOGD("field= %s", cur->field); free(cur->field); cur->field = DA_NULL; } - if (cur->value) { free(cur->value); cur->value = DA_NULL; } - pre = cur; cur = cur->next; - free(pre); } - *head = DA_NULL; } -da_result_t http_msg_request_get_iter(http_msg_request_t *http_msg_request, +da_ret_t http_msg_request_get_iter(http_msg_request_t *http_msg_request, http_msg_iter_t *http_msg_iter) { - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (!http_msg_request) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("DA_ERR_INVALID_ARGUMENT"); return DA_ERR_INVALID_ARGUMENT; } @@ -473,17 +338,15 @@ da_result_t http_msg_request_get_iter(http_msg_request_t *http_msg_request, return DA_RESULT_OK; } -da_result_t http_msg_response_get_iter(http_msg_response_t *http_msg_response, +da_ret_t http_msg_response_get_iter(http_msg_response_t *http_msg_response, http_msg_iter_t *http_msg_iter) { if (!http_msg_response) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); + DA_LOGE("DA_ERR_INVALID_ARGUMENT"); return DA_ERR_INVALID_ARGUMENT; } *http_msg_iter = http_msg_response->head; - // DA_LOG_VERBOSE(HTTPManager, "retrieve iter = 0x%x", (unsigned int)http_msg_iter); - return DA_RESULT_OK; } @@ -492,16 +355,12 @@ da_bool_t http_msg_get_field_with_iter(http_msg_iter_t *http_msg_iter, { http_header_t *cur = *http_msg_iter; - // DA_LOG_VERBOSE(HTTPManager, "getting iter = 0x%x", (unsigned int)cur); - if (cur) { *out_field = cur->field; *out_value = cur->value; *http_msg_iter = cur->next; - return DA_TRUE; } else { - // DA_LOG_VERBOSE(HTTPManager, "end of iter"); return DA_FALSE; } } @@ -511,16 +370,12 @@ da_bool_t http_msg_get_header_with_iter(http_msg_iter_t *http_msg_iter, { http_header_t *cur = *http_msg_iter; - // DA_LOG_VERBOSE(HTTPManager, "getting iter = 0x%x", (unsigned int)cur); - if (cur) { *out_field = cur->field; *out_header = cur; *http_msg_iter = cur->next; - return DA_TRUE; } else { - // DA_LOG_VERBOSE(HTTPManager, "end of iter"); return DA_FALSE; } } @@ -531,21 +386,18 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str) char *option_value = NULL; int option_field_len = 0; int option_value_len = 0; - char *org_pos = NULL; int org_str_len = 0; - char *working_str = NULL; char *working_pos = NULL; char *working_pos_field_start = NULL; char *working_pos_value_start = NULL; - da_bool_t is_inside_quotation = DA_FALSE; da_bool_t is_working_for_field = DA_TRUE; int i = 0; http_header_options_t *option = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + // DA_LOGV(""); if (!org_str) return NULL; @@ -564,7 +416,6 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str) for (i = 0; i < org_str_len; i++) { if (*org_pos == '"') is_inside_quotation = !is_inside_quotation; - if (is_inside_quotation) { // Leave anything including blank if it is inside of double quotation mark. *working_pos = *org_pos; @@ -580,7 +431,6 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str) is_working_for_field = DA_FALSE; working_pos_value_start = working_pos; } - org_pos++; } else { *working_pos = *org_pos; @@ -598,21 +448,19 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str) strncpy(option_field, working_pos_field_start, option_field_len); } - if (option_value_len > 0 && working_pos_value_start) { option_value = (char *)calloc(1, option_value_len + 1); if (option_value) strncpy(option_value, working_pos_value_start, option_value_len); } - if (working_str) { free(working_str); working_pos = working_str = NULL; } -// DA_SECURE_LOGD("option_field = [%s], option_value = [%s]", -// option_field, option_value); + DA_SECURE_LOGD("option_field = [%s], option_value = [%s]", + option_field, option_value); if (option_field || option_value) { option = __create_http_header_option( @@ -621,7 +469,6 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str) free(option_field); option_field = NULL; } - if (option_value) { free(option_value); option_value = NULL; @@ -632,7 +479,7 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str) http_header_options_t *__parsing_options(char *org_str) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; http_header_options_t *head = NULL; http_header_options_t *pre = NULL; http_header_options_t *cur = NULL; @@ -643,7 +490,7 @@ http_header_options_t *__parsing_options(char *org_str) char *wanted_str_end = NULL; char *cur_pos = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (!org_str) return NULL; @@ -662,11 +509,10 @@ http_header_options_t *__parsing_options(char *org_str) wanted_str_end = org_str + strlen(org_str); cur_pos = NULL; } - wanted_str_len = wanted_str_end - wanted_str_start; wanted_str = (char *)calloc(1, wanted_str_len + 1); if (!wanted_str) { - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); ret = DA_ERR_FAIL_TO_MEMALLOC; goto ERR; } @@ -688,7 +534,6 @@ http_header_options_t *__parsing_options(char *org_str) ERR: if (ret != DA_RESULT_OK) __http_header_destroy_all_option(&head); - return head; } @@ -696,10 +541,8 @@ void __parsing_raw_value(http_header_t *http_header_field) { char *raw_value = NULL; char *option_str_start = NULL; - char *trimed_value = NULL; int trimed_value_len = 0; - char *trimed_value_start = NULL; char *trimed_value_end = NULL; @@ -710,7 +553,6 @@ void __parsing_raw_value(http_header_t *http_header_field) return; trimed_value_start = raw_value; - trimed_value_end = strchr(raw_value, ';'); if (!trimed_value_end) { // No options @@ -722,10 +564,9 @@ void __parsing_raw_value(http_header_t *http_header_field) // for trimed value trimed_value_len = trimed_value_end - trimed_value_start; - trimed_value = (char *)calloc(1, trimed_value_len + 1); if (!trimed_value) { - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); return; } strncpy(trimed_value, trimed_value_start, trimed_value_len); @@ -733,18 +574,15 @@ void __parsing_raw_value(http_header_t *http_header_field) // for option parsing option_str_start = trimed_value_end + 1; - http_header_field->options = __parsing_options(option_str_start); /////////////// show http_header_options_t *cur = NULL; - cur = http_header_field->options; while (cur) { // DA_SECURE_LOGD("field = [%s], value = [%s]", cur->field, cur->value); cur = cur->next; } - } da_bool_t __get_http_header_option_for_field( @@ -753,10 +591,10 @@ da_bool_t __get_http_header_option_for_field( { http_header_options_t *cur = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + // DA_LOGV(""); if (!header_option) { - DA_LOG_ERR(HTTPManager, "input header_option is NULL."); + DA_LOGE("input header_option is NULL."); return DA_FALSE; } @@ -773,7 +611,6 @@ da_bool_t __get_http_header_option_for_field( } cur = cur->next; } - return DA_FALSE; } @@ -784,12 +621,33 @@ da_bool_t __get_http_header_for_field(http_msg_response_t *http_msg_response, http_header_t *header = NULL; char *field = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + //DA_LOGV(""); http_msg_response_get_iter(http_msg_response, &http_msg_iter); while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) { if (field && header && !strncasecmp(field, in_field, strlen(field))) { -// DA_SECURE_LOGD("[%s][%s]", field, header->value); + //DA_SECURE_LOGD("[%s][%s]", field, header->value); + *out_header = header; + return DA_TRUE; + } + } + + return DA_FALSE; +} + +da_bool_t __get_http_req_header_for_field(http_msg_request_t *http_msg_request, + const char *in_field, http_header_t **out_header) +{ + http_msg_iter_t http_msg_iter; + http_header_t *header = NULL; + char *field = NULL; + + //DA_LOGV(""); + + http_msg_request_get_iter(http_msg_request, &http_msg_iter); + while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) { + if (field && header && !strncasecmp(field, in_field, strlen(field))) { + //DA_SECURE_LOGD("[%s][%s]", field, header->value); *out_header = header; return DA_TRUE; } @@ -800,7 +658,7 @@ da_bool_t __get_http_header_for_field(http_msg_response_t *http_msg_response, void __exchange_header_value(http_header_t *header, const char *in_raw_value) { - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (!header || !in_raw_value) return; @@ -811,7 +669,6 @@ void __exchange_header_value(http_header_t *header, const char *in_raw_value) free(header->value); header->value = DA_NULL; } - if (header->raw_value) free(header->raw_value); header->raw_value = strdup(in_raw_value); @@ -825,15 +682,14 @@ da_bool_t http_msg_response_get_content_type( da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); - b_ret = __get_http_header_for_field(http_msg_response, "Content-Type", - &header); + b_ret = __get_http_header_for_field(http_msg_response, + HTTP_FIELD_CONTENT_TYPE, &header); if (!b_ret) { - DA_LOG(HTTPManager, "no Content-Type"); + DA_LOGV("no Content-Type"); return DA_FALSE; } - if (out_type) *out_type = strdup(header->value); @@ -846,13 +702,13 @@ void http_msg_response_set_content_type(http_msg_response_t *http_msg_response, da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); if (!http_msg_response || !in_type) return; - b_ret = __get_http_header_for_field(http_msg_response, "Content-Type", - &header); + b_ret = __get_http_header_for_field(http_msg_response, + HTTP_FIELD_CONTENT_TYPE, &header); if (b_ret) { if (header->raw_value && (!strncmp(header->raw_value, in_type, strlen(header->raw_value)))) @@ -862,22 +718,22 @@ void http_msg_response_set_content_type(http_msg_response_t *http_msg_response, __exchange_header_value(header, in_type); } else { __http_header_add_field(&(http_msg_response->head), - "Content-Type", in_type, WITH_PARSING_OPTION); + HTTP_FIELD_CONTENT_TYPE, in_type, WITH_PARSING_OPTION); } } da_bool_t http_msg_response_get_content_length( - http_msg_response_t *http_msg_response, unsigned long long *out_length) + http_msg_response_t *http_msg_response, da_size_t *out_length) { da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); b_ret = __get_http_header_for_field(http_msg_response, - "Content-Length", &header); + HTTP_FIELD_CONTENT_LENGTH, &header); if (!b_ret) { - DA_LOG(HTTPManager, "no Content-Length"); + DA_LOGV( "no Content-Length"); return DA_FALSE; } @@ -894,32 +750,29 @@ da_bool_t http_msg_response_get_content_disposition( da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; char *file_name = NULL; - char *wanted_str = NULL; char *wanted_str_start = NULL; char *wanted_str_end = NULL; char *decoded_str = NULL; int wanted_str_len = 0; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); b_ret = __get_http_header_for_field(http_msg_response, - "Content-Disposition", &header); + HTTP_FIELD_CONTENT_DISPOSITION, &header); if (!b_ret) { - DA_LOG_VERBOSE(HTTPManager, "no Content-Disposition"); + DA_LOGV( "no Content-Disposition"); return DA_FALSE; } - if (out_disposition) *out_disposition = strdup(header->value); - if (!out_file_name) return DA_FALSE; b_ret = __get_http_header_option_for_field(header->options, "filename", &file_name); if (!b_ret) { - DA_LOG(HTTPManager, "no option"); + DA_LOGV( "no option"); return DA_FALSE; } @@ -936,14 +789,14 @@ da_bool_t http_msg_response_get_content_disposition( wanted_str_len = wanted_str_end - wanted_str_start; wanted_str = (char*)calloc(1, wanted_str_len + 1); if (!wanted_str) { - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); return DA_FALSE; } strncpy(wanted_str, wanted_str_start, wanted_str_len); b_ret = is_base64_encoded_word(wanted_str); if (b_ret) { - DA_LOG(HTTPManager, "It's base64 encoded-word string"); + DA_LOGV("It's base64 encoded-word string"); if (DA_RESULT_OK == decode_base64_encoded_str( wanted_str, &decoded_str)) { DA_SECURE_LOGD("base64 decoded str = [%s]", decoded_str); @@ -951,10 +804,10 @@ da_bool_t http_msg_response_get_content_disposition( wanted_str = decoded_str; decoded_str = NULL; } else { - DA_LOG(HTTPManager, "Fail to base64 decode. Just use un-decoded string."); + DA_LOGV("Fail to base64 decode. Just use un-decoded string."); } } else { - DA_LOG(HTTPManager, "It's NOT base64 encoded-word string"); + DA_LOGV("It's NOT base64 encoded-word string"); } decode_url_encoded_str(wanted_str, &decoded_str); /* If it is url encoded string */ @@ -964,14 +817,11 @@ da_bool_t http_msg_response_get_content_disposition( wanted_str = decoded_str; decoded_str = NULL; } - *out_file_name = wanted_str; - - DA_SECURE_LOGD("out_file_name = [%s]", *out_file_name); - + DA_SECURE_LOGI("out_file_name = [%s]", *out_file_name); return DA_TRUE; } else { - DA_LOG_ERR(HTTPManager, "Not matched \" !"); + DA_LOGE("Not matched \" !"); return DA_FALSE; } } @@ -983,51 +833,54 @@ da_bool_t http_msg_response_get_ETag(http_msg_response_t *http_msg_response, da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); - b_ret = __get_http_header_for_field(http_msg_response, "ETag", &header); + b_ret = __get_http_header_for_field(http_msg_response, HTTP_FIELD_ETAG, + &header); if (!b_ret) { - DA_LOG_VERBOSE(HTTPManager, "no ETag"); + DA_LOGV( "no ETag"); return DA_FALSE; } - if (out_value) *out_value = strdup(header->value); return DA_TRUE; } -da_bool_t http_msg_response_get_date(http_msg_response_t *http_msg_response, +#ifdef _RAF_SUPPORT +da_bool_t http_msg_response_get_RAF_mode(http_msg_response_t *http_msg_response, char **out_value) { da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); - b_ret = __get_http_header_for_field(http_msg_response, "Date", &header); + b_ret = __get_http_header_for_field(http_msg_response, HTTP_FIELD_RAF_MODE, + &header); if (!b_ret) { - DA_LOG(HTTPManager, "no Date"); + DA_LOGV( "no RAF mode"); return DA_FALSE; } - if (out_value) *out_value = strdup(header->value); return DA_TRUE; } +#endif -da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response, +da_bool_t http_msg_response_get_date(http_msg_response_t *http_msg_response, char **out_value) { da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); - b_ret = __get_http_header_for_field(http_msg_response, "Location", &header); + b_ret = __get_http_header_for_field(http_msg_response, + HTTP_FIELD_DATA, &header); if (!b_ret) { - DA_LOG(HTTPManager, "no Location"); + DA_LOGV( "no Date"); return DA_FALSE; } if (out_value) @@ -1036,120 +889,27 @@ da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response, return DA_TRUE; } -da_result_t http_msg_response_get_boundary( - http_msg_response_t *http_msg_response, char **out_val) -{ - da_result_t ret = DA_RESULT_OK; - - http_msg_iter_t http_msg_iter; - char *field = NULL; - char *value = NULL; - char *boundary = NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!http_msg_response) { - DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT"); - return DA_ERR_INVALID_ARGUMENT; - } - - http_msg_response_get_iter(http_msg_response, &http_msg_iter); - while (http_msg_get_field_with_iter(&http_msg_iter, &field, &value)) { - if ((field != DA_NULL) && (value != DA_NULL)) { - if (!strncasecmp(field, "Content-Type", - strlen("Content-Type"))) { - char *org_str = NULL; - char *boundary_str_start = NULL; - char *boundary_value_start = NULL; - char *boundary_value_end = NULL; - int boundary_value_len = 0; - - org_str = value; - - boundary_str_start - = strstr(org_str, "boundary"); - if (boundary_str_start) { - DA_LOG(HTTPManager, "boundary_str_start = %s", boundary_str_start); - // this "Content-Type" value has "boundary" in it, so get the value - boundary_value_start = strchr( - boundary_str_start, '"'); - boundary_value_start += 1; // start without " - - boundary_value_end = strchr( - boundary_value_start, '"'); - boundary_value_len = boundary_value_end - - boundary_value_start; - - DA_LOG(HTTPManager, "boundary_value_start = %s", boundary_value_start); - DA_LOG(HTTPManager, "boundary_value_end = %s", boundary_value_end); - DA_LOG(HTTPManager, "boundary_value_len = %d", boundary_value_len); - - } else { - // no "boundary" field on this "Content-Type" value - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - // end of clear - - boundary = (char *)calloc(1, - boundary_value_len + 1); - if (!boundary) { - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - - goto ERR; - } - strncpy(boundary, boundary_value_start, - boundary_value_len); - DA_SECURE_LOGD("[boundary][%s]", boundary); - break; - } - } - } - - *out_val = boundary; - -ERR: - return ret; -} - -char *get_http_response_header_raw(http_msg_response_t *http_msg_response) +da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response, + char **out_value) { - http_msg_iter_t http_msg_iter; + da_bool_t b_ret = DA_FALSE; http_header_t *header = NULL; - char *field = NULL; - char tmp_buf[1024*4] = {0,}; - char line_buf[1024] = {0,}; - int len = 0; - char *buff = NULL; - DA_LOG_FUNC_LOGV(HTTPManager); + DA_LOGV(""); - http_msg_response_get_iter(http_msg_response, &http_msg_iter); - while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) { - if (field && header) { - // FIXME later :: buffer length is more than total length. think about getting header's conent length from libsoup - len = strlen(field) + strlen(header->value) + 2; - snprintf(line_buf, len,"%s:%s", field, header->value); - strncat(tmp_buf, line_buf, len); - strcat(tmp_buf, "\n"); - } - } - if (strlen(tmp_buf) > 0) { - buff = (char *)calloc(1, strlen(tmp_buf) + 1); - if (buff == DA_NULL) { - DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC"); - return DA_NULL; - } - memcpy(buff, tmp_buf, strlen(tmp_buf)); - DA_SECURE_LOGD("\n---raw response header---\n%s\n------\n",buff); - return buff; - } else { - return DA_NULL; + b_ret = __get_http_header_for_field(http_msg_response, + HTTP_FIELD_LOCATION, &header); + if (!b_ret) { + DA_LOGV( "no Location"); + return DA_FALSE; } + if (out_value) + *out_value = strdup(header->value); + + return DA_TRUE; } -char *_stristr(const char *long_str, const char *find_str) +char *__stristr(const char *long_str, const char *find_str) { int i = 0; int length_long = 0; @@ -1159,7 +919,7 @@ char *_stristr(const char *long_str, const char *find_str) char *look_ptr = NULL; if (long_str == NULL || find_str == NULL) { - DA_LOG_ERR(Default,"INVALID ARGUMENT"); + DA_LOGE("INVALID ARGUMENT"); return NULL; } @@ -1169,14 +929,14 @@ char *_stristr(const char *long_str, const char *find_str) org_ptr = (char*)calloc(1, length_long + 1); if (org_ptr == NULL) { - DA_LOG_ERR(Default,"INVALID ARGUMENT"); + DA_LOGE("INVALID ARGUMENT"); return NULL; } look_ptr = (char*)calloc(1, length_find + 1); if (look_ptr == NULL) { - DA_LOG_ERR(Default,"INVALID ARGUMENT"); + DA_LOGE("INVALID ARGUMENT"); free(org_ptr); return NULL; } @@ -1191,7 +951,6 @@ char *_stristr(const char *long_str, const char *find_str) } else { org_ptr[i] = long_str[i]; } - i++; } @@ -1207,7 +966,6 @@ char *_stristr(const char *long_str, const char *find_str) } else { look_ptr[i] = find_str[i]; } - i++; } @@ -1233,7 +991,6 @@ da_bool_t extract_attribute_from_header( const char *szFindStr, char **ppRtnValue) { - char *pValuePos = NULL; int index = 0; int startPos = 0; @@ -1241,21 +998,19 @@ da_bool_t extract_attribute_from_header( int need_to_end_quataion_mark = 0; if (szHeadStr == DA_NULL || szFindStr == DA_NULL) { - DA_LOG_ERR(Default,"INVALID ARGUMENT"); + DA_LOGE("INVALID ARGUMENT"); return DA_FALSE; } - if (strlen(szHeadStr) <= 0 || strlen(szFindStr) <= 0) { - DA_LOG_ERR(Default,"INVALID ARGUMENT");; + DA_LOGE("INVALID ARGUMENT");; return DA_FALSE; } - if (ppRtnValue == NULL) { return DA_FALSE; } - pValuePos = _stristr(szHeadStr, (char*)szFindStr); + pValuePos = __stristr(szHeadStr, (char*)szFindStr); if (pValuePos == NULL) { *ppRtnValue = NULL; goto ERR; @@ -1287,7 +1042,8 @@ da_bool_t extract_attribute_from_header( startPos = index; /* Find the end of data. */ - if (0 == strncasecmp(szFindStr, "Location", strlen("Location")))//terminate character list does not contain ';' in case of URI + if (0 == strncasecmp(szFindStr, HTTP_FIELD_LOCATION, + strlen(HTTP_FIELD_LOCATION)))//terminate character list does not contain ';' in case of URI { while (DA_FALSE == IS_URI_TERMINATING_CHAR(pValuePos[index])) { index++; @@ -1305,14 +1061,14 @@ da_bool_t extract_attribute_from_header( strLen = index - startPos; if (strLen < 1) { - DA_LOG_ERR(Default," strLen is < 1"); + DA_LOGE(" strLen is < 1"); goto ERR; } *ppRtnValue = (char*)calloc(1, sizeof(char) * (strLen + 1)); if (*ppRtnValue == NULL) { - DA_LOG_ERR(Default," *ppRtnValue is NULL"); + DA_LOGE(" *ppRtnValue is NULL"); goto ERR; } @@ -1320,14 +1076,50 @@ da_bool_t extract_attribute_from_header( *(*ppRtnValue + strLen) = '\0'; return DA_TRUE; - ERR: - if (*ppRtnValue) { free(*ppRtnValue); *ppRtnValue = NULL; } - return DA_FALSE; } +da_bool_t http_msg_request_get_if_range(http_msg_request_t *http_msg_request, + char **out_value) +{ + da_bool_t b_ret = DA_FALSE; + http_header_t *header = NULL; + + DA_LOGV(""); + + b_ret = __get_http_req_header_for_field(http_msg_request, HTTP_FIELD_IF_RANGE, + &header); + if (!b_ret) { + DA_LOGV( "no If Range"); + return DA_FALSE; + } + if (out_value) + *out_value = strdup(header->value); + + return DA_TRUE; +} + +da_bool_t http_msg_request_get_range(http_msg_request_t *http_msg_request, + char **out_value) +{ + da_bool_t b_ret = DA_FALSE; + http_header_t *header = NULL; + + DA_LOGV(""); + + b_ret = __get_http_req_header_for_field(http_msg_request, HTTP_FIELD_RANGE, + &header); + if (!b_ret) { + DA_LOGV( "no Range"); + return DA_FALSE; + } + if (out_value) + *out_value = strdup(header->value); + + return DA_TRUE; +} diff --git a/agent/download-agent-http-queue.c b/agent/download-agent-http-queue.c deleted file mode 100755 index 06fe084..0000000 --- a/agent/download-agent-http-queue.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "download-agent-http-queue.h" -#include "download-agent-http-mgr.h" -#include "download-agent-debug.h" -#include "download-agent-pthread.h" - -void init_q_event_data_http(q_event_t *q_event); -void init_q_event_control(q_event_t *q_event); - -void Q_init_queue(queue_t *queue) -{ - queue->having_data = DA_FALSE; - queue->control_head = DA_NULL; - queue->data_head = DA_NULL; - queue->queue_size = 0; - - _da_thread_mutex_init(&(queue->mutex_queue), DA_NULL); - _da_thread_cond_init(&(queue->cond_queue), DA_NULL); -} - -void Q_destroy_queue(queue_t *queue) -{ - q_event_t *event = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - do { - Q_pop_event(queue, &event); - Q_destroy_q_event(&event); - } while(event); - - queue->having_data = DA_FALSE; - queue->control_head = DA_NULL; - queue->data_head = DA_NULL; - queue->queue_size = 0; - - _da_thread_mutex_destroy(&(queue->mutex_queue)); - _da_thread_cond_destroy(&(queue->cond_queue)); -} - -void Q_init_q_event(q_event_t *q_event) -{ - switch(q_event->event_type) { - case Q_EVENT_TYPE_DATA_HTTP: - init_q_event_data_http(q_event); - break; - - case Q_EVENT_TYPE_DATA_DRM: - break; - - case Q_EVENT_TYPE_CONTROL: - init_q_event_control(q_event); - break; - } - - q_event->size = 0; - q_event->next = DA_NULL; -} - -void Q_destroy_q_event(q_event_t **in_q_event) -{ - q_event_t *q_event = DA_NULL; - q_event = *in_q_event; - - if(q_event == DA_NULL) - return; - - switch(q_event->event_type) { - case Q_EVENT_TYPE_DATA_HTTP: - init_q_event_data_http(q_event); - q_event->size = 0; - q_event->next = DA_NULL; - free(q_event); - break; - - case Q_EVENT_TYPE_DATA_DRM: - q_event->size = 0; - q_event->next = DA_NULL; - free(q_event); - break; - - case Q_EVENT_TYPE_CONTROL: - init_q_event_control(q_event); - q_event->size = 0; - q_event->next = DA_NULL; - free(q_event); - break; - } -} - -da_result_t Q_make_control_event(q_event_type_control control_type, q_event_t **out_event) -{ - da_result_t ret = DA_RESULT_OK; - q_event_t *q_event = DA_NULL; - - DA_LOG_FUNC_LOGD(HTTPManager); - - q_event = (q_event_t *)calloc(1, sizeof(q_event_t)); - if(q_event == DA_NULL) { - DA_LOG_ERR(HTTPManager, "calloc fail for q_event"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - - *out_event = DA_NULL; - } else { - q_event->event_type = Q_EVENT_TYPE_CONTROL; - q_event->type.q_event_control.control_type = control_type; - q_event->next = DA_NULL; - - *out_event = q_event; - } - - return ret; -} - -da_result_t Q_make_http_data_event(q_event_type_data data_type, q_event_t **out_event) -{ - da_result_t ret = DA_RESULT_OK; - q_event_t *q_event = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - q_event = (q_event_t *)calloc(1, sizeof(q_event_t)); - if(q_event == DA_NULL) { - DA_LOG_ERR(HTTPManager, "calloc fail for q_event"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - *out_event = DA_NULL; - } else { - q_event->event_type = Q_EVENT_TYPE_DATA_HTTP; - q_event->type.q_event_data_http.data_type = data_type; - q_event->next = DA_NULL; - - *out_event = q_event; - -// DA_LOG_VERBOSE(HTTPManager, "made event = %x", *out_event); - } - - return ret; - -} - -da_result_t Q_set_status_code_on_http_data_event(q_event_t *q_event, int status_code) -{ - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) { - DA_LOG_ERR(HTTPManager, "status_code can be set only for Q_EVENT_TYPE_DATA_HTTP."); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - q_event->type.q_event_data_http.status_code = status_code; - -// DA_LOG_VERBOSE(HTTPManager, "status_code = %d, q_event = %x", q_event->type.q_event_data_http.status_code, q_event); - -ERR: - return ret; - -} - -da_result_t Q_set_http_body_on_http_data_event(q_event_t *q_event, int body_len, char *body_data) -{ - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) { - DA_LOG_ERR(HTTPManager, "http body can be set only for Q_EVENT_TYPE_DATA_HTTP."); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - q_event->type.q_event_data_http.body_len = body_len; - q_event->type.q_event_data_http.body_data = body_data; - q_event->size = body_len; - -// DA_LOG_VERBOSE(HTTPManager, "body_len = %d, body_data = %x, q_event = %x", q_event->type.q_event_data_http.body_len, q_event->type.q_event_data_http.body_data, q_event); - -ERR: - return ret; - -} - -da_result_t Q_set_error_type_on_http_data_event(q_event_t *q_event, int error_type) -{ - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) { - DA_LOG_ERR(HTTPManager, "error_type can be set only for Q_EVENT_TYPE_DATA_HTTP."); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - q_event->type.q_event_data_http.error_type = error_type; - - DA_LOG_VERBOSE(HTTPManager, "error_type = %d, q_event = %p", q_event->type.q_event_data_http.error_type, q_event); - -ERR: - return ret; - -} - -da_bool_t Q_push_event(const queue_t *in_queue, const q_event_t *in_event) -{ - da_bool_t b_ret = DA_FALSE; - queue_t *queue = (queue_t *)in_queue; - - _da_thread_mutex_lock (&(queue->mutex_queue)); - b_ret = Q_push_event_without_lock(in_queue, in_event); - _da_thread_mutex_unlock (&(queue->mutex_queue)); - - return b_ret; -} - -da_bool_t Q_push_event_without_lock(const queue_t *in_queue, const q_event_t *in_event) -{ - da_bool_t b_ret = DA_FALSE; - queue_t *queue = (queue_t *)in_queue; - q_event_t *event = (q_event_t *)in_event; - q_event_type event_type; - q_event_t *head = DA_NULL; - q_event_t *cur = DA_NULL; - -// DA_LOG_VERBOSE(HTTPManager, "queue = %x", in_queue); - - event_type = event->event_type; - -// _da_thread_mutex_lock (&(queue->mutex_queue)); - - if(event_type == Q_EVENT_TYPE_CONTROL) { - head = queue->control_head; - if(head == DA_NULL) { - queue->control_head = event; - } else { - cur = head; - - while(cur->next != DA_NULL) { - cur = cur->next; - } - cur->next= event; - } - b_ret = DA_TRUE; - } else { - if((event->size == 0) || (queue->queue_size < MAX_QUEUE_SIZE)) { - head = queue->data_head; - if(head == DA_NULL) { - queue->data_head = event; - } else { - cur = head; - while(cur->next != DA_NULL) { - cur = cur->next; - } - cur->next= event ; - } - - queue->queue_size += event->size; -// DA_LOG_VERBOSE(HTTPManager, "queue size is %d", queue->queue_size); - - b_ret = DA_TRUE; - } else { - DA_LOG_CRITICAL(HTTPManager, "rejected event's size is %d queue_size %d", event->size, queue->queue_size); - b_ret = DA_FALSE; - } - } - - queue->having_data = DA_TRUE; - Q_wake_up(queue); -// _da_thread_mutex_unlock (&(queue->mutex_queue)); - return b_ret; -} - -void Q_pop_event(const queue_t *in_queue, q_event_t **out_event) -{ - queue_t *queue = (queue_t*)in_queue; - -// DA_LOG_VERBOSE(HTTPManager, "queue = %x", in_queue); - - /** Pop Priority - * 1. If there are control event, control event should pop first - * 2. If there is no control event, data event should pop - * 3. If there is no control and data event on queue, pop NULL - */ - - _da_thread_mutex_lock (&(queue->mutex_queue)); - - if(queue->control_head != DA_NULL) {/* Priority 1 */ - *out_event = queue->control_head; - queue->control_head = queue->control_head->next; - } else { - if(queue->data_head != DA_NULL) {/* Priority 2 */ - *out_event = queue->data_head; - queue->data_head = queue->data_head->next; - queue->queue_size -= (*out_event)->size; - DA_LOG_VERBOSE(HTTPManager, "queue size is %d", queue->queue_size); - } else {/* Priority 3 */ - *out_event = DA_NULL; - } - } - - if((queue->control_head == DA_NULL) && (queue->data_head == DA_NULL)) { - queue->having_data = DA_FALSE; - } else { - queue->having_data = DA_TRUE; - } - - _da_thread_mutex_unlock (&(queue->mutex_queue)); - -} - -void Q_goto_sleep(const queue_t *in_queue) -{ - DA_LOG_VERBOSE(HTTPManager, "sleep for %p", in_queue); - -//** SHOULD NOT use mutex **// - -// _da_thread_mutex_lock (&(in_queue->mutex_queue)); - _da_thread_cond_wait((pthread_cond_t*)(&(in_queue->cond_queue)),(pthread_mutex_t*) (&(in_queue->mutex_queue))); -// _da_thread_mutex_unlock (&(in_queue->mutex_queue)); -} - -void Q_wake_up(const queue_t *in_queue) -{ - DA_LOG_VERBOSE(HTTPManager, "wake up for %p", in_queue); - -//** SHOULD NOT use mutex **// - -// _da_thread_mutex_lock (&(in_queue->mutex_queue)); - _da_thread_cond_signal((pthread_cond_t*)(&(in_queue->cond_queue))); -// _da_thread_mutex_unlock (&(in_queue->mutex_queue)); -} - -void init_q_event_data_http(q_event_t *q_event) -{ - q_event_data_http_t *q_event_data_http; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if(q_event->event_type == Q_EVENT_TYPE_DATA_HTTP) { - q_event_data_http = &(q_event->type.q_event_data_http); - - if(q_event_data_http) { - q_event_data_http->status_code = 0; - if(q_event_data_http->http_response_msg) { - http_msg_response_destroy(&(q_event_data_http->http_response_msg)); - q_event_data_http->http_response_msg = DA_NULL; - } - - if(q_event_data_http->body_len > 0 ) { - if (q_event_data_http->body_data) { - free(q_event_data_http->body_data); - q_event_data_http->body_data = DA_NULL; - } - } - q_event_data_http->error_type = 0; - } - } -} - -void init_q_event_control(q_event_t *q_event) -{ - q_event_control_t *q_event_control; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if(q_event->event_type == Q_EVENT_TYPE_CONTROL) { - q_event_control = &(q_event->type.q_event_control); - if(q_event_control) { - q_event_control->control_type = Q_EVENT_TYPE_CONTROL_NONE; - } - } - -} diff --git a/agent/download-agent-interface.c b/agent/download-agent-interface.c index 7d994e6..0b19813 100755 --- a/agent/download-agent-interface.c +++ b/agent/download-agent-interface.c @@ -15,214 +15,131 @@ */ #include "download-agent-interface.h" -#include "download-agent-debug.h" -#include "download-agent-utils.h" -#include "download-agent-http-mgr.h" -#include "download-agent-http-misc.h" -#include "download-agent-client-mgr.h" #include "download-agent-dl-mgr.h" -#include "download-agent-basic.h" -#include "download-agent-file.h" -int da_init( - da_client_cb_t *da_client_callback) +int da_init() { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGD(Default); - - if (!da_client_callback) { - ret = DA_ERR_INVALID_ARGUMENT; - return ret; - } - - ret = init_log_mgr(); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = init_client_app_mgr(); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = reg_client_app(da_client_callback); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = init_http_mgr(); - if (ret != DA_RESULT_OK) - goto ERR; - - ret = init_download_mgr(); - if (ret != DA_RESULT_OK) - goto ERR; - -ERR: - if (DA_RESULT_OK != ret) - da_deinit(); - - DA_LOG_CRITICAL(Default, "Return ret = %d", ret); - + DA_LOGV(""); + da_ret_t ret = DA_RESULT_OK; + DA_LOGI("Return ret = %d", ret); return ret; } -/* TODO:: deinit should clean up all the clients... */ int da_deinit() { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGV(Default); - - deinit_http_mgr(); - deinit_download_mgr(); - /* Do not clean temporary download path - * The client can resume or restart download with temporary file in case of failed download. - */ - dereg_client_app(); - DA_LOG(Default, "====== da_deinit EXIT ====="); + da_ret_t ret = DA_RESULT_OK; + DA_LOGV(""); + destroy_da_info_list(); + DA_LOGI("====== da_deint EXIT ====="); return ret; } -int da_start_download( - const char *url, - int *download_id) +int da_start_download(const char *url, req_data_t *ext_data, + da_cb_t *da_cb_data, int *download_id) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_FUNC_LOGD(Default); - - *download_id = DA_INVALID_ID; - - if (DA_FALSE == is_valid_url(url, &ret)) - goto ERR; - - DA_SECURE_LOGI("url = %s", url); - - ret = start_download(url, download_id); - if (ret != DA_RESULT_OK) - goto ERR; - -ERR: - DA_LOG_CRITICAL(Default, "Return: Dl req id = %d, ret = %d", *download_id, ret); - return ret; -} - -int da_start_download_with_extension( - const char *url, - extension_data_t *extension_data, - int *download_id -) -{ - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; int req_header_count = 0; int i = 0; - - DA_LOG_FUNC_LOGV(Default); + int da_id = DA_INVALID_ID; + da_info_t *da_info = DA_NULL; *download_id = DA_INVALID_ID; - if (DA_FALSE == is_valid_url(url, &ret)) - goto ERR; - - DA_SECURE_LOGI("url = %s", url); - - if (ret != DA_RESULT_OK) - goto ERR; - if (!extension_data) { - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - if (extension_data->request_header_count > 0) { - DA_LOG_VERBOSE(Default, "input request_header_count = [%d]", - extension_data->request_header_count); - for (i = 0; i < extension_data->request_header_count; i++) { - if (extension_data->request_header[i]) { + if (ext_data->request_header_count > 0) { + DA_LOGI("request_header_count[%d]", ext_data->request_header_count); + for (i = 0; i < ext_data->request_header_count; i++) { + if (ext_data->request_header[i]) { req_header_count++; - DA_SECURE_LOGI("request_header = [%s]", - extension_data->request_header[i]); + DA_SECURE_LOGI("request_header[%s]", ext_data->request_header[i]); } } - DA_LOG_VERBOSE(Default, "actual request_header_count = [%d]", req_header_count); - if (extension_data->request_header_count != req_header_count) { - DA_LOG_ERR(Default, "Request header count is not matched with number of request header array"); - extension_data->request_header = NULL; - extension_data->request_header_count = 0; + DA_LOGI("actual request_header_count[%d]", req_header_count); + if (ext_data->request_header_count != req_header_count) { + DA_LOGE("Request header count is not matched with number of request header array"); ret = DA_ERR_INVALID_ARGUMENT; goto ERR; } } - if (extension_data->install_path) { - if (!is_dir_exist(extension_data->install_path)) - return DA_ERR_INVALID_INSTALL_PATH; - DA_SECURE_LOGI("install_path = [%s]", extension_data->install_path); - } - - if (extension_data->file_name) - DA_SECURE_LOGI("file_name = [%s]", extension_data->file_name); - if (extension_data->temp_file_path) - DA_SECURE_LOGI("temp_file_path = [%s]", extension_data->temp_file_path); - if (extension_data->etag) - DA_SECURE_LOGI("etag = [%s]", extension_data->etag); - if (extension_data->pkg_name) - DA_SECURE_LOGI("pkg_name = [%s]", extension_data->pkg_name); - if (extension_data->user_data) - DA_LOG_VERBOSE(Default, "user_data = [%p]", extension_data->user_data); + if (ext_data->install_path) + DA_SECURE_LOGI("install path[%s]", ext_data->install_path); + if (ext_data->file_name) + DA_SECURE_LOGI("file_name[%s]", ext_data->file_name); + if (ext_data->temp_file_path) + DA_SECURE_LOGI("temp_file_path[%s]", ext_data->temp_file_path); + if (ext_data->etag) + DA_SECURE_LOGI("etag[%s]", ext_data->etag); + if (ext_data->pkg_name) + DA_SECURE_LOGI("pkg_name[%s]", ext_data->pkg_name); + if (ext_data->network_bonding) + DA_LOGD("network bonding option[%d]", ext_data->network_bonding); + if (ext_data->user_req_data) + DA_LOGI("user_req_data[%p]", ext_data->user_req_data); + if (ext_data->user_client_data) + DA_LOGI("user_client_data[%p]", ext_data->user_client_data); + + ret = get_available_da_id(&da_id); + if (ret != DA_RESULT_OK) + goto ERR; - ret = start_download_with_extension(url, download_id, extension_data); + da_info = da_info_list[da_id]; + da_info->da_id = da_id; + ret = copy_user_input_data(da_info, url, ext_data, da_cb_data); + if (ret != DA_RESULT_OK) + goto ERR; + *download_id = da_id; + ret = start_download(da_info); ERR: - DA_LOG_CRITICAL(Default, "Return: Dl req id = %d, ret = %d", *download_id, ret); + DA_LOGI("Return:id[%d],ret[%d]", *download_id, ret); return ret; } int da_cancel_download(int download_id) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_VERBOSE(Default, "Cancel for dl_id = %d", download_id); + da_ret_t ret = DA_RESULT_OK; - ret = cancel_download(download_id); + DA_LOGV("download_id[%d]", download_id); + ret = cancel_download(download_id, DA_TRUE); + DA_LOGI("Return:id[%d],ret[%d]", download_id, ret); + return ret; +} - DA_LOG_CRITICAL(Default, "Return: Cancel id = %d, ret = %d", download_id, ret); +int da_cancel_download_without_update(int download_id) +{ + da_ret_t ret = DA_RESULT_OK; + DA_LOGV("download_id[%d]", download_id); + ret = cancel_download(download_id, DA_FALSE); + DA_LOGI("Return:id[%d],ret[%d]", download_id, ret); return ret; } int da_suspend_download(int download_id) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_VERBOSE(Default, "Suspend for dl_id = %d", download_id); - + da_ret_t ret = DA_RESULT_OK; + DA_LOGV("download_id[%d]", download_id); ret = suspend_download(download_id, DA_TRUE); - - DA_LOG_CRITICAL(Default, "Return: Suspend id = %d, ret = %d", download_id, ret); + DA_LOGI("Return:id[%d],ret[%d]", download_id, ret); return ret; } int da_suspend_download_without_update(int download_id) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_VERBOSE(Default, "Suspend for dl_id = %d", download_id); - + da_ret_t ret = DA_RESULT_OK; + DA_LOGV("download_id[%d]", download_id); ret = suspend_download(download_id, DA_FALSE); - - DA_LOG_CRITICAL(Default, "Return: Suspend id = %d, ret = %d", download_id, ret); + DA_LOGI("Return:id[%d],ret[%d]", download_id, ret); return ret; } int da_resume_download(int download_id) { - da_result_t ret = DA_RESULT_OK; - - DA_LOG_VERBOSE(Default, "Resume for dl_id = %d", download_id); - + da_ret_t ret = DA_RESULT_OK; + DA_LOGV("download_id[%d]", download_id); ret = resume_download(download_id); - - DA_LOG_CRITICAL(Default, "Return: Resume id = %d, ret = %d", download_id, ret); + DA_LOGI("Return:id[%d],ret[%d]", download_id, ret); return ret; } @@ -230,5 +147,6 @@ int da_is_valid_download_id(int download_id) { da_bool_t ret = DA_FALSE; ret = is_valid_download_id(download_id); + DA_LOGI("Return:id[%d],ret[%d]", download_id, ret); return ret; } diff --git a/agent/download-agent-mime-util.c b/agent/download-agent-mime-util.c index 53bab8b..71e08eb 100755 --- a/agent/download-agent-mime-util.c +++ b/agent/download-agent-mime-util.c @@ -69,8 +69,6 @@ pthread_mutex_t mutex_for_xdgmime = PTHREAD_MUTEX_INITIALIZER; da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type) { - DA_LOG_FUNC_LOGV(Default); - if (!in_mime_type) return DA_FALSE; @@ -79,7 +77,7 @@ da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type) for (index = 0 ; index < list_size ; index++) { if (0 == strncmp(in_mime_type, ambiguous_MIME_Type_list[index], strlen(ambiguous_MIME_Type_list[index]))) { - DA_SECURE_LOGD("It is ambiguous! [%s]", ambiguous_MIME_Type_list[index]); + //DA_SECURE_LOGD("It is ambiguous! [%s]", ambiguous_MIME_Type_list[index]); return DA_TRUE; } } @@ -87,42 +85,41 @@ da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type) return DA_FALSE; } -da_result_t da_mime_get_ext_name(char *mime, char **ext) +da_ret_t da_mime_get_ext_name(char *mime, char **ext) { - da_result_t ret = DA_RESULT_OK; + da_ret_t ret = DA_RESULT_OK; const char **extlist = DA_NULL; const char *unaliased_mimetype = DA_NULL; char ext_temp[DA_MAX_STR_LEN] = {0,}; char *temp = NULL; - DA_LOG_FUNC_LOGV(Default); + DA_LOGV(""); if (DA_NULL == mime || DA_NULL == ext) { ret = DA_ERR_INVALID_ARGUMENT; - DA_LOG_ERR(Default,"Invalid mime type"); + DA_LOGE("Invalid mime type"); goto ERR; } // DA_SECURE_LOGD("mime str[%s]ptr[%p]len[%d]",mime,mime,strlen(mime)); /* unaliased_mimetype means representative mime among similar types */ - _da_thread_mutex_lock(&mutex_for_xdgmime); + DA_MUTEX_LOCK(&mutex_for_xdgmime); unaliased_mimetype = xdg_mime_unalias_mime_type(mime); - _da_thread_mutex_unlock(&mutex_for_xdgmime); if (unaliased_mimetype == DA_NULL) { ret = DA_ERR_INVALID_MIME_TYPE; - DA_LOG_ERR(Default,"Invalid mime type : No unsaliased mime type"); + DA_LOGI("Invalid mime type : No unsaliased mime type"); + DA_MUTEX_UNLOCK(&mutex_for_xdgmime); goto ERR; } DA_SECURE_LOGD("unaliased_mimetype[%s]\n",unaliased_mimetype); /* Get extension name from shared-mime-info */ - _da_thread_mutex_lock(&mutex_for_xdgmime); extlist = xdg_mime_get_file_names_from_mime_type(unaliased_mimetype); - _da_thread_mutex_unlock(&mutex_for_xdgmime); + DA_MUTEX_UNLOCK(&mutex_for_xdgmime); if (extlist == DA_NULL || *extlist == DA_NULL) { int i = 0; ret = DA_ERR_INVALID_MIME_TYPE; - DA_LOG(Default,"No extension list"); + DA_LOGV("No extension list"); #ifdef _SAMSUNG_MIME_POLICY for (i = 0; i < MAX_SEC_MIME_TABLE_INDEX; i++) { @@ -134,8 +131,8 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext) } #endif } else { /* For drm case, this else statement is needed */ - DA_SECURE_LOGD("extlist[%s]\n",*extlist); - strncpy(ext_temp, *extlist, DA_MAX_STR_LEN); +// DA_LOGD("extlist[%s]\n",*extlist); + strncpy(ext_temp, *extlist, DA_MAX_STR_LEN - 1); /* If only one extension name is existed, don't enter here */ while (*extlist != NULL) { int i = 0; @@ -151,12 +148,12 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext) break; } } - DA_LOG_VERBOSE(Default,"index[%d]\n",i); + DA_LOGV("index[%d]\n",i); /* If there is a mime at extension transform table */ if (i < MAX_EXT_TABLE_INDEX) { break; } - DA_SECURE_LOGD("extlist[%s]\n",*extlist); +// DA_LOGD("extlist[%s]\n",*extlist); extlist++; } // DA_SECURE_LOGD("extension from shared mime info[%s]",ext_temp); @@ -165,18 +162,18 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext) if (strlen(ext_temp) < 1) { /* If there is no mime string for OMA descriptor mime type */ if (strncmp(DD_MIME_STR, mime, strlen(DD_MIME_STR)) == 0) { - strncpy(ext_temp, DD_EXT_STR, DA_MAX_STR_LEN-1); + strncpy(ext_temp, DD_EXT_STR, DA_MAX_STR_LEN - 1); ret = DA_RESULT_OK; /* If there is no extension name for "applicaion/vnd.oma.drm.messeages" * at shared-mime-info*/ - } else if (strncmp(DRM_MIME_MSG_STR, mime, - strlen(DRM_MIME_MSG_STR)) == 0) { - strncpy(ext_temp, DRM_EXT_STR, DA_MAX_STR_LEN-1); + } else if (strncmp(DRM_MIME_MSG_STR, mime, strlen(DRM_MIME_MSG_STR)) == + 0) { + strncpy(ext_temp, DRM_EXT_STR, DA_MAX_STR_LEN - 1); /* If there is extension name at extlist, the return value can have an error.*/ ret = DA_RESULT_OK; } else { ret = DA_ERR_INVALID_MIME_TYPE; - DA_LOG_ERR(Default,"Invalid mime type : no extension name at list"); + DA_LOGI("Invalid mime type : no extension name at list"); } } if (ret != DA_RESULT_OK) @@ -188,6 +185,7 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext) else temp++; + DA_SECURE_LOGD("final extension name:[%s]",temp); *ext = (char*)calloc(1, strlen(temp) + 1); if (*ext != DA_NULL) { strncpy(*ext, temp,strlen(temp)); @@ -206,11 +204,11 @@ da_bool_t da_get_extension_name_from_url(char *url, char **ext) char *temp_str = DA_NULL; int buf_len = 0; - DA_LOG_FUNC_LOGV(Default); + DA_LOGV(""); if (DA_NULL == url || DA_NULL == ext) { ret = DA_FALSE; - DA_LOG_ERR(Default,"Invalid Argument"); + DA_LOGE("Invalid Argument"); return ret; } @@ -229,7 +227,7 @@ da_bool_t da_get_extension_name_from_url(char *url, char **ext) if (DA_NULL == *ext) { ret = DA_FALSE; - DA_LOG_ERR(Default,"Memory Fail"); + DA_LOGE("Memory Fail"); goto ERR; } strncpy(*ext,buff,buf_len); @@ -258,24 +256,24 @@ da_bool_t da_get_file_name_from_url(char *url, char **name) int len_name = 0; char name_buff[DA_MAX_FILE_PATH_LEN] = {0,}; - DA_LOG_FUNC_LOGV(Default); + DA_LOGV(""); if (DA_NULL == url || DA_NULL == name) { ret = DA_FALSE; - DA_LOG_ERR(Default,"Invalid Argument"); + DA_LOGE("Invalid Argument"); goto ERR; } - *name = DA_NULL; + if (!strstr(url, "http") && !strstr(url, "https")) { ret = DA_FALSE; - DA_LOG_ERR(Default,"Invalid Argument"); + DA_LOGE("Invalid Argument"); goto ERR; } buff = (char*) calloc(1, strlen(url) +1); if(DA_NULL == buff) { ret = DA_FALSE; - DA_LOG_ERR(Default,"Memory Fail"); + DA_LOGE("Memory Fail"); goto ERR; } @@ -339,7 +337,6 @@ da_bool_t da_get_file_name_from_url(char *url, char **name) } // DA_SECURE_LOGD("file name BEFORE removing prohibited character = %s", name_buff); delete_prohibited_char(name_buff, strlen(name_buff)); -// DA_SECURE_LOGD("file name AFTER removing prohibited character = %s", name_buff); len_name = strlen(name_buff); *name = (char*) calloc(1, len_name + 1); if (*name) { @@ -363,7 +360,7 @@ void delete_prohibited_char(char *szTarget, int str_len) int tar_len = 0; if(szTarget == NULL || str_len <= 0 || strlen(szTarget) != str_len) { - DA_LOG_ERR(Default,"Invaild Parameter\n"); + DA_LOGE("Invaild Parameter\n"); return; } @@ -399,3 +396,54 @@ void delete_prohibited_char(char *szTarget, int str_len) return; } +#ifdef _ENABLE_OMA_DRM +da_bool_t is_content_drm_dcf(char *content_type) +{ + if (content_type == DA_NULL) + return DA_FALSE; + + if (0 == strcmp(content_type, DRM_MIME_CONTENT_STR)) { + DA_LOGV("DRM_DM content"); + return DA_TRUE; + } else { + return DA_FALSE; + } +} + +da_bool_t is_content_drm_dm(char *content_type) +{ + if (content_type == DA_NULL) + return DA_FALSE; + + if (0 == strcmp(content_type, DRM_MIME_MSG_STR)) { + DA_LOGV("DRM_DM content"); + return DA_TRUE; + } else { + return DA_FALSE; + } +} +#endif + +da_ret_t get_extension_from_mime_type(char *mime_type, char **extension) +{ + da_ret_t ret = DA_RESULT_OK; + char *ext = DA_NULL; + + DA_LOGV(""); + if (DA_NULL == mime_type || DA_NULL == extension) { + DA_LOGE("received mime_type is null"); + ret = DA_ERR_INVALID_ARGUMENT; + goto ERR; + } +// DA_SECURE_LOGD("input mime type = %s", mime_type); + if (DA_RESULT_OK != (ret = da_mime_get_ext_name(mime_type, &ext))) { + DA_LOGE("can't find proper extension!"); + goto ERR; + } + *extension = ext; +// DA_SECURE_LOGD("found extension = %s", *extension); + +ERR: + return ret; +} + diff --git a/agent/download-agent-plugin-conf.c b/agent/download-agent-plugin-conf.c index 8a547f7..6cb76cb 100755 --- a/agent/download-agent-plugin-conf.c +++ b/agent/download-agent-plugin-conf.c @@ -17,12 +17,9 @@ #include #include #include - -#ifdef _EFL_PLATFORM -#include -#include -#include -#endif /* _EFL_PLATFORM */ +#include "vconf.h" +#include "vconf-keys.h" +#include "net_connection.h" #include "download-agent-plugin-conf.h" #include "download-agent-debug.h" @@ -30,74 +27,58 @@ #define DEFAULT_UA_STR "Mozilla/5.0 (Linux; U; Tizen 1.0; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Mobile Tizen Browser/1.0" -da_result_t __get_conf_string(const char *key, char **out_string); - -da_result_t __get_conf_string(const char *key, char **out_string) +da_ret_t __get_conf_string(const char *key, char **out_string) { -#ifdef _EFL_PLATFORM if (!key || !out_string) { - DA_LOG_ERR(Default,"Invalid Argument"); + DA_LOGE("Invalid Argument"); return DA_ERR_INVALID_ARGUMENT; } *out_string = vconf_get_str(key); return DA_RESULT_OK; -#else - if (out_string) - *out_string = NULL; - - return DA_RESULT_OK; -#endif } -da_result_t get_user_agent_string(char **uagent_str) +da_ret_t get_user_agent_string(char **uagent_str) { - da_result_t ret = DA_RESULT_OK; -#ifdef _EFL_PLATFORM + da_ret_t ret = DA_RESULT_OK; char *key = DA_NULL; -#endif - DA_LOG_FUNC_LOGV(Default); + DA_LOGV(""); if (!uagent_str) { - DA_LOG_ERR(Default,"Invalid Argument"); + DA_LOGE("Invalid Argument"); return DA_ERR_INVALID_ARGUMENT; } -#ifdef _EFL_PLATFORM key = VCONFKEY_BROWSER_USER_AGENT; ret = __get_conf_string(key, uagent_str); if(ret == DA_RESULT_OK) { if(*uagent_str) { - DA_SECURE_LOGD("getting uagent_str = \n%s", *uagent_str); +// DA_SECURE_LOGD("getting uagent_str = \n%s", *uagent_str); return ret; } } - DA_LOG_ERR(Default,"No UA information from vconf !!"); - *uagent_str = strdup(DEFAULT_UA_STR); - DA_LOG(Default,"Set default UA"); -#else + DA_LOGI("No UA information from vconf !!"); *uagent_str = strdup(DEFAULT_UA_STR); -#endif + DA_LOGV("Set default UA"); return ret; } char *get_proxy_address(void) { -#ifdef _EFL_PLATFORM char *proxy = NULL; char *proxyRet = NULL; connection_h handle = NULL; - connection_address_family_e family = CONNECTION_ADDRESS_FAMILY_IPV4; + connection_address_family_e family = CONNECTION_ADDRESS_FAMILY_IPV4; - DA_LOG_FUNC_LOGV(Default); + DA_LOGV(""); if (connection_create(&handle) < 0) { - DA_LOG_ERR(Default,"Fail to create connection handle"); + DA_LOGE("Fail to create connection handle"); return NULL; } if (connection_get_proxy(handle, family, &proxyRet) < 0) { - DA_LOG_ERR(Default,"Fail to get proxy address"); + DA_LOGE("Fail to get proxy address"); connection_destroy(handle); return NULL; } @@ -112,11 +93,17 @@ char *get_proxy_address(void) } if (connection_destroy(handle) < 0) { - DA_LOG_ERR(Default,"Fail to desctory connection handle"); + DA_LOGE("Fail to desctory connection handle"); return NULL; } return NULL; -#else - return NULL; -#endif } +#ifdef _RAF_SUPPORT +// test code +void get_smart_bonding_vconf() +{ + int ret = 0; + vconf_get_int("file/private/wifi/network_bonding", &ret); + DA_LOGI("Smart Bonding Vconf:%d", ret); +} +#endif diff --git a/agent/download-agent-plugin-drm.c b/agent/download-agent-plugin-drm.c new file mode 100644 index 0000000..22e6f34 --- /dev/null +++ b/agent/download-agent-plugin-drm.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "drm_client.h" +#include "drm_client_types.h" +#include "drm_trusted_client.h" +#include "drm_trusted_client_types.h" + +#include "download-agent-debug.h" +#include "download-agent-plugin-drm.h" + + +void __EDRM_clean_up() +{ + int ret = 0; + ret = drm_trusted_handle_request(DRM_TRUSTED_REQ_TYPE_CLIENT_CLEAN_UP, NULL, NULL); + if (DRM_RETURN_SUCCESS == ret) { + DA_LOGD( "Clean up successfull"); + } else { + DA_LOGE("ret[%0x%x]",ret); + } +} + +da_bool_t EDRM_convert(const char *in_file_path, char **out_file_path) +{ + drm_trusted_conv_info_s input; + drm_trusted_conv_resp_info_s output; + size_t len = 0; + int ret = 0; + + memset(&input, 0x0, sizeof(drm_trusted_conv_info_s)); + memset(&output, 0x0, sizeof(drm_trusted_conv_resp_info_s)); + + len = strlen(in_file_path); + if (len >= sizeof(input.filePath)) + len = sizeof(input.filePath) - 1; + memcpy(input.filePath, in_file_path, len); + + ret = drm_trusted_convert_dm(&input, &output); + + if (DRM_TRUSTED_RETURN_SUCCESS != ret) { + DA_LOGE("ret[%0x%x]",ret); + __EDRM_clean_up(); + return DA_FALSE; + } else { + DA_SECURE_LOGD("Returned filePath[%s]", output.filePath); + *out_file_path = strdup(output.filePath); + } + __EDRM_clean_up(); + return DA_TRUE; +} + +da_ret_t EDRM_wm_get_license(char *rights_url, char **out_content_url) +{ + int ret = 0; + int len = 0; + drm_initiator_info_s init_info; + drm_web_server_resp_data_s resp_data; + + if (rights_url == NULL) + return DA_ERR_DRM_FAIL; + + memset(&init_info, 0, sizeof(init_info)); + memset(&resp_data, 0, sizeof(resp_data)); + strncpy(init_info.initiator_url, rights_url, + DRM_MAX_LEN_INITIATOR_URL - 1); + len = strlen(rights_url); + if (len > DRM_MAX_LEN_INITIATOR_URL - 1) + init_info.initiator_url_len = (unsigned int)len; + else + init_info.initiator_url_len = DRM_MAX_LEN_INITIATOR_URL; + ret = drm_process_request(DRM_REQUEST_TYPE_SUBMIT_INITIATOR_URL, + &init_info, &resp_data); + if (DRM_RETURN_SUCCESS == ret) { + DA_SECURE_LOGD("resp_data.content_url = %s", resp_data.content_url); + /* Rights or Domain Certificate are installed successfully */ + /* Check for contentURL */ + if (strlen(resp_data.content_url) > 0) { + char *content_url = NULL; + size_t content_url_len = 0; + content_url_len = strlen(resp_data.content_url); + content_url = (char *)calloc(1, content_url_len + 1); + if (content_url) { + strncpy(content_url, resp_data.content_url, + content_url_len); + *out_content_url = content_url; + DA_SECURE_LOGD("drm sumitted initiator url " + "succeeded with [%s]", *out_content_url); + __EDRM_clean_up(); + return DA_RESULT_OK; + } else { + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); + __EDRM_clean_up(); + return DA_ERR_FAIL_TO_MEMALLOC; + } + } else { + DA_LOGV("content_url is NULL.\ + Join/Leave Domain, Metering case."); + *out_content_url = DA_NULL; + __EDRM_clean_up(); + return DA_RESULT_OK; + } + } else { + DA_LOGE("drm_process_request() failed"); + __EDRM_clean_up(); + return DA_ERR_DRM_FAIL; + } +} + diff --git a/agent/download-agent-plugin-libcurl.c b/agent/download-agent-plugin-libcurl.c new file mode 100644 index 0000000..0c221d2 --- /dev/null +++ b/agent/download-agent-plugin-libcurl.c @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "glib.h" + +#include "download-agent-dl-info.h" +#include "download-agent-http-msg-handler.h" +#include "download-agent-plugin-libcurl.h" + +da_bool_t using_content_sniffing = DA_FALSE; + +int __translate_error_code(int curl_error) +{ + switch (curl_error) { + case CURLE_OPERATION_TIMEDOUT: + return DA_ERR_HTTP_TIMEOUT; + case CURLE_SSL_CONNECT_ERROR: + case CURLE_SSL_ENGINE_NOTFOUND: + case CURLE_SSL_ENGINE_SETFAILED: + case CURLE_SSL_CERTPROBLEM: + case CURLE_SSL_CIPHER: + case CURLE_SSL_CACERT: + case CURLE_SSL_ENGINE_INITFAILED: + case CURLE_SSL_CACERT_BADFILE: + case CURLE_SSH: + case CURLE_SSL_SHUTDOWN_FAILED: + case CURLE_SSL_CRL_BADFILE: + case CURLE_SSL_ISSUER_ERROR: + return DA_ERR_SSL_FAIL; + case CURLE_TOO_MANY_REDIRECTS: + return DA_ERR_TOO_MANY_REDIRECTS; + case CURLE_OUT_OF_MEMORY: + return DA_ERR_FAIL_TO_MEMALLOC; + case CURLE_UNSUPPORTED_PROTOCOL: + case CURLE_URL_MALFORMAT: + case CURLE_COULDNT_RESOLVE_PROXY: + case CURLE_COULDNT_RESOLVE_HOST: + case CURLE_COULDNT_CONNECT: + case CURLE_REMOTE_ACCESS_DENIED: + case CURLE_HTTP_POST_ERROR: + case CURLE_BAD_DOWNLOAD_RESUME: + return DA_ERR_CONNECTION_FAIL; + case CURLE_ABORTED_BY_CALLBACK: + return DA_RESULT_USER_CANCELED; + default: + return DA_ERR_NETWORK_FAIL; + } +} + +int my_trace(CURL *handle, curl_infotype type, char *data, size_t size, void *user) +{ + switch(type) { + case CURLINFO_TEXT: + if (data) + DA_SECURE_LOGI("[curl] Info:%s", data); + break; + case CURLINFO_HEADER_OUT: + DA_LOGD("[curl] Send header"); + if (data) + DA_SECURE_LOGI("[curl] %s", data); + break; + case CURLINFO_DATA_OUT: + DA_LOGD("[curl] Send data"); + if (data) + DA_SECURE_LOGI("[curl] %s", data); + break; + case CURLINFO_SSL_DATA_OUT: + DA_LOGD("[curl] Send SSL data"); + break; + case CURLINFO_HEADER_IN: + DA_LOGD("[curl] Recv header"); + if (data) + DA_SECURE_LOGI("[curl] %s", data); + break; +#if 0 + case CURLINFO_DATA_IN: + DA_LOGD("[curl] Recv data"); + if (data) + DA_SECURE_LOGI("[curl] %d", strlen(data)); + break; +#endif + case CURLINFO_SSL_DATA_IN: + DA_SECURE_LOGI("[curl] Recv SSL data"); + break; + default: + return 0; + } + return 0; +} + +void __parse_raw_header(const char *raw_data, http_info_t *http_info) +{ + char *ptr = DA_NULL; + char *ptr2 = DA_NULL; + int len = 0; + char *field = DA_NULL; + char *value = DA_NULL; + http_msg_response_t *http_msg_response = NULL; + + if (!raw_data || !http_info) { + DA_LOGE("NULL Check!: raw_data or http_info"); + return; + } + + if (!http_info->http_msg_response) { + http_info->http_msg_response = (http_msg_response_t *)calloc(1, + sizeof(http_msg_response_t)); + if (!http_info->http_msg_response) { + DA_LOGE("Fail to calloc"); + return; + } + http_info->http_msg_response->head = DA_NULL; + } + http_msg_response = http_info->http_msg_response; + + ptr = strchr(raw_data, ':'); + if (!ptr) + return; + len = ptr - (char *)raw_data; + field = (char *)calloc(len + 1, sizeof(char)); + if (!field) { + DA_LOGE("Fail to calloc"); + return; + } + memcpy(field, raw_data, len); + field[len] = '\0'; + ptr++; + while(ptr) { + if (*ptr == ' ') + ptr++; + else + break; + } + ptr2 = strchr(raw_data, '\n'); + if (ptr2) { + len = ptr2 - ptr -1; + } else { + len = strlen(ptr); + } + value = (char *)calloc(len + 1, sizeof(char)); + if (!value) { + DA_LOGE("Fail to calloc"); + free(field); + return; + } + memcpy(value, ptr, len); + value[len] = '\0'; + http_msg_response_add_field(http_msg_response, field, value); + free(field); + free(value); +} + +void __store_header(void *msg, da_info_t *da_info, size_t header_size, + const char *sniffed_type) +{ + http_info_t *http_info = DA_NULL; + + if (!da_info || !msg) { + DA_LOGE("NULL Check!: da_info or msg"); + return; + } + http_info = da_info->http_info; + if (!http_info) { + DA_LOGE("NULL Check!: http_info"); + return; + } + + // FIXME later : check status code and redirection case check. + + if (strncmp(msg, HTTP_FIELD_END_OF_FIELD, + strlen(HTTP_FIELD_END_OF_FIELD)) == 0) { + long status = 0; + CURLcode res; + CURL *curl; + http_raw_data_t *raw_data = DA_NULL; + curl = http_info->http_msg->curl; + res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status); + if (res != CURLE_OK) { + DA_LOGE("Fail to get response status code"); + return; + } + DA_LOGV("status code[%d]", (int)status); + if (http_info->http_msg_response) { + http_info->http_msg_response->status_code = (int)status; + } + raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t)); + if (!raw_data) { + DA_LOGE("Fail to calloc"); + return; + } + + raw_data->status_code = (int)status; + raw_data->type = HTTP_EVENT_GOT_HEADER; + + if (http_info->update_cb) { + http_info->update_cb(raw_data, da_info); + } else { + free(raw_data); + } + return; + } + DA_LOGI("%s",(char *)msg); + __parse_raw_header((const char *)msg, http_info); +} + +size_t __http_gotheaders_cb(void *ptr, size_t size, size_t nmemb, void *userdata) +{ + da_info_t *da_info = DA_NULL; + if (!ptr || !userdata) { + DA_LOGE("Check NULL!: ptr, userdata"); + return 0; + } + da_info = (da_info_t *)userdata; + if (da_info->http_info && da_info->http_info->http_msg + && da_info->http_info->http_msg->is_cancel_reqeusted) { + DA_LOGI("Cancel requested"); + return -1; + } + if (!using_content_sniffing) + __store_header(ptr, da_info, (size * nmemb), DA_NULL); + else + DA_LOGV("ignore because content sniffing is turned on"); +/* +#ifdef _RAF_SUPPORT + DA_LOGI("[RAF] __http_gotheaders_cb done"); +#endif +*/ + return (size * nmemb); +} + +#ifdef _RAF_SUPPORT +da_ret_t PI_http_set_file_name_to_curl(http_msg_t *http_msg, char *file_path) +{ + NULL_CHECK_RET(http_msg); + NULL_CHECK_RET(file_path); + DA_LOGI("[RAF]set file_path[%s]", file_path); + curl_easy_setopt(http_msg->curl, CURLOPT_BOOSTER_RAF_FILE, file_path); + return DA_RESULT_OK; +} +#endif + +size_t __http_gotchunk_cb(void *ptr, size_t size, size_t nmemb, void *userdata) +{ + http_info_t *http_info = DA_NULL; + da_info_t *da_info = DA_NULL; + http_raw_data_t *raw_data = DA_NULL; + if (!ptr || !userdata) { + DA_LOGE("Check NULL!: ptr, stream"); + return 0; + } + da_info = (da_info_t *)userdata; + NULL_CHECK_RET_OPT(da_info, 0); + http_info = da_info->http_info; + NULL_CHECK_RET_OPT(http_info, 0); + NULL_CHECK_RET_OPT(http_info->http_msg, 0); + if (da_info->http_info->http_msg->is_cancel_reqeusted) { + DA_LOGI("Cancel requested"); + return -1; + } + //DA_LOGV("size=%ld, nmemb=%ld, datalen=%ld", size, nmemb, strlen((const char *)ptr)); +#ifdef _RAF_SUPPORT + //DA_LOGI("size=%ld, nmemb=%ld, datalen=%ld", size, nmemb, strlen((const char *)ptr)); + if (http_info->is_raf_mode_confirmed) { + DA_LOGI("[RAF] return chunked callback"); + return (size * nmemb); + } +#endif + + if (ptr && size * nmemb > 0) { + if (http_info->update_cb) { + raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t)); + if (!raw_data) { + DA_LOGE("Fail to calloc"); + return 0; + } + raw_data->body = (char *)calloc(size, nmemb); + if (!(raw_data->body)) { + DA_LOGE("Fail to calloc"); + free(raw_data); + return 0; + } + memcpy(raw_data->body, ptr, size * nmemb); + raw_data->body_len = size*nmemb; + raw_data->type = HTTP_EVENT_GOT_PACKET; + http_info->update_cb(raw_data, da_info); + } + } + return (size * nmemb); +} + +long __http_finished_cb(void *ptr) +{ + if (!ptr) { + DA_LOGE("Check NULL!: ptr"); + return CURL_CHUNK_END_FUNC_FAIL; + } + DA_LOGI(""); + return CURL_CHUNK_END_FUNC_OK; +} + + +da_ret_t __set_proxy_on_soup_session(char *proxy_addr, CURL *curl) +{ + da_ret_t ret = DA_RESULT_OK; + + if (proxy_addr && strlen(proxy_addr) > 0) { + DA_SECURE_LOGI("received proxy[%s]", proxy_addr); + if (!strstr(proxy_addr, "0.0.0.0")) { + if (strstr((const char *)proxy_addr, "http") == DA_NULL) { + char *tmp_str = DA_NULL; + int needed_len = 0; + + needed_len = strlen(proxy_addr) + strlen( + SCHEME_HTTP) + 1; + tmp_str = (char *) calloc(1, needed_len); + if (!tmp_str) { + DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC"); + ret = DA_ERR_FAIL_TO_MEMALLOC; + goto ERR; + } + snprintf(tmp_str, needed_len, "%s%s", + SCHEME_HTTP, proxy_addr); + + curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr); + + free(tmp_str); + } else { + DA_LOGV("There is \"http\" on uri, so, push this address to soup directly."); + curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr); + } + } + } +ERR: + return ret; +} + +struct curl_slist *__fill_soup_msg_header(CURL *curl, http_info_t *info) +{ + http_msg_request_t *input_http_msg_request; + struct curl_slist *headers = DA_NULL; + + if (!curl) { + DA_LOGE("NULL Check!: curl"); + return DA_NULL; + } + input_http_msg_request = info->http_msg_request; + + if (input_http_msg_request) { + char *field = DA_NULL; + char *value = DA_NULL; + char *buff = DA_NULL; + int len = 0; + http_header_t *cur = DA_NULL; + cur = input_http_msg_request->head; + while (cur) { + field = cur->field; + value = cur->value; + if (field && value) { + len = strlen(field) + strlen(value) + 1; + buff = (char *)calloc(len + 1, sizeof(char)); + if (!buff) { + DA_LOGE("Fail to memalloc"); + break; + } +// DA_SECURE_LOGI("[%s] %s", field, value); + snprintf(buff, len + 1, "%s:%s", field, value); + headers = curl_slist_append(headers, (const char *)buff); + free(buff); + buff = DA_NULL; + } + cur = cur->next; + } + } else { + DA_LOGE("NULL Check!: input_http_msg_request"); + return DA_NULL; + } + if (input_http_msg_request->http_body) { + char buff[256] = {0,}; + int body_len = strlen(input_http_msg_request->http_body); + snprintf(buff, sizeof(buff), "%s:%d", HTTP_FIELD_CONTENT_LENGTH, + body_len); + headers = curl_slist_append(headers, buff); + memset(buff, 0x00, 256); + snprintf(buff, sizeof(buff), "%s:text/plain", HTTP_FIELD_CONTENT_TYPE); + headers = curl_slist_append(headers, buff); + headers = curl_slist_append(headers, input_http_msg_request->http_body); + } + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + return headers; +} + +#ifdef _RAF_SUPPORT +int __http_progress_cb(void *clientp, double dltotal, double dlnow, + double ultotal, double ulnow) +{ + da_info_t *da_info = DA_NULL; + http_info_t *http_info = DA_NULL; + http_raw_data_t *raw_data = DA_NULL; +/* + if (dlnow > 0 || ulnow > 0) + DA_LOGI("[RAF]dlnow/ulnow[%llu/%llu][%llu,%llu]", (da_size_t)dlnow, (da_size_t)ulnow, (da_size_t)dltotal, (da_size_t)ultotal); +*/ + +/* + if (dlnow == 0) { + DA_LOGI("[RAF]dlnow is zero. Why is this callback called although there is zero size?"); + } +*/ + NULL_CHECK_RET_OPT(clientp, -1); + da_info = (da_info_t *)clientp; + http_info = da_info->http_info; + NULL_CHECK_RET_OPT(http_info, -1); + NULL_CHECK_RET_OPT(http_info->http_msg, -1); + + if (http_info->http_msg->is_cancel_reqeusted) { + DA_LOGI("Cancel requested"); + return -1; + } + + if (dlnow > 0) { + if (http_info->update_cb) { + raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t)); + if (!raw_data) { + DA_LOGE("Fail to calloc"); + return 0; + } + raw_data->received_len = (da_size_t)dlnow; + raw_data->type = HTTP_EVENT_GOT_PACKET; + http_info->update_cb(raw_data, da_info); + } + } + return CURLE_OK; +} +#endif + +da_ret_t PI_http_start(da_info_t *da_info) +{ + da_ret_t ret = DA_RESULT_OK; + http_method_t http_method; + CURL *curl = DA_NULL; + CURLcode res; + http_msg_t *http_msg = DA_NULL; + char *url = DA_NULL; + http_info_t *http_info = DA_NULL; + long http_status = 0; + struct curl_httppost* post = NULL; + struct curl_slist *headers = DA_NULL; + char err_buffer[CURL_ERROR_SIZE] = {0,}; + + DA_LOGV(""); +#ifdef _RAF_SUPPORT + // test code + get_smart_bonding_vconf(); +#endif + NULL_CHECK_GOTO(da_info); + NULL_CHECK_GOTO(da_info->req_info); + url = da_info->req_info->url; + NULL_CHECK_GOTO(url); + http_info = da_info->http_info; + NULL_CHECK_GOTO(http_info); + + http_method = http_info->http_method; + ret = init_http_msg_t(&http_msg); + if (ret != DA_RESULT_OK) + goto ERR; + http_info->http_msg = http_msg; + + curl_global_init(CURL_GLOBAL_ALL); + curl = curl_easy_init(); + + if (!curl) { + DA_LOGE("Fail to create curl"); + return DA_ERR_FAIL_TO_MEMALLOC; + } + DA_LOGI("curl[%p]", curl); + + curl_easy_setopt(curl, CURLOPT_MAXCONNECTS, MAX_SESSION_COUNT); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, MAX_TIMEOUT); + + __set_proxy_on_soup_session(http_info->proxy_addr, curl); + + curl_easy_setopt(curl, CURLOPT_URL, url); + switch (http_method) { + case HTTP_METHOD_GET: + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + break; + case HTTP_METHOD_POST: + // FIXME later : If the post method is supprot, the post data should be set with curl_fromadd + curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); + DA_LOGI("Need more information for post filed"); + break; + case HTTP_METHOD_HEAD: + DA_LOGI("Donnot implement yet"); + break; + default: + DA_LOGE("Cannot enter here"); + break; + } + + if (using_content_sniffing) { + /* FIXME later*/ + } else { + /* FIXME later*/ + } + headers = __fill_soup_msg_header(curl, http_info); + + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, __http_gotheaders_cb); // can replace to started_cb + curl_easy_setopt(curl, CURLOPT_HEADERDATA, da_info); // param .. same with CURLOPT_WRITEHEADER + curl_easy_setopt(curl, CURLOPT_HEADER, 0L); // does not include header to body + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, __http_gotchunk_cb); // can replace to progress_ + curl_easy_setopt(curl, CURLOPT_WRITEDATA, da_info); // param .. same with CURLOPT_WRITEHEADERcb + curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, __http_finished_cb); + curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, da_info); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); +// curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, err_buffer); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); +#ifdef _RAF_SUPPORT + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, __http_progress_cb); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, da_info); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); +#endif + + if (da_info->req_info->network_bonding) { +#ifdef _DOWNLOAD_BOOSTER_SUPPORT + DA_LOGI("network bonding enable"); + curl_easy_setopt(curl, CURLOPT_MULTIRAT_NEEDED, 1L); +#endif +#ifdef _RAF_SUPPORT + curl_easy_setopt(curl, CURLOPT_BOOSTER_RAF_MODE, 1L); +#endif + } + http_msg->curl = curl; + res = curl_easy_perform(curl); + DA_LOGD("perform done! res[%d]",res); + if (res != CURLE_OK) { + //DA_LOGE("Fail to send data :%d[%s]", res, curl_easy_strerror(res)); + DA_LOGE("Fail to perform :%d[%s]", res, curl_multi_strerror(res)); + if (strlen(err_buffer) > 1) + DA_LOGE("Fail to error buffer[%s]", err_buffer); + } + if (res != CURLE_OK) { + //DA_LOGE("Fail to send data :%d[%s]", res, curl_easy_strerror(res)); + DA_LOGE("Fail to send data :%d[%s]", res, curl_easy_strerror(res)); + if (strlen(err_buffer) > 1) + DA_LOGE("Fail to error buffer[%s]", err_buffer); + } else { + res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status); + if (res != CURLE_OK) { + //DA_LOGE("Fail to get response code:%d[%s]", res, curl_easy_strerror(res)); + DA_LOGE("Fail to get response code:%d[%s]", res, curl_easy_strerror(res)); + ret = DA_ERR_FAIL_TO_MEMALLOC;; + goto ERR; + } else { + DA_LOGD("Response Http Status code[%d]", (int)http_status); + } + } + if (http_info->update_cb) { + http_raw_data_t *raw_data = DA_NULL; + raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t)); + if (!raw_data) { + DA_LOGE("Fail to calloc"); + ret = DA_ERR_FAIL_TO_MEMALLOC; + goto ERR; + } + if (http_msg->is_cancel_reqeusted || + res == CURLE_ABORTED_BY_CALLBACK) { + DA_LOGI("canceled exit. Err[%d]", http_info->error_code); + if (http_info->error_code < 0) + ret = http_info->error_code; + else + ret = DA_RESULT_USER_CANCELED; + } else if ((http_status > 0 && http_status < 100)) { + raw_data->error = __translate_error_code(res); + ret = DA_ERR_NETWORK_FAIL; + } else if (res != CURLE_OK) { + raw_data->error = __translate_error_code(res); + ret = DA_ERR_NETWORK_FAIL; + } else { + raw_data->status_code = (int)http_status; + } + raw_data->type = HTTP_EVENT_FINAL; + http_info->update_cb(raw_data, da_info); + } + if (DA_NULL != headers) + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + http_msg->curl = DA_NULL; + DA_MUTEX_INIT(&(http_msg->mutex), DA_NULL); +ERR: + DA_LOGD("Done"); + return ret; + +} + +da_ret_t PI_http_disconnect(http_info_t *info) +{ + da_ret_t ret = DA_RESULT_OK; + http_msg_t *http_msg = DA_NULL; + + DA_LOGD(""); + NULL_CHECK_RET(info); + http_msg = info->http_msg; + NULL_CHECK_RET(http_msg); + DA_LOGV("session [%p]", http_msg->curl); + DA_MUTEX_LOCK(&(http_msg->mutex)); + if (http_msg->is_paused) + PI_http_unpause(info); + if (http_msg->curl) + curl_easy_cleanup(http_msg->curl); + + http_msg->curl = DA_NULL; + http_msg->is_paused = DA_FALSE; + http_msg->is_cancel_reqeusted = DA_FALSE; + DA_MUTEX_UNLOCK(&(http_msg->mutex)); + DA_MUTEX_DESTROY(&(http_msg->mutex)); + destroy_http_msg_t(http_msg); + info->http_msg = DA_NULL; + return ret; +} + +da_ret_t PI_http_cancel(http_info_t *info) +{ + da_ret_t ret = DA_RESULT_OK; + http_msg_t *http_msg = DA_NULL; + + DA_LOGV(""); + + NULL_CHECK_RET(info); + http_msg = info->http_msg; + NULL_CHECK_RET(http_msg); + NULL_CHECK_RET(http_msg->curl); + DA_MUTEX_LOCK(&(http_msg->mutex)); + DA_LOGI("curl[%p]", http_msg->curl); + http_msg->is_cancel_reqeusted = DA_TRUE; + DA_MUTEX_UNLOCK(&(http_msg->mutex)); + DA_LOGD("Done - soup cancel"); + return ret; +} + +da_ret_t PI_http_pause(http_info_t *info) +{ + da_ret_t ret = DA_RESULT_OK; + http_msg_t *http_msg = DA_NULL; + CURLcode res = CURLE_OK; + DA_LOGV(""); + + NULL_CHECK_RET(info); + http_msg = info->http_msg; + NULL_CHECK_RET(http_msg); + DA_LOGD("curl [%p]", http_msg->curl); + NULL_CHECK_RET(http_msg->curl); + DA_MUTEX_LOCK(&(http_msg->mutex)); + DA_LOGE("curl_easy_pause call"); + curl_easy_pause(http_msg->curl, CURLPAUSE_ALL); + DA_LOGE("curl_easy_pause:%d", res); + if (res == CURLE_OK) { + http_msg->is_paused = DA_TRUE; + } else { + ret = DA_ERR_CANNOT_SUSPEND; + } + DA_MUTEX_UNLOCK(&(http_msg->mutex)); + return ret; +} + +da_ret_t PI_http_unpause(http_info_t *info) +{ + da_ret_t ret = DA_RESULT_OK; + http_msg_t *http_msg = DA_NULL; + CURLcode res = CURLE_OK; + DA_LOGV(""); + + NULL_CHECK_RET(info); + http_msg = info->http_msg; + DA_LOGV("curl [%p]", http_msg->curl); + NULL_CHECK_RET(http_msg->curl); + DA_MUTEX_LOCK(&(http_msg->mutex)); + res = curl_easy_pause(http_msg->curl, CURLPAUSE_CONT); + if (res == CURLE_OK) + http_msg->is_paused = DA_FALSE; + else + ret = DA_ERR_CANNOT_RESUME; + DA_MUTEX_UNLOCK(&(http_msg->mutex)); + return ret; +} diff --git a/agent/download-agent-plugin-libsoup.c b/agent/download-agent-plugin-libsoup.c deleted file mode 100755 index 6d54afd..0000000 --- a/agent/download-agent-plugin-libsoup.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "download-agent-debug.h" -#include "download-agent-plugin-libsoup.h" -#include "download-agent-http-misc.h" -#include "download-agent-utils.h" -#include "download-agent-pthread.h" - -pthread_mutex_t mutex_for_session_table = PTHREAD_MUTEX_INITIALIZER; - -pi_session_table_t pi_session_table[MAX_SESSION_COUNT] = { { 0, }, }; -da_bool_t using_content_sniffing; - -da_bool_t _pi_http_is_this_session_table_entry_using( - const int in_session_table_entry); - -da_result_t PI_http_init(void) -{ - DA_LOG_FUNC_LOGV(HTTPManager); - - using_content_sniffing = DA_TRUE; - - return DA_RESULT_OK; -} - -void PI_http_deinit(void) -{ - DA_LOG_FUNC_LOGV(HTTPManager); - - return; -} - -da_result_t _set_proxy_on_soup_session(SoupSession *session, char *proxy_addr) -{ - da_result_t ret = DA_RESULT_OK; - - - if (proxy_addr && strlen(proxy_addr) > 0) { - DA_SECURE_LOGD("received proxy = %s \n", proxy_addr); - if (!strstr(proxy_addr, "0.0.0.0")) { - if (strstr((const char *)proxy_addr, "http") == DA_NULL) { - DA_LOG_VERBOSE(Default,"There is no \"http://\" on received uri, so, add it."); - - char *tmp_str = DA_NULL; - int needed_len = 0; - - needed_len = strlen(proxy_addr) + strlen( - SCHEME_HTTP) + 1; - tmp_str = (char *) calloc(1, needed_len); - if (!tmp_str) { - DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - snprintf(tmp_str, needed_len, "%s%s", - SCHEME_HTTP, proxy_addr); - - g_object_set(session, SOUP_SESSION_PROXY_URI, - soup_uri_new(tmp_str), NULL); - - free(tmp_str); - } else { - DA_LOG(HTTPManager,"There is \"http\" on uri, so, push this address to soup directly."); - g_object_set(session, SOUP_SESSION_PROXY_URI, - soup_uri_new(proxy_addr), NULL); - } - } - } else { - DA_LOG_VERBOSE(HTTPManager,"There is no proxy value"); - } -ERR: - return ret; -} - -void _fill_soup_msg_header(SoupMessage *msg, - const input_for_tranx_t *input_for_tranx) -{ - SoupMessageHeaders *headers = msg->request_headers; - - http_msg_request_t *input_http_msg_request; - http_msg_iter_t http_msg_iter; - http_msg_iter_t http_msg_iter_pre; - - char *field; - char *value; - - input_http_msg_request = input_for_tranx->http_msg_request; - - http_msg_request_get_iter(input_http_msg_request, &http_msg_iter); - http_msg_iter_pre = http_msg_iter; - while (http_msg_get_field_with_iter(&http_msg_iter, &field, &value)) { - if ((field != DA_NULL) && (value != DA_NULL)) { - DA_SECURE_LOGD("[%s] %s", field, value); - soup_message_headers_append(headers, field, value); - } - http_msg_iter_pre = http_msg_iter; - } - - if (input_http_msg_request->http_body) { - char body_len_str[16] = { 0, }; - int body_len = strlen(input_http_msg_request->http_body); - - snprintf(body_len_str, sizeof(body_len_str), "%d", body_len); - - soup_message_headers_append(headers, "Content-Length", - body_len_str); - soup_message_headers_append(headers, "Content-Type", - "text/plain"); - soup_message_body_append(msg->request_body, SOUP_MEMORY_COPY, - input_http_msg_request->http_body, body_len); - } -} - -da_result_t PI_http_start_transaction(const input_for_tranx_t *input_for_tranx, - int *out_tranx_id) -{ - da_result_t ret = DA_RESULT_OK; - int session_table_entry = -1; - pi_http_method_t pi_http_method = PI_HTTP_METHOD_GET; - queue_t *queue = DA_NULL; - char *url = DA_NULL; - SoupSession *session = DA_NULL; - SoupMessage *msg = DA_NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if (DA_FALSE == _pi_http_is_valid_input_for_tranx(input_for_tranx)) { - DA_LOG_ERR(HTTPManager,"input_for_tranx is invalid"); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } else { - queue = input_for_tranx->queue; - pi_http_method = input_for_tranx->http_method; - url = input_for_tranx->http_msg_request->url; - } - - session_table_entry = _pi_http_get_avaiable_session_table_entry(); - if (session_table_entry == -1) { - ret = DA_ERR_ALREADY_MAX_DOWNLOAD; - goto ERR; - } - DA_LOG_VERBOSE(HTTPManager,"session_table_entry = %d", session_table_entry); - - if (DA_FALSE == _pi_http_register_queue_to_session_table( - session_table_entry, queue)) { - _pi_http_destroy_session_table_entry(session_table_entry); - ret = DA_ERR_ALREADY_MAX_DOWNLOAD; - goto ERR; - } - - /* modified by keunsoon.lee 2010-09-20 use sync_new() instead of async_new() for make different soup thread from UI main thread*/ - session = soup_session_sync_new(); - /* session=soup_session_async_new(); */ - if (!session) { - DA_LOG_ERR(HTTPManager,"Fail to create session"); - return DA_ERR_INVALID_URL; - } - DA_LOG(HTTPManager,"session[%p]", session); -/* - SoupLogger* logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1); - soup_logger_attach(logger, session); - g_object_unref(logger); -*/ - if (DA_FALSE == _pi_http_register_session_to_session_table( - session_table_entry, session)) { - _pi_http_init_session_table_entry(session_table_entry); - ret = DA_ERR_ALREADY_MAX_DOWNLOAD; - goto ERR; - } - - g_object_set(session, SOUP_SESSION_MAX_CONNS, MAX_SESSION_COUNT, NULL); - /* Set timeout unlimited time to resume a download which has ETag when the network is re-connected - * => This is changed to 180 seconds due to limitation of max downloading items. - */ - g_object_set(session, SOUP_SESSION_TIMEOUT, MAX_TIMEOUT, NULL); - - _set_proxy_on_soup_session(session, input_for_tranx->proxy_addr); - - switch (pi_http_method) { - case PI_HTTP_METHOD_GET: - msg = soup_message_new(METHOD_GET, url); - break; - case PI_HTTP_METHOD_POST: - msg = soup_message_new(METHOD_POST, url); - break; - case PI_HTTP_METHOD_HEAD: - msg = soup_message_new(METHOD_HEAD, url); - break; - default: - DA_LOG_ERR(HTTPManager,"Cannot enter here"); - break; - } - DA_LOG_VERBOSE(HTTPManager,"msg[%p]", msg); - /* if it is failed to create a msg, the url can be invalid, becasue of the input argument of soup_message_new API */ - if (msg == NULL) { - DA_LOG_ERR(HTTPManager,"Fail to create message"); - ret = DA_ERR_INVALID_URL; - goto ERR; - } - - _fill_soup_msg_header(msg, input_for_tranx); - - g_signal_connect(msg, "restarted", G_CALLBACK(_pi_http_restarted_cb), - NULL); /* for redirection case */ - g_signal_connect(msg, "got-headers", - G_CALLBACK(_pi_http_gotheaders_cb), NULL); - g_signal_connect(msg, "got-chunk", G_CALLBACK(_pi_http_gotchunk_cb), - NULL); - - if (using_content_sniffing) { - soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER); - g_signal_connect(msg, "content-sniffed", - G_CALLBACK(_pi_http_contentsniffed_cb), NULL); - } else { - soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER); - } - - soup_session_queue_message(session, msg, _pi_http_finished_cb, NULL); -// g_signal_connect(msg, "finished", G_CALLBACK(_pi_http_finished_cb), NULL); - - if (DA_FALSE == _pi_http_register_msg_to_session_table( - session_table_entry, msg)) { - _pi_http_destroy_session_table_entry(session_table_entry); - ret = DA_ERR_ALREADY_MAX_DOWNLOAD; - goto ERR; - } - - *out_tranx_id = session_table_entry; - DA_LOG(HTTPManager,"*out_tranx_id = %d", *out_tranx_id); - -ERR: - return ret; -} - -da_result_t PI_http_disconnect_transaction(int in_tranx_id) -{ - da_result_t ret = DA_RESULT_OK; - int session_table_entry = -1; - - DA_LOG_VERBOSE(HTTPManager,"in_tranx_id = %d", in_tranx_id); - - session_table_entry = in_tranx_id; - - _pi_http_destroy_session_table_entry(session_table_entry); - - return ret; -} - -da_result_t PI_http_cancel_transaction(int in_tranx_id, da_bool_t abort_option) -{ - da_result_t ret = DA_RESULT_OK; - SoupSession *session; - SoupMessage *msg; - int session_table_entry = -1; - - DA_LOG_FUNC_LOGV(HTTPManager); - - session_table_entry = in_tranx_id; - if (!_pi_http_is_this_session_table_entry_using(session_table_entry)) { - DA_LOG_CRITICAL(HTTPManager,"not using session"); - return ret; - } - session = GET_SESSION_FROM_TABLE_ENTRY(session_table_entry); - msg = GET_MSG_FROM_TABLE_ENTRY(session_table_entry); - - if (DA_NULL == session) { - DA_LOG_ERR(HTTPManager,"invalid session = %p", session); - goto ERR; - } - - if (DA_NULL == msg) { - DA_LOG_ERR(HTTPManager,"invalid message = %p", msg); - goto ERR; - } - DA_LOG(HTTPManager,"soup cancel API:abort option[%d] tranx_id[%d]", - abort_option, in_tranx_id); - if (abort_option) - soup_session_abort(session); - else - soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED); - DA_LOG(HTTPManager,"soup cancel API-Done"); -ERR: - return ret; -} - -void PI_http_pause_transaction(int transaction_id) -{ - int session_table_entry = -1; - pthread_mutex_t *mutex; - pthread_cond_t *cond; - - DA_LOG_FUNC_LOGD(HTTPManager); - - DA_LOG(HTTPManager,"in_tranx_id = %d", transaction_id); - - session_table_entry = transaction_id; - - if (!_pi_http_is_this_session_table_entry_using(session_table_entry)) - return; - - mutex = &(pi_session_table[session_table_entry].mutex); - cond = &(pi_session_table[session_table_entry].cond); - - _da_thread_mutex_lock (mutex); - - if (pi_session_table[session_table_entry].is_paused == DA_FALSE) { - DA_LOG_CRITICAL(HTTPManager,"paused!"); - pi_session_table[session_table_entry].is_paused = DA_TRUE; - _da_thread_cond_wait(cond, mutex); - } else { - DA_LOG_CRITICAL(HTTPManager,"NOT paused!"); - } - - _da_thread_mutex_unlock (mutex); - -} - -void PI_http_unpause_transaction(int transaction_id) -{ - int session_table_entry = -1; - pthread_mutex_t *mutex; - pthread_cond_t *cond; - - DA_LOG_FUNC_LOGV(Default); - - session_table_entry = transaction_id; - - if (!_pi_http_is_this_session_table_entry_using(session_table_entry)) - return; - - mutex = &(pi_session_table[session_table_entry].mutex); - cond = &(pi_session_table[session_table_entry].cond); - - _da_thread_mutex_lock (mutex); - - if (pi_session_table[session_table_entry].is_paused == DA_TRUE) { - DA_LOG_CRITICAL(HTTPManager,"wake up!"); - pi_session_table[session_table_entry].is_paused = DA_FALSE; - _da_thread_cond_signal(cond); - } - - _da_thread_mutex_unlock (mutex); - -} - -da_bool_t _pi_http_is_valid_input_for_tranx( - const input_for_tranx_t *input_for_tranx) -{ - if (!(input_for_tranx->http_msg_request)) { - DA_LOG_ERR(HTTPManager,"http_msg_request is NULL"); - return DA_FALSE; - } - - if (!((input_for_tranx->http_method == PI_HTTP_METHOD_GET) || - (input_for_tranx->http_method == PI_HTTP_METHOD_POST) || - (input_for_tranx->http_method == PI_HTTP_METHOD_HEAD))) { - DA_LOG_ERR(HTTPManager,"http_method is neither GET or POST or HEAD"); - return DA_FALSE; - } - - return DA_TRUE; -} - -da_bool_t _pi_http_is_this_session_table_entry_using( - const int in_session_table_entry) -{ - da_bool_t is_using = DA_FALSE; - - if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(in_session_table_entry)) - return DA_FALSE; - - _da_thread_mutex_lock (&mutex_for_session_table); - - is_using = pi_session_table[in_session_table_entry].is_using; - - _da_thread_mutex_unlock (&mutex_for_session_table); - - return is_using; -} - -void _pi_http_init_session_table_entry(const int in_session_table_entry) -{ - int entry = in_session_table_entry; - - if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) - return; - -// _da_thread_mutex_lock (&mutex_for_session_table); - - pi_session_table[entry].is_using = DA_TRUE; - pi_session_table[entry].msg = NULL; - pi_session_table[entry].session = NULL; - pi_session_table[entry].queue = NULL; - - _da_thread_mutex_init(&(pi_session_table[entry].mutex), DA_NULL); - _da_thread_cond_init(&(pi_session_table[entry].cond), NULL); - pi_session_table[entry].is_paused = DA_FALSE; - -// _da_thread_mutex_unlock (&mutex_for_session_table); - - return; -} - -void _pi_http_destroy_session_table_entry(const int in_session_table_entry) -{ - int entry = in_session_table_entry; - - if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) - return; - - _da_thread_mutex_lock (&mutex_for_session_table); - - if (pi_session_table[entry].is_paused == DA_TRUE) - PI_http_unpause_transaction(entry); - - /* Warning! Do not g_object_unref(msg) here! - * soup_session_queue_message() steals msg's reference count, - * so, we don't need to do anything for memory management. - * - * But, if using soup_session_send_message(), MUST call g_object_unref(msg). */ - /* if (pi_session_table[entry].msg) - g_object_unref(pi_session_table[entry].msg); */ - - pi_session_table[entry].msg = NULL; - - /* FIXME Cannot g_object_unref(session) here, - * because msg inside this session is not destoryed yet. - * The msg's reference count is stealed by soup_session_queue_message(), - * and it will be destroyed when _pi_http_finished_cb() is returned. - * For now, this _pi_http_destroy_session_table_entry() is called inside - * _pi_http_finished_cb(), so, g_object_unref(session) is not working. - * Should find out call this function after _pi_http_finished_cb(). */ - if (pi_session_table[entry].session) - g_object_unref(pi_session_table[entry].session); - else - DA_LOG_ERR(HTTPManager,"session is NULL. Cannot unref this."); - DA_LOG(HTTPManager,"unref session [%p]",pi_session_table[entry].session); - - pi_session_table[entry].session = NULL; - - pi_session_table[entry].queue = NULL; - pi_session_table[entry].is_paused = DA_FALSE; - pi_session_table[entry].is_using = DA_FALSE; - - _da_thread_mutex_destroy(&(pi_session_table[entry].mutex)); - _da_thread_cond_destroy(&(pi_session_table[entry].cond)); - - _da_thread_mutex_unlock (&mutex_for_session_table); - - return; -} - -int _pi_http_get_avaiable_session_table_entry(void) -{ - int i; - int avaiable_entry = -1; - - _da_thread_mutex_lock (&mutex_for_session_table); - - for (i = 0; i < MAX_SESSION_COUNT; i++) { - if (pi_session_table[i].is_using == DA_FALSE) { - /* pi_session_table[i].is_using = DA_TRUE; */ - DA_LOG_VERBOSE(HTTPManager,"available entry = %d", i); - - avaiable_entry = i; - - break; - } - } - _pi_http_init_session_table_entry(avaiable_entry); - _da_thread_mutex_unlock (&mutex_for_session_table); - - return avaiable_entry; -} - -da_bool_t _pi_http_register_queue_to_session_table( - const int in_session_table_entry, const queue_t *in_queue) -{ - int entry = in_session_table_entry; - queue_t *queue = (queue_t *) in_queue; - da_bool_t ret = DA_FALSE; - - if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) { - DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry); - return DA_FALSE; - } - - _da_thread_mutex_lock (&mutex_for_session_table); - - if (pi_session_table[entry].is_using == DA_FALSE) { - DA_LOG_ERR(HTTPManager,"this entry [%d] is not using", entry); - ret = DA_FALSE; - } else { - pi_session_table[entry].queue = queue; - DA_LOG_VERBOSE(HTTPManager,"queue = %p", pi_session_table[entry].queue); - ret = DA_TRUE; - } - - _da_thread_mutex_unlock (&mutex_for_session_table); - - return ret; -} - -da_bool_t _pi_http_register_session_to_session_table( - const int in_session_table_entry, SoupSession *session) -{ - int entry = in_session_table_entry; - da_bool_t ret = DA_FALSE; - - if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) { - DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry); - return DA_FALSE; - } - - if (DA_NULL == session) { - DA_LOG_ERR(HTTPManager,"invalid session = %p",session); - return DA_FALSE; - } - - _da_thread_mutex_lock (&mutex_for_session_table); - - if (pi_session_table[entry].is_using == DA_FALSE) { - ret = DA_FALSE; - } else { - pi_session_table[entry].session = session; - ret = DA_TRUE; - } - - _da_thread_mutex_unlock (&mutex_for_session_table); - - return ret; -} - -da_bool_t _pi_http_register_msg_to_session_table( - const int in_session_table_entry, SoupMessage *msg) -{ - int entry = in_session_table_entry; - da_bool_t ret = DA_FALSE; - - if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) { - DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry); - return DA_FALSE; - } - - if (DA_NULL == msg) { - DA_LOG_ERR(HTTPManager,"invalid msg = %p",msg); - return DA_FALSE; - } - - _da_thread_mutex_lock (&mutex_for_session_table); - - if (pi_session_table[entry].is_using == DA_FALSE) { - ret = DA_FALSE; - } else { - pi_session_table[entry].msg = msg; - ret = DA_TRUE; - } - - _da_thread_mutex_unlock (&mutex_for_session_table); - - return ret; -} - -queue_t *_pi_http_get_queue_from_session_table_entry( - const int in_session_table_entry) -{ - int entry = in_session_table_entry; - queue_t *out_queue = NULL; - - if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) { - DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry); - return out_queue; - } - - _da_thread_mutex_lock (&mutex_for_session_table); - - out_queue = pi_session_table[entry].queue; - _da_thread_mutex_unlock (&mutex_for_session_table); - - return out_queue; -} - -void _pi_http_store_read_header_to_queue(SoupMessage *msg, const char *sniffedType) -{ - da_result_t ret = DA_RESULT_OK; - - queue_t *da_queue = NULL; - q_event_t *da_event = NULL; - q_event_type_data da_event_type_data; - - int session_table_entry = -1; - SoupMessageHeadersIter headers_iter; - - const char *header_name; - const char *header_value; - - http_msg_response_t *http_msg_response = NULL; - - if (msg->response_headers) { - ret = http_msg_response_create(&http_msg_response); - if (ret != DA_RESULT_OK) - return; - - http_msg_response_set_status_code(http_msg_response, - msg->status_code); - - DA_LOG_VERBOSE(HTTPManager,"\n----raw header---------------------------------------------"); - DA_LOG(HTTPManager,"status code = %d", msg->status_code); - soup_message_headers_iter_init(&headers_iter, - msg->response_headers); - while (soup_message_headers_iter_next(&headers_iter, - &header_name, &header_value)) { - if ((header_name != DA_NULL) && (header_value - != DA_NULL)) { - http_msg_response_add_field(http_msg_response, - header_name, header_value); - DA_SECURE_LOGI("[%s][%s]", header_name, header_value); - } - } - DA_LOG_VERBOSE(HTTPManager,"\n-------------------------------------------------------------\n"); - - } - - if (using_content_sniffing && sniffedType) - http_msg_response_set_content_type(http_msg_response, sniffedType); - - session_table_entry - = _pi_http_get_session_table_entry_from_message(msg); - if (session_table_entry == -1) { - DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry.."); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - da_event_type_data = Q_EVENT_TYPE_DATA_PACKET; - - da_queue = _pi_http_get_queue_from_session_table_entry( - session_table_entry); - - ret = Q_make_http_data_event(da_event_type_data, &da_event); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(HTTPManager,"fail to make da_event"); - goto ERR; - } else { - Q_set_status_code_on_http_data_event(da_event, msg->status_code); - da_event->type.q_event_data_http.http_response_msg - = http_msg_response; - - Q_push_event(da_queue, da_event); - } - return; - -ERR: - if (DA_RESULT_OK != ret) - http_msg_response_destroy(&http_msg_response); - - return; -} - -void _pi_http_store_read_data_to_queue(SoupMessage *msg, const char *body_data, - int received_body_len) -{ - da_result_t ret = DA_RESULT_OK; - da_bool_t b_ret = DA_FALSE; - - char *body_buffer = NULL; - queue_t *da_queue = NULL; - q_event_t *da_event = NULL; - q_event_type_data da_event_type_data; - int session_table_entry = -1; - int http_status = -1; - - http_status = msg->status_code; - - session_table_entry - = _pi_http_get_session_table_entry_from_message(msg); - if (session_table_entry == -1) { - DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry.."); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - if (received_body_len == 0) { - DA_LOG_VERBOSE(HTTPManager,"Q_EVENT_TYPE_DATA_FINAL"); - da_event_type_data = Q_EVENT_TYPE_DATA_FINAL; - } else { - da_event_type_data = Q_EVENT_TYPE_DATA_PACKET; - if (received_body_len > 0) { - body_buffer = (char*) calloc(1, received_body_len); - DA_LOG_VERBOSE(HTTPManager,"body_buffer[%p]msg[%p]",body_buffer,msg); - if (body_buffer == DA_NULL) { - DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC"); - goto ERR; - } - memcpy(body_buffer, body_data, received_body_len); - } - } - - da_queue = _pi_http_get_queue_from_session_table_entry( - session_table_entry); - - ret = Q_make_http_data_event(da_event_type_data, &da_event); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(HTTPManager,"fail to make da_event"); - goto ERR; - } else { - Q_set_status_code_on_http_data_event(da_event, http_status); - Q_set_http_body_on_http_data_event(da_event, received_body_len, - body_buffer); - - _da_thread_mutex_lock (&(da_queue->mutex_queue)); - b_ret = Q_push_event_without_lock(da_queue, da_event); - if (b_ret == DA_FALSE) { - DA_LOG_CRITICAL(HTTPManager,"----------------------------------------fail to push!"); - - pthread_mutex_t *session_mutex = NULL; - pthread_cond_t *session_cond = NULL; - - session_mutex - = &(pi_session_table[session_table_entry].mutex); - session_cond - = &(pi_session_table[session_table_entry].cond); - - /* MUST keep this order for these mutexes */ - _da_thread_mutex_lock (session_mutex); - _da_thread_mutex_unlock (&(da_queue->mutex_queue)); - - if (pi_session_table[session_table_entry].is_paused - == DA_FALSE) { - DA_LOG_CRITICAL(HTTPManager,"paused!"); - pi_session_table[session_table_entry].is_paused - = DA_TRUE; - _da_thread_cond_wait(session_cond, session_mutex); - } else { - DA_LOG_CRITICAL(HTTPManager,"NOT paused!"); - } - - _da_thread_mutex_unlock (session_mutex); - - DA_LOG_CRITICAL(HTTPManager,"wake up! push again"); - Q_push_event(da_queue, da_event); - } else { - _da_thread_mutex_unlock (&(da_queue->mutex_queue)); - } - - } - - return; - -ERR: - if (DA_RESULT_OK != ret) { - if (DA_NULL != body_buffer) { - free(body_buffer); - } - } - - return; -} - -int _translate_error_code(int soup_error) -{ - DA_LOG_CRITICAL(HTTPManager, "soup error code[%d]", soup_error); - switch (soup_error) { - case SOUP_STATUS_CANT_RESOLVE: - case SOUP_STATUS_CANT_RESOLVE_PROXY: - case SOUP_STATUS_CANT_CONNECT: - case SOUP_STATUS_CANT_CONNECT_PROXY: - case SOUP_STATUS_IO_ERROR: - case SOUP_STATUS_MALFORMED: - case SOUP_STATUS_TRY_AGAIN: - return DA_ERR_NETWORK_FAIL; - case SOUP_STATUS_SSL_FAILED: - return DA_ERR_SSL_FAIL; - case SOUP_STATUS_REQUEST_TIMEOUT: - return DA_ERR_HTTP_TIMEOUT; - case SOUP_STATUS_TOO_MANY_REDIRECTS: - return DA_ERR_TOO_MANY_REDIECTS; - default: - return DA_ERR_NETWORK_FAIL; - } -} - -void _pi_http_store_neterr_to_queue(SoupMessage *msg) -{ - da_result_t ret = DA_RESULT_OK; - int error_type = -1; - queue_t *da_queue = NULL; - q_event_t *da_event = NULL; - int session_table_entry = -1; - - DA_LOG_FUNC_LOGD(HTTPManager); - - error_type = _translate_error_code(msg->status_code); - - session_table_entry - = _pi_http_get_session_table_entry_from_message(msg); - if (session_table_entry == -1) { - DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry.."); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } - - da_queue = _pi_http_get_queue_from_session_table_entry( - session_table_entry); - - DA_LOG_CRITICAL(HTTPManager,"Q_EVENT_TYPE_DATA_ABORT"); - ret = Q_make_http_data_event(Q_EVENT_TYPE_DATA_ABORT, &da_event); - if (ret != DA_RESULT_OK) { - DA_LOG_ERR(HTTPManager,"fail to make da_event"); - goto ERR; - } else { - Q_set_error_type_on_http_data_event(da_event, error_type); - - Q_push_event(da_queue, da_event); - } - -ERR: - return; -} - -int _pi_http_get_session_table_entry_from_message(SoupMessage *msg) -{ - - int out_entry = -1; - int i; - - if (DA_NULL == msg) { - DA_LOG_ERR(HTTPManager,"invalid message = %p", msg); - return out_entry; - } - - _da_thread_mutex_lock (&mutex_for_session_table); - - for (i = 0; i < MAX_SESSION_COUNT; i++) { - if (pi_session_table[i].is_using == DA_TRUE) { - if (pi_session_table[i].msg == msg) { - out_entry = i; - break; - } - } - } - - _da_thread_mutex_unlock (&mutex_for_session_table); - - if (i == MAX_SESSION_COUNT) { - DA_LOG_ERR(HTTPManager,"fail to find message = %p", msg); - } - - return out_entry; - -} - -void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data) -{ - char *url = NULL; - - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!msg) { - DA_LOG_ERR(HTTPManager, "Check NULL:msg"); - return; - } - - url = soup_uri_to_string(soup_message_get_uri(msg), DA_FALSE); - - DA_SECURE_LOGI("status_code[%d], reason[%s], url[%s]",msg->status_code,msg->reason_phrase,url); - - if (url) { - free(url); - url = NULL; - } - - if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) { - if (msg->status_code == SOUP_STATUS_CANCELLED) { - _pi_http_store_read_data_to_queue(msg, DA_NULL, 0); - } else { - _pi_http_store_neterr_to_queue(msg); - } - } else { - _pi_http_store_read_data_to_queue(msg, DA_NULL, 0); - } - -} - -/* this callback is called in case of redirection */ -void _pi_http_restarted_cb(SoupMessage *msg, gpointer data) -{ - DA_LOG_FUNC_LOGD(HTTPManager); - /* Location URL is needed when extracting the file name from url. - * So, the response header should be handled by http mgr.*/ - - if (!msg) { - DA_LOG_ERR(HTTPManager, "Check NULL:msg"); - return; - } - // If there are user id and password at url, libsoup handle it automatically. - if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) { - DA_LOG(HTTPManager,"Ignore:Unauthorized"); - return; - } - _pi_http_store_read_header_to_queue(msg, NULL); -} - -void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data) -{ - DA_LOG_FUNC_LOGV(HTTPManager); - - if (!msg) { - DA_LOG_ERR(HTTPManager, "Check NULL:msg"); - return; - } - - if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) { - DA_LOG(HTTPManager,"Redirection !!"); - if (SOUP_STATUS_NOT_MODIFIED != msg->status_code) - return; - } - - // If there are user id and password at url, libsoup handle it automatically. - if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) { - DA_LOG(HTTPManager,"Ignore:Unauthorized"); - return; - } - - soup_message_body_set_accumulate(msg->response_body, DA_FALSE); - - if (!using_content_sniffing) - _pi_http_store_read_header_to_queue(msg, NULL); - else - DA_LOG_DEBUG(HTTPManager,"ignore because content sniffing is turned on"); -} - -void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType, - GHashTable *params, gpointer data) -{ - DA_LOG_FUNC_LOGD(HTTPManager); - - if (!msg) { - DA_LOG_ERR(HTTPManager, "Check NULL:msg"); - return; - } - - if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) { - DA_LOG(HTTPManager,"Redirection !!"); - if (SOUP_STATUS_NOT_MODIFIED != msg->status_code) - return; - } - - // If there are user id and password at url, libsoup handle it automatically. - if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) { - DA_LOG(HTTPManager,"Ignore:Unauthorized"); - return; - } - - if (using_content_sniffing) - _pi_http_store_read_header_to_queue(msg, sniffedType); -} - -void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data) -{ -// DA_LOG_FUNC_LOGV(HTTPManager); - - if (!msg) { - DA_LOG_ERR(HTTPManager, "Check NULL:msg"); - return; - } - - if (!chunk) { - DA_LOG_ERR(HTTPManager, "Check NULL:chunk"); - return; - } - - if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) - return; - - if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) { - DA_LOG(HTTPManager,"Ignore:Unauthorized"); - return; - } - - if (chunk->data && chunk->length > 0) { - _pi_http_store_read_data_to_queue(msg, chunk->data, - chunk->length); - } -} diff --git a/agent/download-agent-utils-dl-id-history.c b/agent/download-agent-utils-dl-id-history.c deleted file mode 100755 index c6e747d..0000000 --- a/agent/download-agent-utils-dl-id-history.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "download-agent-type.h" -#include "download-agent-utils.h" -#include "download-agent-utils-dl-id-history.h" - -da_result_t init_dl_id_history(dl_id_history_t *dl_id_history) -{ - da_result_t ret = DA_RESULT_OK; - - /* Initial dl_id_history will be starting number for dl_id. - * dl_id will be sequentially increased from the dl_id_history, - * then dl_id_history will be updated. */ - _da_thread_mutex_init(&(dl_id_history->mutex), DA_NULL); - _da_thread_mutex_lock(&(dl_id_history->mutex)); - get_random_number(&(dl_id_history->starting_num)); - dl_id_history->cur_dl_id = DA_INVALID_ID; - _da_thread_mutex_unlock(&(dl_id_history->mutex)); - - DA_LOG_VERBOSE(Default,"starting num = %d", dl_id_history->starting_num); - return ret; -} - -da_result_t deinit_dl_id_history(dl_id_history_t *dl_id_history) -{ - da_result_t ret = DA_RESULT_OK; - - _da_thread_mutex_lock(&(dl_id_history->mutex)); - dl_id_history->starting_num = DA_INVALID_ID; - dl_id_history->cur_dl_id = DA_INVALID_ID; - _da_thread_mutex_unlock(&(dl_id_history->mutex)); - - _da_thread_mutex_destroy(&(dl_id_history->mutex)); - - return ret; -} - -int get_available_dl_id(dl_id_history_t *dl_id_history) -{ - int dl_id = 0; - - _da_thread_mutex_lock(&(dl_id_history->mutex)); - - if (dl_id_history->cur_dl_id == DA_INVALID_ID) - dl_id_history->cur_dl_id = dl_id_history->starting_num; - else if (dl_id_history->cur_dl_id > 254) - dl_id_history->cur_dl_id = 1; - else - dl_id_history->cur_dl_id++; - - dl_id = dl_id_history->cur_dl_id; - - _da_thread_mutex_unlock(&(dl_id_history->mutex)); - - DA_LOG_VERBOSE(Default,"dl_id = %d", dl_id); - return dl_id; -} diff --git a/agent/download-agent-utils.c b/agent/download-agent-utils.c deleted file mode 100755 index 71aca16..0000000 --- a/agent/download-agent-utils.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "download-agent-client-mgr.h" -#include "download-agent-debug.h" -#include "download-agent-dl-mgr.h" -#include "download-agent-file.h" -#include "download-agent-http-misc.h" -#include "download-agent-mime-util.h" -#include "download-agent-utils.h" -#include "download-agent-plugin-conf.h" -#include "download-agent-dl-info-util.h" - -#define DA_HTTP_HEADER_CONTENT_TYPE "Content-Type" -#define DA_HTTP_HEADER_CONTENT_LENGTH "Content-Length" -#define DA_FILE_NUMBER_LIMIT (1024*1024) - -typedef struct _da_descriptor_mime_table_t { - char *content_type; - da_mime_type_id_t mime_type; -} da_descriptor_mime_table_t; - -da_descriptor_mime_table_t - descriptor_mime_table[] = { - {"", DA_MIME_TYPE_NONE}, - /* DRM1.0 */ - {"application/vnd.oma.drm.message", - DA_MIME_TYPE_DRM1_MESSATE}, /* drm1.0 FL.CD*/ - {"", DA_MIME_TYPE_END}}; - -void get_random_number(int *out_num) -{ - int temp = DA_INVALID_ID; - unsigned int seed = (unsigned)time(0); - - temp = (int)(rand_r(&seed) % 100 + 1.0); - *out_num = temp; -} - -da_result_t get_extension_from_mime_type(char *mime_type, char **extension) -{ - da_result_t ret = DA_RESULT_OK; - char *ext = DA_NULL; - - DA_LOG_FUNC_LOGV(Default); - if (DA_NULL == mime_type || DA_NULL == extension) { - DA_LOG_ERR(Default,"received mime_type is null"); - ret = DA_ERR_INVALID_ARGUMENT; - goto ERR; - } -// DA_SECURE_LOGD("input mime type = %s", mime_type); - if (DA_RESULT_OK != (ret = da_mime_get_ext_name(mime_type, &ext))) { - DA_LOG_ERR(Default,"can't find proper extension!"); - goto ERR; - } - *extension = ext; -// DA_SECURE_LOGD("found extension = %s", *extension); - -ERR: - return ret; -} - -int read_data_from_file(char *file, char **out_buffer) -{ - FILE *fd; - unsigned long long file_size = -1; - char *buffer = NULL; - int buffer_len = 0; - size_t read_len = 0; - - *out_buffer = NULL; - - if (!file) - return 0; - - /* open file with "rb", because fread() handles the file as binary mode */ - fd = fopen(file, "rb"); - if (!fd) { - DA_LOG_ERR(FileManager,"File open err! received file path"); - return 0; - } - - get_file_size(file, &file_size); - if (file_size <= 0) { - DA_LOG_ERR(FileManager,"file size is [%llu]", file_size); - fclose(fd); - return 0; - } - - /* A guide from www.securecoding.cert.org - * : FIO17-C. Do not rely on an ending null character when using fread() - * - * buffer is initialized with null through calloc(), so, it is always null-terminated even if fread() failed. - * allocate memory one more byte to ensure null-terminated even if the file is not null-terminated. - */ - buffer_len = sizeof(char) * file_size; - buffer = (char *)calloc(1, buffer_len + 1); - if (buffer) { - read_len = fread(buffer, sizeof(char), file_size, fd); - if (read_len == file_size) { - *out_buffer = buffer; - } else { - DA_LOG_ERR(FileManager,"File Read Not Complete read length = %d", read_len); - free(buffer); - buffer = NULL; - buffer_len = 0; - } - } else { - buffer_len = 0; - } - - fclose(fd); - - return buffer_len; -} - -da_result_t get_available_memory(da_storage_size_t *avail_memory) -{ - da_result_t ret = DA_RESULT_OK; - int fs_ret = 0; - struct statfs filesys_info = {0, }; - char *default_install_dir = NULL; - - DA_LOG_FUNC_LOGD(Default); - - if (!avail_memory) - return DA_ERR_INVALID_ARGUMENT; - - ret = get_default_install_dir(&default_install_dir); - - if (ret == DA_RESULT_OK && default_install_dir) { - fs_ret = statfs(default_install_dir, &filesys_info); - } else { - return DA_ERR_FAIL_TO_ACCESS_STORAGE; - } - - if (fs_ret != 0) { - DA_LOG_ERR(Default,"Phone file path :statfs error - [%d]", errno); - free(default_install_dir); - return DA_ERR_INVALID_INSTALL_PATH; - } - - avail_memory->b_available = filesys_info.f_bavail; - avail_memory->b_size = filesys_info.f_bsize; - - DA_LOG_VERBOSE(Default, "Available Memory(f_bavail) : %llu", filesys_info.f_bavail); - DA_LOG_VERBOSE(Default, "Available Memory(f_bsize) : %d", filesys_info.f_bsize); - DA_LOG_VERBOSE(Default, "Available Memory(kbytes) : %lu", (filesys_info.f_bavail/1024)*filesys_info.f_bsize); - - free(default_install_dir); - return DA_RESULT_OK; -} - -da_mime_type_id_t get_mime_type_id(char *content_type) -{ - int i = 0; - - if (content_type == NULL) { - DA_LOG_CRITICAL(Default, "No Mime Type Id"); - return DA_MIME_TYPE_NONE; - } - - while(descriptor_mime_table[i].mime_type != DA_MIME_TYPE_END) - { - if (!strcmp(descriptor_mime_table[i].content_type, content_type)) { - break; - } - i++; - } - //DA_LOG_VERBOSE(Default, "dd mime type check: index[%d] type[%d]", i, descriptor_mime_table[i].mime_type); - return descriptor_mime_table[i].mime_type; -} - - - -da_bool_t is_valid_url(const char *url, da_result_t *err_code) -{ - da_result_t ret = DA_RESULT_OK; - da_bool_t b_ret = DA_FALSE; - - int wanted_str_len = 0; - char *wanted_str = NULL; - char *wanted_str_start = NULL; - char *wanted_str_end = NULL; - - if ((DA_NULL == url) || (1 > strlen(url))) { - ret = DA_ERR_INVALID_URL; - goto ERR; - } - - wanted_str_start = (char*)url; - wanted_str_end = strstr(url, "://"); - if (!wanted_str_end) { - DA_LOG_ERR(Default,"No protocol on this url"); - ret = DA_ERR_INVALID_URL; - goto ERR; - } - - wanted_str_len = wanted_str_end - wanted_str_start; - wanted_str = (char*)calloc(1, wanted_str_len + 1); - if (!wanted_str) { - DA_LOG_ERR(Default,"DA_ERR_FAIL_TO_MEMALLOC"); - ret = DA_ERR_FAIL_TO_MEMALLOC; - goto ERR; - } - strncpy(wanted_str, wanted_str_start, wanted_str_len); - - b_ret = is_supporting_protocol(wanted_str); - if (!b_ret) { - ret = DA_ERR_UNSUPPORTED_PROTOCAL; - goto ERR; - } - -ERR: - if (wanted_str) { - free(wanted_str); - wanted_str = NULL; - } - - if (err_code) - *err_code = ret; - - return b_ret; -} - -da_result_t move_file(const char *from_path, const char *to_path) -{ - da_result_t ret = DA_RESULT_OK; - - if (!from_path || !to_path) - return DA_ERR_INVALID_ARGUMENT; - - if (rename(from_path, to_path) != 0) { - DA_LOG_CRITICAL(FileManager,"rename failed : syserr[%d]",errno); - if (errno == EXDEV) { - DA_LOG_CRITICAL(FileManager,"File system is diffrent. Try to copy a file"); - ret = copy_file(from_path, to_path); - if (ret == DA_RESULT_OK) { - remove_file(from_path); - } else { - if (is_file_exist(to_path)) - remove_file(to_path); - ret = DA_ERR_FAIL_TO_INSTALL_FILE; - } - } else { - ret = DA_ERR_FAIL_TO_INSTALL_FILE; - } - } - return ret; -} - -void remove_file(const char *file_path) -{ - DA_LOG_FUNC_LOGD(FileManager); - - if (file_path && is_file_exist(file_path)) { - DA_SECURE_LOGD("remove file [%s]", file_path); - if (unlink(file_path) < 0) { - DA_LOG_ERR(FileManager,"file removing failed."); - } - } -} diff --git a/agent/include/download-agent-basic.h b/agent/include/download-agent-basic.h deleted file mode 100755 index 340a34a..0000000 --- a/agent/include/download-agent-basic.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Basic_H -#define _Download_Agent_Basic_H - -#include - -#include "download-agent-type.h" -#include "download-agent-interface.h" -#include "download-agent-dl-mgr.h" - -da_result_t start_download(const char *url, int *dl_id); -da_result_t start_download_with_extension(const char *url , int *dl_id, extension_data_t *extension_data); - -#endif diff --git a/agent/include/download-agent-client-mgr.h b/agent/include/download-agent-client-mgr.h index f4c6234..b2ce1c8 100755 --- a/agent/include/download-agent-client-mgr.h +++ b/agent/include/download-agent-client-mgr.h @@ -14,77 +14,14 @@ * limitations under the License. */ -#ifndef _Download_Agent_Client_Mgr_H -#define _Download_Agent_Client_Mgr_H +#ifndef DOWNLOAD_AGENT_CLIENT_MGR_H +#define DOWNLOAD_AGENT_CLIENT_MGR_H -#include +#include "download-agent-dl-info.h" -#include "download-agent-type.h" -#include "download-agent-interface.h" - -#include "download-agent-pthread.h" - -typedef enum { - Q_CLIENT_NOTI_TYPE_STARTED_INFO = 0, - Q_CLIENT_NOTI_TYPE_PROGRESS_INFO, - Q_CLIENT_NOTI_TYPE_PAUSED_INFO, - Q_CLIENT_NOTI_TYPE_FINISHED_INFO, - Q_CLIENT_NOTI_TYPE_TERMINATE, -} client_noti_type; - -typedef struct _client_noti_t client_noti_t; -struct _client_noti_t { - int slot_id; - void *user_data; - client_noti_type noti_type; - union _client_type { - user_download_info_t update_dl_info; - user_progress_info_t update_progress_info; - user_paused_info_t paused_info; - user_finished_info_t finished_info; - } type; - - client_noti_t *next; -}; - -typedef struct _client_queue_t { - da_bool_t having_data; - client_noti_t *client_q_head; - pthread_mutex_t mutex_client_queue; - pthread_cond_t cond_client_queue; -} client_queue_t; - -typedef struct _client_app_info_t { - da_client_cb_t client_callback; - char *client_user_agent; -} client_app_info_t; - -typedef struct _client_app_mgr_t { - da_bool_t is_init; - client_queue_t client_queue; - client_app_info_t client_app_info; - pthread_t thread_id; - da_bool_t is_thread_init; - pthread_mutex_t mutex_client_mgr; -} client_app_mgr_t; - -da_result_t init_client_app_mgr(void); -da_bool_t is_client_app_mgr_init(void); - -da_result_t reg_client_app(da_client_cb_t *da_client_callback); -da_result_t dereg_client_app(void); - -da_result_t send_client_paused_info (int slot_id); -da_result_t send_client_update_dl_info (int slot_id, int dl_id, - char *file_type, unsigned long int file_size, char *tmp_saved_path, - char *pure_file_name, char *etag, char *extension); -da_result_t send_client_update_progress_info (int slot_id, int dl_id, - unsigned long int received_size); -da_result_t send_client_finished_info (int slot_id, int dl_id, - char *saved_path, char *etag, int error, int http_status); - -char *get_client_user_agent_string(void); - -void push_client_noti(client_noti_t *client_noti); +da_ret_t send_client_paused_info(da_info_t *da_info); +da_ret_t send_client_update_dl_info(da_info_t *da_info); +da_ret_t send_client_update_progress_info(da_info_t *da_info); +da_ret_t send_client_finished_info(da_info_t *da_info, int err); #endif diff --git a/agent/include/download-agent-debug.h b/agent/include/download-agent-debug.h index 24ac67e..23c2a66 100755 --- a/agent/include/download-agent-debug.h +++ b/agent/include/download-agent-debug.h @@ -14,94 +14,55 @@ * limitations under the License. */ -#ifndef _Download_Agent_Debug_H -#define _Download_Agent_Debug_H +#ifndef _DOWNLOAD_AGENT_DEBUG_H +#define _DOWNLOAD_AGENT_DEBUG_H #include "download-agent-type.h" -#define DA_DEBUG_ENV_KEY "DOWNLOAD_AGENT_DEBUG" -#define DA_DEBUG_CONFIG_FILE_PATH "/tmp/.download_agent.conf" - -#define IS_LOG_ON(channel) (DALogBitMap & (0x1<<(channel))) - -typedef enum { - Soup, - HTTPManager, - FileManager, - DRMManager, - DownloadManager, - ClientNoti, - HTTPMessageHandler, - Encoding, - QueueManager, - Parsing, - Thread, - Default, - DA_LOG_CHANNEL_MAX -} da_log_channel; - -extern int DALogBitMap; - -da_result_t init_log_mgr(void); - -#ifdef NODEBUG - #define DA_LOG(channel, format, ...) ((void)0) - #define DA_LOG_CRITICAL(channel, format, ...) ((void)0) - #define DA_LOG_VERBOSE(channel, format, ...) ((void)0) - #define DA_LOG_ERR(channel, format, ...) ((void)0) - #define DA_LOG_FUNC_LOGD(channel, ...) ((void)0) - #define DA_LOG_FUNC_LOGV(channel, ...) ((void)0) - #define DA_SECURE_LOGD(format, ...) ((void)0) - #define DA_SECURE_LOGI(format, ...) ((void)0) - #define DA_SECURE_LOGE(format, ...) ((void)0) - -#else /* NODEBUG */ #include #include #include -#ifdef DA_DEBUG_USING_DLOG - #include +// ansi color +#define COLOR_RED "\033[0;31m" +#define COLOR_GREEN "\033[0;32m" +#define COLOR_BROWN "\033[0;33m" +#define COLOR_LIGHTBLUE "\033[0;37m" +#define COLOR_END "\033[0;m" + +#ifdef _ENABLE_DLOG +#include +#include +#include + #ifdef LOG_TAG #undef LOG_TAG #endif /* LOG_TAG */ - #define LOG_TAG "DOWNLOAD_AGENT" - #define DA_LOG(channel, format, ...) LOGI_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__) - #define DA_LOG_DEBUG(channel, format, ...) LOGD_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__) - #define DA_LOG_CRITICAL(channel, format, ...) LOGI_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__) - #define DA_LOG_VERBOSE(channel, format, ...) ((void)0)//LOGD_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__) - #define DA_LOG_ERR(channel, format, ...) LOGE_IF(IS_LOG_ON(channel), "ERR! "format, ##__VA_ARGS__) - #define DA_LOG_FUNC_LOGD(channel, ...) LOGD_IF(IS_LOG_ON(channel), "starting...") - #define DA_LOG_FUNC_LOGV(channel, ...) ((void)0)//LOGD_IF(IS_LOG_ON(channel), "starting...") - #define DA_SECURE_LOGD(format, ...) SECURE_LOGD(format, ##__VA_ARGS__) - #define DA_SECURE_LOGI(format, ...) SECURE_LOGI(format, ##__VA_ARGS__) - #define DA_SECURE_LOGE(format, ...) SECURE_LOGE(format, ##__VA_ARGS__) -#else /* DA_DEBUG_USING_DLOG */ - #include - #include + #define LOG_TAG "DP_DA" + #define DA_LOGV(format, ...) ((void)0)//LOGD("[%d]:"format, syscall(__NR_gettid), ##__VA_ARGS__) + #define DA_LOGD(format, ...) LOGD(COLOR_LIGHTBLUE "[%d]:"format COLOR_END, syscall(__NR_gettid), ##__VA_ARGS__) + #define DA_LOGI(format, ...) LOGI(COLOR_BROWN "[%d]:"format COLOR_END, syscall(__NR_gettid), ##__VA_ARGS__) + #define DA_LOGE(format, ...) LOGE(COLOR_RED "[%d]:"format COLOR_END, syscall(__NR_gettid), ##__VA_ARGS__) + #define DA_SECURE_LOGD(format, ...) SECURE_LOGD(COLOR_GREEN format COLOR_END, ##__VA_ARGS__) + #define DA_SECURE_LOGI(format, ...) SECURE_LOGI(COLOR_GREEN format COLOR_END, ##__VA_ARGS__) + #define DA_SECURE_LOGE(format, ...) SECURE_LOGE(COLOR_GREEN format COLOR_END, ##__VA_ARGS__) +#else - #define DA_LOG(channel, format, ...) do {\ - IS_LOG_ON(channel) \ - ? fprintf(stderr, "[DA][%u][%s(): %d] "format"\n",(unsigned int)syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__) \ - : ((void)0);\ - }while(0) - #define DA_LOG_ERR(channel, format, ...) do {\ - IS_LOG_ON(channel) \ - ? fprintf(stderr, "[DA][%u][ERR][%s(): %d]\n",(unsigned int)syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__) \ - : ((void)0); \ +#include +#include + + #define DA_LOGD(format, ...) do {\ + fprintf(stderr, "[DA][%d][%s():%d] "format"\n",syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__);\ }while(0) - #define DA_LOG_FUNC_LOGD(channel, ...) do {\ - IS_LOG_ON(channel) \ - ? fprintf(stderr, "[DA][%u][%s(): %d] starting\n",(unsigned int)syscall(__NR_gettid), __FUNCTION__,__LINE__) \ - : ((void)0); \ + #define DA_LOGE(format, ...) do {\ + fprintf(stderr, "[DA][%d][ERR][%s():%d]\n",syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__);\ }while(0) - #define DA_LOG_CRITICAL DA_LOG - #define DA_LOG_VERBOSE DA_LOG - #define DA_LOG_FUNC_LOGV ((void)0) + #define DA_LOGV DA_LOGD + #define DA_LOGI DA_LOGD #define DA_SECURE_LOGD(format, ...) ((void)0) #define DA_SECURE_LOGI(format, ...) ((void)0) #define DA_SECURE_LOGE(format, ...) ((void)0) -#endif /* DA_DEBUG_USING_DLOG */ -#endif /* NDEBUG */ -#endif /* _Download_Agent_Debug_H */ +#endif /* _ENABLE_DLOG */ + +#endif /* DOWNLOAD_AGENT_DEBUG_H */ diff --git a/agent/include/download-agent-defs.h b/agent/include/download-agent-defs.h index b69690a..d5b6a5e 100755 --- a/agent/include/download-agent-defs.h +++ b/agent/include/download-agent-defs.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef _Download_Agent_Defs_H -#define _Download_Agent_Defs_H +#ifndef _DOWNLOAD_AGENT_DEFS_H +#define _DOWNLOAD_AGENT_DEFS_H #ifndef DEPRECATED #define DEPRECATED __attribute__((deprecated)) @@ -26,6 +26,7 @@ * Main reason for this restriction is because of Network bandwidth. */ #define DA_MAX_DOWNLOAD_REQ_AT_ONCE 50 +#define DA_MAX_TIME_OUT 65 #define DA_RESULT_OK 0 @@ -57,33 +58,28 @@ // System error (-200 ~ -299) #define DA_ERR_FAIL_TO_MEMALLOC -200 #define DA_ERR_FAIL_TO_CREATE_THREAD -210 -#define DA_ERR_FAIL_TO_OBTAIN_MUTEX -220 #define DA_ERR_FAIL_TO_ACCESS_FILE -230 #define DA_ERR_DISK_FULL -240 -// Platform error (-300 ~ -399) -#define DA_ERR_FAIL_TO_GET_CONF_VALUE -300 -#define DA_ERR_FAIL_TO_ACCESS_STORAGE -310 -#define DA_ERR_DLOPEN_FAIL -330 - // Network error (-400 ~ -499) #define DA_ERR_NETWORK_FAIL -400 #define DA_ERR_UNREACHABLE_SERVER -410 -#define DA_ERR_HTTP_TIMEOUT -420 -#define DA_ERR_SSL_FAIL -430 -#define DA_ERR_TOO_MANY_REDIECTS -440 +#define DA_ERR_CONNECTION_FAIL -420 +#define DA_ERR_HTTP_TIMEOUT -430 +#define DA_ERR_SSL_FAIL -440 +#define DA_ERR_TOO_MANY_REDIRECTS -450 +#define DA_ERR_NETWORK_UNAUTHORIZED -460 // HTTP error - not conforming with HTTP spec (-500 ~ -599) #define DA_ERR_MISMATCH_CONTENT_TYPE -500 -#define DA_ERR_MISMATCH_CONTENT_SIZE -501 -#define DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT -502 +#define DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT -501 +#define DA_ERR_MISMATCH_CONTENT_SIZE -502 -// DRM error - not conforming with DRM spec (-700 ~ -799) -#define DA_ERR_DRM_FAIL -700 -#define DA_ERR_DRM_FILE_FAIL -710 +// DRM error - not conforming with DRM spec (-600 ~ -699) +#define DA_ERR_DRM_FAIL -600 -// install error (-800 ~ -899) -#define DA_ERR_FAIL_TO_INSTALL_FILE -800 +// string to check invalid characters in path before using open() and fopen() API's +#define DA_INVALID_PATH_STRING ";\\\":*?<>|()" #endif diff --git a/agent/include/download-agent-dl-info-util.h b/agent/include/download-agent-dl-info-util.h deleted file mode 100755 index d6e20a8..0000000 --- a/agent/include/download-agent-dl-info-util.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Dl_Info_Util_H -#define _Download_Agent_Dl_Info_Util_H - -#include "download-agent-type.h" -#include "download-agent-http-queue.h" -#include "download-agent-utils-dl-id-history.h" - -#define DA_MAX_DOWNLOAD_ID DA_MAX_DOWNLOAD_REQ_AT_ONCE -#define DA_MAX_TYPE_COUNT 10 - -#define DOWNLOAD_NOTIFY_LIMIT (1024*32) //bytes -extern pthread_mutex_t mutex_download_state[]; - -typedef enum { - DOWNLOAD_STATE_IDLE = 0, - DOWNLOAD_STATE_NEW_DOWNLOAD = 10, /* stage */ - DOWNLOAD_STATE_FINISH = 50, /* stage */ - DOWNLOAD_STATE_PAUSED = 60, /* http */ - DOWNLOAD_STATE_CANCELED = 70, /* http */ - DOWNLOAD_STATE_ABORTED = 80 /* satge */ -} download_state_t; - -typedef enum { - HTTP_STATE_READY_TO_DOWNLOAD = 0, - HTTP_STATE_REDIRECTED = 1, - HTTP_STATE_DOWNLOAD_REQUESTED = 2, - HTTP_STATE_DOWNLOAD_STARTED = 3, - HTTP_STATE_DOWNLOADING = 4, - HTTP_STATE_DOWNLOAD_FINISH = 5, - HTTP_STATE_REQUEST_CANCEL = 6, - HTTP_STATE_REQUEST_PAUSE = 7, - HTTP_STATE_REQUEST_RESUME = 8, - HTTP_STATE_CANCELED = 9, - HTTP_STATE_PAUSED = 10, - HTTP_STATE_RESUMED = 11, - HTTP_STATE_ABORTED = 12, -} http_state_t; - -typedef struct _client_input_basic_t { - char *req_url; - char **user_request_header; - int user_request_header_count; -} client_input_basic_t; - -typedef struct _client_input_t { - void *user_data; - char *install_path; - char *file_name; - char *etag; - char *temp_file_path; - char *pkg_name; - client_input_basic_t client_input_basic; -} client_input_t; - -typedef struct _download_thread_input { - int slot_id; - client_input_t *client_input; -} download_thread_input; - -typedef struct _source_info_basic_t { - int dl_id; - char *url; - char **user_request_header; - int user_request_header_count; -} source_info_basic_t; - -typedef struct _source_info_t { - union _source_info_type { - source_info_basic_t *source_info_basic; - } source_info_type; -} source_info_t; - -#define GET_SOURCE_TYPE(SOURCE) ((SOURCE)->source_type) -#define GET_SOURCE_BASIC(SOURCE) ((SOURCE)->source_info_type.source_info_basic) -#define GET_SOURCE_BASIC_URL(SOURCE) (GET_SOURCE_BASIC(SOURCE)->url) - -typedef struct _req_dl_info { - http_info_t http_info; - - /* This is just pointer assignment from stage source info. */ - char *destination_url; - /* The location url is assigned here in case of redirection. - * At this time, the pointer should be freed. */ - char *location_url; - char **user_request_header; - int user_request_header_count; - char *user_request_etag; - char *user_request_temp_file_path; - - http_state_t http_state; - pthread_mutex_t mutex_http_state; - - da_result_t result; - /*************** will be depreciated ***********************/ - /* ToDo : previous http_info should be saved in case of pause */ - char *content_type_from_header; /* calloced in set hdr fiels on download info */ - unsigned long long content_len_from_header; - char *etag_from_header; - - unsigned long int downloaded_data_size; - - int invloved_transaction_id; -} req_dl_info; - -#define GET_REQUEST_HTTP_RESULT(REQUEST) (REQUEST->result) -#define GET_REQUEST_HTTP_TRANS_ID(REQUEST) (REQUEST->invloved_transaction_id) -#define GET_REQUEST_HTTP_REQ_URL(REQUEST) (REQUEST->destination_url) -#define GET_REQUEST_HTTP_REQ_LOCATION(REQUEST) (REQUEST->location_url) -#define GET_REQUEST_HTTP_USER_REQUEST_HEADER(REQUEST) (REQUEST->user_request_header) -#define GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(REQUEST) (REQUEST->user_request_header_count) -#define GET_REQUEST_HTTP_USER_REQUEST_ETAG(REQUEST) (REQUEST->user_request_etag) -#define GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(REQUEST) (REQUEST->user_request_temp_file_path) -#define GET_REQUEST_HTTP_HDR_ETAG(REQUEST) (REQUEST->etag_from_header) -#define GET_REQUEST_HTTP_HDR_CONT_TYPE(REQUEST) (REQUEST->content_type_from_header) -#define GET_REQUEST_HTTP_HDR_CONT_LEN(REQUEST) (REQUEST->content_len_from_header) -#define GET_REQUEST_HTTP_CONTENT_OFFSET(REQUEST)(REQUEST->downloaded_data_size) -#define GET_REQUEST_HTTP_MUTEX_HTTP_STATE(STAGE) (GET_STAGE_TRANSACTION_INFO(STAGE)->mutex_http_state) -#define GET_HTTP_STATE_ON_STAGE(STAGE) (GET_STAGE_TRANSACTION_INFO(STAGE)->http_state) -#define CHANGE_HTTP_STATE(STATE,STAGE) {\ - _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(STAGE)));\ - GET_HTTP_STATE_ON_STAGE(STAGE) = STATE;\ - DA_LOG_DEBUG(Default, "Changed http_state to - [%d] ", GET_HTTP_STATE_ON_STAGE(STAGE));\ - _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(STAGE)));\ -} - -typedef struct _file_info { - void *file_handle; - char *pure_file_name; - char *extension; - char *file_name_final; /* malloced in set_file_path_for_final_saving */ - char *content_type; /* malloced in make file info. */ - char *add_to_buffer; - unsigned int file_size; /* http header's Content-Length has higher priority than DD's */ - unsigned int total_bytes_written_to_file; /* current written file size */ - unsigned int bytes_written_to_file; - unsigned int current_buffer_len; -} file_info; - -#define GET_CONTENT_STORE_PURE_FILE_NAME(FILE_CNTXT) (FILE_CNTXT)->pure_file_name -#define GET_CONTENT_STORE_EXTENSION(FILE_CNTXT) (FILE_CNTXT)->extension -#define GET_CONTENT_STORE_ACTUAL_FILE_NAME(FILE_CNTXT) (FILE_CNTXT)->file_name_final -#define GET_CONTENT_STORE_FILE_HANDLE(FILE_CNTXT) (FILE_CNTXT)->file_handle -#define GET_CONTENT_STORE_FILE_SIZE(FILE_CNTXT) (FILE_CNTXT)->file_size -#define GET_CONTENT_STORE_CURRENT_FILE_SIZE(FILE_CNTXT) (FILE_CNTXT)->total_bytes_written_to_file -#define IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(FILE_CNTXT) (FILE_CNTXT)->bytes_written_to_file -#define GET_CONTENT_STORE_FILE_BUFFER(FILE_CNTXT) (FILE_CNTXT)->add_to_buffer -#define GET_CONTENT_STORE_FILE_BUFF_LEN(FILE_CNTXT) ((FILE_CNTXT)->current_buffer_len) -#define GET_CONTENT_STORE_CONTENT_TYPE(FILE_CNTXT) (FILE_CNTXT)->content_type - -typedef struct _stage_info { - int dl_id; - int thread_id; - source_info_t dl_request; - req_dl_info dl_tansaction_context; - file_info dl_content_storage; - struct _stage_info *next_stage_info; -} stage_info; - -#define GET_STAGE_DL_ID(STAGE) ((STAGE)->dl_id) -#define GET_STAGE_THREAD_ID(STAGE) ((STAGE)->thread_id) -#define GET_STAGE_SOURCE_INFO(STAGE) (&((STAGE)->dl_request)) -#define GET_STAGE_TRANSACTION_INFO(STAGE) (&((STAGE)->dl_tansaction_context)) -#define GET_STAGE_CONTENT_STORE_INFO(STAGE) (&((STAGE)->dl_content_storage)) -#define GET_STAGE_INSTALLATION_INFO(STAGE) (&((STAGE)->post_dl_context)) - -typedef struct { - da_bool_t is_using; - int slot_id; - int dl_id; - pthread_t active_dl_thread_id; - download_state_t state; - stage_info *download_stage_data; - queue_t queue; - int http_status; - da_bool_t enable_pause_update; - // FIXME have client_input itself, not to have each of them - char *user_install_path; - char *user_file_name; - char *user_etag; - char *user_temp_file_path; - void *user_data; -} dl_info_t; - -#define GET_DL_THREAD_ID(ID) (download_mgr.dl_info[ID].active_dl_thread_id) -#define GET_DL_STATE_ON_ID(ID) (download_mgr.dl_info[ID].state) -#define GET_DL_STATE_ON_STAGE(STAGE) (GET_DL_STATE_ON_ID(GET_STAGE_DL_ID(STAGE))) -#define GET_DL_CURRENT_STAGE(ID) (download_mgr.dl_info[ID].download_stage_data) -#define GET_DL_ID(ID) (download_mgr.dl_info[ID].dl_id) -#define GET_DL_QUEUE(ID) &(download_mgr.dl_info[ID].queue) -#define GET_DL_ENABLE_PAUSE_UPDATE(ID) (download_mgr.dl_info[ID].enable_pause_update) -#define GET_DL_USER_INSTALL_PATH(ID) (download_mgr.dl_info[ID].user_install_path) -#define GET_DL_USER_FILE_NAME(ID) (download_mgr.dl_info[ID].user_file_name) -#define GET_DL_USER_ETAG(ID) (download_mgr.dl_info[ID].user_etag) -#define GET_DL_USER_TEMP_FILE_PATH(ID) (download_mgr.dl_info[ID].user_temp_file_path) -#define GET_DL_USER_DATA(ID) (download_mgr.dl_info[ID].user_data) -#define IS_THIS_DL_ID_USING(ID) (download_mgr.dl_info[ID].is_using) - -#define CHANGE_DOWNLOAD_STATE(STATE,STAGE) {\ - _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(STAGE)]);\ - GET_DL_STATE_ON_STAGE(STAGE) = STATE;\ - DA_LOG_DEBUG(Default, "Changed download_state to - [%d] ", GET_DL_STATE_ON_STAGE(STAGE));\ - _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(STAGE)]);\ - } - -typedef struct _download_mgr_t { - da_bool_t is_init; - dl_info_t dl_info[DA_MAX_DOWNLOAD_ID]; - dl_id_history_t dl_id_history; - /* FIXME: This is temporary solution to prevent crash on following case; - * 1) OMA download(that is, DA's libsoup is using) is on progressing on Browser - * 2) User push END hard key - * 3) da_deinit() is called. - on UI thread - * 4) cancel_download(all) is called. - * 5) plugin-libsoup.c calls soup_session_cancel_message(). - * 6) da_deinit() is finished and process is over. - * 7) soup's callback for soup_session_cancel_message() is trying to be called - on UI thread - * 8) Browser crashed because the callback address is no longer exist. - * - * Here is a temporary solution; - * If cancel is from da_deinit(), plugin-libsoup.c will not call soup_session_cancel_message(). - * So, append following variable to recognize this. - **/ - //da_bool_t is_progressing_deinit; -} download_mgr_t; - -extern download_mgr_t download_mgr; - -da_result_t init_download_mgr(); -da_result_t deinit_download_mgr(void); -void init_download_info(int slot_id); -void destroy_download_info(int slot_id); -void *Add_new_download_stage(int slot_id); -void remove_download_stage(int slot_id, stage_info *in_stage); -void empty_stage_info(stage_info *in_stage); -void clean_up_client_input_info(client_input_t *client_input); -da_result_t get_available_slot_id(int *available_id); -da_result_t get_slot_id_for_dl_id(int dl_id , int* slot_id); -da_bool_t is_valid_slot_id(int slot_id); -void store_http_status(int dl_id, int status); -int get_http_status(int dl_id); -#endif /* _Download_Agent_Dl_Info_Util_H */ diff --git a/agent/include/download-agent-dl-info.h b/agent/include/download-agent-dl-info.h new file mode 100644 index 0000000..820135e --- /dev/null +++ b/agent/include/download-agent-dl-info.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _DOWNLOAD_AGENT_INFO_H +#define _DOWNLOAD_AGENT_INFO_H + +#include "download-agent-type.h" +#include "download-agent-interface.h" +#include "download-agent-pthread.h" + +#include "curl/curl.h" + +typedef struct { + CURL *curl; + pthread_mutex_t mutex; + da_bool_t is_paused; + da_bool_t is_cancel_reqeusted; +} http_msg_t; + +typedef enum { + HTTP_STATE_READY_TO_DOWNLOAD = 0, + HTTP_STATE_REDIRECTED = 1, + HTTP_STATE_DOWNLOAD_REQUESTED = 2, + HTTP_STATE_DOWNLOAD_STARTED = 3, + HTTP_STATE_DOWNLOADING = 4, + HTTP_STATE_DOWNLOAD_FINISH = 5, + HTTP_STATE_REQUEST_CANCEL = 6, + HTTP_STATE_REQUEST_PAUSE = 7, + HTTP_STATE_REQUEST_RESUME = 8, + HTTP_STATE_CANCELED = 9, + HTTP_STATE_FAILED = 10, + HTTP_STATE_PAUSED = 11, + HTTP_STATE_RESUMED = 12, + HTTP_STATE_ABORTED = 13, + HTTP_STATE_WAIT_FOR_NET_ERR = 14, +} http_state_t; + +typedef enum { + HTTP_METHOD_GET = 1, + HTTP_METHOD_HEAD, + HTTP_METHOD_POST +} http_method_t; + +typedef struct { + char *url; + char **req_header; + int req_header_count; + char *install_path; + char *file_name; + char *etag; + char *temp_file_path; + char *pkg_name; + int network_bonding; + void *user_req_data; + void *user_client_data; +} req_info_t; + +typedef enum { + HTTP_EVENT_GOT_HEADER = 0, + HTTP_EVENT_GOT_PACKET, + HTTP_EVENT_FINAL, +// HTTP_EVENT_ABORT +} http_event_type_t; + +typedef struct _http_header_options_t http_header_options_t; +struct _http_header_options_t{ + char *field; + char *value; + http_header_options_t *next; +}; + +typedef struct _http_header_t http_header_t; +typedef http_header_t *http_msg_iter_t; +struct _http_header_t{ + char *field; + char *value; + http_header_options_t *options; + char *raw_value; // raw string including options + http_header_t *next; +}; + +typedef struct{ + char *http_method; + char *url; + http_header_t *head; + char *http_body; +} http_msg_request_t; + + +typedef struct{ + int status_code; + http_header_t *head; +} http_msg_response_t; + +typedef struct { + http_event_type_t type; + char *body; + int body_len; +#ifdef _RAF_SUPPORT + da_size_t received_len; +#endif + int status_code; + int error; +} http_raw_data_t; + +typedef void (*http_update_cb) (http_raw_data_t *data, void *user_param); + +typedef struct { + char *location_url; + http_state_t state; + pthread_mutex_t mutex_state; + pthread_mutex_t mutex_http; + pthread_cond_t cond_http; + http_msg_request_t *http_msg_request; + http_msg_response_t *http_msg_response; + http_method_t http_method; + http_msg_t *http_msg; + char *proxy_addr; + char *content_type_from_header; + char *file_name_from_header; + da_size_t content_len_from_header; + char *etag_from_header; + int error_code; // for error value for http abort. + da_size_t total_size; +#ifdef _RAF_SUPPORT + da_bool_t is_raf_mode_confirmed; +#endif + http_update_cb update_cb; +} http_info_t; + +typedef struct { + void *file_handle; + char *pure_file_name; + char *extension; + char *file_path; /* malloced in set_file_path_for_final_saving */ + char *mime_type;// For drm converting + char *buffer; + da_size_t buffer_len; + da_size_t file_size; /* http header's Content-Length has higher priority than DD's */ + da_size_t bytes_written_to_file; /* The file size to be written at actual file */ +#ifdef _RAF_SUPPORT + da_size_t file_size_of_temp_file; /* If the temporary file is existed, the file size of it */ +#endif + da_bool_t is_updated; /* The flag for updating progress event only if the data is wrriten to file not buffer */ +} file_info_t; + +typedef struct { + int da_id; + int tid; + pthread_t thread_id; + http_info_t *http_info; + file_info_t *file_info; + req_info_t *req_info; + da_cb_t cb_info; + da_bool_t is_cb_update; + int update_time; +} da_info_t; + +da_info_t *da_info_list[DA_MAX_ID]; + +#define GET_STATE_MUTEX(INFO) (INFO->mutex_state) +#define GET_STATE(INFO) (INFO->state) +#define CHANGE_STATE(STATE,INFO) {\ + DA_MUTEX_LOCK (&GET_STATE_MUTEX(INFO));\ + GET_STATE(INFO) = STATE;\ + DA_LOGV("Changed state[%d]", GET_STATE(INFO));\ + DA_MUTEX_UNLOCK (&GET_STATE_MUTEX(INFO));\ + } + +da_ret_t get_available_da_id(int *available_id); +da_ret_t copy_user_input_data(da_info_t *da_info, const char *url, + req_data_t *ext_data, da_cb_t *da_cb_data); +da_bool_t is_valid_download_id(int id); +void destroy_da_info(int id); +void destroy_da_info_list(void); +da_ret_t get_da_info_with_da_id(int id, da_info_t **out_info); +da_ret_t init_http_msg_t(http_msg_t **http_msg); +void destroy_http_msg_t(http_msg_t *http_msg); +void reset_http_info(http_info_t *http_info); +void reset_http_info_for_resume(http_info_t *http_info); +void destroy_http_info(http_info_t *http_info); +void destroy_file_info(file_info_t *file_info); + +#endif /* _DOWNLOAD_AGENT_INFO_H */ diff --git a/agent/include/download-agent-dl-mgr.h b/agent/include/download-agent-dl-mgr.h index b273fd8..c6be7c7 100755 --- a/agent/include/download-agent-dl-mgr.h +++ b/agent/include/download-agent-dl-mgr.h @@ -14,20 +14,14 @@ * limitations under the License. */ -#ifndef _Download_Agent_Dl_Mgr_H -#define _Download_Agent_Dl_Mgr_H +#ifndef _Download_Agent_Basic_H +#define _Download_Agent_Basic_H -#include "download-agent-type.h" -#include "download-agent-dl-info-util.h" +#include "download-agent-dl-info.h" -da_result_t cancel_download(int dl_id); -da_result_t suspend_download(int dl_id, da_bool_t is_enable_cb); -da_result_t resume_download (int dl_id); +da_ret_t start_download(da_info_t *da_info); +da_ret_t cancel_download(int dl_id, da_bool_t is_enable_cb); +da_ret_t suspend_download(int dl_id, da_bool_t is_enable_cb); +da_ret_t resume_download(int dl_id); -da_result_t requesting_download(stage_info *stage); -da_result_t handle_after_download(stage_info *stage); -da_result_t send_user_noti_and_finish_download_flow( - int slot_id, char *installed_path, char *etag); - -da_bool_t is_valid_download_id(int dl_id); #endif diff --git a/agent/include/download-agent-encoding.h b/agent/include/download-agent-encoding.h index c5c7fe5..49e74e9 100755 --- a/agent/include/download-agent-encoding.h +++ b/agent/include/download-agent-encoding.h @@ -20,7 +20,7 @@ #include "download-agent-type.h" da_bool_t is_base64_encoded_word(const char *in_str); -da_result_t decode_base64_encoded_str(const char *in_encoded_str, +da_ret_t decode_base64_encoded_str(const char *in_encoded_str, char **out_decoded_ascii_str); void decode_url_encoded_str(const char *in_encoded_str, char **out_str); diff --git a/agent/include/download-agent-file.h b/agent/include/download-agent-file.h index b4d3995..2788fdd 100755 --- a/agent/include/download-agent-file.h +++ b/agent/include/download-agent-file.h @@ -14,39 +14,32 @@ * limitations under the License. */ -#ifndef _Download_Agent_File_H -#define _Download_Agent_File_H +#ifndef _DOWNLOAD_AGENT_FILE_H +#define _DOWNLOAD_AGENT_FILE_H #include #include #include #include "download-agent-type.h" -#include "download-agent-dl-mgr.h" +#include "download-agent-dl-info.h" -#define DA_DEFAULT_INSTALL_PATH_FOR_PHONE "/opt/usr/media/Downloads" +#define DA_FILE_BUF_SIZE (1024*32) //bytes +da_ret_t check_drm_convert(file_info_t *file_info); da_bool_t is_file_exist(const char *file_path); -da_bool_t is_dir_exist(const char *dir_path); - -void get_file_size(char *file_path, unsigned long long *out_file_size); - -da_result_t clean_files_from_dir(char *dir_path); -da_result_t file_write_ongoing(stage_info *stage, char *body, int body_len); -da_result_t file_write_complete(stage_info *stage); -da_result_t start_file_writing(stage_info *stage); -da_result_t start_file_writing_append(stage_info *stage); -da_result_t start_file_writing_append_with_new_download(stage_info *stage); - -da_result_t get_mime_type(stage_info *stage, char **out_mime_type); -da_result_t discard_download(stage_info *stage) ; -void clean_paused_file(stage_info *stage); -da_result_t replace_content_file_in_stage(stage_info *stage, const char *dest_dd_file_path); -da_result_t decide_tmp_file_path(stage_info *stage); -char *get_full_path_avoided_duplication(char *in_dir, char *in_candidate_file_name, char *in_extension); - -da_result_t copy_file(const char *src, const char *dest); -da_result_t create_dir(const char *install_dir); -da_result_t get_default_install_dir(char **out_path); - +void get_file_size(char *file_path, da_size_t *out_file_size); +da_ret_t file_write_ongoing(file_info_t *file_info, char *body, int body_len); +da_ret_t file_write_complete(file_info_t *file_info); +#ifdef _RAF_SUPPORT +da_ret_t file_write_complete_for_raf(file_info_t *file_info); +#endif +da_ret_t start_file_writing(da_info_t *da_info); +da_ret_t start_file_append(file_info_t *file_info); +da_ret_t discard_download(file_info_t *file_info) ; +void clean_paused_file(file_info_t *file_info); +char *get_full_path_avoided_duplication(char *in_dir, + char *in_candidate_file_name, char *in_extension); +void remove_file(const char *file_path); +da_ret_t get_available_memory(char *dir_path, da_size_t len); #endif diff --git a/agent/include/download-agent-http-mgr.h b/agent/include/download-agent-http-mgr.h index 6653af0..95a0b3a 100755 --- a/agent/include/download-agent-http-mgr.h +++ b/agent/include/download-agent-http-mgr.h @@ -21,27 +21,14 @@ #include "download-agent-type.h" #include "download-agent-dl-mgr.h" -#include "download-agent-http-queue.h" #define DA_MAX_SESSION_INFO DA_MAX_DOWNLOAD_ID -#define DA_MAX_TRANSACTION_INFO 10 -#define DA_MAX_TRANSACTION_MUTEX DA_MAX_SESSION_INFO*DA_MAX_TRANSACTION_INFO -typedef struct _http_mgr_t -{ - da_bool_t is_init; - da_bool_t is_http_init; -}http_mgr_t; - -extern http_mgr_t http_mgr; - -da_result_t init_http_mgr(void); -void deinit_http_mgr(void); -da_result_t make_req_dl_info_http(stage_info *stage, req_dl_info *out_info); -da_result_t request_http_download(stage_info *stage); -da_result_t request_to_cancel_http_download(stage_info *stage); -da_result_t request_to_abort_http_download(stage_info *stage); -da_result_t request_to_suspend_http_download(stage_info *stage); -da_result_t request_to_resume_http_download(stage_info *stage); +da_ret_t request_http_download(da_info_t *da_info); +da_ret_t request_to_cancel_http_download(da_info_t *da_info); +da_ret_t request_to_abort_http_download(da_info_t *da_info); +da_ret_t request_to_suspend_http_download(da_info_t *da_info); +da_ret_t request_to_resume_http_download(da_info_t *da_info); +da_bool_t is_stopped_state(da_info_t *da_info); #endif diff --git a/agent/include/download-agent-http-misc.h b/agent/include/download-agent-http-misc.h deleted file mode 100755 index 3bf137b..0000000 --- a/agent/include/download-agent-http-misc.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Http_Misc_H -#define _Download_Agent_Http_Misc_H - -#include - -#include "download-agent-type.h" - -#define SCHEME_HTTP "http://" -#define SCHEME_HTTPS "https://" -#define SCHEME_CID "cid:" - -#define METHOD_GET "GET" -#define METHOD_POST "POST" -#define METHOD_HEAD "HEAD" - -#define HTTP_TAG_UAGENT "User-Agent: " -#define HTTP_TAG_HOST "Host: " -#define HTTP_TAG_UAPROF "X-Wap-Profile: " -#define HTTP_TAG_CONTENT_LENGTH "Content-Length: " -#define HTTP_TAG_CONTENT_TYPE "Content-Type: " -#define HTTP_TAG_IF_MATCH "If-Match: " -#define HTTP_TAG_RANGE "Range: " -#define HTTP_TAG_IF_RANGE "If-Range: " - -#define END_OF_FIELD "\r\n" - -char *get_user_agent(); - -da_bool_t is_supporting_protocol(const char *protocol); - -#endif diff --git a/agent/include/download-agent-http-msg-handler.h b/agent/include/download-agent-http-msg-handler.h index 29d0ae4..70abbda 100755 --- a/agent/include/download-agent-http-msg-handler.h +++ b/agent/include/download-agent-http-msg-handler.h @@ -18,103 +18,60 @@ #define _Download_Agent_Http_Msg_Handler_H #include "download-agent-type.h" +#include "download-agent-dl-info.h" +// Reqeust Header #define HTTP_FIELD_UAGENT "User-Agent" #define HTTP_FIELD_HOST "Host" #define HTTP_FIELD_UAPROF "X-Wap-Profile" -#define HTTP_FIELD_CONTENT_LENGTH "Content-Length" -#define HTTP_FIELD_CONTENT_TYPE "Content-Type" #define HTTP_FIELD_IF_MATCH "If-Match" #define HTTP_FIELD_RANGE "Range" #define HTTP_FIELD_IF_RANGE "If-Range" #define HTTP_FIELD_ACCEPT_LANGUAGE "Accept-Language" #define HTTP_FIELD_ACCEPT_CHARSET "Accept-Charset" -typedef struct _http_header_options_t http_header_options_t; -struct _http_header_options_t{ - char *field; - char *value; - - http_header_options_t *next; -}; - -typedef struct _http_header_t http_header_t; -struct _http_header_t{ - char *field; - char *value; - http_header_options_t *options; - - char *raw_value; // raw string including options - - http_header_t *next; -}; - -typedef struct{ - char *http_method; - char *url; - http_header_t *head; - char *http_body; -}http_msg_request_t; - - -typedef struct{ - int status_code; - http_header_t *head; -}http_msg_response_t; - -typedef http_header_t *http_msg_iter_t; - - -typedef struct{ - http_msg_request_t *http_msg_request; - http_msg_response_t *http_msg_response; -}http_info_t; +// Response Header +#define HTTP_FIELD_CONTENT_LENGTH "Content-Length" +#define HTTP_FIELD_CONTENT_TYPE "Content-Type" +#define HTTP_FIELD_CONTENT_DISPOSITION "Content-Disposition" +#define HTTP_FIELD_LOCATION "Location" +#define HTTP_FIELD_DATA "Date" +#define HTTP_FIELD_ETAG "ETag" +#ifdef _RAF_SUPPORT +#define HTTP_FIELD_RAF_MODE "x-direct-write" +#endif +#define HTTP_FIELD_END_OF_FIELD "\r\n" -da_result_t http_msg_request_create(http_msg_request_t **http_msg_request); +da_ret_t http_msg_request_create(http_msg_request_t **http_msg_request); void http_msg_request_destroy(http_msg_request_t **http_msg_request); +da_ret_t http_msg_request_set_url(http_msg_request_t *http_msg_request, const char *url); +da_ret_t http_msg_request_get_url(http_msg_request_t *http_msg_request, const char **url); +da_ret_t http_msg_request_add_field(http_msg_request_t *http_msg_request, const char *field, const char *value); -da_result_t http_msg_request_set_method(http_msg_request_t *http_msg_request, const char *method); -da_result_t http_msg_request_get_method(http_msg_request_t *http_msg_request, const char **method); - -da_result_t http_msg_request_set_url(http_msg_request_t *http_msg_request, const char *url); -da_result_t http_msg_request_get_url(http_msg_request_t *http_msg_request, const char **url); - -da_result_t http_msg_request_set_body(http_msg_request_t *http_msg_request, const char *body); -da_result_t http_msg_request_get_body(http_msg_request_t *http_msg_request, const char **body); - -da_result_t http_msg_request_add_field(http_msg_request_t *http_msg_request, const char *field, const char *value); - - -da_result_t http_msg_response_create(http_msg_response_t **http_msg_response); +da_ret_t http_msg_response_create(http_msg_response_t **http_msg_response); void http_msg_response_destroy(http_msg_response_t **http_msg_response); - -da_result_t http_msg_response_set_status_code(http_msg_response_t *http_msg_response, int status_code); -da_result_t http_msg_response_get_status_code(http_msg_response_t *http_msg_response, int *status_code); - -da_result_t http_msg_response_add_field(http_msg_response_t *http_msg_response, const char *field, const char *value); - +da_ret_t http_msg_response_add_field(http_msg_response_t *http_msg_response, const char *field, const char *value); /* Caution! Caller must free memory for every "char** out_xxx" for followings */ da_bool_t http_msg_response_get_content_type(http_msg_response_t *http_msg_response, char **out_type); void http_msg_response_set_content_type(http_msg_response_t *http_msg_response, const char *in_type); -da_bool_t http_msg_response_get_content_length(http_msg_response_t *http_msg_response, unsigned long long *out_length); +da_bool_t http_msg_response_get_content_length(http_msg_response_t *http_msg_response, da_size_t *out_length); da_bool_t http_msg_response_get_content_disposition(http_msg_response_t *http_msg_response, char **out_disposition, char **out_file_name); da_bool_t http_msg_response_get_ETag(http_msg_response_t *http_msg_response, char **out_value); da_bool_t http_msg_response_get_date(http_msg_response_t *http_msg_response, char **out_value); da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response, char **out_value); -// should be refactored later -da_result_t http_msg_response_get_boundary(http_msg_response_t *http_msg_response, char **out_val); - - -da_result_t http_msg_request_get_iter(http_msg_request_t *http_msg_request, http_msg_iter_t *http_msg_iter); -da_result_t http_msg_response_get_iter(http_msg_response_t *http_msg_response, http_msg_iter_t *http_msg_iter); - +#ifdef _RAF_SUPPORT +da_bool_t http_msg_response_get_RAF_mode(http_msg_response_t *http_msg_response, + char **out_value); +#endif +da_ret_t http_msg_request_get_iter(http_msg_request_t *http_msg_request, http_msg_iter_t *http_msg_iter); +da_ret_t http_msg_response_get_iter(http_msg_response_t *http_msg_response, http_msg_iter_t *http_msg_iter); // should remove later da_bool_t http_msg_get_field_with_iter(http_msg_iter_t *http_msg_iter, char **field, char **value); da_bool_t http_msg_get_header_with_iter(http_msg_iter_t *http_msg_iter, char **out_field, http_header_t **out_header); - -char *get_http_response_header_raw(http_msg_response_t *http_msg_response); - da_bool_t extract_attribute_from_header(char *szHeadStr, const char *szFindStr, char **ppRtnValue); +da_bool_t http_msg_request_get_if_range(http_msg_request_t *http_msg_request, char **out_value); +da_bool_t http_msg_request_get_range(http_msg_request_t *http_msg_request, char **out_value); + #endif // _Download_Agent_Http_Msg_Handler_H diff --git a/agent/include/download-agent-http-queue.h b/agent/include/download-agent-http-queue.h deleted file mode 100755 index 9973698..0000000 --- a/agent/include/download-agent-http-queue.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Http_Queue_H -#define _Download_Agent_Http_Queue_H - - -#include "download-agent-type.h" -#include "download-agent-http-msg-handler.h" - -#include -#include - -#define MAX_QUEUE_SIZE 1024*64 - -typedef enum -{ - Q_EVENT_TYPE_DATA_HTTP, - Q_EVENT_TYPE_DATA_DRM, - Q_EVENT_TYPE_CONTROL, -}q_event_type; - -typedef enum -{ - Q_EVENT_TYPE_CONTROL_NONE = 0, - Q_EVENT_TYPE_CONTROL_CANCEL, - Q_EVENT_TYPE_CONTROL_SUSPEND, - Q_EVENT_TYPE_CONTROL_RESUME, - Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED, - Q_EVENT_TYPE_CONTROL_ABORT, -// [090205][jungki]not used yet. -// Q_EVENT_TYPE_CONTROL_USER_CONFIRM_RESULT, -// Q_EVENT_TYPE_CONTROL_INSTALL_RESULT, -}q_event_type_control; - -typedef enum -{ - Q_EVENT_TYPE_DATA_PACKET, - Q_EVENT_TYPE_DATA_FINAL, - Q_EVENT_TYPE_DATA_ABORT, -}q_event_type_data; - -typedef struct _q_event_data_http_t -{ - q_event_type_data data_type; - - int status_code; - - http_msg_response_t* http_response_msg; - - int body_len; - char *body_data; - - da_result_t error_type; -}q_event_data_http_t; - -typedef struct _q_event_control_t -{ - q_event_type_control control_type; -}q_event_control_t; - -typedef struct _q_event_t q_event_t; -struct _q_event_t -{ - int size; - q_event_type event_type; - union _type - { - q_event_data_http_t q_event_data_http; - q_event_control_t q_event_control; - } type; - - q_event_t *next; -}; - -typedef struct _queue_t -{ - da_bool_t having_data; - - q_event_t *control_head; - q_event_t *data_head; - - pthread_mutex_t mutex_queue; - pthread_cond_t cond_queue; - - int queue_size; -}queue_t; - -void Q_init_queue(queue_t *queue); -void Q_destroy_queue(queue_t *queue); - -void Q_init_q_event(q_event_t *q_event); -void Q_destroy_q_event(q_event_t **q_event); - -da_result_t Q_make_control_event(q_event_type_control control_type, q_event_t **out_event); - -da_result_t Q_make_http_data_event(q_event_type_data data_type, q_event_t **out_event); -da_result_t Q_set_status_code_on_http_data_event(q_event_t *q_event, int status_code); -da_result_t Q_set_http_body_on_http_data_event(q_event_t *q_event, int body_len, char *body_data); -da_result_t Q_set_error_type_on_http_data_event(q_event_t *q_event, int error_type); - - -da_bool_t Q_push_event(const queue_t *in_queue, const q_event_t *in_event); -da_bool_t Q_push_event_without_lock(const queue_t *in_queue, const q_event_t *in_event); -void Q_pop_event(const queue_t *in_queue, q_event_t **out_event); - -#define GET_IS_Q_HAVING_DATA(QUEUE) (QUEUE->having_data) - -void Q_goto_sleep(const queue_t *in_queue); -void Q_wake_up(const queue_t *in_queue); - - -#endif diff --git a/agent/include/download-agent-interface.h b/agent/include/download-agent-interface.h index 44081bd..f5ce653 100755 --- a/agent/include/download-agent-interface.h +++ b/agent/include/download-agent-interface.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef _Download_Agent_Interface_H -#define _Download_Agent_Interface_H +#ifndef _DOWNLOAD_AGENT_INTERFACE_H +#define _DOWNLOAD_AGENT_INTERFACE_H #ifndef EXPORT_API #define EXPORT_API __attribute__((visibility("default"))) @@ -29,450 +29,69 @@ extern "C" #include "download-agent-defs.h" #include -/** - * @struct user_paused_info_t - * @brief Download Agent will send its state through this structure. - * @see da_paused_info_cb - * @par - * This is used only by callback /a user_paused_info_t. \n - */ -typedef struct { - /// download request id for this notification - int download_id; -} user_paused_info_t; - -/** - * @struct user_progress_info_t - * @brief Download Agent will send current downloading file's information through this structure. - * @see da_progress_info_cb - * @par - * This is used only by callback /a da_progress_info_cb. \n - */ -typedef struct { - /// download request id for this updated download information - int download_id; - /// received size of chunked data. - unsigned long int received_size; -} user_progress_info_t; - -/** - * @struct user_download_info_t - * @brief Download Agent will send current download's information through this structure. - * @see da_started_info_cb - * @par - * This is used only by callback /a da_started_info_cb. \n - */ typedef struct { - /// download request id for this updated download information int download_id; - /// file's mime type from http header. char *file_type; - /// file size from http header. - unsigned long int file_size; - /// This is temporary file path. + unsigned long long file_size; char *tmp_saved_path; - /// This is the file name for showing to user. char *content_name; - /// etag string value for resume download, char *etag; -} user_download_info_t; +} download_info_t; typedef struct { - /// download request id for this updated download information int download_id; - /// This has only file name for now. char *saved_path; - /// etag string value for resume download, - /// This is returned when the download is failed and the etag is received from content server char *etag; - /// convey error code if necessary, or it is zero. int err; - /// http status code if necessary, or it is zero. int http_status; -} user_finished_info_t; +} finished_info_t; typedef struct { const char **request_header; int request_header_count; const char *install_path; const char *file_name; - const char *temp_file_path; /* For resume download, the "etag" value should be existed together */ - const char *etag; /* For resume download */ - const char *pkg_name; /* For system resource */ - void *user_data; -} extension_data_t; - -/** - * @typedef da_paused_cb - * @brief Download Agent will call this function to paused its state. - * - * This is user callback function registered on \a da_init. \n - * - * @remarks For the most of time, this state is just informative, so, user doesn't need to do any action back to Download Agent. - * - * @warning Download will be holding until getting user confirmation result through the function. - * - * @param[in] state state from Download Agent - * @param[in] user_param user parameter which is set with \a DA_FEATURE_USER_DATA - * - * @see da_init - * @see da_client_cb_t - */ -typedef void (*da_paused_info_cb) (user_paused_info_t *paused_info, void *user_param); - -/** - * @brief Download Agent will call this function to update received size of download-requested file. - * - * This is user callback function registered on \a da_init. \n - * This is informative, so, user doesn't need to do any action back to Download Agent.\n - * - * @param[in] progress_info updated downloading information - * @param[in] user_param user parameter which is set with \a DA_FEATURE_USER_DATA - * - * @see da_init - * @see da_client_cb_t - */ -typedef void (*da_progress_info_cb) (user_progress_info_t *progress_info, void *user_param); - -/** - * @brief Download Agent will call this function to update mime type, temp file name, total file sizeand installed path. - * - * This is user callback function registered on \a da_init. \n - * This is informative, so, user doesn't need to do any action back to Download Agent.\n - * - * @param[in] download_info updated download information - * @param[in] user_param user parameter which is set with \a DA_FEATURE_USER_DATA - * - * @see da_init - * @see da_client_cb_t - */ -typedef void (*da_started_info_cb) (user_download_info_t *download_info, void *user_param); + const char *temp_file_path; + const char *etag; + const char *pkg_name; + int network_bonding; + void *user_req_data; + void *user_client_data; +} req_data_t; + +typedef void (*da_paused_cb) (int download_id, + void *user_param1, void *user_param2); +typedef void (*da_progress_cb) (int download_id, + unsigned long long received_size, + void *user_param1, void *user_param2); +typedef void (*da_started_cb) (download_info_t *download_info, + void *user_param1, void *user_param2); +typedef void (*da_finished_cb) (finished_info_t *finished_info, + void *user_param1, void *user_param2); -typedef void (*da_finished_info_cb) (user_finished_info_t *finished_info, void *user_param); - /** - * @struct da_client_cb_t - * @brief This structure convey User's callback functions for \a da_init - * @see da_init - */ typedef struct { - /// callback to convey download information - da_started_info_cb update_dl_info_cb; - /// callback to convey downloading information while downloading including received file size - da_progress_info_cb update_progress_info_cb; - /// callback to convey saved path - da_finished_info_cb finished_info_cb; - /// callback to convey etag value - da_paused_info_cb paused_info_cb; -} da_client_cb_t; - -/** - * @fn int da_init (da_client_cb_t *da_client_callback) - * @brief This function initiates Download Agent and registers user callback functions. - * @warning This should be called at once when client application is initialized before using other Download Agent APIs - * @warning This function is paired with da_deinit function. - * - * @pre None. - * @post None. - * - * @param[in] da_client_callback User callback function structure. The type is struct data pointer. - * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h. - * @remarks User MUST call this function first rather than any other DA APIs. \n - * Please do not call UI code at callback function in direct. \n - * It is better that it returns as soon as copying the data of callback functon. \n - * @see da_deinit - * @par Example - * @code - * #include - * - * void da_started_info_cb(user_download_info_t *download_info,void *user_param); - * void da_progress_info_cb(user_downloading_info_t *downloading_info,void *user_param); - * void da_finished_cb(user_finished_info_t *complted_info, void *user_param); - * void da_paused_info_cb(user_paused_info_t *paused_info, void *user_param); - * - * int download_initialize() - * { - * int da_ret; - * da_client_cb_t da_cb = {0}; - * - * da_cb.update_dl_info_cb = &update_download_info_cb; - * da_cb.update_progress_info_cb = &progress_info_cb; - * da_cb.finished_info_cb = &finished_info_cb; - * da_cb.paused_info_cb = &paused_cb; - * - * da_ret = da_init (&da_cb, 0); - * if (da_ret == DA_RESULT_OK) { - * // printf("successed\n"); - * return true; - * } else { - * // printf("failed with error code %d\n", da_ret); - * return fail; - * } - * } - * @endcode - */ -EXPORT_API int da_init(da_client_cb_t *da_client_callback); + da_started_cb download_info_cb; + da_progress_cb progress_cb; + da_finished_cb finished_cb; + da_paused_cb paused_cb; +} da_cb_t; - /** - * @fn int da_deinit () - * @brief This function deinitiates Download Agent. - * - * This function destroys all infomation for client manager. - * When Download Agent is not used any more, please call this function. - * Usually when client application is destructed, this is needed. - * - * @remarks This is paired with da_init. \n - * The client Id should be the one from /a da_init(). \n - * Otherwise, it cannot excute to deinitialize. \n - * - * @pre da_init() must be called in advance. - * @post None. - * - * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h. - * @see da_init - * @par Example - * @code - * #include - * - * - * int download_deinitialize() - * { - * int da_ret; - * da_ret = da_deinit(); - * if(da_ret == DA_RESULT_OK) { - * // printf("successed\n"); - * return true; - * } else { - * // printf("failed with error code %d\n", da_ret); - * return fail; - * } - * } - @endcode - */ +EXPORT_API int da_init(); EXPORT_API int da_deinit(); - /** - * @fn int da_start_download(const char *url, int *download_id) - * @brief This function starts to download a content on passed URL. - * - * Useful information and result are conveyed through following callbacks. - * @li da_started_info_cb - * @li da_progress_cb - * - * @pre da_init() must be called in advance. - * @post None. - * @remarks - * Downloaded file is automatically registered to system. (e.g. File DB) \n - * If there is another file has same name on registering directory, new one's name would have numbering postfix. \n - * (e.g. abc.mp3 to abc_1.mp3) - * - * @param[in] url url to start download - * @param[out] download_id assigned download request id for this URL - * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h. - * - * @see None. - * - * @par Example - * @code - * #include - * - * int da_ret; - * int download_id; - * char *url = "http://www.test.com/sample.mp3"; - * - * da_ret = da_start_download(url,&download_id); - * if (da_ret == DA_RESULT_OK) - * printf("download requesting is successed\n"); - * else - * printf("download requesting is failed with error code %d\n", da_ret); - * @endcode - */ -EXPORT_API int da_start_download(const char *url, int *download_id); - -/** -* @fn int da_start_download_with_extension(const char *url, extension_data_t ext_data, int *download_id) -* @brief This function starts to download a content on passed URL with passed extension. -* -* Useful information and result are conveyed through following callbacks. -* @li da_started_info_cb -* @li da_progress_cb -* -* @pre da_init() must be called in advance. -* @post None. -* @remarks This API operation is exactly same with da_start_download(), except for input properties. \n -* -* @param[in] url url to start download -* @param[in] ext_data extension data -* @param[out] download_id assigned download request id for this URL -* @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h. -* -* -* @par Example -* @code - #include - - int da_ret; - int download_id; - extension_data_t ext_data = {0,}; - const char *url = "https://www.test.com/sample.mp3"; - const char *install_path = "/myFiles/music"; - const char *my_data = strdup("data"); - ext_data.install_path = install_path; - ext_data.user_data = (void *)my_data; - - da_ret = da_start_download_with_extension(url, &download_id, &ext_data); - if (da_ret == DA_RESULT_OK) - printf("download requesting is successed\n"); - else - printf("download requesting is failed with error code %d\n", da_ret); - @endcode -*/ -EXPORT_API int da_start_download_with_extension(const char *url, - extension_data_t *ext_data, - int *download_id -); - - -/** - * @fn int da_cancel_download(int download_id) - * @brief This function cancels a download for passed download_id. - * - * Client can use this function if user wants to cancel already requested download. - * - * @remarks Should check return value. \n - * If return value is not DA_RESULT_OK, then previous requested download can be keep downloading. - * @remarks After calling this function, all information for the download_id will be deleted. So, client cannot request anything for the download_id. - * - * @pre There should be exist ongoing or suspended download for download_id. - * @post None. - * - * @param[in] download_id download request id - * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail - * - * @see None. - * - * @par Example - * @code - #include - - int da_ret; - int download_id; - - da_ret = da_cancel_download(download_id); - if(da_ret == DA_RESULT_OK) { - // printf("download with [%d] is successfully canceled.\n", download_id); - } - else { - // in this case, downloading with download_id is keep ongoing. - printf("failed to cancel with error code %d\n", da_ret); - } - @endcode - */ +EXPORT_API int da_start_download(const char *url, req_data_t *ext_data, + da_cb_t *da_cb_data, int *download_id); EXPORT_API int da_cancel_download(int download_id); - - -/** - * @fn int da_suspend_download(int download_id) - * @brief This function suspends downloading for passed download_id. - * - * Client can use this function if user wants to suspend already requested download. - * - * @remarks Should check return value. \n - * If return value is not DA_RESULT_OK, then previous requested download can be keep downloading. - * @remarks After calling this function, all information for the download_id will be remained. So, client can request resume for the download_id. - * @remarks Client should cancel or resume for this download_id, or all information for the download_id will be leaved forever. - * - * @pre There should be exist ongoing download for download_id. - * @post None. - * - * @param[in] download_id download request id - * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail - * - * @see da_resume_download() - * @see da_cancel_download() - * - * @par Example - * @code - #include - - int da_ret; - int download_id; - - da_ret = da_suspend_download(download_id); - if(da_ret == DA_RESULT_OK) { - // printf("download with [%d] is successfully suspended.\n", download_id); - } - else { - // in this case, downloading with download_id is keep ongoing. - printf("failed to suspend with error code %d\n", da_ret); - } - @endcode - */ +EXPORT_API int da_cancel_download_without_update(int download_id); EXPORT_API int da_suspend_download(int download_id); - EXPORT_API int da_suspend_download_without_update(int download_id); -/** - * @fn int da_resume_download(int download_id) - * @brief This function resumes downloading for passed download_id. - * - * Client can use this function if user wants to resume suspended download. - * - * @remarks Should check return value. \n - * If return value is not DA_RESULT_OK, then requested download can be not to resume. - * - * @pre There should be exist suspended download for download_id. - * @post None. - * - * @param[in] download_id download request id - * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail - * - * @see da_suspend_download() - * - * @par Example - * @code - #include - - int da_ret; - int download_id; - - da_ret = da_resume_download(download_id); - if(da_ret == DA_RESULT_OK) { - // printf("download with [%d] is successfully resumed.\n", download_id); - } - else { - // in this case, downloading with download_id is keep suspended. - printf("failed to resume with error code %d\n", da_ret); - } - @endcode - */ EXPORT_API int da_resume_download(int download_id); - -/** - * @fn int da_is_valid_download_id(int download_id) - * @brief This function return the download id is valid and the download thread is still alive. - * - * Client can use this function if user wants to resume download. - * If the download id is vaild and the download thread is alive, it can resume download with using da_resume_download() - * If the the download thread was already terminated due to restarting the process, - * it can resume download with using da_start_download_with_extension() - * - * - * - * @remarks Should check return value. \n - * If return value is not DA_RESULT_OK, then requested download can be not to resume. - * - * @pre There should be exist suspended download for download_id. - * @post None. - * - * @param[in] download_id download request id - * @return 1 for success, or 0 for fail - * - */ EXPORT_API int da_is_valid_download_id(int download_id); #ifdef __cplusplus } #endif -#endif //_Download_Agent_Interface_H +#endif //_DOWNLOAD_AGENT_INTERFACE_H diff --git a/agent/include/download-agent-mime-util.h b/agent/include/download-agent-mime-util.h index 5f143e9..7f57899 100755 --- a/agent/include/download-agent-mime-util.h +++ b/agent/include/download-agent-mime-util.h @@ -34,7 +34,15 @@ typedef struct { da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type); da_bool_t da_get_extension_name_from_url(char *url, char **ext); -da_result_t da_mime_get_ext_name(char *mime, char **ext); +da_ret_t da_mime_get_ext_name(char *mime, char **ext); da_bool_t da_get_file_name_from_url(char *url, char **name) ; void delete_prohibited_char(char *szTarget, int str_len); +da_ret_t get_extension_from_mime_type(char *mime_type, char **extension); +#ifdef _ENABLE_OMA_DRM +da_bool_t is_content_drm_dcf(char *content_type); +da_bool_t is_content_drm_dm(char *content_type); +#endif + + + #endif diff --git a/agent/include/download-agent-plugin-conf.h b/agent/include/download-agent-plugin-conf.h index 2c4f55f..11e8095 100755 --- a/agent/include/download-agent-plugin-conf.h +++ b/agent/include/download-agent-plugin-conf.h @@ -19,9 +19,12 @@ #include "download-agent-type.h" #include "download-agent-interface.h" -#include "download-agent-utils.h" -da_result_t get_user_agent_string(char **uagent_str); +da_ret_t get_user_agent_string(char **uagent_str); char *get_proxy_address(void); +#ifdef _RAF_SUPPORT +//test code +void get_smart_bonding_vconf(); +#endif #endif diff --git a/agent/include/download-agent-plugin-drm.h b/agent/include/download-agent-plugin-drm.h new file mode 100644 index 0000000..361f387 --- /dev/null +++ b/agent/include/download-agent-plugin-drm.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _Download_Agent_Plugin_Drm_H +#define _Download_Agent_Plugin_Drm_H + +#include "download-agent-type.h" + +da_bool_t EDRM_convert(const char *in_file_path, char **out_file_path); +da_ret_t EDRM_wm_get_license(char *rights_url, char **out_content_url); + +#endif diff --git a/agent/include/download-agent-plugin-http-interface.h b/agent/include/download-agent-plugin-http-interface.h deleted file mode 100755 index b9698bb..0000000 --- a/agent/include/download-agent-plugin-http-interface.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Plugin_Http_Interface_H -#define _Download_Agent_Plugin_Http_Interface_H - -#include "download-agent-type.h" -#include "download-agent-http-msg-handler.h" - -typedef enum { - PI_HTTP_METHOD_GET = 1, - PI_HTTP_METHOD_POST = 2, - PI_HTTP_METHOD_HEAD = 3 -} pi_http_method_t; - - -typedef struct _input_for_tranx_t { - pi_http_method_t http_method; - - char *proxy_addr; - queue_t *queue; - - http_msg_request_t* http_msg_request; -} input_for_tranx_t; - - - -da_result_t PI_http_init(void); -void PI_http_deinit(void); - -da_result_t PI_http_start_transaction(const input_for_tranx_t *input_for_tranx, int *out_tranx_id); -da_result_t PI_http_cancel_transaction(int in_tranx_id, da_bool_t abort_option); -da_result_t PI_http_disconnect_transaction(int in_tranx_id); -void PI_http_pause_transaction(int transaction_id); -void PI_http_unpause_transaction(int transaction_id); - -#endif - diff --git a/agent/include/download-agent-plugin-libcurl.h b/agent/include/download-agent-plugin-libcurl.h new file mode 100644 index 0000000..67a4c53 --- /dev/null +++ b/agent/include/download-agent-plugin-libcurl.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _Download_Agent_Plugin_Libcurl_H +#define _Download_Agent_Plugin_Libcrul_H + +#include "download-agent-type.h" +#include "download-agent-dl-info.h" + +#define MAX_SESSION_COUNT DA_MAX_DOWNLOAD_REQ_AT_ONCE +#define MAX_TIMEOUT DA_MAX_TIME_OUT + +da_ret_t PI_http_start(da_info_t *da_info); +da_ret_t PI_http_disconnect(http_info_t *info); +da_ret_t PI_http_cancel(http_info_t *info); +da_ret_t PI_http_pause(http_info_t *info); +da_ret_t PI_http_unpause(http_info_t *info); +#ifdef _RAF_SUPPORT +da_ret_t PI_http_set_file_name_to_curl(http_msg_t *http_msg, char *file_path); +#endif + +#endif diff --git a/agent/include/download-agent-plugin-libsoup.h b/agent/include/download-agent-plugin-libsoup.h deleted file mode 100755 index 8160042..0000000 --- a/agent/include/download-agent-plugin-libsoup.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Plugin_Libsoup_H -#define _Download_Agent_Plugin_Libsoup_H - -#include -#include - -#include "download-agent-http-queue.h" -#include "download-agent-pthread.h" -#include "download-agent-plugin-http-interface.h" - -typedef struct _pi_session_table_t { - da_bool_t is_using; - SoupSession *session; - SoupMessage *msg; - queue_t *queue; - pthread_mutex_t mutex; - pthread_cond_t cond; - da_bool_t is_paused; -} pi_session_table_t; - -extern pi_session_table_t pi_session_table[]; - -#define MAX_SESSION_COUNT DA_MAX_DOWNLOAD_REQ_AT_ONCE -#define MAX_TIMEOUT 60 // second - -#define IS_VALID_SESSION_TABLE_ENTRY(ENTRY) ((((ENTRY) < 0) || ((ENTRY) > MAX_SESSION_COUNT-1)) ? 0 : 1) - - -#define GET_SESSION_FROM_TABLE_ENTRY(ENTRY) (pi_session_table[ENTRY].session) -#define GET_MSG_FROM_TABLE_ENTRY(ENTRY) (pi_session_table[ENTRY].msg) -#define GET_QUEUE_FROM_TABLE_ENTRY(ENTRY) (pi_session_table[ENTRY].queue) - - -da_bool_t _pi_http_is_valid_input_for_tranx(const input_for_tranx_t *input_for_tranx); - -void _pi_http_init_session_table_entry(const int in_session_table_entry); -void _pi_http_destroy_session_table_entry(const int in_session_table_entry); -int _pi_http_get_avaiable_session_table_entry(void); - -da_bool_t _pi_http_register_queue_to_session_table(const int session_table_entry, const queue_t *in_queue); -da_bool_t _pi_http_register_session_to_session_table(const int in_session_table_entry, SoupSession *session); -da_bool_t _pi_http_register_msg_to_session_table(const int in_session_table_entry, SoupMessage *msg); - -queue_t *_pi_http_get_queue_from_session_table_entry(const int in_session_table_entry); -int _pi_http_get_session_table_entry_from_message(SoupMessage *msg); - -void _pi_http_store_read_data_to_queue(SoupMessage *msg, const char *body_data, int received_body_len); -void _pi_http_store_read_header_to_queue(SoupMessage *msg, const char *sniffedType); -void _pi_http_store_neterr_to_queue(SoupMessage *msg); - - -void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data); -void _pi_http_restarted_cb(SoupMessage *msg, gpointer data); -void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data); -void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType, GHashTable *params, gpointer data); -void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data); - - -#endif diff --git a/agent/include/download-agent-pthread.h b/agent/include/download-agent-pthread.h index 8523567..2748581 100755 --- a/agent/include/download-agent-pthread.h +++ b/agent/include/download-agent-pthread.h @@ -14,134 +14,131 @@ * limitations under the License. */ -#ifndef _Download_Agent_Pthread_H -#define _Download_Agent_Pthread_H +#ifndef _DOWNLOAD_AGENT_PTHREAD_H +#define _DOWNLOAD_AGENT_PTHREAD_H #include #include #include -#include "download-agent-type.h" #include "download-agent-debug.h" -#define _da_thread_mutex_init(mutex_add, attr) { \ - int ret = 0; \ - do{ \ - ret = pthread_mutex_init(mutex_add, attr); \ - if (0 == ret){ \ - break; \ - } \ - else if(EINVAL == ret){ \ - DA_LOG_ERR(Default, "pthread_mutex_init FAIL with EINVAL."); \ - break; \ - } \ - else if(ENOMEM == ret){ \ - DA_LOG_ERR(Default, "pthread_mutex_init FAIL with ENOMEM."); \ - break; \ - } \ - else{ \ - DA_LOG_ERR(Default, "pthread_mutex_init FAIL with %d.", ret); \ - break; \ - } \ - }while(1); \ - } - -#define _da_thread_cond_init(cond_add, attr) do{ \ - if (0 != pthread_cond_init(cond_add, attr)){\ - DA_LOG_ERR(Default, "pthread_cond_init FAIL");} \ - }while(0) - - - -#define _da_thread_mutex_lock(mutex_add) {\ - int ret = 0;\ - do{\ - ret = pthread_mutex_lock(mutex_add);\ - if (0 == ret){\ - break;\ - }\ - else if(EINVAL == ret){\ - DA_LOG_ERR(Default, "pthread_mutex_lock FAIL with EINVAL.");\ - break;\ - }\ - else if(EDEADLK == ret){\ - DA_LOG_ERR(Default, "pthread_mutex_lock FAIL with EDEADLK.");\ - break;\ - }\ - else{\ - DA_LOG_ERR(Default, "pthread_mutex_lock FAIL with %d.", ret);\ - break;\ - }\ - }while(1);\ - } - - -#define _da_thread_mutex_unlock(mutex_add) {\ - int ret = 0;\ - do{\ - ret = pthread_mutex_unlock(mutex_add);\ - if (0 == ret){\ - break;\ - }\ - else if(EINVAL == ret){\ - DA_LOG_ERR(Default, "pthread_mutex_unlock FAIL with EINVAL.");\ - break;\ - }\ - else if(EPERM == ret){\ - DA_LOG_ERR(Default, "pthread_mutex_unlock FAIL with EPERM.");\ - break;\ - }\ - else{\ - DA_LOG_ERR(Default, "pthread_mutex_unlock FAIL with %d.", ret);\ - break;\ - }\ - }while(1);\ - } - - -#define _da_thread_cond_signal(cond_add) do{ \ - if (0 != pthread_cond_signal(cond_add)){\ - DA_LOG_ERR(Default, "pthread_cond_signal FAIL");} \ - }while(0) - - - -#define _da_thread_cond_wait(cond_add, mutex_add) do{ \ - if (0 != pthread_cond_wait(cond_add, mutex_add)){\ - DA_LOG_ERR(Default, "pthread_cond_wait FAIL");} \ - }while(0) - -#define _da_thread_cond_timed_wait(cond_add, mutex_add, time) do{ \ - if (0 != pthread_cond_timedwait(cond_add, mutex_add, time)){\ - DA_LOG_ERR(Default, "pthread_cond_wait FAIL");} \ - }while(0) - - -#define _da_thread_cond_destroy(cond_add) do{ \ - if (0 != pthread_cond_destroy(cond_add)){\ - DA_LOG_ERR(Default, "pthread_cond_destroy FAIL");} \ - }while(0) - -#define _da_thread_mutex_destroy(mutex_add) {\ - int ret = 0;\ - do{\ - ret = pthread_mutex_destroy(mutex_add);\ - if (0 == ret){\ - break;\ - }\ - else if(EINVAL == ret){\ - DA_LOG_ERR(Default, "pthread_mutex_destroy FAIL with EINVAL.");\ - break;\ - }\ - else if(EBUSY == ret){\ - DA_LOG_ERR(Default, "pthread_mutex_destroy FAIL with EBUSY.");\ - break;\ - }\ - else{\ - DA_LOG_ERR(Default, "pthread_mutex_destroy FAIL with %d.", ret);\ - break;\ - }\ - }while(1);\ - } - +#define DA_MUTEX_INIT(mutex_add, attr) {\ + int ret = 0;\ + do {\ + ret = pthread_mutex_init(mutex_add, attr);\ + if (0 == ret){\ + break;\ + }\ + else if (EINVAL == ret){\ + DA_LOGE("pthread_mutex_init FAIL with EINVAL.");\ + break;\ + }\ + else if (ENOMEM == ret){\ + DA_LOGE("pthread_mutex_init FAIL with ENOMEM.");\ + break;\ + }\ + else{\ + DA_LOGE("pthread_mutex_init FAIL with %d.", ret);\ + break;\ + }\ + } while(1);\ +} + +#define DA_COND_INIT(cond_add, attr) do {\ + if (0 != pthread_cond_init(cond_add, attr)){\ + DA_LOGE("pthread_cond_init FAIL");\ + }\ +} while(0) + +#define DA_MUTEX_LOCK(mutex_add) {\ + int ret = 0;\ + do {\ + ret = pthread_mutex_lock(mutex_add);\ + if (0 == ret){\ + break;\ + }\ + else if (EINVAL == ret){\ + DA_LOGE("pthread_mutex_lock FAIL with EINVAL.");\ + break;\ + }\ + else if (EDEADLK == ret){\ + DA_LOGE("pthread_mutex_lock FAIL with EDEADLK.");\ + break;\ + }\ + else{\ + DA_LOGE("pthread_mutex_lock FAIL with %d.", ret);\ + break;\ + }\ + } while(1);\ +} + +#define DA_MUTEX_UNLOCK(mutex_add) {\ + int ret = 0;\ + do {\ + ret = pthread_mutex_unlock(mutex_add);\ + if (0 == ret){\ + break;\ + }\ + else if (EINVAL == ret) {\ + DA_LOGE("pthread_mutex_unlock FAIL with EINVAL.");\ + break;\ + }\ + else if (EPERM == ret) {\ + DA_LOGE("pthread_mutex_unlock FAIL with EPERM.");\ + break;\ + }\ + else {\ + DA_LOGE("pthread_mutex_unlock FAIL with %d.", ret);\ + break;\ + }\ + } while(1);\ +} + +#define DA_COND_SIGNAL(cond_add) do {\ + if (0 != pthread_cond_signal(cond_add)) {\ + DA_LOGE("pthread_cond_signal FAIL");\ + }\ + } while(0) + +#define DA_COND_WAIT(cond_add, mutex_add) do {\ + if (0 != pthread_cond_wait(cond_add, mutex_add)){\ + DA_LOGE("pthread_cond_wait FAIL");\ + }\ + } while(0) + +#define DA_COND_TIMED_WAIT(cond_add, mutex_add, time) do {\ + if (0 != pthread_cond_timedwait(cond_add, mutex_add, time)){\ + DA_LOGE("pthread_cond_wait FAIL");\ + }\ + } while(0) + + +#define DA_COND_DESTROY(cond_add) do {\ + if (0 != pthread_cond_destroy(cond_add)){\ + DA_LOGE("pthread_cond_destroy FAIL");\ + }\ + } while(0) + +#define DA_MUTEX_DESTROY(mutex_add) {\ + int ret = 0;\ + do {\ + ret = pthread_mutex_destroy(mutex_add);\ + if (0 == ret){\ + break;\ + }\ + else if (EINVAL == ret){\ + DA_LOGE("pthread_mutex_destroy FAIL with EINVAL.");\ + break;\ + }\ + else if (EBUSY == ret){\ + DA_LOGE("pthread_mutex_destroy FAIL with EBUSY.");\ + break;\ + }\ + else {\ + DA_LOGE("pthread_mutex_destroy FAIL with %d.", ret);\ + break;\ + }\ + } while(1);\ +} #endif diff --git a/agent/include/download-agent-type.h b/agent/include/download-agent-type.h index 86fa5ca..e77c121 100755 --- a/agent/include/download-agent-type.h +++ b/agent/include/download-agent-type.h @@ -14,13 +14,14 @@ * limitations under the License. */ -#ifndef _Download_Agent_Types_H -#define _Download_Agent_Types_H +#ifndef _DOWNLOAD_AGENT_TYPE_H +#define _DOWNLOAD_AGENT_TYPE_H #include "download-agent-defs.h" -typedef int da_result_t; +typedef int da_ret_t; typedef int da_bool_t; +typedef unsigned long long da_size_t; #define IS_NOT_VALID_ID(x) (x <= DA_INVALID_ID) @@ -31,5 +32,42 @@ typedef int da_bool_t; #define DA_MAX_MIME_STR_LEN 256 #define DA_MAX_PROXY_ADDR_LEN 64 // e.g. 100.200.300.400:10000 +#define SCHEME_HTTP "http://" + +#define DA_DEFAULT_INSTALL_PATH_FOR_PHONE "/opt/usr/media/Downloads" + +#define DA_MAX_ID DA_MAX_DOWNLOAD_REQ_AT_ONCE + +#define SAVE_FILE_BUFFERING_SIZE_50KB (50*1024) + +#define NULL_CHECK(DATA) {\ + if (!DATA) {\ + DA_LOGE("NULL CHECK!:%s",(#DATA));\ + return;\ + }\ +} + +#define NULL_CHECK_RET(DATA) {\ + if (!DATA) {\ + DA_LOGE("NULL CHECK!:%s",(#DATA));\ + return DA_ERR_INVALID_ARGUMENT;\ + }\ +} + +#define NULL_CHECK_GOTO(DATA) {\ + if (!DATA) {\ + DA_LOGE("NULL CHECK!:%s",(#DATA));\ + ret = DA_ERR_INVALID_ARGUMENT;\ + goto ERR;\ + }\ +} + +#define NULL_CHECK_RET_OPT(DATA, RET_DATA) {\ + if (!DATA) {\ + DA_LOGE("NULL CHECK!:%s",(#DATA));\ + return RET_DATA;\ + }\ +} + #endif diff --git a/agent/include/download-agent-utils-dl-id-history.h b/agent/include/download-agent-utils-dl-id-history.h deleted file mode 100755 index 3e32048..0000000 --- a/agent/include/download-agent-utils-dl-id-history.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Utils_Hash_Table_H -#define _Download_Agent_Utils_Hash_Table_H - -#include "download-agent-pthread.h" - -typedef struct _dl_id_history_t dl_id_history_t; -struct _dl_id_history_t { - int starting_num; - int cur_dl_id; - pthread_mutex_t mutex; -}; - -da_result_t init_dl_id_history(dl_id_history_t *dl_id_history); -da_result_t deinit_dl_id_history(dl_id_history_t *dl_id_history); - -int get_available_dl_id(dl_id_history_t *dl_id_history); - - -#endif /* _Download_Agent_Utils_Hash_Table_H */ diff --git a/agent/include/download-agent-utils.h b/agent/include/download-agent-utils.h deleted file mode 100755 index ee73307..0000000 --- a/agent/include/download-agent-utils.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _Download_Agent_Utils_H -#define _Download_Agent_Utils_H - -#include -#include "download-agent-defs.h" -#include "download-agent-interface.h" -#include "download-agent-dl-mgr.h" - -#define SAVE_FILE_BUFFERING_SIZE_50KB (50*1024) -#define SAVE_FILE_BUFFERING_SIZE_5MB (5*1024*1024) - -#define DA_SLEEP(x) \ - do \ - { \ - struct timespec interval,remainder; \ - interval.tv_sec = (unsigned int)((x)/1000); \ - interval.tv_nsec = (((x)-(interval.tv_sec*1000))*1000000); \ - nanosleep(&interval,&remainder); \ - } while(0) - -typedef struct _da_storage_size_t { - unsigned long b_available; - unsigned long b_size; -} da_storage_size_t; - -typedef enum { - DA_MIME_TYPE_NONE, - DA_MIME_TYPE_DRM1_MESSATE, - DA_MIME_TYPE_END -} da_mime_type_id_t; - -void get_random_number(int *out_num); -da_result_t get_available_dd_id(int *available_id); -da_result_t get_extension_from_mime_type(char *mime_type, char **extension); -da_mime_type_id_t get_mime_type_id(char *content_type); -da_result_t get_available_memory(da_storage_size_t *avail_memory); -da_bool_t is_valid_url(const char *url, da_result_t *err_code); - -int read_data_from_file(char *file, char**out_buffer); -da_result_t move_file(const char *from_path, const char *to_path); -void remove_file(const char *file_path); -char *_stristr(const char *long_str, const char *find_str); - -#endif -- cgit v1.2.3