From: Jinkun Jang Date: Fri, 15 Mar 2013 16:21:31 +0000 (+0900) Subject: merge with master X-Git-Tag: 2.1b_release~16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=149d97b09dac43623b4ca86faf4ab576953c0175;p=platform%2Fframework%2Fweb%2Fdownload-provider.git merge with master --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 51cd43a..9714c18 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,23 +1,47 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +MESSAGE("PROJECT : ${PKG_NAME}") -ADD_SUBDIRECTORY(src/agent) -ADD_SUBDIRECTORY(src/) +# DEFINES -PROJECT(download-provider C) +SET(VERSION ${PKG_VERSION}-${PKG_RELEASE}) +MESSAGE("VERSION : ${VERSION}") + +IF(DEFINED SUPPORT_DBUS_SYSTEM) + MESSAGE("SUPPORT DBUS SYSTEM : ${SUPPORT_DBUS_SYSTEM}") + IF(SUPPORT_DBUS_SYSTEM) + ADD_DEFINITIONS(-DDP_SUPPORT_DBUS_ACTIVATION) + ENDIF(SUPPORT_DBUS_SYSTEM) +ENDIF(DEFINED SUPPORT_DBUS_SYSTEM) + +# BUILD + +ADD_SUBDIRECTORY(agent) +ADD_SUBDIRECTORY(provider-interface) +ADD_SUBDIRECTORY(provider) + +# INSTALL + +PROJECT(${PKG_NAME} C) +SET(PACKAGE_DESCRIPTION "Defines for ${PROJECT_NAME}") CONFIGURE_FILE(download-provider.pc.in download-provider.pc @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/download-provider.pc DESTINATION lib/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/download-provider.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) INSTALL(PROGRAMS download-provider-service DESTINATION /etc/rc.d/init.d) -CONFIGURE_FILE(download-provider-service.service.in download-provider-service.service @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/download-provider-service.service DESTINATION /usr/share/dbus-1/services) - # install images -INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/images/ DESTINATION share/download-provider/ +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/images/ DESTINATION ${IMAGE_DIR} FILES_MATCHING PATTERN "*.png" ) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.APLv2 share/license/${PROJECT_NAME}) -INSTALL(FILES share/license/${PROJECT_NAME} DESTINATION share/license) + +IF(DEFINED DBUS_SERVICE_DIR) + CONFIGURE_FILE(org.download-provider.service.in org.download-provider.service @ONLY) + INSTALL(FILES org.download-provider.service DESTINATION ${DBUS_SERVICE_DIR}) +ENDIF(DEFINED DBUS_SERVICE_DIR) + +IF(DEFINED LICENSE_DIR) + CONFIGURE_FILE(LICENSE.APLv2 share/license/${PROJECT_NAME}) + INSTALL(FILES share/license/${PROJECT_NAME} DESTINATION ${LICENSE_DIR}) +ENDIF(DEFINED LICENSE_DIR) diff --git a/src/agent/CMakeLists.txt b/agent/CMakeLists.txt similarity index 92% rename from src/agent/CMakeLists.txt rename to agent/CMakeLists.txt index ead1561..26f2b34 100755 --- a/src/agent/CMakeLists.txt +++ b/agent/CMakeLists.txt @@ -27,10 +27,8 @@ FOREACH(flag ${subpkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") -SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -Wall") -SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed -Wl,--hash-style=both") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -Wall") IF("${ARCH}" MATCHES "^arm.*") ADD_DEFINITIONS("-D_TARGET") @@ -82,5 +80,5 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.0.1) #+++++++++++++++++++++++++INSTALLATION++++++++++++++++++++++++++++++++++++++++ ############################################################################# -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib COMPONENT RuntimeLibraries) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) diff --git a/src/agent/download-agent-basic.c b/agent/download-agent-basic.c similarity index 99% rename from src/agent/download-agent-basic.c rename to agent/download-agent-basic.c index 03f3a8a..8a7681c 100755 --- a/src/agent/download-agent-basic.c +++ b/agent/download-agent-basic.c @@ -92,7 +92,7 @@ da_result_t start_download_with_extension( client_input->install_path = (char *)calloc(install_path_len+1, sizeof(char)); if (client_input->install_path) - snprintf(client_input->install_path, install_path_len+1, install_path); + strncpy(client_input->install_path, install_path, install_path_len); } if (file_name) { diff --git a/src/agent/download-agent-client-mgr.c b/agent/download-agent-client-mgr.c similarity index 100% rename from src/agent/download-agent-client-mgr.c rename to agent/download-agent-client-mgr.c diff --git a/src/agent/download-agent-debug.c b/agent/download-agent-debug.c similarity index 100% rename from src/agent/download-agent-debug.c rename to agent/download-agent-debug.c diff --git a/src/agent/download-agent-dl-info-util.c b/agent/download-agent-dl-info-util.c similarity index 100% rename from src/agent/download-agent-dl-info-util.c rename to agent/download-agent-dl-info-util.c diff --git a/src/agent/download-agent-dl-mgr.c b/agent/download-agent-dl-mgr.c similarity index 100% rename from src/agent/download-agent-dl-mgr.c rename to agent/download-agent-dl-mgr.c diff --git a/src/agent/download-agent-encoding.c b/agent/download-agent-encoding.c similarity index 100% rename from src/agent/download-agent-encoding.c rename to agent/download-agent-encoding.c diff --git a/src/agent/download-agent-file.c b/agent/download-agent-file.c similarity index 99% rename from src/agent/download-agent-file.c rename to agent/download-agent-file.c index a048c23..e44863f 100755 --- a/src/agent/download-agent-file.c +++ b/agent/download-agent-file.c @@ -146,9 +146,9 @@ da_result_t get_mime_type(stage_info *stage, char **out_mime_type) } /* FIXME really need memory allocation? */ - *out_mime_type = (char *) calloc(1, strlen(mime_type) + 1); + *out_mime_type = (char *)calloc(1, strlen(mime_type) + 1); if (*out_mime_type) { - snprintf(*out_mime_type, strlen(mime_type) + 1, mime_type); + strncpy(*out_mime_type, mime_type, strlen(mime_type)); DA_LOG_VERBOSE(FileManager, "out_mime_type str[%s] ptr[%p] len[%d]", *out_mime_type,*out_mime_type,strlen(*out_mime_type)); } else { @@ -184,7 +184,7 @@ da_bool_t is_file_exist(const char *file_path) } -da_bool_t is_dir_exist(char *file_path) +da_bool_t is_dir_exist(const char *file_path) { struct stat dir_state; int stat_ret; diff --git a/src/agent/download-agent-http-mgr.c b/agent/download-agent-http-mgr.c similarity index 100% rename from src/agent/download-agent-http-mgr.c rename to agent/download-agent-http-mgr.c diff --git a/src/agent/download-agent-http-misc.c b/agent/download-agent-http-misc.c similarity index 100% rename from src/agent/download-agent-http-misc.c rename to agent/download-agent-http-misc.c diff --git a/src/agent/download-agent-http-msg-handler.c b/agent/download-agent-http-msg-handler.c similarity index 100% rename from src/agent/download-agent-http-msg-handler.c rename to agent/download-agent-http-msg-handler.c diff --git a/src/agent/download-agent-http-queue.c b/agent/download-agent-http-queue.c similarity index 100% rename from src/agent/download-agent-http-queue.c rename to agent/download-agent-http-queue.c diff --git a/src/agent/download-agent-interface.c b/agent/download-agent-interface.c similarity index 100% rename from src/agent/download-agent-interface.c rename to agent/download-agent-interface.c diff --git a/src/agent/download-agent-mime-util.c b/agent/download-agent-mime-util.c similarity index 100% rename from src/agent/download-agent-mime-util.c rename to agent/download-agent-mime-util.c diff --git a/src/agent/download-agent-plugin-conf.c b/agent/download-agent-plugin-conf.c similarity index 100% rename from src/agent/download-agent-plugin-conf.c rename to agent/download-agent-plugin-conf.c diff --git a/src/agent/download-agent-plugin-libsoup.c b/agent/download-agent-plugin-libsoup.c similarity index 96% rename from src/agent/download-agent-plugin-libsoup.c rename to agent/download-agent-plugin-libsoup.c index fe4b015..8ef16d0 100755 --- a/src/agent/download-agent-plugin-libsoup.c +++ b/agent/download-agent-plugin-libsoup.c @@ -132,14 +132,10 @@ 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; @@ -883,6 +879,11 @@ void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data) DA_LOG_FUNC_START(HTTPManager); + if (!msg) { + DA_LOG_ERR(HTTPManager, "Check NULL:msg"); + return; + } + url = soup_uri_to_string(soup_message_get_uri(msg), DA_FALSE); DA_LOG(HTTPManager,"status_code[%d], reason[%s], url[%s]",msg->status_code,msg->reason_phrase,url); @@ -910,6 +911,16 @@ void _pi_http_restarted_cb(SoupMessage *msg, gpointer data) DA_LOG_FUNC_START(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); } @@ -917,12 +928,23 @@ void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data) { DA_LOG_FUNC_START(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) @@ -936,12 +958,23 @@ void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType, { DA_LOG_FUNC_START(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); } @@ -950,6 +983,16 @@ void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data) { // DA_LOG_FUNC_START(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; @@ -958,4 +1001,3 @@ void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data) chunk->length); } } - diff --git a/src/agent/download-agent-utils-dl-id-history.c b/agent/download-agent-utils-dl-id-history.c similarity index 100% rename from src/agent/download-agent-utils-dl-id-history.c rename to agent/download-agent-utils-dl-id-history.c diff --git a/src/agent/download-agent-utils.c b/agent/download-agent-utils.c similarity index 100% rename from src/agent/download-agent-utils.c rename to agent/download-agent-utils.c diff --git a/src/agent/include/download-agent-basic.h b/agent/include/download-agent-basic.h similarity index 100% rename from src/agent/include/download-agent-basic.h rename to agent/include/download-agent-basic.h diff --git a/src/agent/include/download-agent-client-mgr.h b/agent/include/download-agent-client-mgr.h similarity index 100% rename from src/agent/include/download-agent-client-mgr.h rename to agent/include/download-agent-client-mgr.h diff --git a/src/agent/include/download-agent-debug.h b/agent/include/download-agent-debug.h similarity index 100% rename from src/agent/include/download-agent-debug.h rename to agent/include/download-agent-debug.h diff --git a/src/agent/include/download-agent-defs.h b/agent/include/download-agent-defs.h similarity index 100% rename from src/agent/include/download-agent-defs.h rename to agent/include/download-agent-defs.h diff --git a/src/agent/include/download-agent-dl-info-util.h b/agent/include/download-agent-dl-info-util.h similarity index 100% rename from src/agent/include/download-agent-dl-info-util.h rename to agent/include/download-agent-dl-info-util.h diff --git a/src/agent/include/download-agent-dl-mgr.h b/agent/include/download-agent-dl-mgr.h similarity index 100% rename from src/agent/include/download-agent-dl-mgr.h rename to agent/include/download-agent-dl-mgr.h diff --git a/src/agent/include/download-agent-encoding.h b/agent/include/download-agent-encoding.h similarity index 100% rename from src/agent/include/download-agent-encoding.h rename to agent/include/download-agent-encoding.h diff --git a/src/agent/include/download-agent-file.h b/agent/include/download-agent-file.h similarity index 97% rename from src/agent/include/download-agent-file.h rename to agent/include/download-agent-file.h index 3bada44..fa886f7 100755 --- a/src/agent/include/download-agent-file.h +++ b/agent/include/download-agent-file.h @@ -29,7 +29,7 @@ #define DA_DEFAULT_INSTALL_PATH_FOR_MMC "/opt/storage/sdcard/Downloads" da_bool_t is_file_exist(const char *file_path); -da_bool_t is_dir_exist(char *dir_path); +da_bool_t is_dir_exist(const char *dir_path); void get_file_size(char *file_path, unsigned long long *out_file_size); diff --git a/src/agent/include/download-agent-http-mgr.h b/agent/include/download-agent-http-mgr.h similarity index 100% rename from src/agent/include/download-agent-http-mgr.h rename to agent/include/download-agent-http-mgr.h diff --git a/src/agent/include/download-agent-http-misc.h b/agent/include/download-agent-http-misc.h similarity index 100% rename from src/agent/include/download-agent-http-misc.h rename to agent/include/download-agent-http-misc.h diff --git a/src/agent/include/download-agent-http-msg-handler.h b/agent/include/download-agent-http-msg-handler.h similarity index 100% rename from src/agent/include/download-agent-http-msg-handler.h rename to agent/include/download-agent-http-msg-handler.h diff --git a/src/agent/include/download-agent-http-queue.h b/agent/include/download-agent-http-queue.h similarity index 100% rename from src/agent/include/download-agent-http-queue.h rename to agent/include/download-agent-http-queue.h diff --git a/src/agent/include/download-agent-interface.h b/agent/include/download-agent-interface.h similarity index 96% rename from src/agent/include/download-agent-interface.h rename to agent/include/download-agent-interface.h index d51aed6..83d6a0f 100755 --- a/src/agent/include/download-agent-interface.h +++ b/agent/include/download-agent-interface.h @@ -17,6 +17,10 @@ #ifndef _Download_Agent_Interface_H #define _Download_Agent_Interface_H +#ifndef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) +#endif + #ifdef __cplusplus extern "C" { @@ -205,7 +209,7 @@ typedef struct { * } * @endcode */ -int da_init(da_client_cb_t *da_client_callback); +EXPORT_API int da_init(da_client_cb_t *da_client_callback); /** * @fn int da_deinit () @@ -243,7 +247,7 @@ int da_init(da_client_cb_t *da_client_callback); * } @endcode */ -int da_deinit(); +EXPORT_API int da_deinit(); /** * @fn int da_start_download(const char *url, int *download_id) @@ -281,7 +285,7 @@ int da_deinit(); * printf("download requesting is failed with error code %d\n", da_ret); * @endcode */ -int da_start_download(const char *url, int *download_id); +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) @@ -321,7 +325,7 @@ int da_start_download(const char *url, int *download_id); printf("download requesting is failed with error code %d\n", da_ret); @endcode */ -int da_start_download_with_extension(const char *url, +EXPORT_API int da_start_download_with_extension(const char *url, extension_data_t *ext_data, int *download_id ); @@ -362,7 +366,7 @@ int da_start_download_with_extension(const char *url, } @endcode */ -int da_cancel_download(int download_id); +EXPORT_API int da_cancel_download(int download_id); /** @@ -402,9 +406,9 @@ int da_cancel_download(int download_id); } @endcode */ -int da_suspend_download(int download_id); +EXPORT_API int da_suspend_download(int download_id); -int da_suspend_download_without_update(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. @@ -439,7 +443,7 @@ int da_suspend_download_without_update(int download_id); } @endcode */ -int da_resume_download(int download_id); +EXPORT_API int da_resume_download(int download_id); /** * @fn int da_is_valid_download_id(int download_id) @@ -462,7 +466,7 @@ int da_resume_download(int download_id); * @return 1 for success, or 0 for fail * */ -int da_is_valid_download_id(int download_id); +EXPORT_API int da_is_valid_download_id(int download_id); #ifdef __cplusplus } diff --git a/src/agent/include/download-agent-mime-util.h b/agent/include/download-agent-mime-util.h similarity index 100% rename from src/agent/include/download-agent-mime-util.h rename to agent/include/download-agent-mime-util.h diff --git a/src/agent/include/download-agent-plugin-conf.h b/agent/include/download-agent-plugin-conf.h similarity index 100% rename from src/agent/include/download-agent-plugin-conf.h rename to agent/include/download-agent-plugin-conf.h diff --git a/src/agent/include/download-agent-plugin-http-interface.h b/agent/include/download-agent-plugin-http-interface.h similarity index 100% rename from src/agent/include/download-agent-plugin-http-interface.h rename to agent/include/download-agent-plugin-http-interface.h diff --git a/src/agent/include/download-agent-plugin-libsoup.h b/agent/include/download-agent-plugin-libsoup.h similarity index 100% rename from src/agent/include/download-agent-plugin-libsoup.h rename to agent/include/download-agent-plugin-libsoup.h diff --git a/src/agent/include/download-agent-pthread.h b/agent/include/download-agent-pthread.h similarity index 100% rename from src/agent/include/download-agent-pthread.h rename to agent/include/download-agent-pthread.h diff --git a/src/agent/include/download-agent-type.h b/agent/include/download-agent-type.h similarity index 100% rename from src/agent/include/download-agent-type.h rename to agent/include/download-agent-type.h diff --git a/src/agent/include/download-agent-utils-dl-id-history.h b/agent/include/download-agent-utils-dl-id-history.h similarity index 100% rename from src/agent/include/download-agent-utils-dl-id-history.h rename to agent/include/download-agent-utils-dl-id-history.h diff --git a/src/agent/include/download-agent-utils.h b/agent/include/download-agent-utils.h similarity index 100% rename from src/agent/include/download-agent-utils.h rename to agent/include/download-agent-utils.h diff --git a/download-provider.manifest b/download-provider.manifest index b2cca84..dd4b8e4 100755 --- a/download-provider.manifest +++ b/download-provider.manifest @@ -12,8 +12,8 @@ - - + + diff --git a/download-provider.pc.in b/download-provider.pc.in index 5ec2085..72ea9e5 100644 --- a/download-provider.pc.in +++ b/download-provider.pc.in @@ -1,9 +1,6 @@ -# Package Information (download-provider daemon style) +# Package Information -prefix=/usr -includedir=${prefix}/include - -Name: Download Provider -Description: Download Provider Daemon +Name: @PROJECT_NAME@ +Description: @PACKAGE_DESCRIPTION@ Version: @VERSION@ -Cflags: -I${includedir}/download-provider +Cflags: -I/usr/include/download-provider diff --git a/download-provider-service.service.in b/org.download-provider.service.in old mode 100644 new mode 100755 similarity index 100% rename from download-provider-service.service.in rename to org.download-provider.service.in diff --git a/packaging/download-provider.spec b/packaging/download-provider.spec index 9fca5cc..5038121 100755 --- a/packaging/download-provider.spec +++ b/packaging/download-provider.spec @@ -1,8 +1,8 @@ Name: download-provider Summary: download the contents in background. -Version: 1.0.2 -Release: 15 +Version: 1.0.5 +Release: 0 Group: Development/Libraries License: Apache License, Version 2.0 Source0: %{name}-%{version}.tar.gz @@ -18,6 +18,7 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(db-util) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-network-connection) BuildRequires: pkgconfig(notification) @@ -38,15 +39,43 @@ Description: download the contents in background (developement files) %prep %setup -q -cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} +%define _imagedir /usr/share/download-provider +%define _databasedir /opt/usr/dbspace +%define _databasefile %{_databasedir}/.download-provider.db +%define _dbusservicedir /usr/share/dbus-1/services +%define _licensedir /usr/share/license + +%define cmake \ + CFLAGS="${CFLAGS:-%optflags} -fPIC -D_REENTRANT -fvisibility=hidden"; export CFLAGS \ + FFLAGS="${FFLAGS:-%optflags} -fPIC -fvisibility=hidden"; export FFLAGS \ + LDFLAGS+=" -Wl,--as-needed -Wl,--hash-style=both"; export LDFLAGS \ + %__cmake \\\ + -DCMAKE_INSTALL_PREFIX:PATH=%{_prefix} \\\ + -DBIN_INSTALL_DIR:PATH=%{_bindir} \\\ + -DLIB_INSTALL_DIR:PATH=%{_libdir} \\\ + -DINCLUDE_INSTALL_DIR:PATH=%{_includedir} \\\ + -DPKG_NAME=%{name} \\\ + -DPKG_VERSION=%{version} \\\ + -DPKG_RELEASE=%{release} \\\ + -DIMAGE_DIR:PATH=%{_imagedir} \\\ + -DDATABASE_FILE:PATH=%{_databasefile} \\\ + -DDBUS_SERVICE_DIR:PATH=%{_dbusservicedir} \\\ + -DLICENSE_DIR:PATH=%{_licensedir} \\\ + -DSUPPORT_DBUS_SYSTEM:BOOL=ON \\\ + %if "%{?_lib}" == "lib64" \ + %{?_cmake_lib_suffix64} \\\ + %endif \ + %{?_cmake_skip_rpath} \\\ + -DBUILD_SHARED_LIBS:BOOL=ON %build +%cmake . make %{?jobs:-j%jobs} %install rm -rf %{buildroot} %make_install -mkdir -p %{buildroot}/usr/share/license +mkdir -p %{buildroot}%{_licensedir} mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d ln -s %{_sysconfdir}/rc.d/init.d/download-provider-service %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S70download-provider-service mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d @@ -56,11 +85,11 @@ mkdir -p %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants install %{SOURCE1} %{buildroot}%{_libdir}/systemd/user/ ln -s ../download-provider.service %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants/ -mkdir -p %{buildroot}/opt/data/download-provider -mkdir -p %{buildroot}/opt/usr/dbspace/ -if [ ! -f %{buildroot}/opt/usr/dbspace/.download-provider.db ]; +mkdir -p %{buildroot}/opt/data/%{name} +mkdir -p %{buildroot}%{_databasedir} +if [ ! -f %{buildroot}%{_databasefile} ]; then -sqlite3 %{buildroot}/opt/usr/dbspace/.download-provider.db 'PRAGMA journal_mode=PERSIST; +sqlite3 %{buildroot}%{_databasefile} 'PRAGMA journal_mode=PERSIST; PRAGMA foreign_keys=ON; CREATE TABLE logging ( @@ -79,6 +108,7 @@ id INTEGER UNIQUE PRIMARY KEY, auto_download BOOLEAN DEFAULT 0, state_event BOOLEAN DEFAULT 0, progress_event BOOLEAN DEFAULT 0, +noti_enable BOOLEAN DEFAULT 0, network_type TINYINT DEFAULT 0, filename TEXT DEFAULT NULL, destination TEXT DEFAULT NULL, @@ -109,8 +139,7 @@ FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE CREATE TABLE notification ( -id INTEGER UNIQUE PRIMARY KEY, -noti_enable BOOLEAN DEFAULT 0, +id INTEGER NOT NULL, extra_key TEXT DEFAULT NULL, extra_data TEXT DEFAULT NULL, FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE @@ -122,19 +151,21 @@ fi %files %defattr(-,root,root,-) -%dir %attr(0775,root,app) /opt/data/download-provider +%dir %attr(0775,root,app) /opt/data/%{name} %manifest download-provider.manifest -/usr/share/download-provider/*.png +%{_imagedir}/*.png %{_libdir}/libdownloadagent2.so.0.0.1 %{_libdir}/libdownloadagent2.so %{_libdir}/systemd/user/download-provider.service %{_libdir}/systemd/user/tizen-middleware.target.wants/download-provider.service -%{_bindir}/download-provider +%{_libdir}/libdownload-provider-interface.so.%{version} +%{_libdir}/libdownload-provider-interface.so.0 +%{_bindir}/%{name} %{_sysconfdir}/rc.d/init.d/download-provider-service %{_sysconfdir}/rc.d/rc3.d/S70download-provider-service %{_sysconfdir}/rc.d/rc5.d/S70download-provider-service -/usr/share/license/%{name} -/usr/share/dbus-1/services/download-provider-service.service +%{_licensedir}/%{name} +%{_dbusservicedir}/org.download-provider.service %attr(660,root,app) /opt/usr/dbspace/.download-provider.db %attr(660,root,app) /opt/usr/dbspace/.download-provider.db-journal @@ -142,11 +173,33 @@ fi %defattr(-,root,root,-) %{_libdir}/libdownloadagent2.so.0.0.1 %{_libdir}/libdownloadagent2.so -%{_bindir}/download-provider +%{_libdir}/libdownload-provider-interface.so %{_includedir}/download-provider/download-provider.h +%{_includedir}/download-provider/download-provider-defs.h +%{_includedir}/download-provider/download-provider-interface.h +%{_bindir}/%{name} %{_libdir}/pkgconfig/download-provider.pc +%{_libdir}/pkgconfig/download-provider-interface.pc %changelog +* Tue Mar 05 2013 Jungki Kwak +- Add function to handle credential URL +- Add functions for notification extra list. +- Close socket and group if failed to read the packet +- Return errorcode if failed to copy string +- Resolve wrong initialization +- Remove warning message in build time +- Functionize accepting the client +- Support N values per a extra-parem key +- Resolve a bug about converting error from agent +- Modify to check return value about DRM API +- Use enum value same with url-download +- Add to ignore SIGPIPE +- [prevent defect] Dereference before null check (REVERSE_INULL) +- [prevent defect] Logically dead code (DEADCODE) +- Check System Signal in all read call +- Apply "ignore EINTR" patch of url-download to provider-interface + * Fri Feb 01 2013 Kwangmin Bang - [smack] manifest for booting-script - [prevent defect] Dereference after null check diff --git a/provider-interface/CMakeLists.txt b/provider-interface/CMakeLists.txt new file mode 100755 index 0000000..1253d80 --- /dev/null +++ b/provider-interface/CMakeLists.txt @@ -0,0 +1,44 @@ + +## PROJECT NAME +PROJECT(download-provider-interface C) +SET(PACKAGE_DESCRIPTION "Interface supported by download-provider") + +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE "Debug") +ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") +MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") + +SET(PC_REQUIRED "glib-2.0 gobject-2.0 dlog capi-base-common capi-appfw-app-manager dbus-1") + +INCLUDE(FindPkgConfig) + +pkg_check_modules(provider_interface_pkgs REQUIRED ${PC_REQUIRED}) + +FOREACH(flag ${provider_interface_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +## INCLUDES +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/provider/include) + +SET(PROVIDER_INTERFACE_LINK_LIBRARIES + ${GLIB-2_LIBRARIES} + ${GOBJECT-2_LIBRARIES} + pthread + ) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -Wall") + +ADD_LIBRARY(${PROJECT_NAME} SHARED + ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.c ) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${provider_interface_pkgs_LDFLAGS} ${PROVIDER_INTERFACE_LINK_LIBRARIES}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${PKG_VERSION}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${PROJECT_NAME}.h DESTINATION ${INCLUDE_INSTALL_DIR}/${PKG_NAME}) +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) diff --git a/provider-interface/download-provider-interface.c b/provider-interface/download-provider-interface.c new file mode 100755 index 0000000..a6a3caa --- /dev/null +++ b/provider-interface/download-provider-interface.c @@ -0,0 +1,1900 @@ +/* + * Copyright (c) 2013 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 +#include + +#include +#include +#include + +#ifdef DP_DBUS_ACTIVATION +#include +#endif + +#ifdef DP_ECHO_TEST +#include +#endif + +#define DP_CHECK_CONNECTION do {\ + TRACE_INFO("");\ + if (__check_connections() != DP_ERROR_NONE) {\ + pthread_mutex_unlock(&g_function_mutex);\ + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR;\ + }\ +} while(0) + +#define DP_CHECK_PROVIDER_STATUS do {\ + dp_error_type errorcode = DP_ERROR_NONE;\ + errorcode = __ipc_check_ready_status(g_interface_info->cmd_socket);\ + if (errorcode != DP_ERROR_NONE) {\ + pthread_mutex_unlock((&g_interface_info->mutex));\ + pthread_mutex_unlock(&g_function_mutex);\ + if (errorcode == DP_ERROR_IO_ERROR)\ + __disconnect_from_provider();\ + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR;\ + }\ +} while(0) + +#define DP_PRE_CHECK_ID do {\ + if (id <= 0) {\ + TRACE_ERROR("[CHECK ID] (%d)", id);\ + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;\ + }\ +} while(0) + +#define MAX_DOWNLOAD_HANDLE 5 + +#define DEBUG_MSG + +#ifdef DEBUG_MSG +#include +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "DOWNLOAD_PROVIDER_INTERFACE" +#define TRACE_ERROR(format, ARG...) \ +{ \ +LOGE(format, ##ARG); \ +} +#define TRACE_STRERROR(format, ARG...) \ +{ \ +LOGE(format" [%s]", ##ARG, strerror(errno)); \ +} +#define TRACE_INFO(format, ARG...) \ +{ \ +LOGI(format, ##ARG); \ +} +#else +#define TRACE_DEBUG_MSG(format, ARG...) ; +#endif + +// define type +typedef struct { + // send command * get return value. + int cmd_socket; + // getting event from download-provider + int event_socket; + pthread_mutex_t mutex; // lock before using, unlock after using +} dp_interface_info; + +typedef struct { + dp_interface_state_changed_cb state; + void *state_data; + dp_interface_progress_cb progress; + void *progress_data; +} dp_interface_callback; + +typedef struct { + int id; + dp_interface_callback callback; +} dp_interface_slot; + +// declare the variables +dp_interface_info *g_interface_info = NULL; +dp_interface_slot g_interface_slots[MAX_DOWNLOAD_HANDLE]; +static pthread_mutex_t g_function_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_t g_interface_event_thread_id = 0; + +#ifdef DP_DBUS_ACTIVATION +/* DBUS Activation */ +static int __dp_call_dp_interface_service(void) +{ + DBusConnection *connection = NULL; + DBusError dbus_error; + + dbus_error_init(&dbus_error); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); + if (connection == NULL) { + TRACE_ERROR("[ERROR] dbus_bus_get"); + if (dbus_error_is_set(&dbus_error)) { + TRACE_ERROR("[DBUS] dbus_bus_get: %s", dbus_error.message); + dbus_error_free(&dbus_error); + } + return -1; + } + + dbus_uint32_t result = 0; + if (dbus_bus_start_service_by_name + (connection, + DP_DBUS_SERVICE_DBUS, 0, &result, &dbus_error) == FALSE) { + if (dbus_error_is_set(&dbus_error)) { + TRACE_ERROR("[DBUS] dbus_bus_start_service_by_name: %s", + dbus_error.message); + dbus_error_free(&dbus_error); + } + dbus_connection_unref(connection); + return -1; + } + if (result == DBUS_START_REPLY_ALREADY_RUNNING) { + TRACE_INFO("DBUS_START_REPLY_ALREADY_RUNNING [%d]", result); + } else if (result == DBUS_START_REPLY_SUCCESS) { + TRACE_INFO("DBUS_START_REPLY_SUCCESS [%d]", result); + } + dbus_connection_unref(connection); + return 0; +} +#endif + +//////////// defines functions ///////////////// + + + +static int __dp_interface_convert_network_adaptor(int type) +{ + switch (type) { + case DOWNLOAD_ADAPTOR_NETWORK_WIFI: + return DP_NETWORK_TYPE_WIFI; + case DOWNLOAD_ADAPTOR_NETWORK_DATA_NETWORK: + return DP_NETWORK_TYPE_DATA_NETWORK; + case DOWNLOAD_ADAPTOR_NETWORK_WIFI_DIRECT: + return DP_NETWORK_TYPE_WIFI_DIRECT; + default: + break; + } + return DP_NETWORK_TYPE_ALL; +} + +static int __dp_interface_convert_network_provider(int type) +{ + switch (type) { + case DP_NETWORK_TYPE_WIFI: + return DOWNLOAD_ADAPTOR_NETWORK_WIFI; + case DP_NETWORK_TYPE_DATA_NETWORK: + return DOWNLOAD_ADAPTOR_NETWORK_DATA_NETWORK; + case DP_NETWORK_TYPE_WIFI_DIRECT: + return DOWNLOAD_ADAPTOR_NETWORK_WIFI_DIRECT; + default: + break; + } + return DOWNLOAD_ADAPTOR_NETWORK_ALL; +} + +static int __dp_interface_convert_state(int state) +{ + switch (state) { + case DP_STATE_READY: + TRACE_INFO("READY"); + return DOWNLOAD_ADPATOR_STATE_READY; + case DP_STATE_CONNECTING: + TRACE_INFO("CONNECTING/QUEUED"); + return DOWNLOAD_ADPATOR_STATE_QUEUED; + case DP_STATE_QUEUED: + TRACE_INFO("QUEUED"); + return DOWNLOAD_ADPATOR_STATE_QUEUED; + case DP_STATE_DOWNLOADING: + TRACE_INFO("DOWNLOADING"); + return DOWNLOAD_ADPATOR_STATE_DOWNLOADING; + case DP_STATE_PAUSE_REQUESTED: + TRACE_INFO("PAUSE_REQUESTED/DOWNLOADING"); + return DOWNLOAD_ADPATOR_STATE_DOWNLOADING; + case DP_STATE_PAUSED: + TRACE_INFO("PAUSED"); + return DOWNLOAD_ADPATOR_STATE_PAUSED; + case DP_STATE_COMPLETED: + TRACE_INFO("COMPLETED"); + return DOWNLOAD_ADPATOR_STATE_COMPLETED; + case DP_STATE_CANCELED: + TRACE_INFO("CANCELED"); + return DOWNLOAD_ADPATOR_STATE_CANCELED; + case DP_STATE_FAILED: + TRACE_INFO("FAILED"); + return DOWNLOAD_ADPATOR_STATE_FAILED; + default: + break; + } + return DOWNLOAD_ADPATOR_STATE_NONE; +} + +static int __dp_interface_convert_errorcode(int errorcode) +{ + switch (errorcode) { + case DP_ERROR_NONE: + TRACE_INFO("ERROR_NONE"); + return DOWNLOAD_ADAPTOR_ERROR_NONE; + case DP_ERROR_INVALID_PARAMETER: + TRACE_INFO("ERROR_INVALID_PARAMETER"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + case DP_ERROR_OUT_OF_MEMORY: + TRACE_INFO("ERROR_OUT_OF_MEMORY"); + return DOWNLOAD_ADAPTOR_ERROR_OUT_OF_MEMORY; + case DP_ERROR_IO_ERROR: + TRACE_INFO("ERROR_IO_ERROR"); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + case DP_ERROR_NETWORK_UNREACHABLE: + TRACE_INFO("ERROR_NETWORK_UNREACHABLE"); + return DOWNLOAD_ADAPTOR_ERROR_NETWORK_UNREACHABLE; + case DP_ERROR_NO_SPACE: + TRACE_INFO("ERROR_NO_SPACE"); + return DOWNLOAD_ADAPTOR_ERROR_NO_SPACE; + case DP_ERROR_FIELD_NOT_FOUND: + TRACE_INFO("ERROR_FIELD_NOT_FOUND"); + return DOWNLOAD_ADAPTOR_ERROR_FIELD_NOT_FOUND; + case DP_ERROR_INVALID_STATE: + TRACE_INFO("ERROR_INVALID_STATE"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_STATE; + case DP_ERROR_CONNECTION_FAILED: + TRACE_INFO("ERROR_CONNECTION_TIMED_OUT/CONNECTION_FAILED"); + return DOWNLOAD_ADAPTOR_ERROR_CONNECTION_TIMED_OUT; + case DP_ERROR_INVALID_URL: + TRACE_INFO("ERROR_INVALID_URL"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_URL; + case DP_ERROR_INVALID_DESTINATION: + TRACE_INFO("ERROR_INVALID_DESTINATION"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_DESTINATION; + case DP_ERROR_QUEUE_FULL: + TRACE_INFO("ERROR_QUEUE_FULL"); + return DOWNLOAD_ADAPTOR_ERROR_QUEUE_FULL; + case DP_ERROR_ALREADY_COMPLETED: + TRACE_INFO("ERROR_ALREADY_COMPLETED"); + return DOWNLOAD_ADAPTOR_ERROR_ALREADY_COMPLETED; + case DP_ERROR_FILE_ALREADY_EXISTS: + TRACE_INFO("ERROR_FILE_ALREADY_EXISTS"); + return DOWNLOAD_ADAPTOR_ERROR_FILE_ALREADY_EXISTS; + case DP_ERROR_TOO_MANY_DOWNLOADS: + TRACE_INFO("ERROR_TOO_MANY_DOWNLOADS"); + return DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_DOWNLOADS; + case DP_ERROR_NO_DATA: + TRACE_INFO("ERROR_NO_DATA"); + return DOWNLOAD_ADAPTOR_ERROR_NO_DATA; + case DP_ERROR_UNHANDLED_HTTP_CODE: + TRACE_INFO("ERROR_UNHANDLED_HTTP_CODE"); + return DOWNLOAD_ADAPTOR_ERROR_UNHANDLED_HTTP_CODE; + case DP_ERROR_CANNOT_RESUME: + TRACE_INFO("ERROR_CANNOT_RESUME"); + return DOWNLOAD_ADAPTOR_ERROR_CANNOT_RESUME; + case DP_ERROR_ID_NOT_FOUND: + TRACE_INFO("ERROR_ID_NOT_FOUND"); + return DOWNLOAD_ADAPTOR_ERROR_ID_NOT_FOUND; + case DP_ERROR_UNKNOWN: + TRACE_INFO("ERROR_INVALID_STATE/UNKNOWN"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_STATE; + default: + break; + } + return DOWNLOAD_ADAPTOR_ERROR_NONE; +} + +static int __get_my_slot_index(int id) +{ + int i = 0; + // search same info in array. + for (; i < MAX_DOWNLOAD_HANDLE; i++) + if (g_interface_slots[i].id == id) + return i; + return -1; +} + +static int __get_empty_slot_index() +{ + int i = 0; + for (; i < MAX_DOWNLOAD_HANDLE; i++) + if (g_interface_slots[i].id <= 0) + return i; + return -1; +} + +static dp_error_type __get_standard_errorcode(dp_error_type basecode) +{ + dp_error_type errorcode = basecode; + if (errno == EPIPE) { + TRACE_ERROR("[EPIPE] Broken Pipe [%d]", errno); + errorcode = DP_ERROR_IO_ERROR; + } else if (errno == EAGAIN) { + TRACE_ERROR + ("[EAGAIN] Resource temporarily unavailable [%d]", + errno); + errorcode = DP_ERROR_IO_EAGAIN; + } else if (errno == EINTR) { + TRACE_ERROR("[EINTR] Interrupted System Call [%d]", errno); + errorcode = DP_ERROR_IO_EINTR; + } + return errorcode; +} + +static int __ipc_read_custom_type(int fd, void *value, size_t type_size) +{ + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return -1; + } + + if (read(fd, value, type_size) < 0) { + TRACE_STRERROR("[CRITICAL] read"); + return -1; + } + return 0; +} + +static int __ipc_read_int(int fd) +{ + int value = -1; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return -1; + } + if (read(fd, &value, sizeof(int)) < 0) { + TRACE_STRERROR("[CRITICAL] read"); + return -1; + } + return value; +} + +// keep the order/ unsigned , str +static char *__ipc_read_string(int fd) +{ + unsigned length = 0; + char *str = NULL; + + if (fd < 0) { + TRACE_ERROR("[CHECK FD]"); + return NULL; + } + + if (read(fd, &length, sizeof(unsigned)) < 0) { + TRACE_STRERROR("failed to read length [%d]", length); + return NULL; + } + if (length < 1 || length > DP_MAX_STR_LEN) { + TRACE_ERROR("[STRING LEGNTH] [%d]", length); + return NULL; + } + str = (char *)calloc((length + 1), sizeof(char)); + if (str == NULL) { + TRACE_STRERROR("[CRITICAL] allocation"); + return NULL; + } + if (read(fd, str, length * sizeof(char)) < 0) { + TRACE_STRERROR("failed to read string"); + free(str); + str = NULL; + return NULL; + } + str[length] = '\0'; + return str; +} + +static dp_error_type __ipc_return(int fd) +{ + dp_error_type errorcode = DP_ERROR_NONE; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return DP_ERROR_IO_ERROR; + } + + if (read(fd, &errorcode, sizeof(dp_error_type)) < 0) { + TRACE_STRERROR("[CRITICAL] read"); + return __get_standard_errorcode(DP_ERROR_IO_ERROR); + } + TRACE_INFO("return : %d", errorcode); + return errorcode; +} + +static dp_event_info* __ipc_event(int fd) +{ + dp_event_info *event = NULL; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return NULL; + } + + event = (dp_event_info *) calloc(1, sizeof(dp_event_info)); + if (event == NULL) { + TRACE_ERROR("[CHECK ALLOCATION]"); + return NULL; + } + if (read(fd, event, sizeof(dp_event_info)) < 0) { + TRACE_STRERROR("[CRITICAL] read"); + free(event); + return NULL; + } + + TRACE_INFO("EVENT INFO (ID : %d state : %d error : %d)", + event->id, event->state, event->err); + return event; +} + +static int __ipc_send_int(int fd, int value) +{ + if (fd < 0) { + TRACE_ERROR("[CHECK FD] [%d]", fd); + return -1; + } + + if (fd >= 0 && write(fd, &value, sizeof(int)) < 0) { + TRACE_STRERROR("[CRITICAL] send"); + return -1; + } + return 0; +} + +// keep the order/ unsigned , str +static dp_error_type __ipc_send_string(int fd, const char *str) +{ + unsigned length = 0; + + if (fd < 0) { + TRACE_ERROR("[CHECK FD]"); + return DP_ERROR_IO_ERROR; + } + if (str == NULL || (length = strlen(str)) <= 0) { + TRACE_ERROR("[CHECK STRING]"); + return DP_ERROR_INVALID_PARAMETER; + } + + if (fd >= 0 && write(fd, &length, sizeof(unsigned)) < 0) { + TRACE_STRERROR("[CRITICAL] send"); + return DP_ERROR_IO_ERROR; + } + if (fd >= 0 && write(fd, str, length * sizeof(char)) < 0) { + TRACE_STRERROR("[CRITICAL] send"); + return DP_ERROR_IO_ERROR; + } + return DP_ERROR_NONE; +} + +static dp_error_type __ipc_send_command + (int fd, int id, dp_command_type cmd) +{ + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return DP_ERROR_IO_ERROR; + } + + dp_command command; + command.id = id; + command.cmd = cmd; + if (fd >= 0 && write(fd, &command, sizeof(dp_command)) < 0) { + TRACE_STRERROR("[CRITICAL] send"); + return DP_ERROR_IO_ERROR; + } + return DP_ERROR_NONE; +} + +static dp_error_type __ipc_send_command_return + (int id, dp_command_type cmd) +{ + TRACE_INFO(""); + + if (cmd <= DP_CMD_NONE) { + TRACE_ERROR("[CHECK COMMAND] (%d)", cmd); + return DP_ERROR_INVALID_PARAMETER; + } + // send commnad with ID + if (__ipc_send_command(g_interface_info->cmd_socket, id, cmd) != + DP_ERROR_NONE) + return DP_ERROR_IO_ERROR; + // return from provider. + return __ipc_return(g_interface_info->cmd_socket); +} + +static int __create_socket() +{ + int sockfd = -1; + struct timeval tv_timeo = { 2, 500000 }; //2.5 second + struct sockaddr_un clientaddr; + + TRACE_INFO(""); + + if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + TRACE_STRERROR("[CRITICAL] socket system error"); + return -1; + } + + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo, + sizeof( tv_timeo ) ) < 0) { + TRACE_STRERROR("[CRITICAL] setsockopt SO_RCVTIMEO"); + close(sockfd); + return -1; + } + + bzero(&clientaddr, sizeof clientaddr); + clientaddr.sun_family = AF_UNIX; + memset(clientaddr.sun_path, 0x00, sizeof(clientaddr.sun_path)); + strncpy(clientaddr.sun_path, DP_IPC, strlen(DP_IPC)); + clientaddr.sun_path[strlen(DP_IPC)] = '\0'; + if (connect(sockfd, + (struct sockaddr*)&clientaddr, sizeof(clientaddr)) < 0) { + close(sockfd); + return -1; + } + TRACE_INFO("sockfd [%d]", sockfd); + return sockfd; +} + +static int __disconnect_from_provider() +{ + TRACE_INFO(""); + + if (g_interface_info != NULL) { + shutdown(g_interface_info->cmd_socket, 0); + close(g_interface_info->cmd_socket); + g_interface_info->cmd_socket= -1; + shutdown(g_interface_info->event_socket, 0); + close(g_interface_info->event_socket); + g_interface_info->event_socket = -1; + pthread_mutex_destroy((&g_interface_info->mutex)); + free(g_interface_info); + g_interface_info = NULL; + } + if (g_interface_event_thread_id > 0) { + TRACE_INFO("STOP event thread"); + pthread_cancel(g_interface_event_thread_id); + g_interface_event_thread_id = 0; + TRACE_INFO("OK terminate event thread"); + } + return DP_ERROR_NONE; +} + +#ifdef DP_ECHO_TEST +// clear read buffer. call in head of API before calling IPC_SEND +static void __clear_read_buffer(int fd) +{ + long i; + long unread_count; + char tmp_char; + + // FIONREAD : Returns the number of bytes immediately readable + if (ioctl(fd, FIONREAD, &unread_count) >= 0) { + if (unread_count > 0) { + TRACE_INFO("[CLEAN] garbage packet[%ld]", unread_count); + for ( i = 0; i < unread_count; i++) { + if (read(fd, &tmp_char, sizeof(char)) < 0) { + TRACE_STRERROR("[CHECK] read"); + break; + } + } + } + } +} +#endif + +// ask to provider before sending a command. +// if provider wait in some commnad, can not response immediately +// capi will wait in read block. +// after asking, call clear_read_buffer. +static dp_error_type __ipc_check_ready_status(int fd) +{ + dp_error_type errorcode = DP_ERROR_NONE; + +#ifdef DP_ECHO_TEST + // echo from provider + errorcode = __ipc_send_command_return(-1, DP_CMD_ECHO); + if (errorcode == DP_ERROR_NONE) + __clear_read_buffer(fd); +#endif + return errorcode; +} + +// listen ASYNC state event, no timeout +static void *__dp_interface_event_manager(void *arg) +{ + int maxfd, index; + fd_set rset, read_fdset; + dp_event_info *eventinfo = NULL; + + if (g_interface_info == NULL) { + TRACE_STRERROR("[CRITICAL] INTERFACE null"); + return 0; + } + if (g_interface_info->event_socket < 0) { + TRACE_STRERROR("[CRITICAL] IPC NOT ESTABILISH"); + return 0; + } + + // deferred wait to cencal until next function called. + // ex) function : select, read in this thread + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); + + TRACE_INFO("FD [%d]", g_interface_info->event_socket); + + maxfd = g_interface_info->event_socket; + FD_ZERO(&read_fdset); + FD_SET(g_interface_info->event_socket, &read_fdset); + + while(g_interface_info != NULL + && g_interface_info->event_socket >= 0) { + rset = read_fdset; + if (select((maxfd + 1), &rset, 0, 0, 0) < 0) { + TRACE_STRERROR("[CRITICAL] select"); + break; + } + + if (g_interface_event_thread_id <=0 + || pthread_self() != g_interface_event_thread_id) { + TRACE_ERROR + ("[CRITICAL] [CHECK TID] SELF ID [%d] Global ID (%d)", + pthread_self(), g_interface_event_thread_id); + // another thread may work. just terminate + return 0; + } + + pthread_mutex_lock(&g_function_mutex); + + if (g_interface_info == NULL + || g_interface_info->event_socket < 0) { + TRACE_ERROR("[CRITICAL] IPC BROKEN Ending Event Thread"); + pthread_mutex_unlock(&g_function_mutex); + // disconnected by main thread. just terminate + return 0; + } + + if (FD_ISSET(g_interface_info->event_socket, &rset) > 0) { + // read state info from socket + eventinfo = __ipc_event(g_interface_info->event_socket); + if (eventinfo == NULL || eventinfo->id <= 0) { + // failed to read from socket // ignore this status + free(eventinfo); + TRACE_STRERROR("[CRITICAL] Can not read Event packet"); + pthread_mutex_unlock(&g_function_mutex); + if (__get_standard_errorcode(DP_ERROR_IO_ERROR) == + DP_ERROR_IO_ERROR) // if not timeout. end thread + break; + continue; + } + + if ((index = __get_my_slot_index(eventinfo->id)) < 0) { + TRACE_ERROR("[CRITICAL] not found slot for [%d]", + eventinfo->id); + free(eventinfo); + pthread_mutex_unlock(&g_function_mutex); + continue; + } + + pthread_mutex_unlock(&g_function_mutex); + + // begin protect callback sections + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + + dp_interface_callback *callback = + &g_interface_slots[index].callback; + + if (eventinfo->state == DP_STATE_DOWNLOADING + && eventinfo->received_size > 0) { + if (callback->progress != NULL) { + // progress event + TRACE_INFO("ID %d progress callback %p", + eventinfo->id, callback->progress ); + callback->progress(eventinfo->id, + eventinfo->received_size, + callback->progress_data); + } + } else { + if (callback->state != NULL) { + // state event + TRACE_INFO("ID %d state callback %p", eventinfo->id, + callback->state); + callback->state(eventinfo->id, + __dp_interface_convert_state(eventinfo->state), + callback->state_data); + } + } + free(eventinfo); + + // end protect callback sections + pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); + continue; + } + pthread_mutex_unlock(&g_function_mutex); + } // while + + FD_ZERO(&read_fdset); + + TRACE_INFO("Terminate Event Thread"); + pthread_mutex_lock(&g_function_mutex); + TRACE_INFO("Disconnect All Connection"); + g_interface_event_thread_id = 0; // set 0 to not call pthread_cancel + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return 0; +} + +static int __connect_to_provider() +{ + TRACE_INFO(""); + + if (g_interface_info == NULL) { + +#ifdef DP_DBUS_ACTIVATION + if (__dp_call_dp_interface_service() < 0) { + TRACE_ERROR("[DBUS IO] __dp_call_dp_interface_service"); + return DP_ERROR_IO_ERROR; + } +#endif + + g_interface_info = + (dp_interface_info *) calloc(1, sizeof(dp_interface_info)); + } + + if (g_interface_info != NULL) { + + int connect_retry = 3; + g_interface_info->cmd_socket = -1; + while(g_interface_info->cmd_socket < 0 && connect_retry-- > 0) { + g_interface_info->cmd_socket = __create_socket(); + if (g_interface_info->cmd_socket < 0) + usleep(50000); + } + if (g_interface_info->cmd_socket < 0) { + TRACE_STRERROR("[CRITICAL] connect system error"); + free(g_interface_info); + g_interface_info = NULL; + return DP_ERROR_IO_ERROR; + } + // send a command + if (__ipc_send_int(g_interface_info->cmd_socket, + DP_CMD_SET_COMMAND_SOCKET) < 0) { + close(g_interface_info->cmd_socket); + free(g_interface_info); + g_interface_info = NULL; + return DP_ERROR_IO_ERROR; + } +#ifndef SO_PEERCRED + // send PID. Not support SO_PEERCRED + if (__ipc_send_int(g_interface_info->cmd_socket, get_pid()) < 0) { + close(g_interface_info->cmd_socket); + free(g_interface_info); + g_interface_info = NULL; + return DP_ERROR_IO_ERROR; + } +#endif + g_interface_info->event_socket = __create_socket(); + if (g_interface_info->event_socket < 0) { + TRACE_STRERROR("[CRITICAL] connect system error"); + close(g_interface_info->cmd_socket); + free(g_interface_info); + g_interface_info = NULL; + return DP_ERROR_IO_ERROR; + } + // send a command + if (__ipc_send_int(g_interface_info->event_socket, + DP_CMD_SET_EVENT_SOCKET) < 0) { + close(g_interface_info->cmd_socket); + close(g_interface_info->event_socket); + free(g_interface_info); + g_interface_info = NULL; + return DP_ERROR_IO_ERROR; + } +#ifndef SO_PEERCRED + // send PID. Not support SO_PEERCRED + if (__ipc_send_int + (g_interface_info->event_socket, get_pid()) < 0) { + close(g_interface_info->cmd_socket); + close(g_interface_info->event_socket); + free(g_interface_info); + g_interface_info = NULL; + return DP_ERROR_IO_ERROR; + } +#endif + + int ret = pthread_mutex_init((&g_interface_info->mutex), NULL); + if (ret != 0) { + TRACE_STRERROR("ERR:pthread_mutex_init FAIL with %d.", ret); + __disconnect_from_provider(); + return DP_ERROR_IO_ERROR; + } + + if (g_interface_event_thread_id <= 0) { + // create thread here ( getting event_socket ) + pthread_attr_t thread_attr; + if (pthread_attr_init(&thread_attr) != 0) { + TRACE_STRERROR("[CRITICAL] pthread_attr_init"); + __disconnect_from_provider(); + return DP_ERROR_IO_ERROR; + } + if (pthread_attr_setdetachstate(&thread_attr, + PTHREAD_CREATE_DETACHED) != 0) { + TRACE_STRERROR + ("[CRITICAL] pthread_attr_setdetachstate"); + __disconnect_from_provider(); + return DP_ERROR_IO_ERROR; + } + if (pthread_create(&g_interface_event_thread_id, + &thread_attr, __dp_interface_event_manager, + g_interface_info) != 0) { + TRACE_STRERROR("[CRITICAL] pthread_create"); + __disconnect_from_provider(); + return DP_ERROR_IO_ERROR; + } + } + } + return DP_ERROR_NONE; +} + +static dp_error_type __check_connections() +{ + int ret = 0; + + if (g_interface_info == NULL) + if ((ret = __connect_to_provider()) != DP_ERROR_NONE) + return ret; + + if (g_interface_info == NULL || g_interface_info->cmd_socket < 0) { + TRACE_ERROR("[CHECK IPC]"); + return DP_ERROR_IO_ERROR; + } + return DP_ERROR_NONE; +} + +// used frequently +static dp_error_type __dp_interface_set_string + (const int id, const dp_command_type cmd, const char *value) +{ + dp_error_type errorcode = DP_ERROR_NONE; + int fd = g_interface_info->cmd_socket; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + if (value == NULL || strlen(value) <= 0) { + TRACE_ERROR("[CHECK url]"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + // send commnad with ID + errorcode = __ipc_send_command(fd, id, cmd); + if (errorcode == DP_ERROR_NONE) { + // send string + errorcode = __ipc_send_string(fd, value); + if (errorcode == DP_ERROR_NONE) { + // return from provider. + errorcode = __ipc_return(fd); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +static dp_error_type __dp_interface_set_strings + (const int id, const dp_command_type cmd, const char **strings, + const unsigned count) +{ + dp_error_type errorcode = DP_ERROR_NONE; + int fd = g_interface_info->cmd_socket; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + if (strings == NULL || count == 0) { + TRACE_ERROR("[CHECK strings]"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + // send commnad with ID + errorcode = __ipc_send_command(fd, id, cmd); + if (errorcode == DP_ERROR_NONE) { + if (__ipc_send_int(fd, (int)count) == 0) { + int i = 0; + for (; i < count; i++) { + // send string + TRACE_INFO("[SEND] %s", strings[i]); + errorcode = __ipc_send_string(fd, strings[i]); + if (errorcode != DP_ERROR_NONE) + break; + } + } else { + errorcode = DP_ERROR_IO_ERROR; + } + if (errorcode == DP_ERROR_NONE) { + // return from provider. + errorcode = __ipc_return(fd); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +static dp_error_type __dp_interface_get_string + (const int id, const dp_command_type cmd, char **value) +{ + int errorcode = DP_ERROR_NONE; + int fd = g_interface_info->cmd_socket; + char *recv_str = NULL; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command_return(id, cmd); + if (errorcode == DP_ERROR_NONE) { + // getting state with ID from provider. + recv_str = __ipc_read_string(fd); + if (recv_str != NULL) { + *value = recv_str; + TRACE_INFO("ID : %d recv_str : %s", id, *value); + } else { + errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +static dp_error_type __dp_interface_get_strings + (const int id, const dp_command_type cmd, const char **strings, + const unsigned length, char ***values, unsigned *count) +{ + int errorcode = DP_ERROR_NONE; + int fd = g_interface_info->cmd_socket; + int i = 0; + int recv_str_index = 0; + char **recv_strings = NULL; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command(fd, id, cmd); + if (errorcode == DP_ERROR_NONE) { + if (__ipc_send_int(fd, (int)length) == 0) { + for (i = 0; i < length; i++) { + // send string + TRACE_INFO("[SEND] %s", strings[i]); + errorcode = __ipc_send_string(fd, strings[i]); + if (errorcode != DP_ERROR_NONE) + break; + } + } else { + errorcode = DP_ERROR_IO_ERROR; + } + if (errorcode == DP_ERROR_NONE) { + // return from provider. + errorcode = __ipc_return(fd); + } + } + if (errorcode == DP_ERROR_NONE) { + int recv_int = __ipc_read_int(fd); + if (recv_int < 0) { + errorcode = DP_ERROR_IO_ERROR; + } else if (recv_int > 0) { + recv_strings = (char **)calloc(recv_int, sizeof(char *)); + if (recv_strings == NULL) { + errorcode = DP_ERROR_OUT_OF_MEMORY; + } else { + for (i = 0; i < recv_int; i++) { + char *recv_str = __ipc_read_string(fd); + if (recv_str == NULL) { + errorcode = + __get_standard_errorcode(DP_ERROR_IO_ERROR); + break; + } else { + recv_strings[recv_str_index++] = recv_str; + TRACE_INFO("[RECV] %s", recv_str); + } + } + } + } + if (errorcode == DP_ERROR_NONE) { + *count = recv_str_index; + *values = recv_strings; + } else { + *count = 0; + for (i = 0; i < recv_str_index; i++) + free(recv_strings[i]); + free(recv_strings); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +static dp_error_type __dp_interface_get_int + (const int id, dp_command_type cmd, int *value) +{ + int errorcode = DP_ERROR_NONE; + int recv_int = -1; + int fd = g_interface_info->cmd_socket; + + if (fd < 0) { + TRACE_ERROR("[CHECK SOCKET]"); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command_return(id, cmd); + if (errorcode == DP_ERROR_NONE) { + recv_int = __ipc_read_int(fd); + if (recv_int >= 0) { + *value = recv_int; + TRACE_INFO("ID : %d recv_int : %d", id, *value); + } else { + errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +static dp_error_type __dp_interface_set_int + (const int id, dp_command_type cmd, const int value) +{ + int errorcode = DP_ERROR_NONE; + int fd = g_interface_info->cmd_socket; + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + // send commnad with ID + errorcode = __ipc_send_command(fd, id, cmd); + if (errorcode == DP_ERROR_NONE) { + // send string + if (__ipc_send_int(fd, value) == 0) { + // return from provider. + errorcode = __ipc_return(fd); + } else { + errorcode = DP_ERROR_IO_ERROR; + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + + +/////////////////////// APIs ///////////////////////////////// + +int dp_interface_create(int *id) +{ + int errorcode = DP_ERROR_NONE; + int t_id = 0; + int index = -1; + + pthread_mutex_lock(&g_function_mutex); + + if ((index = __get_empty_slot_index()) < 0) { + TRACE_ERROR + ("[ERROR] TOO_MANY_DOWNLOADS[%d]", MAX_DOWNLOAD_HANDLE); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_DOWNLOADS; + } + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command_return(-1, DP_CMD_CREATE); + if (errorcode == DP_ERROR_NONE) { + // getting state with ID from provider. + t_id = __ipc_read_int(g_interface_info->cmd_socket); + if (t_id >= 0) { + *id = t_id; + g_interface_slots[index].id = t_id; + g_interface_slots[index].callback.state = NULL; + g_interface_slots[index].callback.state_data = NULL; + g_interface_slots[index].callback.progress = NULL; + g_interface_slots[index].callback.progress_data = NULL; + errorcode = DP_ERROR_NONE; + } else { + errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_destroy(const int id) +{ + int index = -1; + int errorcode = DP_ERROR_NONE; + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + if ((index = __get_my_slot_index(id)) >= 0) { + g_interface_slots[index].id = 0; + g_interface_slots[index].callback.state = NULL; + g_interface_slots[index].callback.state_data = NULL; + g_interface_slots[index].callback.progress = NULL; + g_interface_slots[index].callback.progress_data = NULL; + } + errorcode = __ipc_send_command_return(id, DP_CMD_DESTROY); + if (errorcode == DP_ERROR_NONE) { + // after getting errorcode, send FREE to provider. + TRACE_INFO("Request to Free the memory for ID : %d", id); + // send again DP_CMD_FREE with ID. + errorcode = __ipc_send_command + (g_interface_info->cmd_socket, id, DP_CMD_FREE); + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_start(const int id) +{ + int errorcode = DP_ERROR_NONE; + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command_return(id, DP_CMD_START); + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_pause(const int id) +{ + int errorcode = DP_ERROR_NONE; + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command_return(id, DP_CMD_PAUSE); + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_cancel(const int id) +{ + int errorcode = DP_ERROR_NONE; + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command_return(id, DP_CMD_CANCEL); + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_set_url(const int id, const char *url) +{ + TRACE_INFO(""); + return __dp_interface_set_string(id, DP_CMD_SET_URL, url); +} + +int dp_interface_get_url(const int id, char **url) +{ + TRACE_INFO(""); + return __dp_interface_get_string(id, DP_CMD_GET_URL, url); +} + +int dp_interface_set_network_type(const int id, int net_type) +{ + TRACE_INFO(""); + return __dp_interface_set_int(id, DP_CMD_SET_NETWORK_TYPE, + __dp_interface_convert_network_adaptor(net_type)); +} + +int dp_interface_get_network_type(const int id, int *net_type) +{ + TRACE_INFO(""); + int network_type = DP_NETWORK_TYPE_ALL; + int ret = __dp_interface_get_int + (id, DP_CMD_GET_NETWORK_TYPE, &network_type); + if (ret == DOWNLOAD_ADAPTOR_ERROR_NONE) + *net_type = + __dp_interface_convert_network_provider(network_type); + return ret; +} + +int dp_interface_set_destination(const int id, const char *path) +{ + TRACE_INFO(""); + return __dp_interface_set_string(id, DP_CMD_SET_DESTINATION, path); +} + + +int dp_interface_get_destination(const int id, char **path) +{ + TRACE_INFO(""); + return __dp_interface_get_string(id, DP_CMD_GET_DESTINATION, path); +} + +int dp_interface_set_file_name(const int id, const char *file_name) +{ + TRACE_INFO(""); + return __dp_interface_set_string(id, DP_CMD_SET_FILENAME, file_name); +} + +int dp_interface_get_file_name(const int id, char **file_name) +{ + TRACE_INFO(""); + return __dp_interface_get_string(id, DP_CMD_GET_FILENAME, file_name); +} + +int dp_interface_set_ongoing_notification(const int id, int enable) +{ + return dp_interface_set_notification(id, enable); +} + +int dp_interface_set_notification(const int id, int enable) +{ + TRACE_INFO(""); + return __dp_interface_set_int(id, DP_CMD_SET_NOTIFICATION, enable); +} + +int dp_interface_get_ongoing_notification(const int id, int *enable) +{ + return dp_interface_get_notification(id, enable); +} + +int dp_interface_get_notification(const int id, int *enable) +{ + TRACE_INFO(""); + return __dp_interface_get_int(id, DP_CMD_GET_NOTIFICATION, enable); +} + +int dp_interface_get_downloaded_file_path(const int id, char **path) +{ + TRACE_INFO(""); + return __dp_interface_get_string(id, DP_CMD_GET_SAVED_PATH, path); +} + +int dp_interface_set_notification_extra_param(const int id, char *key, + char *value) +{ +#if 0 + DP_PRE_CHECK_ID; + + if (key == NULL || value == NULL) { + TRACE_ERROR("[CHECK param]"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + // send commnad with ID + if (__ipc_send_command + (g_interface_info->cmd_socket, id, DP_CMD_SET_EXTRA_PARAM) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + if (__ipc_send_string(g_interface_info->cmd_socket, key) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + if (__ipc_send_string(g_interface_info->cmd_socket, value) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + int errorcode = + __ipc_return(g_interface_info->cmd_socket); + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) { + TRACE_ERROR("[CHECK IO] (%d)", id); + __disconnect_from_provider(); + } + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +#endif + return DOWNLOAD_ADAPTOR_ERROR_NONE; +} + +int dp_interface_get_notification_extra_param(const int id, char **key, + char **value) +{ +#if 0 + int errorcode = DP_ERROR_NONE; + char *key_str = NULL; + char *value_str = NULL; + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = __ipc_send_command_return(id, DP_CMD_GET_EXTRA_PARAM); + if (errorcode != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); + } + // getting state with ID from provider. + key_str = __ipc_read_string(g_interface_info->cmd_socket); + if (key_str == NULL) { + pthread_mutex_unlock((&g_interface_info->mutex)); + errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); + } + + value_str = __ipc_read_string(g_interface_info->cmd_socket); + pthread_mutex_unlock((&g_interface_info->mutex)); + if (value_str == NULL) { + free(key_str); + errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); + } + + *key = key_str; + *value = value_str; + TRACE_INFO("ID : %d key : %s value : %s", id, *key, *value); + pthread_mutex_unlock(&g_function_mutex); +#endif + return DOWNLOAD_ADAPTOR_ERROR_NONE; +} + +int dp_interface_add_http_header_field(const int id, const char *field, + const char *value) +{ + int errorcode = DP_ERROR_NONE; + + DP_PRE_CHECK_ID; + + if (field == NULL || value == NULL) { + TRACE_ERROR("[CHECK field or value]"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + // send commnad with ID + if (__ipc_send_command + (g_interface_info->cmd_socket, id, DP_CMD_SET_HTTP_HEADER) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + if (__ipc_send_string(g_interface_info->cmd_socket, field) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + if (__ipc_send_string(g_interface_info->cmd_socket, value) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + // return from provider. + errorcode = __ipc_return(g_interface_info->cmd_socket); + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) { + TRACE_ERROR("[CHECK IO] (%d)", id); + __disconnect_from_provider(); + } + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_get_http_header_field(const int id, const char *field, + char **value) +{ + int errorcode = DP_ERROR_NONE; + char *str = NULL; + + DP_PRE_CHECK_ID; + + if (field == NULL || value == NULL) { + TRACE_ERROR("[CHECK field or value]"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + if (__ipc_send_command + (g_interface_info->cmd_socket, id, DP_CMD_GET_HTTP_HEADER) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + if (__ipc_send_string(g_interface_info->cmd_socket, field) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + + errorcode = __ipc_return(g_interface_info->cmd_socket); + if (errorcode == DP_ERROR_NONE) { + // getting string with ID from provider. + str = __ipc_read_string(g_interface_info->cmd_socket); + if (str != NULL) { + *value = str; + TRACE_INFO("ID : %d field:%s value: %s", id, field, *value); + } else { + errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR || str == NULL) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_remove_http_header_field(const int id, + const char *field) +{ + int errorcode = DP_ERROR_NONE; + + DP_PRE_CHECK_ID; + + if (field == NULL) { + TRACE_ERROR("[CHECK field]"); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + // send commnad with ID + if (__ipc_send_command + (g_interface_info->cmd_socket, id, DP_CMD_DEL_HTTP_HEADER) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + if (__ipc_send_string(g_interface_info->cmd_socket, field) + != DP_ERROR_NONE) { + pthread_mutex_unlock((&g_interface_info->mutex)); + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR; + } + // return from provider. + errorcode = __ipc_return(g_interface_info->cmd_socket); + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) { + TRACE_ERROR("[CHECK IO] (%d)", id); + __disconnect_from_provider(); + } + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_set_state_changed_cb(const int id, + dp_interface_state_changed_cb callback, void *user_data) +{ + int errorcode = DP_ERROR_NONE; + int index = -1; + + if (callback == NULL) { + dp_interface_unset_state_changed_cb(id); + return DOWNLOAD_ADAPTOR_ERROR_NONE; + } + + errorcode = + __dp_interface_set_int(id, DP_CMD_SET_STATE_CALLBACK, 1); + if (errorcode == DOWNLOAD_ADAPTOR_ERROR_NONE) { + pthread_mutex_lock(&g_function_mutex); + // search same info in array. + index = __get_my_slot_index(id); + if (index < 0) { + index = __get_empty_slot_index(); + if (index >= 0) { + g_interface_slots[index].id = id; + } else { + TRACE_ERROR("[ERROR] TOO_MANY_DOWNLOADS [%d]", + MAX_DOWNLOAD_HANDLE); + errorcode = DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_DOWNLOADS; + } + } + if (index >= 0) { + g_interface_slots[index].callback.state = callback; + g_interface_slots[index].callback.state_data = user_data; + } + pthread_mutex_unlock(&g_function_mutex); + } + return errorcode; +} + +int dp_interface_unset_state_changed_cb(const int id) +{ + int errorcode = DP_ERROR_NONE; + int index = -1; + + errorcode = + __dp_interface_set_int(id, DP_CMD_SET_STATE_CALLBACK, 0); + // clear by force although failed to clear in provider + pthread_mutex_lock(&g_function_mutex); + if ((index = __get_my_slot_index(id)) >= 0) { + g_interface_slots[index].callback.state = NULL; + g_interface_slots[index].callback.state_data = NULL; + } + pthread_mutex_unlock(&g_function_mutex); + return errorcode; +} + +int dp_interface_set_progress_cb(const int id, + dp_interface_progress_cb callback, void *user_data) +{ + int errorcode = DP_ERROR_NONE; + int index = -1; + + if (callback == NULL) { + dp_interface_unset_progress_cb(id); + return DOWNLOAD_ADAPTOR_ERROR_NONE; + } + + errorcode = + __dp_interface_set_int(id, DP_CMD_SET_PROGRESS_CALLBACK, 1); + if (errorcode == DOWNLOAD_ADAPTOR_ERROR_NONE) { + pthread_mutex_lock(&g_function_mutex); + // search same info in array. + index = __get_my_slot_index(id); + if (index < 0) { + index = __get_empty_slot_index(); + if (index >= 0) { + g_interface_slots[index].id = id; + } else { + TRACE_ERROR("[ERROR] TOO_MANY_DOWNLOADS [%d]", + MAX_DOWNLOAD_HANDLE); + errorcode = DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_DOWNLOADS; + } + } + if (index >= 0) { + g_interface_slots[index].callback.progress = callback; + g_interface_slots[index].callback.progress_data = user_data; + } + pthread_mutex_unlock(&g_function_mutex); + } + return errorcode; +} + +int dp_interface_unset_progress_cb(const int id) +{ + int errorcode = DP_ERROR_NONE; + int index = -1; + + errorcode = + __dp_interface_set_int(id, DP_CMD_SET_PROGRESS_CALLBACK, 0); + // clear by force although failed to clear in provider + pthread_mutex_lock(&g_function_mutex); + if ((index = __get_my_slot_index(id)) >= 0) { + g_interface_slots[index].callback.progress = NULL; + g_interface_slots[index].callback.progress_data = NULL; + } + pthread_mutex_unlock(&g_function_mutex); + return errorcode; +} + +int dp_interface_get_state(const int id, int *state) +{ + TRACE_INFO(""); + int statecode = DOWNLOAD_ADPATOR_STATE_NONE; + int ret = __dp_interface_get_int(id, DP_CMD_GET_STATE, &statecode); + if (ret == DOWNLOAD_ADAPTOR_ERROR_NONE) + *state = __dp_interface_convert_state(statecode); + return ret; +} + +int dp_interface_get_temp_path(const int id, char **temp_path) +{ + TRACE_INFO(""); + return __dp_interface_get_string + (id, DP_CMD_GET_TEMP_SAVED_PATH, temp_path); +} + +int dp_interface_get_content_name(const int id, char **content_name) +{ + TRACE_INFO(""); + return __dp_interface_get_string + (id, DP_CMD_GET_CONTENT_NAME, content_name); +} + +int dp_interface_get_content_size(const int id, + unsigned long long *content_size) +{ + int errorcode = DP_ERROR_NONE; + + DP_PRE_CHECK_ID; + + pthread_mutex_lock(&g_function_mutex); + + DP_CHECK_CONNECTION; + + pthread_mutex_lock((&g_interface_info->mutex)); + + DP_CHECK_PROVIDER_STATUS; + + errorcode = + __ipc_send_command_return(id, DP_CMD_GET_TOTAL_FILE_SIZE); + if (errorcode == DP_ERROR_NONE) { + // getting content_size from provider. + if (__ipc_read_custom_type(g_interface_info->cmd_socket, + content_size, sizeof(unsigned long long)) < 0) { + errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR); + } else { + TRACE_INFO("ID : %d content_size %lld", id, *content_size); + } + } + pthread_mutex_unlock((&g_interface_info->mutex)); + if (errorcode == DP_ERROR_IO_ERROR) + __disconnect_from_provider(); + pthread_mutex_unlock(&g_function_mutex); + return __dp_interface_convert_errorcode(errorcode); +} + +int dp_interface_get_mime_type(const int id, char **mime_type) +{ + TRACE_INFO(""); + return __dp_interface_get_string + (id, DP_CMD_GET_MIME_TYPE, mime_type); +} + +int dp_interface_set_auto_download(const int id, int enable) +{ + TRACE_INFO(""); + return __dp_interface_set_int(id, DP_CMD_SET_AUTO_DOWNLOAD, enable); +} + +int dp_interface_get_auto_download(const int id, int *enable) +{ + TRACE_INFO(""); + return __dp_interface_get_int(id, DP_CMD_GET_AUTO_DOWNLOAD, enable); +} + +int dp_interface_get_error(const int id, int *error) +{ + TRACE_INFO(""); + int errorcode = DP_ERROR_NONE; + int ret = __dp_interface_get_int(id, DP_CMD_GET_ERROR, &errorcode); + if (ret == DOWNLOAD_ADAPTOR_ERROR_NONE) + *error = __dp_interface_convert_errorcode(errorcode); + return ret; +} + +int dp_interface_get_http_status(const int id, int *http_status) +{ + TRACE_INFO(""); + return __dp_interface_get_int + (id, DP_CMD_GET_HTTP_STATUS, http_status); +} + +int dp_interface_add_noti_extra(const int id, const char *key, + const char **values, const unsigned length) +{ + int i = 0; + + TRACE_INFO(""); + + if (key == NULL || values == NULL) { + TRACE_ERROR("[CHECK key/values] (%d)", id); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + if (length <= 0) { + TRACE_ERROR("[CHECK legnth] (%d)", id); + return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER; + } + + char *strings[length + 1]; + strings[0] = (char *)key; + for (i = 0; i < length; i++) { + strings[i + 1] = (char *)values[i]; + } + return __dp_interface_set_strings(id, DP_CMD_ADD_EXTRA_PARAM, + (const char **)strings, length + 1); +} + +int dp_interface_get_noti_extra_values(const int id, const char *key, + char ***values, unsigned *length) +{ + TRACE_INFO(""); + return __dp_interface_get_strings(id, DP_CMD_GET_EXTRA_PARAM, + &key, 1, values, length); +} + +int dp_interface_remove_noti_extra_key(const int id, const char *key) +{ + TRACE_INFO(""); + return __dp_interface_set_string + (id, DP_CMD_REMOVE_EXTRA_PARAM, key); +} diff --git a/provider-interface/download-provider-interface.pc.in b/provider-interface/download-provider-interface.pc.in new file mode 100644 index 0000000..35e1cc9 --- /dev/null +++ b/provider-interface/download-provider-interface.pc.in @@ -0,0 +1,8 @@ +# Package Information + +Name: @PROJECT_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L/usr/lib -l@PROJECT_NAME@ +Cflags: -I/usr/include/@PKG_NAME@ diff --git a/provider-interface/include/download-provider-interface.h b/provider-interface/include/download-provider-interface.h new file mode 100755 index 0000000..9800dee --- /dev/null +++ b/provider-interface/include/download-provider-interface.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013 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_PROVIDER_INTERFACE_H__ +#define __DOWNLOAD_PROVIDER_INTERFACE_H__ + +#ifndef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +// sync with url-download +typedef enum +{ + DOWNLOAD_ADPATOR_STATE_NONE, + DOWNLOAD_ADPATOR_STATE_READY, + DOWNLOAD_ADPATOR_STATE_QUEUED, + DOWNLOAD_ADPATOR_STATE_DOWNLOADING, + DOWNLOAD_ADPATOR_STATE_PAUSED, + DOWNLOAD_ADPATOR_STATE_COMPLETED, + DOWNLOAD_ADPATOR_STATE_FAILED, + DOWNLOAD_ADPATOR_STATE_CANCELED, +} download_adaptor_state_e; + +typedef enum +{ + DOWNLOAD_ADAPTOR_NETWORK_DATA_NETWORK, + DOWNLOAD_ADAPTOR_NETWORK_WIFI, + DOWNLOAD_ADAPTOR_NETWORK_WIFI_DIRECT, + DOWNLOAD_ADAPTOR_NETWORK_ALL +} download_adaptor_network_type_e ; + +typedef enum +{ + DOWNLOAD_ADAPTOR_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + DOWNLOAD_ADAPTOR_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + DOWNLOAD_ADAPTOR_ERROR_NETWORK_UNREACHABLE = TIZEN_ERROR_NETWORK_UNREACHABLE, /**< Network is unreachable */ + DOWNLOAD_ADAPTOR_ERROR_CONNECTION_TIMED_OUT = TIZEN_ERROR_CONNECTION_TIME_OUT, /**< Http session time-out */ + DOWNLOAD_ADAPTOR_ERROR_NO_SPACE = TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE, /**< No space left on device */ + DOWNLOAD_ADAPTOR_ERROR_FIELD_NOT_FOUND = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Specified field not found */ + DOWNLOAD_ADAPTOR_ERROR_INVALID_STATE = TIZEN_ERROR_WEB_CLASS | 0x21, /**< Invalid state */ + DOWNLOAD_ADAPTOR_ERROR_CONNECTION_FAILED = TIZEN_ERROR_WEB_CLASS | 0x22, /**< Connection failed */ + DOWNLOAD_ADAPTOR_ERROR_INVALID_URL = TIZEN_ERROR_WEB_CLASS | 0x24, /**< Invalid URL */ + DOWNLOAD_ADAPTOR_ERROR_INVALID_DESTINATION = TIZEN_ERROR_WEB_CLASS | 0x25, /**< Invalid destination */ + DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_DOWNLOADS = TIZEN_ERROR_WEB_CLASS | 0x26, /**< Full of available simultaneous downloads */ + DOWNLOAD_ADAPTOR_ERROR_QUEUE_FULL = TIZEN_ERROR_WEB_CLASS | 0x27, /**< Full of available downloading items from server*/ + DOWNLOAD_ADAPTOR_ERROR_ALREADY_COMPLETED = TIZEN_ERROR_WEB_CLASS | 0x28, /**< The download is already completed */ + DOWNLOAD_ADAPTOR_ERROR_FILE_ALREADY_EXISTS = TIZEN_ERROR_WEB_CLASS | 0x29, /**< It is failed to rename the downloaded file */ + DOWNLOAD_ADAPTOR_ERROR_CANNOT_RESUME = TIZEN_ERROR_WEB_CLASS | 0x2a, /**< It cannot resume */ + DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_REDIRECTS = TIZEN_ERROR_WEB_CLASS | 0x30, /**< In case of too may redirects from http response header*/ + DOWNLOAD_ADAPTOR_ERROR_UNHANDLED_HTTP_CODE = TIZEN_ERROR_WEB_CLASS | 0x31, /**< The download cannot handle the http status value */ + DOWNLOAD_ADAPTOR_ERROR_REQUEST_TIMEOUT = TIZEN_ERROR_WEB_CLASS | 0x32, /**< There are no action after client create a download id*/ + DOWNLOAD_ADAPTOR_ERROR_RESPONSE_TIMEOUT = TIZEN_ERROR_WEB_CLASS | 0x33, /**< It does not call start API in some time although the download is created*/ + DOWNLOAD_ADAPTOR_ERROR_SYSTEM_DOWN = TIZEN_ERROR_WEB_CLASS | 0x34, /**< There are no response from client after rebooting download daemon*/ + DOWNLOAD_ADAPTOR_ERROR_ID_NOT_FOUND = TIZEN_ERROR_WEB_CLASS | 0x35, /**< The download id is not existed in download service module*/ + DOWNLOAD_ADAPTOR_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No data because the set API is not called */ + DOWNLOAD_ADAPTOR_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR , /**< Internal I/O error */ +} download_adaptor_error_e; +// sync with url-download + + +// sync types with url-download.. +typedef void (*dp_interface_state_changed_cb) (int id, int state, void *user_data); +typedef void (*dp_interface_progress_cb) (int id, unsigned long long received, void *user_data); + +EXPORT_API int dp_interface_set_state_changed_cb + (const int id, dp_interface_state_changed_cb callback, void *user_data); +EXPORT_API int dp_interface_unset_state_changed_cb(int id); +EXPORT_API int dp_interface_set_progress_cb + (const int id, dp_interface_progress_cb callback, void *user_data); +EXPORT_API int dp_interface_unset_progress_cb(const int id); + +EXPORT_API int dp_interface_create(int *id); +EXPORT_API int dp_interface_destroy(const int id); + +EXPORT_API int dp_interface_start(const int id); +EXPORT_API int dp_interface_pause(const int id); +EXPORT_API int dp_interface_cancel(const int id); + +EXPORT_API int dp_interface_set_url(const int id, const char *url); +EXPORT_API int dp_interface_get_url(const int id, char **url); +EXPORT_API int dp_interface_set_network_type(const int id, int net_type); +EXPORT_API int dp_interface_get_network_type(const int id, int *net_type); +EXPORT_API int dp_interface_set_destination(const int id, const char *path); +EXPORT_API int dp_interface_get_destination(const int id, char **path); +EXPORT_API int dp_interface_set_file_name(const int id, const char *file_name); +EXPORT_API int dp_interface_get_file_name(const int id, char **file_name); +EXPORT_API int dp_interface_set_notification(const int id, int enable); +EXPORT_API int dp_interface_get_notification(const int id, int *enable); +EXPORT_API int dp_interface_set_notification_extra_param(const int id, char *key, char *value); +EXPORT_API int dp_interface_get_notification_extra_param(const int id, char **key, char **value); +EXPORT_API int dp_interface_get_downloaded_file_path(const int id, char **path); +EXPORT_API int dp_interface_get_mime_type(const int id, char **mime_type); +EXPORT_API int dp_interface_set_auto_download(const int id, int enable); +EXPORT_API int dp_interface_get_auto_download(const int id, int *enable); +EXPORT_API int dp_interface_add_http_header_field(const int id, const char *field, const char *value); +EXPORT_API int dp_interface_get_http_header_field(const int id, const char *field, char **value); +EXPORT_API int dp_interface_remove_http_header_field(const int id, const char *field); +EXPORT_API int dp_interface_get_state(const int id, int *state); +EXPORT_API int dp_interface_get_temp_path(const int id, char **temp_path); +EXPORT_API int dp_interface_get_content_name(const int id, char **content_name); +EXPORT_API int dp_interface_get_content_size(const int id, unsigned long long *content_size); +EXPORT_API int dp_interface_get_error(const int id, int *error); +EXPORT_API int dp_interface_get_http_status(const int id, int *http_status); + +// Notification Extra Param +// N values per a key +EXPORT_API int dp_interface_add_noti_extra(const int id, const char *key, const char **values, const unsigned length); +EXPORT_API int dp_interface_get_noti_extra_values(const int id, const char *key, char ***values, unsigned *length); +EXPORT_API int dp_interface_remove_noti_extra_key(const int id, const char *key); + +#ifdef __cplusplus +} +#endif + +#endif /* __DOWNLOAD_PROVIDER_INTERFACE_H__ */ diff --git a/src/CMakeLists.txt b/provider/CMakeLists.txt similarity index 67% rename from src/CMakeLists.txt rename to provider/CMakeLists.txt index 66ca5cb..e65f638 100755 --- a/src/CMakeLists.txt +++ b/provider/CMakeLists.txt @@ -1,16 +1,12 @@ ## PROJECT NAME -PROJECT(download-provider C) -SET(VERSION "0.0.1") +PROJECT(${PKG_NAME} C) IF("${CMAKE_BUILD_TYPE}" STREQUAL "") SET(CMAKE_BUILD_TYPE "Debug") ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") -SET(DATABASE_FILE "/opt/usr/dbspace/.download-provider.db") -SET(IMAGE_DIR "/usr/share/download-provider") - INCLUDE(FindPkgConfig) pkg_check_modules(dp2_pkgs REQUIRED glib-2.0 @@ -30,7 +26,7 @@ FOREACH(flag ${dp2_pkgs_CFLAGS}) ENDFOREACH(flag) ## INCLUDES -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src/agent/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/agent/include) set(DP2_LINK_LIBRARIES ${GLIB-2_LIBRARIES} ${GOBJECT-2_LIBRARIES} @@ -39,17 +35,16 @@ set(DP2_LINK_LIBRARIES ${GLIB-2_LIBRARIES} downloadagent2 ) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -D_REENTRANT") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g -fpie -Wall") - -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed -Wl,-pie,--hash-style=both") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -Wall") -ADD_DEFINITIONS( - -DDATABASE_FILE=\"${DATABASE_FILE}\" - -DIMAGE_DIR=\"${IMAGE_DIR}\" - ) +IF(DEFINED DATABASE_FILE) + ADD_DEFINITIONS(-DDATABASE_FILE=\"${DATABASE_FILE}\") +ENDIF(DEFINED DATABASE_FILE) -ADD_DEFINITIONS(-DDP_SUPPORT_DBUS_ACTIVATION) +IF(DEFINED IMAGE_DIR) + ADD_DEFINITIONS(-DIMAGE_DIR=\"${IMAGE_DIR}\") +ENDIF(DEFINED IMAGE_DIR) ADD_EXECUTABLE(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-pid.c @@ -64,6 +59,7 @@ ADD_EXECUTABLE(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-notification.c ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-main.c ) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${dp2_pkgs_LDFLAGS} ${DP2_LINK_LIBRARIES}) -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BIN_INSTALL_DIR}) -INSTALL(FILES include/download-provider.h DESTINATION include/download-provider/) +INSTALL(FILES include/download-provider.h DESTINATION ${INCLUDE_INSTALL_DIR}/${PKG_NAME}) +INSTALL(FILES include/download-provider-defs.h DESTINATION ${INCLUDE_INSTALL_DIR}/${PKG_NAME}) diff --git a/src/download-provider-da-interface.c b/provider/download-provider-da-interface.c similarity index 99% rename from src/download-provider-da-interface.c rename to provider/download-provider-da-interface.c index 2d875c3..14e77d3 100755 --- a/src/download-provider-da-interface.c +++ b/provider/download-provider-da-interface.c @@ -95,6 +95,7 @@ static int __change_error(int err) case DA_ERR_FAIL_TO_ACCESS_FILE: case DA_ERR_FAIL_TO_GET_CONF_VALUE: case DA_ERR_FAIL_TO_ACCESS_STORAGE: + default: ret = DP_ERROR_IO_ERROR; break; } diff --git a/src/download-provider-db.c b/provider/download-provider-db.c similarity index 78% rename from src/download-provider-db.c rename to provider/download-provider-db.c index 0c9d5b6..476f725 100755 --- a/src/download-provider-db.c +++ b/provider/download-provider-db.c @@ -1317,3 +1317,362 @@ int dp_db_get_http_headers_list(int id, char **headers) __dp_finalize(stmt); return headers_index; } + +static char *__merge_strings(char *dest, const char *src, char sep) +{ + int dest_length = 0; + int src_length = 0; + + if (dest == NULL || src == NULL) + return NULL; + + dest_length = strlen(dest); + src_length = strlen(src); + + dest = sqlite3_realloc(dest, dest_length + src_length + 1); + dest = strncat(dest, &sep, 1); + dest = strncat(dest, src, src_length); + return dest; +} + +static char *__get_conds_query(int count, db_conds_list_fmt *conds, char *op) +{ + char *conditions = NULL; + int i = 0; + + if (count > 0 && conds != NULL) { + conditions = sqlite3_mprintf("WHERE"); + for (i = 0; i < count; i++) { + char *token = + sqlite3_mprintf("%s %s ?", conds[i].column, + (conds[i].is_like == 1 ? "LIKE" : "=")); + if (token != NULL) { + conditions = __merge_strings(conditions, token, ' '); + sqlite3_free(token); + token = NULL; + } + if (i < count - 1 && op) + conditions = __merge_strings(conditions, op, ' '); + } + } + return conditions; +} + +static int __bind_value(sqlite3_stmt *stmt, + db_column_data_type condtype, void *value, int index) +{ + int errorcode = SQLITE_ERROR; + int *cast_value = 0; + + if (stmt == NULL) + return SQLITE_ERROR; + + switch (condtype) { + case DP_DB_COL_TYPE_INT: + cast_value = value; + errorcode = sqlite3_bind_int(stmt, index, *cast_value); + TRACE_INFO("INT %d", *cast_value); + break; + case DP_DB_COL_TYPE_INT64: +#ifdef SQLITE_INT64_TYPE + sqlite3_int64 *cast_value = value; + errorcode = sqlite3_bind_int64(stmt, index, *cast_value); + TRACE_INFO("INT %ld", *cast_value); +#else + cast_value = value; + errorcode = sqlite3_bind_int(stmt, index, *cast_value); + TRACE_INFO("INT %d", *cast_value); +#endif + break; + case DP_DB_COL_TYPE_TEXT: + errorcode = + sqlite3_bind_text(stmt, index, (char *)value, -1, SQLITE_STATIC); + TRACE_INFO("TEXT %s", value); + break; + default: + errorcode = SQLITE_ERROR; + break; + } + return errorcode; +} + +int dp_db_insert_columns(char *table, int column_count, + db_conds_list_fmt *columns) +{ + int errorcode = SQLITE_OK; + int ret = -1; + sqlite3_stmt *stmt = NULL; + char *query = NULL; + int i = 0; + + if (table == NULL) { + TRACE_ERROR("[CHECK TABLE NAME]"); + return -1; + } + if (column_count <= 0) { + TRACE_ERROR("[CHECK db_conds_list_fmt count]"); + return -1; + } + if (__dp_sql_open() < 0) { + TRACE_ERROR("[SQL HANDLE] [%s]", sqlite3_errmsg(g_dp_db_handle)); + return -1; + } + + query = + sqlite3_mprintf("INSERT INTO %s ", table); + query = __merge_strings(query, columns[0].column, '('); + for (i = 1; i < column_count; i++) { + char *column_query = NULL; + column_query = sqlite3_mprintf(", %s", columns[i].column); + query = __merge_strings(query, column_query, ' '); + sqlite3_free(column_query); + } + query = __merge_strings(query, " VALUES ", ')'); + query = __merge_strings(query, "?", '('); + for (i = 1; i < column_count; i++) { + query = __merge_strings(query, ", ?", ' '); + } + query = __merge_strings(query, ")", ' '); + if (query == NULL) { + TRACE_ERROR("[CHECK COMBINE]"); + return -1; + } + + TRACE_INFO("[QUERY] %s", query); + + ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &stmt, NULL); + sqlite3_free(query); + if ( ret != SQLITE_OK) { + TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle)); + __dp_finalize(stmt); + return -1; + } + + for (i = 0; i < column_count; i++) { + if (__bind_value + (stmt, columns[i].type, columns[i].value, (i + 1)) != + SQLITE_OK) { + TRACE_ERROR("[BIND][%d][%s]", columns[i].type, + sqlite3_errmsg(g_dp_db_handle)); + __dp_finalize(stmt); + return -1; + } + } + + errorcode = sqlite3_step(stmt); + if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) { + __dp_finalize(stmt); + return 0; + } + __dp_finalize(stmt); + return -1; +} + +int dp_db_get_conds_rows_count(char *table, + char *getcolumn, char *op, + int conds_count, db_conds_list_fmt *conds) +{ + int errorcode = SQLITE_OK; + int ret = -1; + sqlite3_stmt *stmt = NULL; + char *query = NULL; + int i = 0; + + if (table == NULL) { + TRACE_ERROR("[CHECK TABLE NAME]"); + return -1; + } + if (getcolumn == NULL) { + TRACE_ERROR("[CHECK RESULT COLUMN]"); + return -1; + } + if (op == NULL) { + TRACE_ERROR("[CHECK OPERATOR] AND or OR"); + return -1; + } + if (conds_count <= 0) { + TRACE_ERROR("[CHECK db_conds_list_fmt count]"); + return -1; + } + if (__dp_sql_open() < 0) { + TRACE_ERROR("[SQL HANDLE] [%s]", sqlite3_errmsg(g_dp_db_handle)); + return -1; + } + + query = + sqlite3_mprintf("SELECT count(%s) FROM %s", getcolumn, table); + + char *conditions = __get_conds_query(conds_count, conds, op); + if (conditions != NULL) { + query = __merge_strings(query, conditions, ' '); + sqlite3_free(conditions); + } + + if (query == NULL) { + TRACE_ERROR("[CHECK COMBINE]"); + return -1; + } + + TRACE_INFO("[QUERY] %s", query); + + ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &stmt, NULL); + sqlite3_free(query); + if (ret != SQLITE_OK) { + TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle)); + __dp_finalize(stmt); + return -1; + } + for (i = 0; i < conds_count; i++) { + if (__bind_value + (stmt, conds[i].type, conds[i].value, (i + 1)) != + SQLITE_OK) { + TRACE_ERROR("[BIND][%d][%s]", conds[i].type, + sqlite3_errmsg(g_dp_db_handle)); + __dp_finalize(stmt); + return -1; + } + } + errorcode = sqlite3_step(stmt); + if (errorcode == SQLITE_ROW) { + int count = sqlite3_column_int(stmt, 0); + __dp_finalize(stmt); + return count; + } + __dp_finalize(stmt); + return 0; +} + +int dp_db_get_conds_list(char *table, char *getcolumn, + db_column_data_type gettype, void **list, + int rowslimit, int rowsoffset, + char *ordercolumn, char *ordering, + char *op, int conds_count, + db_conds_list_fmt *conds) +{ + int errorcode = SQLITE_OK; + int rows_count = 0; + sqlite3_stmt *stmt = NULL; + int i = 0; + + if (table == NULL) { + TRACE_ERROR("[CHECK TABLE NAME]"); + return -1; + } + if (op == NULL) { + TRACE_ERROR("[CHECK OPERATOR] AND or OR"); + return -1; + } + if (getcolumn == NULL) { + TRACE_ERROR("[CHECK COLUMN NAME]"); + return -1; + } + if (conds_count <= 0) { + TRACE_ERROR("[CHECK db_conds_list_fmt count]"); + return -1; + } + if (__dp_sql_open() < 0) { + TRACE_ERROR("[SQL HANDLE] [%s]", sqlite3_errmsg(g_dp_db_handle)); + return -1; + } + + char *limit = NULL; + char *order = NULL; + char *query = sqlite3_mprintf("SELECT %s FROM %s", getcolumn, table); + char *conditions = __get_conds_query(conds_count, conds, op); + if (conditions != NULL) { + query = __merge_strings(query, conditions, ' '); + sqlite3_free(conditions); + } + + if (ordercolumn != NULL) { + order = + sqlite3_mprintf + ("ORDER BY %s %s", ordercolumn, + (ordering == NULL ? "ASC" : ordering)); + if (order != NULL) { + query = __merge_strings(query, order, ' '); + sqlite3_free(order); + } + } + if (rowslimit > 0) { // 0 or negative : no limitation + if (rowsoffset >= 0) + limit = + sqlite3_mprintf("LIMIT %d OFFSET %d", rowslimit, + rowsoffset); + else + limit = sqlite3_mprintf("LIMIT %d", rowslimit); + if (limit != NULL) { + query = __merge_strings(query, limit, ' '); + sqlite3_free(limit); + } + } + + if (query == NULL) { + TRACE_ERROR("[CHECK COMBINE]"); + return -1; + } + TRACE_INFO("[QUERY] %s", query); + + errorcode = + sqlite3_prepare_v2(g_dp_db_handle, query, -1, &stmt, NULL); + sqlite3_free(query); + if (errorcode != SQLITE_OK) { + TRACE_ERROR("sqlite3_prepare_v2 is failed. [%s]", + sqlite3_errmsg(g_dp_db_handle)); + __dp_finalize(stmt); + return -1; + } + for (i = 0; i < conds_count; i++) { + if (__bind_value + (stmt, conds[i].type, conds[i].value, (i + 1)) != + SQLITE_OK) { + TRACE_ERROR + ("[BIND][%d][%s]", conds[i].type, + sqlite3_errmsg(g_dp_db_handle)); + __dp_finalize(stmt); + return -1; + } + } + while ((errorcode = sqlite3_step(stmt)) == SQLITE_ROW) { + switch (gettype) { + case DP_DB_COL_TYPE_INT: + { + int **list_int_p = (int **)list; + *list_int_p[rows_count++] = sqlite3_column_int(stmt, 0); + break; + } + case DP_DB_COL_TYPE_INT64: + { +#ifdef SQLITE_INT64_TYPE + long long **list_long_p = (long long **)list; + *list_long_p[rows_count++] = sqlite3_column_int64(stmt, 0); +#else + int **list_int_p = (int **)list; + *list_int_p[rows_count++] = sqlite3_column_int(stmt, 0); +#endif + break; + } + case DP_DB_COL_TYPE_TEXT: + { + int getbytes = sqlite3_column_bytes(stmt, 0); + if (getbytes > 0) { + char *getstr = (char *)calloc((getbytes + 1), sizeof(char)); + if (getstr != NULL) { + memcpy(getstr, sqlite3_column_text(stmt, 0), + getbytes * sizeof(char)); + getstr[getbytes] = '\0'; + list[rows_count++] = getstr; + } + } + break; + } + default: + break; + } + if (rows_count >= rowslimit) + break; + } + __dp_finalize(stmt); + return rows_count; +} + diff --git a/src/download-provider-main.c b/provider/download-provider-main.c similarity index 98% rename from src/download-provider-main.c rename to provider/download-provider-main.c index 79968ba..96495ec 100755 --- a/src/download-provider-main.c +++ b/provider/download-provider-main.c @@ -144,6 +144,10 @@ int main(int argc, char **argv) TRACE_ERROR("failed to register signal callback"); exit(EXIT_FAILURE); } + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + TRACE_ERROR("failed to register signal callback"); + exit(EXIT_FAILURE); + } // write IPC_FD_PATH. and lock if ((lock_fd = dp_lock_pid(DP_LOCK_PID)) < 0) { TRACE_ERROR diff --git a/src/download-provider-network.c b/provider/download-provider-network.c similarity index 100% rename from src/download-provider-network.c rename to provider/download-provider-network.c diff --git a/src/download-provider-notification.c b/provider/download-provider-notification.c similarity index 62% rename from src/download-provider-notification.c rename to provider/download-provider-notification.c index f04b010..6b7a167 100755 --- a/src/download-provider-notification.c +++ b/provider/download-provider-notification.c @@ -31,55 +31,27 @@ #define S_(s) dgettext("sys_string", s) #define DP_NOTIFICATION_ICON_PATH IMAGE_DIR"/Q02_Notification_Download_failed.png" -/* This should be same value of SERVICE_OPERATION_DOWNLOAD_NOTIFICATION from download.h */ -#define DP_DOWNLOAD_NOTI_OPERATION "http://tizen.org/appcontrol/operation/download_notification" -static void __print_app_error_message(int ret) +static const char *__noti_error_str( + notification_error_e err) { - switch (ret) { - case APPSVC_RET_OK: - TRACE_INFO("APPSVC_RET_OK"); - break; - case APPSVC_RET_ELAUNCH: - TRACE_ERROR("APPSVC_RET_ELAUNCH"); - break; - case APPSVC_RET_ENOMATCH: - TRACE_ERROR("APPSVC_RET_ENOMATCH"); - break; - case APPSVC_RET_EINVAL: - TRACE_ERROR("APPSVC_RET_EINVAL"); - break; - case APPSVC_RET_ERROR: - TRACE_ERROR("APPSVC_RET_ERROR"); - break; - } -} - -static void __print_notification_error_message(int ret) -{ - switch (ret) { + switch (err) { case NOTIFICATION_ERROR_INVALID_DATA: - TRACE_ERROR("NOTIFICATION_ERROR_INVALID_DATA"); - break; + return "NOTIFICATION_ERROR_INVALID_DATA"; case NOTIFICATION_ERROR_NO_MEMORY: - TRACE_ERROR("NOTIFICATION_ERROR_NO_MEMORY"); - break; + return "NOTIFICATION_ERROR_NO_MEMORY"; case NOTIFICATION_ERROR_FROM_DB: - TRACE_ERROR("NOTIFICATION_ERROR_FROM_DB"); - break; + return "NOTIFICATION_ERROR_FROM_DB"; case NOTIFICATION_ERROR_ALREADY_EXIST_ID: - TRACE_ERROR("NOTIFICATION_ERROR_ALREADY_EXIST_ID"); - break; + return "NOTIFICATION_ERROR_ALREADY_EXIST_ID"; case NOTIFICATION_ERROR_FROM_DBUS: - TRACE_ERROR("NOTIFICATION_ERROR_FROM_DBUS"); - break; + return "NOTIFICATION_ERROR_FROM_DBUS"; case NOTIFICATION_ERROR_NOT_EXIST_ID: - TRACE_ERROR("NOTIFICATION_ERROR_NOT_EXIST_ID"); - break; + return "NOTIFICATION_ERROR_NOT_EXIST_ID"; default: - TRACE_ERROR("Unknown error"); break; } + return "Unknown error"; } static char *__get_string_status(dp_state_type state) @@ -103,6 +75,116 @@ static char *__get_string_status(dp_state_type state) } return message; } +static void __free_char_pointer_array(char **array, int count) +{ + int i = 0; + if (count < 0) + count = 0; + for (i = 0; i < count; i++) { + if (array[i]) + free(array[i]); + } + free(array); +} + +static int __set_extra_data(bundle *b, int id) +{ + db_conds_list_fmt conds_p; + int conds_count = 0; + int count = 0; + // get count of key list. + conds_count = 1; + memset(&conds_p, 0x00, sizeof(db_conds_list_fmt)); + conds_p.column = DP_DB_COL_ID; + conds_p.type = DP_DB_COL_TYPE_INT; + conds_p.value = &id; + count = dp_db_get_conds_rows_count(DP_DB_TABLE_NOTIFICATION, + DP_DB_COL_DISTINCT_EXTRA_KEY, "AND", 1, &conds_p); + if (count > 0) { + char **keys_array = NULL; + int i = 0; + keys_array = (char **)calloc(count, sizeof(char *)); + if (keys_array == NULL) { + TRACE_ERROR("[FAIL] calloc failed"); + return -1; + } + // get key list + int keys_count = + dp_db_get_conds_list(DP_DB_TABLE_NOTIFICATION, + DP_DB_COL_DISTINCT_EXTRA_KEY , DP_DB_COL_TYPE_TEXT, + (void **)keys_array, count, -1, NULL, NULL, + "AND", 1, &conds_p); + if (keys_count <= 0) { + TRACE_ERROR("[FAIL] Wrong db data"); + __free_char_pointer_array(keys_array, 0); + return -1; + } + for (i = 0; i < keys_count; i++) { + db_conds_list_fmt conds_p2[2]; + int conds_count2 = 2; + char **values_array = NULL; + int check_rows = 0; + int values_count = 0; + + memset(conds_p2, 0x00, conds_count2 * sizeof(db_conds_list_fmt)); + conds_p2[0].column = DP_DB_COL_ID; + conds_p2[0].type = DP_DB_COL_TYPE_INT; + conds_p2[0].value = &id; + conds_p2[1].column = DP_DB_COL_EXTRA_KEY; + conds_p2[1].type = DP_DB_COL_TYPE_TEXT; + conds_p2[1].value = (void *)(keys_array[i]); + // get value list + check_rows = dp_db_get_conds_rows_count( + DP_DB_TABLE_NOTIFICATION, DP_DB_COL_EXTRA_VALUE, "AND", + conds_count2, conds_p2); + if (check_rows <= 0) { + TRACE_ERROR("[FAIL] No values about key"); + __free_char_pointer_array(keys_array, keys_count); + return -1; + } + values_array = (char **)calloc(check_rows, sizeof(char *)); + if (values_array == NULL) { + TRACE_ERROR("[FAIL] calloc failed"); + __free_char_pointer_array(keys_array, keys_count); + return -1; + } + values_count = + dp_db_get_conds_list(DP_DB_TABLE_NOTIFICATION, + DP_DB_COL_EXTRA_VALUE, DP_DB_COL_TYPE_TEXT, + (void **)values_array, check_rows, -1, NULL, NULL, + "AND", conds_count2, conds_p2); + if (values_count <= 0) { + TRACE_ERROR("[FAIL] No values about key"); + __free_char_pointer_array(keys_array, keys_count); + __free_char_pointer_array(values_array, 0); + return -1; + } + if (values_count == 1) { + char *key = keys_array[i]; + char *value = values_array[values_count-1]; + if (appsvc_add_data(b, key, value) != + APPSVC_RET_OK) { + TRACE_ERROR("[FAIL] set add data"); + __free_char_pointer_array(keys_array, keys_count); + __free_char_pointer_array(values_array, values_count); + return -1; + } + } else { + char *key = keys_array[i]; + if (appsvc_add_data_array(b, key, (const char **)values_array, + values_count) != APPSVC_RET_OK) { + TRACE_ERROR("[FAIL] set add data"); + __free_char_pointer_array(keys_array, keys_count); + __free_char_pointer_array(values_array, values_count); + return -1; + } + } + __free_char_pointer_array(values_array, values_count); + } + __free_char_pointer_array(keys_array, keys_count); + } + return 0; +} int dp_set_downloadinginfo_notification(int id, char *packagename) { @@ -137,7 +219,7 @@ int dp_set_downloadinginfo_notification(int id, char *packagename) free(content_name); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set title [%d]", err); + TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -145,7 +227,7 @@ int dp_set_downloadinginfo_notification(int id, char *packagename) err = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON, DP_NOTIFICATION_ICON_PATH); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set icon [%d]", err); + TRACE_ERROR("[FAIL] set icon [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -165,41 +247,17 @@ int dp_set_downloadinginfo_notification(int id, char *packagename) return -1; } - if (appsvc_set_operation(b, DP_DOWNLOAD_NOTI_OPERATION) != - APPSVC_RET_OK) { - TRACE_ERROR("[FAIL] set noti operation"); + if (__set_extra_data(b, id) < 0) { bundle_free(b); notification_free(noti_handle); return -1; } - char *extra_key = - dp_db_get_text_column(id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_KEY); - char *extra_value = - dp_db_get_text_column(id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_VALUE); - - if (extra_key && extra_value) { - if (appsvc_add_data(b, extra_key, extra_value) != APPSVC_RET_OK) { - TRACE_ERROR("[FAIL] set add data"); - free(extra_key); - free(extra_value); - bundle_free(b); - notification_free(noti_handle); - return -1; - } - } - if (extra_key) - free(extra_key); - if (extra_value) - free(extra_value); - err = notification_set_execute_option(noti_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set execute option [%d]", err); + TRACE_ERROR("[FAIL] set execute option [%s]", __noti_error_str(err)); bundle_free(b); notification_free(noti_handle); return -1; @@ -209,14 +267,14 @@ int dp_set_downloadinginfo_notification(int id, char *packagename) err = notification_set_property(noti_handle, NOTIFICATION_PROP_DISABLE_TICKERNOTI); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set property [%d]", err); + TRACE_ERROR("[FAIL] set property [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } err = notification_insert(noti_handle, &privId); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set insert [%d]", err); + TRACE_ERROR("[FAIL] set insert [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -237,7 +295,8 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d err = notification_delete_by_priv_id(NULL, NOTIFICATION_TYPE_ONGOING, priv_id); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] delete notification handle, err", err); + TRACE_ERROR("[FAIL] delete notification handle [%s]", + __noti_error_str(err)); } } @@ -267,7 +326,7 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d free(content_name); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set title [%d]", err); + TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -277,7 +336,7 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d __get_string_status(state), NULL, NOTIFICATION_VARIABLE_TYPE_NONE); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set text [%d]", err); + TRACE_ERROR("[FAIL] set text [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -285,7 +344,7 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d err = notification_set_time(noti_handle, tt); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set time [%d]", err); + TRACE_ERROR("[FAIL] set time [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -320,36 +379,19 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d free(savedpath); err = notification_set_execute_option(noti_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b); - } else if (state == DP_STATE_CANCELED || state == DP_STATE_FAILED) { - if (appsvc_set_operation(b, DP_DOWNLOAD_NOTI_OPERATION) != - APPSVC_RET_OK) { - TRACE_ERROR("[FAIL] set noti operation [%d]", err); + if (err != NOTIFICATION_ERROR_NONE) { + TRACE_ERROR("[FAIL] set execute option[%s]", __noti_error_str(err)); bundle_free(b); notification_free(noti_handle); return -1; } - char *extra_key = - dp_db_get_text_column(id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_KEY); - char *extra_value = - dp_db_get_text_column(id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_VALUE); - if (extra_key && extra_value) { - if (appsvc_add_data(b, extra_key, extra_value) != - APPSVC_RET_OK) { - TRACE_ERROR("[FAIL] set add data"); - free(extra_key); - free(extra_value); - bundle_free(b); - notification_free(noti_handle); - return -1; - } + } else if (state == DP_STATE_CANCELED || state == DP_STATE_FAILED) { + if (__set_extra_data(b, id) < 0) { + bundle_free(b); + notification_free(noti_handle); + return -1; } - if (extra_key) - free(extra_key); - if (extra_value) - free(extra_value); if (packagename && appsvc_set_pkgname(b, packagename) != @@ -361,6 +403,12 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d } err = notification_set_execute_option(noti_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b); + if (err != NOTIFICATION_ERROR_NONE) { + TRACE_ERROR("[FAIL] set execute option[%s]", __noti_error_str(err)); + bundle_free(b); + notification_free(noti_handle); + return -1; + } } else { TRACE_ERROR("[CRITICAL] invalid state"); bundle_free(b); @@ -369,7 +417,7 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d } if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set time [%d]", err); + TRACE_ERROR("[FAIL] set time [%s]", __noti_error_str(err)); notification_free(noti_handle); bundle_free(b); return -1; @@ -380,7 +428,7 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d err = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON, DP_NOTIFICATION_ICON_PATH); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set icon [%d]", err); + TRACE_ERROR("[FAIL] set icon [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -388,14 +436,14 @@ int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, d err = notification_set_property(noti_handle, NOTIFICATION_PROP_DISABLE_TICKERNOTI); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set property [%d]", err); + TRACE_ERROR("[FAIL] set property [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } err = notification_insert(noti_handle, &privId); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] set insert [%d]", err); + TRACE_ERROR("[FAIL] set insert [%s]", __noti_error_str(err)); notification_free(noti_handle); return -1; } @@ -418,11 +466,13 @@ void dp_update_downloadinginfo_notification(int priv_id, double received_size, d progress = received_size / file_size; err = notification_update_progress(NULL, priv_id, progress); if (err != NOTIFICATION_ERROR_NONE) - TRACE_ERROR("[FAIL] update noti progress[%d]", err); + TRACE_ERROR("[FAIL] update noti progress[%s]", + __noti_error_str(err)); } else { err = notification_update_size(NULL, priv_id, received_size); if (err != NOTIFICATION_ERROR_NONE) - TRACE_ERROR("[FAIL] update noti progress[%d]", err); + TRACE_ERROR("[FAIL] update noti progress[%s]", + __noti_error_str(err)); } } @@ -431,7 +481,7 @@ void dp_clear_downloadinginfo_notification() notification_error_e err = NOTIFICATION_ERROR_NONE; err = notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_ONGOING); if (err != NOTIFICATION_ERROR_NONE) { - TRACE_ERROR("[FAIL] clear noti [%d]", err); + TRACE_ERROR("[FAIL] clear noti [%s]", __noti_error_str(err)); } return; } diff --git a/src/download-provider-pid.c b/provider/download-provider-pid.c similarity index 100% rename from src/download-provider-pid.c rename to provider/download-provider-pid.c diff --git a/src/download-provider-request.c b/provider/download-provider-request.c similarity index 99% rename from src/download-provider-request.c rename to provider/download-provider-request.c index 869a9e5..c9c70ad 100755 --- a/src/download-provider-request.c +++ b/provider/download-provider-request.c @@ -376,7 +376,7 @@ dp_error_type dp_request_set_notification(int id, dp_request *request, unsigned // update queue DB if (dp_db_replace_column - (id, DP_DB_TABLE_NOTIFICATION, + (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_NOTIFICATION_ENABLE, DP_DB_COL_TYPE_INT, &enable) < 0) { TRACE_ERROR("[CHECK SQL][%d]", id); diff --git a/src/download-provider-slots.c b/provider/download-provider-slots.c similarity index 92% rename from src/download-provider-slots.c rename to provider/download-provider-slots.c index 208f993..e2c4732 100755 --- a/src/download-provider-slots.c +++ b/provider/download-provider-slots.c @@ -108,20 +108,17 @@ int dp_request_free(dp_request *request) int dp_client_group_free(dp_client_group *group) { TRACE_INFO(""); - if (!group) - return -1; - - if (group->cmd_socket > 0) - dp_socket_free(group->cmd_socket); - group->cmd_socket = -1; - if (group->event_socket > 0) - dp_socket_free(group->event_socket); - group->event_socket = -1; - group->queued_count = 0; - if (group->pkgname) + if (group != NULL) { + if (group->cmd_socket > 0) + dp_socket_free(group->cmd_socket); + group->cmd_socket = -1; + if (group->event_socket > 0) + dp_socket_free(group->event_socket); + group->event_socket = -1; + group->queued_count = 0; free(group->pkgname); - free(group); - group = NULL; + free(group); + } return 0; } diff --git a/src/download-provider-socket.c b/provider/download-provider-socket.c similarity index 99% rename from src/download-provider-socket.c rename to provider/download-provider-socket.c index 0899ffe..b7728bc 100755 --- a/src/download-provider-socket.c +++ b/provider/download-provider-socket.c @@ -205,6 +205,7 @@ int dp_accept_socket_new() int dp_socket_free(int sockfd) { + TRACE_INFO("[%d]", sockfd); if (sockfd < 0) return -1; shutdown(sockfd, 0); diff --git a/src/download-provider-thread-queue.c b/provider/download-provider-thread-queue.c similarity index 100% rename from src/download-provider-thread-queue.c rename to provider/download-provider-thread-queue.c diff --git a/src/download-provider-thread-request.c b/provider/download-provider-thread-request.c similarity index 72% rename from src/download-provider-thread-request.c rename to provider/download-provider-thread-request.c index a4ae548..1ab5f24 100755 --- a/src/download-provider-thread-request.c +++ b/provider/download-provider-thread-request.c @@ -78,8 +78,6 @@ static char *__print_command(dp_command_type cmd) return "SET_NETWORK_TYPE"; case DP_CMD_SET_HTTP_HEADER : return "SET_HTTP_HEADER"; - case DP_CMD_SET_EXTRA_PARAM : - return "SET_EXTRA_PARAM"; case DP_CMD_DEL_HTTP_HEADER : return "DEL_HTTP_HEADER"; case DP_CMD_GET_HTTP_HEADER : @@ -98,8 +96,12 @@ static char *__print_command(dp_command_type cmd) return "GET_PROGRESS_CALLBACK"; case DP_CMD_GET_HTTP_HEADERS : return "GET_HTTP_HEADERS"; + case DP_CMD_ADD_EXTRA_PARAM : + return "ADD_EXTRA_PARAM"; case DP_CMD_GET_EXTRA_PARAM : return "GET_EXTRA_PARAM"; + case DP_CMD_REMOVE_EXTRA_PARAM : + return "REMOVE_EXTRA_PARAM"; case DP_CMD_GET_AUTO_DOWNLOAD : return "GET_AUTO_DOWNLOAD"; case DP_CMD_GET_NETWORK_TYPE : @@ -223,6 +225,437 @@ static void __send_return_custom_type(int fd, dp_error_type errcode, void *value dp_ipc_send_custom_type(fd, value, type_size); } +static void __clear_group(dp_privates *privates, dp_client_group *group) +{ + dp_request *request = NULL; + int i = 0; + + TRACE_INFO(""); + + for (i = 0; i < DP_MAX_REQUEST; i++) { + if (privates->requests[i].request == NULL) + continue; + if (privates->requests[i].request->group == NULL) + continue; + if (privates->requests[i].request->id <= 0) + continue; + + request = privates->requests[i].request; + + CLIENT_MUTEX_LOCK(&request->mutex); + + if (request->group != group || + request->group->cmd_socket != group->cmd_socket) { + CLIENT_MUTEX_UNLOCK(&request->mutex); + continue; + } + + // cancel the requests which not setted auto-downloading + int auto_download = dp_db_get_int_column(request->id, + DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_AUTO_DOWNLOAD); + if (auto_download <= 0) { + int agentid = request->agent_id; + int requestid = request->id; + int state = request->state; + TRACE_INFO("[CANCEL][%d] [%s] fd[%d]", requestid, + request->group->pkgname, request->group->cmd_socket); + + if ((state == DP_STATE_READY || state == DP_STATE_QUEUED || + state == DP_STATE_CONNECTING || + state == DP_STATE_DOWNLOADING || + state == DP_STATE_PAUSE_REQUESTED || + state == DP_STATE_PAUSED)) { + request->state = DP_STATE_FAILED; + request->error = DP_ERROR_CLIENT_DOWN; + if (dp_db_set_column(request->id, DP_DB_TABLE_LOG, + DP_DB_COL_STATE, DP_DB_COL_TYPE_INT, + &request->state) < 0) { + TRACE_ERROR("[ERROR][%d][SQL]", requestid); + dp_db_remove_all(request->id); + } else { + if (dp_db_set_column(request->id, DP_DB_TABLE_LOG, + DP_DB_COL_ERRORCODE, DP_DB_COL_TYPE_INT, + &request->error) < 0) { + TRACE_ERROR("[ERROR][%d][SQL]", requestid); + } + } + } + + CLIENT_MUTEX_UNLOCK(&request->mutex); + dp_request_free(request); + privates->requests[i].request = NULL; + + // call cancel_agent after free. + if (agentid > 0 && + dp_is_alive_download(agentid)) { + TRACE_INFO + ("[CANCEL-AGENT][%d] state [%s]", + requestid, dp_print_state(state)); + if (dp_cancel_agent_download(agentid) < 0) + TRACE_INFO("[CANCEL FAILURE]"); + } + + continue; + } + + + // disconnect the request from group. + TRACE_INFO + ("[DISCONNECT][%d] [%s] fd[%d]", request->id, + request->group->pkgname, request->group->cmd_socket); + + request->group = NULL; + request->state_cb = 0; + request->progress_cb = 0; + + CLIENT_MUTEX_UNLOCK(&request->mutex); + // yield to agent thread before free + + // free finished slot without client process + request = privates->requests[i].request; + if (request != NULL) { + CLIENT_MUTEX_LOCK(&request->mutex); + if (request->state == DP_STATE_COMPLETED || + request->state == DP_STATE_FAILED || + request->state == DP_STATE_CANCELED) { + TRACE_INFO("[FREE][%d] state[%s]", request->id, + dp_print_state(request->state)); + CLIENT_MUTEX_UNLOCK(&request->mutex); + dp_request_free(request); + privates->requests[i].request = NULL; + continue; + } + CLIENT_MUTEX_UNLOCK(&request->mutex); + } + } + // clear this group + dp_client_group_free(group); +} + +static int __dp_add_extra_param(int fd, int id) +{ + dp_error_type ret = DP_ERROR_NONE; + int length = 0; + int i = 0; + unsigned values_length = 0; + char *key = NULL; + char **values = NULL; + + if (fd < 0) { + TRACE_ERROR("[CHECK] socket"); + return DP_ERROR_IO_ERROR; + } + if (id < 0) { + TRACE_ERROR("[CHECK] ID"); + return DP_ERROR_INVALID_PARAMETER; + } + + if (dp_ipc_read_custom_type(fd, &length, sizeof(int)) < 0) { + TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", id); + ret = DP_ERROR_IO_ERROR; + } else { + TRACE_INFO("[RECV] length %d", length); + if (length <= 0) { + ret = DP_ERROR_INVALID_PARAMETER; + } else { + key = dp_ipc_read_string(fd); + if (key == NULL) { + TRACE_ERROR("[ERROR][%d][IO_ERROR] key", id); + ret = DP_ERROR_IO_ERROR; + } else { + if (length > 1) { + TRACE_INFO("[RECV] key : %s", key); + // get values + values = (char **)calloc((length - 1), sizeof(char *)); + if (values == NULL) { + ret = DP_ERROR_OUT_OF_MEMORY; + } else { + for (i = 0; i < length - 1; i++) { + values[i] = dp_ipc_read_string(fd); + if (values[i] == NULL) { + ret = DP_ERROR_IO_ERROR; + break; + } + values_length++; + } + } + } else { + TRACE_ERROR("[ERROR][%d] length [%d]", id, length); + ret = DP_ERROR_INVALID_PARAMETER; + } + } + } + } + if (ret == DP_ERROR_NONE) { + // store to DB + for (i = 0; i < length - 1; i++) { + int conds_count = 3; + db_conds_list_fmt conds_p[conds_count]; // id + key + value + memset(&conds_p, 0x00, conds_count * sizeof(db_conds_list_fmt)); + conds_p[0].column = DP_DB_COL_ID; + conds_p[0].type = DP_DB_COL_TYPE_INT; + conds_p[0].value = &id; + conds_p[1].column = DP_DB_COL_EXTRA_KEY; + conds_p[1].type = DP_DB_COL_TYPE_TEXT; + conds_p[1].value = key; + conds_p[2].column = DP_DB_COL_EXTRA_VALUE; + conds_p[2].type = DP_DB_COL_TYPE_TEXT; + conds_p[2].value = values[i]; + int check_key = + dp_db_get_conds_rows_count(DP_DB_TABLE_NOTIFICATION, + DP_DB_COL_ID, "AND", conds_count, conds_p); + if (check_key <= 0) { // create newly + // insert + if (dp_db_insert_columns(DP_DB_TABLE_NOTIFICATION, + conds_count, conds_p) < 0) { + ret = DP_ERROR_OUT_OF_MEMORY; + break; + } + } // else skip. already exist + } + } + free(key); + for (i = 0; i < values_length; i++) { + free(values[i]); + } + free(values); + return ret; +} + +static int __dp_get_extra_param_values(int fd, int id, char ***values, + unsigned *count) +{ + dp_error_type ret = DP_ERROR_NONE; + int length = 0; + char *key = NULL; + char **rows_array = NULL; + + if (fd < 0) { + TRACE_ERROR("[CHECK] socket"); + return DP_ERROR_IO_ERROR; + } + if (id < 0) { + TRACE_ERROR("[CHECK] ID"); + return DP_ERROR_INVALID_PARAMETER; + } + + if (dp_ipc_read_custom_type(fd, &length, sizeof(int)) < 0) { + TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", id); + ret = DP_ERROR_IO_ERROR; + } else { + TRACE_INFO("[RECV] length %d", length); + if (length != 1) { // only a key + ret = DP_ERROR_INVALID_PARAMETER; + } else { + if ((key = dp_ipc_read_string(fd)) == NULL) { + TRACE_ERROR("[ERROR][%d][IO_ERROR] key", id); + ret = DP_ERROR_IO_ERROR; + } + } + } + if (ret == DP_ERROR_NONE) { + int conds_count = 2; + db_conds_list_fmt conds_p[conds_count]; // id + key + value + memset(&conds_p, 0x00, conds_count * sizeof(db_conds_list_fmt)); + conds_p[0].column = DP_DB_COL_ID; + conds_p[0].type = DP_DB_COL_TYPE_INT; + conds_p[0].value = &id; + conds_p[1].column = DP_DB_COL_EXTRA_KEY; + conds_p[1].type = DP_DB_COL_TYPE_TEXT; + conds_p[1].value = key; + int check_rows = dp_db_get_conds_rows_count + (DP_DB_TABLE_NOTIFICATION, DP_DB_COL_EXTRA_VALUE, "AND", + conds_count, conds_p); + if (check_rows <= 0) { + // NO_DATA + ret = DP_ERROR_NO_DATA; + } else { + rows_array = (char **)calloc(check_rows, sizeof(char *)); + if (rows_array == NULL) { + ret = DP_ERROR_OUT_OF_MEMORY; + } else { + // getting the array from DB with key condition + int rows_count = + dp_db_get_conds_list(DP_DB_TABLE_NOTIFICATION, + DP_DB_COL_EXTRA_VALUE, DP_DB_COL_TYPE_TEXT, + (void **)rows_array, check_rows, -1, NULL, NULL, + "AND", conds_count, conds_p); + if (rows_count <= 0) { + // NO_DATA + ret = DP_ERROR_NO_DATA; + free(rows_array); + } else { + *count = rows_count; + *values = rows_array; + } + } + free(key); + } + } + return ret; +} + +static int __dp_remove_extra_param(int fd, int id) +{ + dp_error_type ret = DP_ERROR_NONE; + char *key = NULL; + + if (fd < 0) { + TRACE_ERROR("[CHECK] socket"); + return DP_ERROR_IO_ERROR; + } + if (id < 0) { + TRACE_ERROR("[CHECK] ID"); + return DP_ERROR_INVALID_PARAMETER; + } + + if ((key = dp_ipc_read_string(fd)) == NULL) { + TRACE_ERROR("[ERROR][%d] INVALID_PARAMETER", id); + ret = DP_ERROR_IO_ERROR; + } + if (ret == DP_ERROR_NONE) { + if (dp_db_cond_remove(id, DP_DB_TABLE_NOTIFICATION, + DP_DB_COL_EXTRA_KEY, DP_DB_COL_TYPE_TEXT, key) < 0) { + TRACE_ERROR("[ERROR][%d][SQL]", id); + ret = DP_ERROR_IO_ERROR; + } + } + TRACE_ERROR + ("[ERROR][%d][%s] key:%s", id, dp_print_errorcode(ret), key); + free(key); + return ret; +} + +static int __dp_set_group_new(int clientfd, dp_group_slots *groups, + dp_credential credential, fd_set *listen_fdset) +{ + // search in groups. + // if same group. update it. + // search same pkg or pid in groups + int pkg_len = 0; + int i = 0; + struct timeval tv_timeo; // 2.5 sec + char *pkgname = NULL; + + tv_timeo.tv_sec = 2; + tv_timeo.tv_usec = 500000; + if (setsockopt(clientfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo, + sizeof(tv_timeo)) < 0) { + TRACE_STRERROR("[CRITICAL] setsockopt SO_RCVTIMEO"); + return -1; + } + + // getting the package name via pid + if (app_manager_get_package(credential.pid, &pkgname) == + APP_MANAGER_ERROR_NONE) { + TRACE_INFO("package : %s", pkgname); + } else + TRACE_ERROR("[CRITICAL] app_manager_get_package"); + + //// TEST CODE ... to allow sample client ( no package name ). + if (pkgname == NULL) { + pkgname = dp_strdup("unknown_app"); + TRACE_INFO("default package naming : %s", pkgname); + } + + if (pkgname == NULL) { + TRACE_ERROR("[CRITICAL] app_manager_get_package"); + return -1; + } + if ((pkg_len = strlen(pkgname)) <= 0) { + TRACE_ERROR("[CRITICAL] pkgname:%s", pkgname); + return -1; + } + + for (i = 0; i < DP_MAX_GROUP; i++) { + if (groups[i].group != NULL) { + // clean garbage slot + if (groups[i].group->cmd_socket <= 0 || + groups[i].group->pkgname == NULL) { + dp_client_group_free(groups[i].group); + groups[i].group = NULL; + continue; + } + if (strlen(groups[i].group->pkgname) == pkg_len && + strncmp(groups[i].group->pkgname, pkgname, + pkg_len) == 0 ) { + // Found Same Group + TRACE_INFO("UPDATE Group: slot:%d pid:%d sock:%d [%s]", + i, credential.pid, clientfd, pkgname); + if (groups[i].group->cmd_socket > 0 && + groups[i].group->cmd_socket != clientfd) { + FD_CLR(groups[i].group->cmd_socket, listen_fdset); + dp_socket_free(groups[i].group->cmd_socket); + } + groups[i].group->cmd_socket = clientfd; + free(pkgname); + return 0; + } + } + } + + // new client + // search emtpy slot in groups + for (i = 0; i < DP_MAX_GROUP; i++) + if (groups[i].group == NULL) + break; + if (i >= DP_MAX_GROUP) { + TRACE_ERROR("[CRITICAL] No space in groups"); + free(pkgname); + return -1; + } + // allocation + groups[i].group = + (dp_client_group *)calloc(1, sizeof(dp_client_group)); + if (groups[i].group == NULL) { + TRACE_ERROR("[CRITICAL] calloc, ignore this client"); + free(pkgname); + return -1; + } + // fill info + groups[i].group->cmd_socket = clientfd; + groups[i].group->event_socket = -1; + groups[i].group->queued_count = 0; + groups[i].group->pkgname = dp_strdup(pkgname); + groups[i].group->credential.pid = credential.pid; + groups[i].group->credential.uid = credential.uid; + groups[i].group->credential.gid = credential.gid; + TRACE_INFO("New Group: slot:%d pid:%d sock:%d [%s]", i, + credential.pid, clientfd, pkgname); + free(pkgname); + return 0; +} + + +static int __dp_set_group_event_sock(int clientfd, + dp_group_slots *groups, dp_credential credential) +{ + int i = 0; + + TRACE_INFO("Check event pid:%d sock:%d", credential.pid, clientfd); + // search same pid in groups + for (i = 0; i < DP_MAX_GROUP; i++) { + if (groups[i].group != NULL && + groups[i].group->credential.pid == credential.pid) { + if (groups[i].group->event_socket > 0 && + groups[i].group->event_socket != clientfd) + dp_socket_free(groups[i].group->event_socket); + groups[i].group->event_socket = clientfd; + TRACE_INFO + ("Found Group : slot:%d pid:%d csock:%d esock:%d [%s]", + i, credential.pid, groups[i].group->cmd_socket, + clientfd, groups[i].group->pkgname); + break; + } + } + if (i >= DP_MAX_GROUP) { + TRACE_ERROR + ("[CRITICAL] Not found group for PID [%d]", credential.pid); + return -1; + } + return 0; +} + // in url-download, make 3 connection before send CREATE command. // after accepting, fill info to pacakgelist. // 3 socket per 1 package ( info/request/progress ) @@ -240,7 +673,7 @@ void *dp_thread_requests_manager(void *arg) dp_error_type errorcode = DP_ERROR_NONE; dp_privates *privates = (dp_privates*)arg; - if (!privates || !privates->groups) { + if (privates == NULL || privates->groups == NULL) { TRACE_ERROR("[CRITICAL] Invalid Address"); dp_terminate(SIGTERM); pthread_exit(NULL); @@ -257,7 +690,7 @@ void *dp_thread_requests_manager(void *arg) FD_SET(listenfd, &listen_fdset); FD_SET(listenfd, &except_fdset); - while (privates && privates->listen_fd) { + while (privates != NULL && privates->listen_fd >= 0) { // select with timeout // initialize timeout structure for calling timeout exactly @@ -277,7 +710,7 @@ void *dp_thread_requests_manager(void *arg) break; } - if (!privates) { + if (privates == NULL) { TRACE_INFO("Terminate Thread"); break; } @@ -297,9 +730,6 @@ void *dp_thread_requests_manager(void *arg) clientfd = accept(listenfd, (struct sockaddr*)&clientaddr, &clientlen); - - TRACE_INFO("[New Connection]"); - if (clientfd < 0) { TRACE_ERROR("[CRITICAL] accept provider was crashed ?"); // provider need the time of refresh. @@ -318,14 +748,8 @@ void *dp_thread_requests_manager(void *arg) close(clientfd); continue; } - if (connect_cmd != DP_CMD_SET_COMMAND_SOCKET - && connect_cmd != DP_CMD_SET_EVENT_SOCKET) { - TRACE_ERROR("[CRITICAL] Bad access, ignore this client"); - close(clientfd); - continue; - } - #ifdef SO_PEERCRED +#ifdef SO_PEERCRED // getting the info of client socklen_t cr_len = sizeof(credential); if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED, @@ -334,7 +758,7 @@ void *dp_thread_requests_manager(void *arg) ("credential : pid=%d, uid=%d, gid=%d", credential.pid, credential.uid, credential.gid); } - #else // In case of not supported SO_PEERCRED +#else // In case of not supported SO_PEERCRED int client_pid = 0; if (dp_ipc_read_custom_type(clientfd, &client_pid, sizeof(int)) < 0) { @@ -350,193 +774,42 @@ void *dp_thread_requests_manager(void *arg) credential.pid = client_pid; credential.uid = 5000; credential.gid = 5000; - #endif - - struct timeval tv_timeo; // 2.5 sec - tv_timeo.tv_sec = 2; - tv_timeo.tv_usec = 500000; - if (setsockopt(clientfd, SOL_SOCKET, SO_SNDTIMEO, &tv_timeo, - sizeof( tv_timeo ) ) < 0) { - TRACE_STRERROR("[CRITICAL] setsockopt SO_SNDTIMEO"); - close(clientfd); - continue; - } - if (setsockopt(clientfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo, - sizeof( tv_timeo ) ) < 0) { - TRACE_STRERROR("[CRITICAL] setsockopt SO_SNDTIMEO"); - close(clientfd); - continue; - } - - if (connect_cmd == DP_CMD_SET_COMMAND_SOCKET) { - - // search in groups. - // if same group. update it. - // search same pkg or pid in groups - int group_index = -1; - int pkgname_length = 0; - char *client_pkgname = NULL; - - // getting the package name via pid - int errcode = - app_manager_get_package(credential.pid, &client_pkgname); - if (errcode == APP_MANAGER_ERROR_NONE && client_pkgname - && strlen(client_pkgname) < DP_MAX_STR_LEN) { - TRACE_INFO("package : %s", client_pkgname); - } else - TRACE_ERROR("[CRITICAL] app_manager_get_package"); - - if (client_pkgname - && (pkgname_length = strlen(client_pkgname)) > 1) { - for (i = 0; i < DP_MAX_GROUP; i++) { - if (privates->groups[i].group) { - if (privates->groups[i].group->cmd_socket - <= 0 - || !privates->groups[i].group->pkgname) { - dp_client_group_free - (privates->groups[i].group); - privates->groups[i].group = NULL; - continue; - } - if (strlen - (privates->groups[i].group->pkgname) - == pkgname_length - && strncmp - (privates->groups[i].group->pkgname, - client_pkgname, pkgname_length) - == 0 ) { - // Found Same Group - TRACE_INFO - ("UPDATE Group : I %d [%s] PID [%d] cmd_socket[%d]", - i, client_pkgname, credential.pid, clientfd); - if (privates->groups[i].group->cmd_socket - > 0 - && privates->groups[i].group->cmd_socket - != clientfd) { - FD_CLR - (privates->groups[i].group->cmd_socket, - &listen_fdset); - dp_socket_free - (privates->groups[i].group->cmd_socket); - } - privates->groups[i].group->cmd_socket = clientfd; - FD_SET(privates->groups[i].group->cmd_socket, &listen_fdset); - if (privates->groups[i].group->cmd_socket > maxfd) - maxfd = privates->groups[i].group->cmd_socket; - group_index = i; - break; - } - } - } - } - if (group_index == -1) { // search emtpy slot in groups - // search empty slot in groups - for (i = 0; i < DP_MAX_GROUP; i++) - if (!privates->groups[i].group) - break; - if (i >= DP_MAX_GROUP) { - TRACE_ERROR("[CRITICAL] No space in groups"); - close(clientfd); // how to deal in url-download ? - if (client_pkgname) - free(client_pkgname); - continue; - } - - //// TEST CODE ... to allow sample client ( no package name ). - if (!client_pkgname) { - client_pkgname = dp_strdup("unknown_app"); - TRACE_INFO("package : %s", client_pkgname); - } - - TRACE_INFO - ("New Group : GI %d [%s] PID [%d] cmd_socket[%d]", - i, client_pkgname, credential.pid, clientfd); - - // allocation - privates->groups[i].group = - (dp_client_group *) calloc(1, - sizeof(dp_client_group)); - if (!privates->groups[i].group) { - TRACE_ERROR - ("[CRITICAL] calloc, ignore this client"); - close(clientfd); - if (client_pkgname) - free(client_pkgname); - continue; - } - // fill info - privates->groups[i].group->cmd_socket = clientfd; - privates->groups[i].group->event_socket = -1; - privates->groups[i].group->queued_count = 0; - privates->groups[i].group->pkgname = - dp_strdup(client_pkgname); - privates->groups[i].group->credential.pid = - credential.pid; - privates->groups[i].group->credential.uid = - credential.uid; - privates->groups[i].group->credential.gid = - credential.gid; - FD_SET(privates->groups[i].group->cmd_socket, - &listen_fdset); - if (privates->groups[i].group->cmd_socket > maxfd) - maxfd = privates->groups[i].group->cmd_socket; - TRACE_INFO - ("Group : GI [%d] [%s] S [%d] Max [%d]", - i, client_pkgname, - privates->groups[i].group->cmd_socket, maxfd); - } - if (client_pkgname) - free(client_pkgname); - - } else if (connect_cmd == DP_CMD_SET_EVENT_SOCKET) { +#endif - // search same pid in groups. have same life-cycle with cmd_socket - TRACE_INFO - ("Group event IPC: PID [%d] cmd_socket[%d]", - credential.pid, clientfd); - // search same pkg or pid in groups - for (i = 0; i < DP_MAX_GROUP; i++) { - if (privates->groups[i].group) { - dp_client_group *group = - privates->groups[i].group; - if (group->credential.pid == credential.pid) { - TRACE_INFO - ("Found Group : I %d [%s] PID [%d] \ - socket (%d/%d)", i, - group->pkgname, credential.pid, - group->cmd_socket, group->event_socket); - if (group->event_socket > 0 - && group->event_socket != clientfd) - dp_socket_free(group->event_socket); - group->event_socket = clientfd; - TRACE_INFO - ("Found Group : I %d PID [%d] \ - event_socket[%d]", - i, credential.pid, clientfd); - break; - } - } - } - if (i >= DP_MAX_GROUP) { - TRACE_ERROR - ("[CRITICAL] Not found group for PID [%d]", - credential.pid); + switch(connect_cmd) { + case DP_CMD_SET_COMMAND_SOCKET: + if (__dp_set_group_new(clientfd, privates->groups, + credential, &listen_fdset) == 0) { + FD_SET(clientfd, &listen_fdset); + if (clientfd > maxfd) + maxfd = clientfd; + } else { close(clientfd); - continue; } + break; + case DP_CMD_SET_EVENT_SOCKET: + { + if (__dp_set_group_event_sock(clientfd, + privates->groups, credential) < 0) + close(clientfd); + break; + } + default: + TRACE_ERROR("[CRITICAL] Bad access, ignore this client"); + close(clientfd); + break; } } // New Connection // listen cmd_socket of all group for (i = 0; i < DP_MAX_GROUP; i++) { - if (!privates->groups[i].group) + dp_client_group *group = privates->groups[i].group; + if (group == NULL) continue; - if (privates->groups[i].group->cmd_socket < 0) { + if (group->cmd_socket < 0) { continue; } - if (FD_ISSET(privates->groups[i].group->cmd_socket, &rset) - > 0) { - dp_client_group *group = privates->groups[i].group; + if (FD_ISSET(group->cmd_socket, &rset) > 0) { dp_command client_cmd; int index = -1; @@ -563,109 +836,8 @@ void *dp_thread_requests_manager(void *arg) ("[Closed Peer] group[%d][%s] socket[%d]", i, group->pkgname, group->cmd_socket); // check all request included to this group - for (index = 0; index < DP_MAX_REQUEST; index++) { - if (!privates->requests[index].request) - continue; - if (!privates->requests[index].request->group) - continue; - if (privates->requests[index].request->id <= 0) - continue; - dp_request *request = - privates->requests[index].request; - - CLIENT_MUTEX_LOCK(&request->mutex); - if (request->group != group || - request->group->cmd_socket != - group->cmd_socket) { - CLIENT_MUTEX_UNLOCK(&request->mutex); - continue; - } - int auto_download = - dp_db_get_int_column(request->id, - DP_DB_TABLE_REQUEST_INFO, - DP_DB_COL_AUTO_DOWNLOAD); - if (auto_download <= 0) { - int agentid = request->agent_id; - int requestid = request->id; - int state = request->state; - TRACE_INFO("[CANCEL][%d] [%s] fd[%d]", - requestid, request->group->pkgname, - request->group->cmd_socket); - - if ((state == DP_STATE_READY || - state == DP_STATE_QUEUED || - state == DP_STATE_CONNECTING || - state == DP_STATE_DOWNLOADING || - state == DP_STATE_PAUSE_REQUESTED || - state == DP_STATE_PAUSED)) { - request->state = DP_STATE_FAILED; - request->error = DP_ERROR_CLIENT_DOWN; - if (dp_db_set_column - (request->id, DP_DB_TABLE_LOG, - DP_DB_COL_STATE, - DP_DB_COL_TYPE_INT, - &request->state) < 0) { - TRACE_ERROR("[ERROR][%d][SQL]", - requestid); - dp_db_remove_all(request->id); - } else { - if (dp_db_set_column - (request->id, DP_DB_TABLE_LOG, - DP_DB_COL_ERRORCODE, - DP_DB_COL_TYPE_INT, - &request->error) < 0) { - TRACE_ERROR("[ERROR][%d][SQL]", - requestid); - } - } - } - CLIENT_MUTEX_UNLOCK(&request->mutex); - dp_request_free(request); - privates->requests[index].request = NULL; - - // call cancel_agent after free. - if (agentid > 0 && - dp_is_alive_download(agentid)) { - TRACE_INFO - ("[CANCEL-AGENT][%d] state [%s]", - requestid, dp_print_state(state)); - if (dp_cancel_agent_download(agentid) < - 0) - TRACE_INFO("[CANCEL FAILURE]"); - } - - continue; - } - - - TRACE_INFO("[DISCONNECT][%d] [%s] fd[%d]", - request->id, request->group->pkgname, - request->group->cmd_socket); - - request->group = NULL; - request->state_cb = 0; - request->progress_cb = 0; - - CLIENT_MUTEX_UNLOCK(&request->mutex); - // yield to agent thread before free - CLIENT_MUTEX_LOCK(&request->mutex); - // free finished slot without client process - if (request->state == DP_STATE_COMPLETED - || request->state == DP_STATE_FAILED - || request->state == DP_STATE_CANCELED) { - TRACE_INFO - ("[FREE][%d] state[%s]", request->id, - dp_print_state(request->state)); - CLIENT_MUTEX_UNLOCK(&request->mutex); - dp_request_free(request); - privates->requests[index].request = NULL; - continue; - } - CLIENT_MUTEX_UNLOCK(&(request->mutex)); - } - // clear this group FD_CLR(group->cmd_socket, &listen_fdset); - dp_client_group_free(group); + __clear_group(privates, group); privates->groups[i].group = NULL; continue; } @@ -674,8 +846,13 @@ void *dp_thread_requests_manager(void *arg) if (client_cmd.cmd == DP_CMD_ECHO) { // provider can clear read buffer here TRACE_INFO("[ECHO] fd[%d]", group->cmd_socket); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_NONE); + if (dp_ipc_send_errorcode + (group->cmd_socket, DP_ERROR_NONE) < 0) { + // disconnect this group, bad client + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; + } continue; } @@ -718,7 +895,7 @@ void *dp_thread_requests_manager(void *arg) DP_ERROR_INVALID_PARAMETER); // disconnect this group, bad client FD_CLR(group->cmd_socket, &listen_fdset); - dp_client_group_free(group); + __clear_group(privates, group); privates->groups[i].group = NULL; continue; } @@ -727,44 +904,44 @@ void *dp_thread_requests_manager(void *arg) index = __get_same_request_index (privates->requests, client_cmd.id); + // GET API works even if request is NULL. dp_request *request = NULL; if (index >= 0) request = privates->requests[index].request; + // Authentication by packagename. char *auth_pkgname = NULL; + errorcode = DP_ERROR_NONE; if (request != NULL) { auth_pkgname = dp_strdup(request->packagename); + if (auth_pkgname == NULL) + errorcode = DP_ERROR_OUT_OF_MEMORY; } else { auth_pkgname = dp_db_get_text_column(client_cmd.id, DP_DB_TABLE_LOG, DP_DB_COL_PACKAGENAME); - if (auth_pkgname == NULL) { + if (auth_pkgname == NULL) + errorcode = DP_ERROR_ID_NOT_FOUND; + } + if (errorcode == DP_ERROR_NONE) { + // auth by pkgname + if (__cmp_string(group->pkgname, auth_pkgname) < 0) { TRACE_ERROR - ("[ERROR][%d] [DP_ERROR_ID_NOT_FOUND]", - client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_ID_NOT_FOUND); - continue; + ("[ERROR][%d] Auth [%s]/[%s]", client_cmd.id, + group->pkgname, auth_pkgname); + errorcode = DP_ERROR_INVALID_PARAMETER; } } - - // auth by pkgname - if (__cmp_string - (group->pkgname, auth_pkgname) < 0) { - TRACE_ERROR - ("[ERROR][%d] Auth [%s]/[%s]", client_cmd.id, - group->pkgname, auth_pkgname); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_INVALID_PARAMETER); - free(auth_pkgname); + free(auth_pkgname); + if (errorcode != DP_ERROR_NONE) { + TRACE_ERROR("[ERROR][%d][%s]", client_cmd.id, + dp_print_errorcode(errorcode)); + dp_ipc_send_errorcode(group->cmd_socket, errorcode); continue; } - if (auth_pkgname != NULL) - free(auth_pkgname); - if (request != NULL && request->group == NULL) { - // if no group, update group. + // if no group, update group. + if (request != NULL && request->group == NULL) request->group = group; - } if (client_cmd.cmd == DP_CMD_DESTROY) { if (request != NULL) { @@ -1081,8 +1258,7 @@ void *dp_thread_requests_manager(void *arg) if (dp_cancel_agent_download(request->agent_id) < 0) { TRACE_ERROR("[ERROR][%d][AGENT][ID:%d] now [%s]", - client_cmd.id, - request->agent_id, + client_cmd.id, request->agent_id, dp_print_state(request->state)); CLIENT_MUTEX_UNLOCK(&(request->mutex)); dp_ipc_send_errorcode @@ -1107,10 +1283,11 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_URL) { char *url = dp_ipc_read_string(group->cmd_socket); if (url == NULL) { - TRACE_ERROR("[ERROR][%d] DP_ERROR_INVALID_URL", + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_INVALID_URL); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1124,11 +1301,11 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_DESTINATION) { char *dest = dp_ipc_read_string(group->cmd_socket); if (dest == NULL) { - TRACE_ERROR - ("[ERROR][%d] DP_ERROR_INVALID_DESTINATION", + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode(group->cmd_socket, - DP_ERROR_INVALID_DESTINATION); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1143,11 +1320,11 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_FILENAME) { char *fname = dp_ipc_read_string(group->cmd_socket); if (fname == NULL) { - TRACE_ERROR - ("[ERROR][%d] DP_ERROR_INVALID_PARAMETER", + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode(group->cmd_socket, - DP_ERROR_INVALID_PARAMETER); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1163,11 +1340,12 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_NOTIFICATION) { int value = 0; if (dp_ipc_read_custom_type(group->cmd_socket, - &value, sizeof(int)) < 0) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", - client_cmd.id); - dp_ipc_send_errorcode(group->cmd_socket, - DP_ERROR_IO_ERROR); + &value, sizeof(int)) < 0) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", + client_cmd.id); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1182,11 +1360,12 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_STATE_CALLBACK) { int value = 0; if (dp_ipc_read_custom_type(group->cmd_socket, - &value, sizeof(int)) < 0) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + &value, sizeof(int)) < 0) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode(group->cmd_socket, - DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1201,11 +1380,12 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_PROGRESS_CALLBACK) { int value = 0; if (dp_ipc_read_custom_type(group->cmd_socket, - &value, sizeof(int)) < 0) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + &value, sizeof(int)) < 0) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode(group->cmd_socket, - DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1220,11 +1400,12 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_AUTO_DOWNLOAD) { int value = 0; if (dp_ipc_read_custom_type(group->cmd_socket, - &value, sizeof(int)) < 0) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + &value, sizeof(int)) < 0) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode(group->cmd_socket, - DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1239,11 +1420,12 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_SET_NETWORK_TYPE) { int value = 0; if (dp_ipc_read_custom_type(group->cmd_socket, - &value, sizeof(int)) < 0) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + &value, sizeof(int)) < 0) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode(group->cmd_socket, - DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } dp_error_type ret = @@ -1255,67 +1437,23 @@ void *dp_thread_requests_manager(void *arg) if (ret != DP_ERROR_NONE) TRACE_ERROR("[ERROR][%d][%s]", client_cmd.id, dp_print_errorcode(ret)); - } else if (client_cmd.cmd == DP_CMD_SET_EXTRA_PARAM) { - char *key = dp_ipc_read_string(group->cmd_socket); - if (key == NULL) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", - client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); - continue; - } - char *value = dp_ipc_read_string(group->cmd_socket); - if (value == NULL) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", - client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); - free(key); - continue; - } - - TRACE_INFO("[EXTRA-PARAM][%d][%s][%s]", - client_cmd.id, key, value); - - if (dp_db_replace_column - (client_cmd.id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_KEY, DP_DB_COL_TYPE_TEXT, - key) < 0) { - TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); - free(key); - free(value); - continue; - } - free(key); - if (dp_db_set_column - (client_cmd.id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_VALUE, DP_DB_COL_TYPE_TEXT, - value) < 0) { - TRACE_ERROR("[ERROR][%d][SQL]", client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); - } else { - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_NONE); - } - free(value); } else if (client_cmd.cmd == DP_CMD_SET_HTTP_HEADER) { char *field = dp_ipc_read_string(group->cmd_socket); if (field == NULL) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } char *value = dp_ipc_read_string(group->cmd_socket); if (value == NULL) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; free(field); continue; } @@ -1360,10 +1498,11 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_DEL_HTTP_HEADER) { char *field = dp_ipc_read_string(group->cmd_socket); if (field == NULL) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } char *check_field = dp_db_cond_get_text_column @@ -1395,10 +1534,11 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_GET_HTTP_HEADER) { char *field = dp_ipc_read_string(group->cmd_socket); if (field == NULL) { - TRACE_ERROR("[ERROR][%d] [DP_ERROR_IO_ERROR]", + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_IO_ERROR); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } char *value = dp_db_cond_get_text_column @@ -1417,34 +1557,63 @@ void *dp_thread_requests_manager(void *arg) (group->cmd_socket, DP_ERROR_NONE, value); free(value); } - } else if (client_cmd.cmd == DP_CMD_GET_EXTRA_PARAM) { - char *key = dp_db_get_text_column - (client_cmd.id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_KEY); - if (key == NULL) { - TRACE_ERROR - ("[ERROR][%d] [DP_ERROR_NO_DATA]", + } else if (client_cmd.cmd == DP_CMD_ADD_EXTRA_PARAM) { + dp_error_type ret = DP_ERROR_NONE; + ret = __dp_add_extra_param(group->cmd_socket, client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_NO_DATA); + if (ret == DP_ERROR_IO_ERROR) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", + client_cmd.id); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; continue; } - char *value = dp_db_get_text_column - (client_cmd.id, DP_DB_TABLE_NOTIFICATION, - DP_DB_COL_EXTRA_VALUE); - if (value == NULL) { - TRACE_ERROR - ("[ERROR][%d] [DP_ERROR_NO_DATA]", - client_cmd.id); - dp_ipc_send_errorcode - (group->cmd_socket, DP_ERROR_NO_DATA); + dp_ipc_send_errorcode(group->cmd_socket, ret); + } else if (client_cmd.cmd == DP_CMD_GET_EXTRA_PARAM) { + dp_error_type ret = DP_ERROR_NONE; + char **values = NULL; + unsigned rows_count = 0; + ret = __dp_get_extra_param_values(group->cmd_socket, + client_cmd.id, &values, &rows_count); + if (ret == DP_ERROR_NONE) { + __send_return_custom_type(group->cmd_socket, + DP_ERROR_NONE, &rows_count, sizeof(int)); + // sending strings + int i = 0; + for (i = 0; i < rows_count; i++) { + if (dp_ipc_send_string + (group->cmd_socket, values[i]) < 0) + break; + } + for (i = 0; i < rows_count; i++) + free(values[i]); } else { - __send_return_string - (group->cmd_socket, DP_ERROR_NONE, key); - dp_ipc_send_string(group->cmd_socket, value); - free(value); + if (ret == DP_ERROR_IO_ERROR) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", + client_cmd.id); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; + continue; + } + dp_ipc_send_errorcode(group->cmd_socket, ret); + } + free(values); + } else if (client_cmd.cmd == DP_CMD_REMOVE_EXTRA_PARAM) { + dp_error_type ret = DP_ERROR_NONE; + ret = + __dp_remove_extra_param(group->cmd_socket, + client_cmd.id); + if (ret == DP_ERROR_IO_ERROR) { + TRACE_ERROR("[ERROR][%d] DP_ERROR_IO_ERROR", + client_cmd.id); + FD_CLR(group->cmd_socket, &listen_fdset); + __clear_group(privates, group); + privates->groups[i].group = NULL; + continue; } - free(key); + dp_ipc_send_errorcode(group->cmd_socket, ret); } else if (client_cmd.cmd == DP_CMD_GET_URL) { char *url = NULL; errorcode = DP_ERROR_NONE; @@ -1493,7 +1662,7 @@ void *dp_thread_requests_manager(void *arg) } else if (client_cmd.cmd == DP_CMD_GET_NOTIFICATION) { int enable = 0; enable = dp_db_get_int_column(client_cmd.id, - DP_DB_TABLE_NOTIFICATION, + DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_NOTIFICATION_ENABLE); if (enable < 0) { TRACE_ERROR @@ -1721,7 +1890,7 @@ void *dp_thread_requests_manager(void *arg) DP_ERROR_INVALID_PARAMETER); // disconnect this group, bad client FD_CLR(group->cmd_socket, &listen_fdset); - dp_client_group_free(group); + __clear_group(privates, group); privates->groups[i].group = NULL; } } // FD_ISSET diff --git a/src/include/download-provider-config.h b/provider/include/download-provider-config.h similarity index 100% rename from src/include/download-provider-config.h rename to provider/include/download-provider-config.h diff --git a/src/include/download-provider-da-interface.h b/provider/include/download-provider-da-interface.h similarity index 100% rename from src/include/download-provider-da-interface.h rename to provider/include/download-provider-da-interface.h diff --git a/src/include/download-provider-db.h b/provider/include/download-provider-db.h similarity index 90% rename from src/include/download-provider-db.h rename to provider/include/download-provider-db.h index 1618e67..f964676 100755 --- a/src/include/download-provider-db.h +++ b/provider/include/download-provider-db.h @@ -118,6 +118,7 @@ CREATE UNIQUE INDEX requests_index ON logging (id, state, errorcode, packagename #define DP_DB_COL_HEADER_DATA "header_data" #define DP_DB_COL_NOTIFICATION_ENABLE "noti_enable" #define DP_DB_COL_EXTRA_KEY "extra_key" +#define DP_DB_COL_DISTINCT_EXTRA_KEY "DISTINCT extra_key" #define DP_DB_COL_EXTRA_VALUE "extra_data" typedef enum { @@ -127,6 +128,13 @@ typedef enum { DP_DB_COL_TYPE_TEXT = 30 } db_column_data_type; +typedef struct { + char *column; + db_column_data_type type; + int is_like; + void *value; +} db_conds_list_fmt; + int dp_db_open(); void dp_db_close(); @@ -171,4 +179,17 @@ dp_request *dp_db_load_logging_request(int id); int dp_db_limit_rows(int limit); int dp_db_get_count_by_limit_time(); int dp_db_get_list_by_limit_time(dp_request_slots *requests, int limit); + +int dp_db_insert_columns(char *table, int column_count, + db_conds_list_fmt *columns); + +int dp_db_get_conds_rows_count(char *table, char *getcolumn, char *op, + int conds_count, db_conds_list_fmt *conds); + +int dp_db_get_conds_list(char *table, char *getcolumn, + db_column_data_type gettype, void **list, + int rowslimit, int rowsoffset, + char *ordercolumn, char *ordering, + char *op, int conds_count, + db_conds_list_fmt *conds); #endif diff --git a/provider/include/download-provider-defs.h b/provider/include/download-provider-defs.h new file mode 100755 index 0000000..0eac01c --- /dev/null +++ b/provider/include/download-provider-defs.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2013 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_PROVIDER_DEFS_H +#define DOWNLOAD_PROVIDER_DEFS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DP_SUPPORT_DBUS_ACTIVATION +#define DP_DBUS_ACTIVATION +#define DP_DBUS_SERVICE_DBUS "org.download-provider" +#endif + +#define DP_ECHO_TEST + +typedef enum { + DP_STATE_NONE = 0, + DP_STATE_READY = DP_STATE_NONE + 5, // created id, set some info. + DP_STATE_QUEUED = DP_STATE_NONE + 10, // request to start + DP_STATE_CONNECTING = DP_STATE_NONE + 15, // try to connect to url + DP_STATE_DOWNLOADING = DP_STATE_NONE + 20, // started + DP_STATE_PAUSE_REQUESTED = DP_STATE_NONE + 25, + DP_STATE_PAUSED = DP_STATE_NONE + 30, // paused actually + DP_STATE_COMPLETED = DP_STATE_NONE + 40, + DP_STATE_CANCELED = DP_STATE_NONE + 45, // stopped with error + DP_STATE_FAILED = DP_STATE_NONE + 50 // failed with error +} dp_state_type; + +typedef enum { + DP_ERROR_NONE = 0, + DP_ERROR_INVALID_PARAMETER = DP_ERROR_NONE + 1, + DP_ERROR_OUT_OF_MEMORY = DP_ERROR_NONE + 2, + DP_ERROR_IO_ERROR = DP_ERROR_NONE + 3, + DP_ERROR_NETWORK_UNREACHABLE = DP_ERROR_NONE + 4, + DP_ERROR_CONNECTION_TIMED_OUT = DP_ERROR_NONE + 5, + DP_ERROR_NO_SPACE = DP_ERROR_NONE + 6, + DP_ERROR_FIELD_NOT_FOUND = DP_ERROR_NONE + 7, + DP_ERROR_INVALID_STATE = DP_ERROR_NONE + 8, + DP_ERROR_CONNECTION_FAILED = DP_ERROR_NONE + 9, + DP_ERROR_INVALID_URL = DP_ERROR_NONE + 10, + DP_ERROR_INVALID_DESTINATION = DP_ERROR_NONE + 11, + DP_ERROR_QUEUE_FULL = DP_ERROR_NONE + 12, + DP_ERROR_ALREADY_COMPLETED = DP_ERROR_NONE + 13, + DP_ERROR_FILE_ALREADY_EXISTS = DP_ERROR_NONE + 14, + DP_ERROR_TOO_MANY_DOWNLOADS = DP_ERROR_NONE + 15, + DP_ERROR_NO_DATA = DP_ERROR_NONE + 17, + DP_ERROR_UNHANDLED_HTTP_CODE = DP_ERROR_NONE + 18, + DP_ERROR_CANNOT_RESUME = DP_ERROR_NONE + 19, + DP_ERROR_RESPONSE_TIMEOUT = DP_ERROR_NONE + 50, + DP_ERROR_REQUEST_TIMEOUT = DP_ERROR_NONE + 55, + DP_ERROR_SYSTEM_DOWN = DP_ERROR_NONE + 60, + DP_ERROR_CLIENT_DOWN = DP_ERROR_NONE + 65, + DP_ERROR_ID_NOT_FOUND = DP_ERROR_NONE + 90, + DP_ERROR_IO_EAGAIN = DP_ERROR_NONE + 97, + DP_ERROR_IO_EINTR = DP_ERROR_NONE + 98, + DP_ERROR_IO_TIMEOUT = DP_ERROR_NONE + 99, + DP_ERROR_UNKNOWN = DP_ERROR_NONE + 100 +} dp_error_type; + +typedef enum { + DP_NETWORK_TYPE_OFF = -1, + DP_NETWORK_TYPE_ALL = 0, + DP_NETWORK_TYPE_WIFI = 1, + DP_NETWORK_TYPE_DATA_NETWORK = 2, + DP_NETWORK_TYPE_ETHERNET = 3, + DP_NETWORK_TYPE_WIFI_DIRECT = 4 +} dp_network_type; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/include/download-provider-log.h b/provider/include/download-provider-log.h similarity index 100% rename from src/include/download-provider-log.h rename to provider/include/download-provider-log.h diff --git a/src/include/download-provider-network.h b/provider/include/download-provider-network.h similarity index 100% rename from src/include/download-provider-network.h rename to provider/include/download-provider-network.h diff --git a/src/include/download-provider-notification.h b/provider/include/download-provider-notification.h similarity index 100% rename from src/include/download-provider-notification.h rename to provider/include/download-provider-notification.h diff --git a/src/include/download-provider-pthread.h b/provider/include/download-provider-pthread.h similarity index 100% rename from src/include/download-provider-pthread.h rename to provider/include/download-provider-pthread.h diff --git a/src/include/download-provider-queue.h b/provider/include/download-provider-queue.h similarity index 100% rename from src/include/download-provider-queue.h rename to provider/include/download-provider-queue.h diff --git a/src/include/download-provider-request.h b/provider/include/download-provider-request.h similarity index 100% rename from src/include/download-provider-request.h rename to provider/include/download-provider-request.h diff --git a/src/include/download-provider-slots.h b/provider/include/download-provider-slots.h similarity index 100% rename from src/include/download-provider-slots.h rename to provider/include/download-provider-slots.h diff --git a/src/include/download-provider-socket.h b/provider/include/download-provider-socket.h similarity index 100% rename from src/include/download-provider-socket.h rename to provider/include/download-provider-socket.h diff --git a/provider/include/download-provider.h b/provider/include/download-provider.h new file mode 100755 index 0000000..d0a4ca6 --- /dev/null +++ b/provider/include/download-provider.h @@ -0,0 +1,102 @@ +/* + * 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_PROVIDER2_H +#define DOWNLOAD_PROVIDER2_H + +#include "download-provider-defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DP_IPC "/tmp/download-provider" + +#define DP_MAX_STR_LEN_64 64 +#define DP_MAX_STR_LEN 256 +#define DP_MAX_PATH_LEN DP_MAX_STR_LEN +#define DP_MAX_URL_LEN 2048 + +typedef enum { + DP_CMD_NONE = 0, + DP_CMD_CREATE = DP_CMD_NONE + 1, + DP_CMD_START = DP_CMD_NONE + 2, + DP_CMD_PAUSE = DP_CMD_NONE + 3, + DP_CMD_CANCEL = DP_CMD_NONE + 4, + DP_CMD_DESTROY = DP_CMD_NONE + 9, + DP_CMD_FREE = DP_CMD_NONE + 10, + DP_CMD_ECHO = DP_CMD_NONE + 15, + DP_CMD_SET_URL = DP_CMD_NONE + 21, + DP_CMD_SET_DESTINATION = DP_CMD_NONE + 22, + DP_CMD_SET_FILENAME = DP_CMD_NONE + 23, + DP_CMD_SET_NOTIFICATION = DP_CMD_NONE + 24, + DP_CMD_SET_STATE_CALLBACK = DP_CMD_NONE + 25, + DP_CMD_SET_PROGRESS_CALLBACK = DP_CMD_NONE + 26, + DP_CMD_SET_AUTO_DOWNLOAD = DP_CMD_NONE + 28, + DP_CMD_SET_NETWORK_TYPE = DP_CMD_NONE + 29, + DP_CMD_SET_HTTP_HEADER = DP_CMD_NONE + 30, + DP_CMD_SET_EXTRA_PARAM = DP_CMD_NONE + 31, // prevent build error + DP_CMD_DEL_HTTP_HEADER = DP_CMD_NONE + 35, + DP_CMD_GET_URL = DP_CMD_NONE + 41, + DP_CMD_GET_DESTINATION = DP_CMD_NONE + 42, + DP_CMD_GET_FILENAME = DP_CMD_NONE + 43, + DP_CMD_GET_NOTIFICATION = DP_CMD_NONE + 44, + DP_CMD_GET_STATE_CALLBACK = DP_CMD_NONE + 45, + DP_CMD_GET_PROGRESS_CALLBACK = DP_CMD_NONE + 46, + DP_CMD_GET_HTTP_HEADERS = DP_CMD_NONE + 47, + DP_CMD_GET_AUTO_DOWNLOAD = DP_CMD_NONE + 48, + DP_CMD_GET_NETWORK_TYPE = DP_CMD_NONE + 49, + DP_CMD_GET_SAVED_PATH = DP_CMD_NONE + 50, + DP_CMD_GET_TEMP_SAVED_PATH = DP_CMD_NONE + 51, + DP_CMD_GET_MIME_TYPE = DP_CMD_NONE + 52, + DP_CMD_GET_HTTP_HEADER = DP_CMD_NONE + 53, + DP_CMD_ADD_EXTRA_PARAM = DP_CMD_NONE + 63, + DP_CMD_GET_EXTRA_PARAM = DP_CMD_NONE + 64, + DP_CMD_REMOVE_EXTRA_PARAM = DP_CMD_NONE + 65, + DP_CMD_GET_RECEIVED_SIZE = DP_CMD_NONE + 71, + DP_CMD_GET_TOTAL_FILE_SIZE = DP_CMD_NONE + 72, + DP_CMD_GET_CONTENT_NAME = DP_CMD_NONE + 73, + DP_CMD_GET_HTTP_STATUS = DP_CMD_NONE + 74, + DP_CMD_GET_ETAG = DP_CMD_NONE + 75, + DP_CMD_GET_STATE = DP_CMD_NONE + 81, + DP_CMD_GET_ERROR = DP_CMD_NONE + 91, + DP_CMD_SET_COMMAND_SOCKET = DP_CMD_NONE + 100, + DP_CMD_SET_EVENT_SOCKET = DP_CMD_NONE + 101 +} dp_command_type; + +typedef struct { + unsigned int length; + char *str; +} dp_string; + +typedef struct { + int id; + dp_state_type state; + dp_error_type err; + unsigned long long received_size; +} dp_event_info; + +typedef struct { + dp_command_type cmd; + int id; +} dp_command; + + // Usage IPC : send(dp_command);send(dp_string); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/include/download-provider.h b/src/include/download-provider.h deleted file mode 100755 index 5083ecd..0000000 --- a/src/include/download-provider.h +++ /dev/null @@ -1,154 +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_PROVIDER2_H -#define DOWNLOAD_PROVIDER2_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define DP_IPC "/tmp/download-provider" - -#define DP_MAX_STR_LEN_64 64 -#define DP_MAX_STR_LEN 256 -#define DP_MAX_PATH_LEN DP_MAX_STR_LEN -#define DP_MAX_URL_LEN 2048 - -#ifdef DP_SUPPORT_DBUS_ACTIVATION -#define DP_DBUS_ACTIVATION -#define DP_DBUS_SERVICE_DBUS "org.download-provider" -#endif - -#define DP_ECHO_TEST - - typedef enum { - DP_CMD_NONE = 0, - DP_CMD_CREATE = DP_CMD_NONE + 1, - DP_CMD_START = DP_CMD_NONE + 2, - DP_CMD_PAUSE = DP_CMD_NONE + 3, - DP_CMD_CANCEL = DP_CMD_NONE + 4, - DP_CMD_DESTROY = DP_CMD_NONE + 9, - DP_CMD_FREE = DP_CMD_NONE + 10, - DP_CMD_ECHO = DP_CMD_NONE + 15, - DP_CMD_SET_URL = DP_CMD_NONE + 21, - DP_CMD_SET_DESTINATION = DP_CMD_NONE + 22, - DP_CMD_SET_FILENAME = DP_CMD_NONE + 23, - DP_CMD_SET_NOTIFICATION = DP_CMD_NONE + 24, - DP_CMD_SET_STATE_CALLBACK = DP_CMD_NONE + 25, - DP_CMD_SET_PROGRESS_CALLBACK = DP_CMD_NONE + 26, - DP_CMD_SET_AUTO_DOWNLOAD = DP_CMD_NONE + 28, - DP_CMD_SET_NETWORK_TYPE = DP_CMD_NONE + 29, - DP_CMD_SET_HTTP_HEADER = DP_CMD_NONE + 30, - DP_CMD_SET_EXTRA_PARAM = DP_CMD_NONE + 31, - DP_CMD_DEL_HTTP_HEADER = DP_CMD_NONE + 35, - DP_CMD_GET_URL = DP_CMD_NONE + 41, - DP_CMD_GET_DESTINATION = DP_CMD_NONE + 42, - DP_CMD_GET_FILENAME = DP_CMD_NONE + 43, - DP_CMD_GET_NOTIFICATION = DP_CMD_NONE + 44, - DP_CMD_GET_STATE_CALLBACK = DP_CMD_NONE + 45, - DP_CMD_GET_PROGRESS_CALLBACK = DP_CMD_NONE + 46, - DP_CMD_GET_HTTP_HEADERS = DP_CMD_NONE + 47, - DP_CMD_GET_AUTO_DOWNLOAD = DP_CMD_NONE + 48, - DP_CMD_GET_NETWORK_TYPE = DP_CMD_NONE + 49, - DP_CMD_GET_SAVED_PATH = DP_CMD_NONE + 50, - DP_CMD_GET_TEMP_SAVED_PATH = DP_CMD_NONE + 51, - DP_CMD_GET_MIME_TYPE = DP_CMD_NONE + 52, - DP_CMD_GET_HTTP_HEADER = DP_CMD_NONE + 53, - DP_CMD_GET_EXTRA_PARAM = DP_CMD_NONE + 54, - DP_CMD_GET_RECEIVED_SIZE = DP_CMD_NONE + 71, - DP_CMD_GET_TOTAL_FILE_SIZE = DP_CMD_NONE + 72, - DP_CMD_GET_CONTENT_NAME = DP_CMD_NONE + 73, - DP_CMD_GET_HTTP_STATUS = DP_CMD_NONE + 74, - DP_CMD_GET_ETAG = DP_CMD_NONE + 75, - DP_CMD_GET_STATE = DP_CMD_NONE + 81, - DP_CMD_GET_ERROR = DP_CMD_NONE + 91, - DP_CMD_SET_COMMAND_SOCKET = DP_CMD_NONE + 100, - DP_CMD_SET_EVENT_SOCKET = DP_CMD_NONE + 101 - } dp_command_type; - - typedef enum { - DP_STATE_NONE = 0, - DP_STATE_READY = DP_STATE_NONE + 5, // created id, set some info. - DP_STATE_QUEUED = DP_STATE_NONE + 10, // request to start - DP_STATE_CONNECTING = DP_STATE_NONE + 15, // try to connect to url - DP_STATE_DOWNLOADING = DP_STATE_NONE + 20, // started - DP_STATE_PAUSE_REQUESTED = DP_STATE_NONE + 25, - DP_STATE_PAUSED = DP_STATE_NONE + 30, // paused actually - DP_STATE_COMPLETED = DP_STATE_NONE + 40, - DP_STATE_CANCELED = DP_STATE_NONE + 45, // stopped with error - DP_STATE_FAILED = DP_STATE_NONE + 50 // failed with error - } dp_state_type; - - typedef enum { - DP_ERROR_NONE = 0, - DP_ERROR_INVALID_PARAMETER = DP_ERROR_NONE + 1, - DP_ERROR_OUT_OF_MEMORY = DP_ERROR_NONE + 2, - DP_ERROR_IO_ERROR = DP_ERROR_NONE + 3, - DP_ERROR_NETWORK_UNREACHABLE = DP_ERROR_NONE + 4, - DP_ERROR_CONNECTION_TIMED_OUT = DP_ERROR_NONE + 5, - DP_ERROR_NO_SPACE = DP_ERROR_NONE + 6, - DP_ERROR_FIELD_NOT_FOUND = DP_ERROR_NONE + 7, - DP_ERROR_INVALID_STATE = DP_ERROR_NONE + 8, - DP_ERROR_CONNECTION_FAILED = DP_ERROR_NONE + 9, - DP_ERROR_INVALID_URL = DP_ERROR_NONE + 10, - DP_ERROR_INVALID_DESTINATION = DP_ERROR_NONE + 11, - DP_ERROR_QUEUE_FULL = DP_ERROR_NONE + 12, - DP_ERROR_ALREADY_COMPLETED = DP_ERROR_NONE + 13, - DP_ERROR_FILE_ALREADY_EXISTS = DP_ERROR_NONE + 14, - DP_ERROR_TOO_MANY_DOWNLOADS = DP_ERROR_NONE + 15, - DP_ERROR_NO_DATA = DP_ERROR_NONE + 17, - DP_ERROR_UNHANDLED_HTTP_CODE = DP_ERROR_NONE + 18, - DP_ERROR_CANNOT_RESUME = DP_ERROR_NONE + 19, - DP_ERROR_RESPONSE_TIMEOUT = DP_ERROR_NONE + 50, - DP_ERROR_REQUEST_TIMEOUT = DP_ERROR_NONE + 55, - DP_ERROR_SYSTEM_DOWN = DP_ERROR_NONE + 60, - DP_ERROR_CLIENT_DOWN = DP_ERROR_NONE + 65, - DP_ERROR_ID_NOT_FOUND = DP_ERROR_NONE + 90, - DP_ERROR_UNKNOWN = DP_ERROR_NONE + 100 - } dp_error_type; - - typedef enum { - DP_NETWORK_TYPE_OFF = -1, - DP_NETWORK_TYPE_ALL = 0, - DP_NETWORK_TYPE_WIFI = 1, - DP_NETWORK_TYPE_DATA_NETWORK = 2, - DP_NETWORK_TYPE_ETHERNET = 3, - } dp_network_type; - - typedef struct { - unsigned int length; - char *str; - } dp_string; - - typedef struct { - int id; - dp_state_type state; - dp_error_type err; - unsigned long long received_size; - } dp_event_info; - - typedef struct { - dp_command_type cmd; - int id; - } dp_command; - - // Usage IPC : send(dp_command);send(dp_string); - -#ifdef __cplusplus -} -#endif -#endif