merge with master
authorJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:21:31 +0000 (01:21 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Fri, 15 Mar 2013 16:21:31 +0000 (01:21 +0900)
74 files changed:
CMakeLists.txt
agent/CMakeLists.txt [moved from src/agent/CMakeLists.txt with 92% similarity]
agent/download-agent-basic.c [moved from src/agent/download-agent-basic.c with 99% similarity]
agent/download-agent-client-mgr.c [moved from src/agent/download-agent-client-mgr.c with 100% similarity]
agent/download-agent-debug.c [moved from src/agent/download-agent-debug.c with 100% similarity]
agent/download-agent-dl-info-util.c [moved from src/agent/download-agent-dl-info-util.c with 100% similarity]
agent/download-agent-dl-mgr.c [moved from src/agent/download-agent-dl-mgr.c with 100% similarity]
agent/download-agent-encoding.c [moved from src/agent/download-agent-encoding.c with 100% similarity]
agent/download-agent-file.c [moved from src/agent/download-agent-file.c with 99% similarity]
agent/download-agent-http-mgr.c [moved from src/agent/download-agent-http-mgr.c with 100% similarity]
agent/download-agent-http-misc.c [moved from src/agent/download-agent-http-misc.c with 100% similarity]
agent/download-agent-http-msg-handler.c [moved from src/agent/download-agent-http-msg-handler.c with 100% similarity]
agent/download-agent-http-queue.c [moved from src/agent/download-agent-http-queue.c with 100% similarity]
agent/download-agent-interface.c [moved from src/agent/download-agent-interface.c with 100% similarity]
agent/download-agent-mime-util.c [moved from src/agent/download-agent-mime-util.c with 100% similarity]
agent/download-agent-plugin-conf.c [moved from src/agent/download-agent-plugin-conf.c with 100% similarity]
agent/download-agent-plugin-libsoup.c [moved from src/agent/download-agent-plugin-libsoup.c with 96% similarity]
agent/download-agent-utils-dl-id-history.c [moved from src/agent/download-agent-utils-dl-id-history.c with 100% similarity]
agent/download-agent-utils.c [moved from src/agent/download-agent-utils.c with 100% similarity]
agent/include/download-agent-basic.h [moved from src/agent/include/download-agent-basic.h with 100% similarity]
agent/include/download-agent-client-mgr.h [moved from src/agent/include/download-agent-client-mgr.h with 100% similarity]
agent/include/download-agent-debug.h [moved from src/agent/include/download-agent-debug.h with 100% similarity]
agent/include/download-agent-defs.h [moved from src/agent/include/download-agent-defs.h with 100% similarity]
agent/include/download-agent-dl-info-util.h [moved from src/agent/include/download-agent-dl-info-util.h with 100% similarity]
agent/include/download-agent-dl-mgr.h [moved from src/agent/include/download-agent-dl-mgr.h with 100% similarity]
agent/include/download-agent-encoding.h [moved from src/agent/include/download-agent-encoding.h with 100% similarity]
agent/include/download-agent-file.h [moved from src/agent/include/download-agent-file.h with 97% similarity]
agent/include/download-agent-http-mgr.h [moved from src/agent/include/download-agent-http-mgr.h with 100% similarity]
agent/include/download-agent-http-misc.h [moved from src/agent/include/download-agent-http-misc.h with 100% similarity]
agent/include/download-agent-http-msg-handler.h [moved from src/agent/include/download-agent-http-msg-handler.h with 100% similarity]
agent/include/download-agent-http-queue.h [moved from src/agent/include/download-agent-http-queue.h with 100% similarity]
agent/include/download-agent-interface.h [moved from src/agent/include/download-agent-interface.h with 96% similarity]
agent/include/download-agent-mime-util.h [moved from src/agent/include/download-agent-mime-util.h with 100% similarity]
agent/include/download-agent-plugin-conf.h [moved from src/agent/include/download-agent-plugin-conf.h with 100% similarity]
agent/include/download-agent-plugin-http-interface.h [moved from src/agent/include/download-agent-plugin-http-interface.h with 100% similarity]
agent/include/download-agent-plugin-libsoup.h [moved from src/agent/include/download-agent-plugin-libsoup.h with 100% similarity]
agent/include/download-agent-pthread.h [moved from src/agent/include/download-agent-pthread.h with 100% similarity]
agent/include/download-agent-type.h [moved from src/agent/include/download-agent-type.h with 100% similarity]
agent/include/download-agent-utils-dl-id-history.h [moved from src/agent/include/download-agent-utils-dl-id-history.h with 100% similarity]
agent/include/download-agent-utils.h [moved from src/agent/include/download-agent-utils.h with 100% similarity]
download-provider.manifest
download-provider.pc.in
org.download-provider.service.in [moved from download-provider-service.service.in with 100% similarity, mode: 0755]
packaging/download-provider.spec
provider-interface/CMakeLists.txt [new file with mode: 0755]
provider-interface/download-provider-interface.c [new file with mode: 0755]
provider-interface/download-provider-interface.pc.in [new file with mode: 0644]
provider-interface/include/download-provider-interface.h [new file with mode: 0755]
provider/CMakeLists.txt [moved from src/CMakeLists.txt with 67% similarity]
provider/download-provider-da-interface.c [moved from src/download-provider-da-interface.c with 99% similarity]
provider/download-provider-db.c [moved from src/download-provider-db.c with 78% similarity]
provider/download-provider-main.c [moved from src/download-provider-main.c with 98% similarity]
provider/download-provider-network.c [moved from src/download-provider-network.c with 100% similarity]
provider/download-provider-notification.c [moved from src/download-provider-notification.c with 62% similarity]
provider/download-provider-pid.c [moved from src/download-provider-pid.c with 100% similarity]
provider/download-provider-request.c [moved from src/download-provider-request.c with 99% similarity]
provider/download-provider-slots.c [moved from src/download-provider-slots.c with 92% similarity]
provider/download-provider-socket.c [moved from src/download-provider-socket.c with 99% similarity]
provider/download-provider-thread-queue.c [moved from src/download-provider-thread-queue.c with 100% similarity]
provider/download-provider-thread-request.c [moved from src/download-provider-thread-request.c with 72% similarity]
provider/include/download-provider-config.h [moved from src/include/download-provider-config.h with 100% similarity]
provider/include/download-provider-da-interface.h [moved from src/include/download-provider-da-interface.h with 100% similarity]
provider/include/download-provider-db.h [moved from src/include/download-provider-db.h with 90% similarity]
provider/include/download-provider-defs.h [new file with mode: 0755]
provider/include/download-provider-log.h [moved from src/include/download-provider-log.h with 100% similarity]
provider/include/download-provider-network.h [moved from src/include/download-provider-network.h with 100% similarity]
provider/include/download-provider-notification.h [moved from src/include/download-provider-notification.h with 100% similarity]
provider/include/download-provider-pthread.h [moved from src/include/download-provider-pthread.h with 100% similarity]
provider/include/download-provider-queue.h [moved from src/include/download-provider-queue.h with 100% similarity]
provider/include/download-provider-request.h [moved from src/include/download-provider-request.h with 100% similarity]
provider/include/download-provider-slots.h [moved from src/include/download-provider-slots.h with 100% similarity]
provider/include/download-provider-socket.h [moved from src/include/download-provider-socket.h with 100% similarity]
provider/include/download-provider.h [new file with mode: 0755]
src/include/download-provider.h [deleted file]

index 51cd43a..9714c18 100755 (executable)
@@ -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)
similarity index 92%
rename from src/agent/CMakeLists.txt
rename to agent/CMakeLists.txt
index ead1561..26f2b34 100755 (executable)
@@ -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)
 
similarity index 99%
rename from src/agent/download-agent-basic.c
rename to agent/download-agent-basic.c
index 03f3a8a..8a7681c 100755 (executable)
@@ -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) {
similarity index 99%
rename from src/agent/download-agent-file.c
rename to agent/download-agent-file.c
index a048c23..e44863f 100755 (executable)
@@ -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;
similarity index 96%
rename from src/agent/download-agent-plugin-libsoup.c
rename to agent/download-agent-plugin-libsoup.c
index fe4b015..8ef16d0 100755 (executable)
@@ -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);
        }
 }
-
similarity index 97%
rename from src/agent/include/download-agent-file.h
rename to agent/include/download-agent-file.h
index 3bada44..fa886f7 100755 (executable)
@@ -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);
 
similarity index 96%
rename from src/agent/include/download-agent-interface.h
rename to agent/include/download-agent-interface.h
index d51aed6..83d6a0f 100755 (executable)
 #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
 }
index b2cca84..dd4b8e4 100755 (executable)
@@ -12,8 +12,8 @@
                <domain name="download-provider" />
        </request>
        <assign>
-               <filesystem path="/usr/lib/libdownloadagent2.so" label="_" />
-               <filesystem path="/usr/lib/libdownloadagent2.so.0.0.1" label="_" />
+               <filesystem path="/usr/lib/libdownload-provider-interface.so*" label="_" exec_label="none" />
+               <filesystem path="/usr/lib/libdownloadagent2.so*" label="_" exec_label="none" />
                <filesystem path="/etc/rc.d/init.d/download-provider-service" label="_" exec_label="none" />
                <filesystem path="/etc/rc.d/rc3.d/S70download-provider-service" label="_" exec_label="none" />
                <filesystem path="/etc/rc.d/rc5.d/S70download-provider-service" label="_" exec_label="none" />
index 5ec2085..72ea9e5 100644 (file)
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
similarity index 100%
rename from download-provider-service.service.in
rename to org.download-provider.service.in
index 9fca5cc..5038121 100755 (executable)
@@ -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 <jungki.kwak@samsung.com>
+- 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 <justine.bang@samsung.com>
 - [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 (executable)
index 0000000..1253d80
--- /dev/null
@@ -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 (executable)
index 0000000..a6a3caa
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <pthread.h>
+#include <signal.h>
+
+#include <dlog.h>
+#include <download-provider-interface.h>
+#include <download-provider.h>
+
+#ifdef DP_DBUS_ACTIVATION
+#include <dbus/dbus.h>
+#endif
+
+#ifdef DP_ECHO_TEST
+#include <sys/ioctl.h>
+#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 <dlog.h>
+#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 (file)
index 0000000..35e1cc9
--- /dev/null
@@ -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 (executable)
index 0000000..9800dee
--- /dev/null
@@ -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 <tizen.h>
+
+#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__ */
similarity index 67%
rename from src/CMakeLists.txt
rename to provider/CMakeLists.txt
index 66ca5cb..e65f638 100755 (executable)
@@ -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})
similarity index 99%
rename from src/download-provider-da-interface.c
rename to provider/download-provider-da-interface.c
index 2d875c3..14e77d3 100755 (executable)
@@ -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;
        }
similarity index 78%
rename from src/download-provider-db.c
rename to provider/download-provider-db.c
index 0c9d5b6..476f725 100755 (executable)
@@ -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;
+}
+
similarity index 98%
rename from src/download-provider-main.c
rename to provider/download-provider-main.c
index 79968ba..96495ec 100755 (executable)
@@ -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
similarity index 62%
rename from src/download-provider-notification.c
rename to provider/download-provider-notification.c
index f04b010..6b7a167 100755 (executable)
 #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;
 }
similarity index 99%
rename from src/download-provider-request.c
rename to provider/download-provider-request.c
index 869a9e5..c9c70ad 100755 (executable)
@@ -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);
similarity index 92%
rename from src/download-provider-slots.c
rename to provider/download-provider-slots.c
index 208f993..e2c4732 100755 (executable)
@@ -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;
 }
 
similarity index 99%
rename from src/download-provider-socket.c
rename to provider/download-provider-socket.c
index 0899ffe..b7728bc 100755 (executable)
@@ -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);
similarity index 72%
rename from src/download-provider-thread-request.c
rename to provider/download-provider-thread-request.c
index a4ae548..1ab5f24 100755 (executable)
@@ -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
similarity index 90%
rename from src/include/download-provider-db.h
rename to provider/include/download-provider-db.h
index 1618e67..f964676 100755 (executable)
@@ -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 (executable)
index 0000000..0eac01c
--- /dev/null
@@ -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/provider/include/download-provider.h b/provider/include/download-provider.h
new file mode 100755 (executable)
index 0000000..d0a4ca6
--- /dev/null
@@ -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 (executable)
index 5083ecd..0000000
+++ /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