summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt58
-rwxr-xr-xagent/CMakeLists.txt138
-rwxr-xr-xagent/download-agent-basic.c431
-rwxr-xr-xagent/download-agent-client-mgr.c680
-rwxr-xr-xagent/download-agent-debug.c205
-rwxr-xr-xagent/download-agent-dl-info-util.c498
-rw-r--r--agent/download-agent-dl-info.c462
-rwxr-xr-xagent/download-agent-dl-mgr.c356
-rwxr-xr-xagent/download-agent-encoding.c61
-rwxr-xr-xagent/download-agent-file.c1477
-rwxr-xr-xagent/download-agent-http-mgr.c2594
-rwxr-xr-xagent/download-agent-http-misc.c64
-rwxr-xr-xagent/download-agent-http-msg-handler.c552
-rwxr-xr-xagent/download-agent-http-queue.c390
-rwxr-xr-xagent/download-agent-interface.c224
-rwxr-xr-xagent/download-agent-mime-util.c112
-rwxr-xr-xagent/download-agent-plugin-conf.c65
-rw-r--r--agent/download-agent-plugin-drm.c124
-rw-r--r--agent/download-agent-plugin-libcurl.c702
-rwxr-xr-xagent/download-agent-plugin-libsoup.c1002
-rwxr-xr-xagent/download-agent-utils-dl-id-history.c71
-rwxr-xr-xagent/download-agent-utils.c285
-rwxr-xr-xagent/include/download-agent-client-mgr.h77
-rwxr-xr-xagent/include/download-agent-debug.h109
-rwxr-xr-xagent/include/download-agent-defs.h32
-rwxr-xr-xagent/include/download-agent-dl-info-util.h257
-rw-r--r--agent/include/download-agent-dl-info.h197
-rwxr-xr-xagent/include/download-agent-dl-mgr.h20
-rwxr-xr-xagent/include/download-agent-encoding.h2
-rwxr-xr-xagent/include/download-agent-file.h45
-rwxr-xr-xagent/include/download-agent-http-mgr.h25
-rwxr-xr-xagent/include/download-agent-http-misc.h47
-rwxr-xr-xagent/include/download-agent-http-msg-handler.h101
-rwxr-xr-xagent/include/download-agent-http-queue.h126
-rwxr-xr-xagent/include/download-agent-interface.h445
-rwxr-xr-xagent/include/download-agent-mime-util.h10
-rwxr-xr-xagent/include/download-agent-plugin-conf.h7
-rw-r--r--[-rwxr-xr-x]agent/include/download-agent-plugin-drm.h (renamed from agent/include/download-agent-basic.h)12
-rwxr-xr-xagent/include/download-agent-plugin-http-interface.h51
-rw-r--r--agent/include/download-agent-plugin-libcurl.h35
-rwxr-xr-xagent/include/download-agent-plugin-libsoup.h75
-rwxr-xr-xagent/include/download-agent-pthread.h243
-rwxr-xr-xagent/include/download-agent-type.h44
-rwxr-xr-xagent/include/download-agent-utils.h60
-rw-r--r--download-provider-schema.sql74
-rw-r--r--download-provider-w.manifest36
-rw-r--r--[-rwxr-xr-x]download-provider.manifest19
-rw-r--r--download-provider.rule17
-rw-r--r--dump-download-provider.sh14
-rw-r--r--[-rwxr-xr-x]packaging/download-provider.spec183
-rwxr-xr-xpo/POTFILES.in.in2
-rwxr-xr-xpo/ar.po3
-rwxr-xr-xpo/az.po3
-rwxr-xr-xpo/bg.po3
-rwxr-xr-xpo/ca.po3
-rwxr-xr-xpo/cs.po3
-rwxr-xr-xpo/da.po3
-rwxr-xr-xpo/de_DE.po3
-rwxr-xr-xpo/en.po3
-rwxr-xr-xpo/en_PH.po3
-rwxr-xr-xpo/en_US.po3
-rwxr-xr-xpo/es_ES.po3
-rwxr-xr-xpo/es_MX.po3
-rwxr-xr-xpo/eu.po3
-rwxr-xr-xpo/fi.po3
-rwxr-xr-xpo/fr_CA.po3
-rwxr-xr-xpo/fr_FR.po3
-rwxr-xr-xpo/ga.po3
-rwxr-xr-xpo/gl.po3
-rwxr-xr-xpo/hi.po3
-rwxr-xr-xpo/hr.po3
-rwxr-xr-xpo/hu.po3
-rwxr-xr-xpo/hy.po3
-rwxr-xr-xpo/is.po3
-rwxr-xr-xpo/it_IT.po3
-rwxr-xr-xpo/ja_JP.po3
-rwxr-xr-xpo/kk.po3
-rwxr-xr-xpo/ko_KR.po3
-rwxr-xr-xpo/lt.po3
-rwxr-xr-xpo/lv.po3
-rwxr-xr-xpo/mk.po3
-rwxr-xr-xpo/nb.po3
-rwxr-xr-xpo/nl_NL.po3
-rwxr-xr-xpo/pl.po3
-rwxr-xr-xpo/pt_BR.po3
-rwxr-xr-xpo/pt_PT.po3
-rw-r--r--[-rwxr-xr-x]po/redwood/CMakeLists.txt (renamed from po/CMakeLists.txt)9
-rw-r--r--po/redwood/az.po6
-rw-r--r--po/redwood/bg.po6
-rw-r--r--po/redwood/ca.po6
-rw-r--r--po/redwood/cs.po6
-rw-r--r--po/redwood/da.po6
-rw-r--r--po/redwood/de.po6
-rw-r--r--[-rwxr-xr-x]po/redwood/el_GR.po (renamed from po/el_GR.po)3
-rw-r--r--po/redwood/en.po6
-rw-r--r--po/redwood/en_US.po6
-rw-r--r--po/redwood/es_ES.po6
-rw-r--r--po/redwood/es_US.po6
-rw-r--r--[-rwxr-xr-x]po/redwood/et.po (renamed from po/et.po)3
-rw-r--r--po/redwood/eu.po6
-rw-r--r--po/redwood/fi.po6
-rw-r--r--po/redwood/fr.po6
-rw-r--r--po/redwood/fr_CA.po6
-rw-r--r--po/redwood/gl.po6
-rw-r--r--po/redwood/hr.po6
-rw-r--r--po/redwood/hu.po6
-rw-r--r--po/redwood/hy.po6
-rw-r--r--po/redwood/is.po6
-rw-r--r--po/redwood/it_IT.po6
-rw-r--r--[-rwxr-xr-x]po/redwood/ka.po (renamed from po/ka.po)3
-rw-r--r--po/redwood/kk.po6
-rw-r--r--po/redwood/ko_KR.po6
-rw-r--r--po/redwood/lt.po6
-rw-r--r--po/redwood/lv.po6
-rw-r--r--po/redwood/mn_MN.po6
-rw-r--r--po/redwood/nb.po6
-rw-r--r--po/redwood/nl.po6
-rw-r--r--po/redwood/pl.po6
-rw-r--r--po/redwood/pt_BR.po6
-rw-r--r--po/redwood/pt_PT.po6
-rw-r--r--po/redwood/ro.po6
-rw-r--r--[-rwxr-xr-x]po/redwood/ru_RU.po (renamed from po/ru_RU.po)3
-rw-r--r--po/redwood/sk.po6
-rw-r--r--po/redwood/sl.po6
-rw-r--r--po/redwood/sr.po6
-rw-r--r--po/redwood/sv.po6
-rw-r--r--po/redwood/tr_TR.po6
-rw-r--r--[-rwxr-xr-x]po/redwood/uk.po (renamed from po/uk.po)3
-rw-r--r--po/redwood/uz.po6
-rwxr-xr-xpo/ro.po3
-rwxr-xr-xpo/sk.po3
-rwxr-xr-xpo/sl.po3
-rwxr-xr-xpo/sr.po3
-rwxr-xr-xpo/sv.po3
-rw-r--r--po/tizen2.3/CMakeLists.txt30
-rw-r--r--po/tizen2.3/ar.po6
-rw-r--r--po/tizen2.3/az.po6
-rw-r--r--po/tizen2.3/bg.po6
-rw-r--r--po/tizen2.3/ca.po6
-rw-r--r--po/tizen2.3/cs.po6
-rw-r--r--po/tizen2.3/da.po6
-rw-r--r--po/tizen2.3/de.po6
-rw-r--r--po/tizen2.3/el_GR.po6
-rw-r--r--po/tizen2.3/en.po6
-rw-r--r--po/tizen2.3/en_PH.po6
-rw-r--r--po/tizen2.3/en_US.po6
-rw-r--r--po/tizen2.3/es_ES.po6
-rw-r--r--po/tizen2.3/es_US.po6
-rw-r--r--po/tizen2.3/et.po6
-rw-r--r--po/tizen2.3/eu.po6
-rw-r--r--po/tizen2.3/fi.po6
-rw-r--r--po/tizen2.3/fr.po6
-rw-r--r--po/tizen2.3/fr_CA.po6
-rw-r--r--po/tizen2.3/ga.po6
-rw-r--r--po/tizen2.3/gl.po6
-rw-r--r--po/tizen2.3/hi.po6
-rw-r--r--po/tizen2.3/hr.po6
-rw-r--r--po/tizen2.3/hu.po6
-rw-r--r--po/tizen2.3/hy.po6
-rw-r--r--po/tizen2.3/is.po6
-rw-r--r--po/tizen2.3/it_IT.po6
-rw-r--r--po/tizen2.3/ja_JP.po6
-rw-r--r--po/tizen2.3/ka.po6
-rw-r--r--po/tizen2.3/kk.po6
-rw-r--r--po/tizen2.3/ko_KR.po6
-rw-r--r--po/tizen2.3/lt.po6
-rw-r--r--po/tizen2.3/lv.po6
-rw-r--r--po/tizen2.3/mk.po6
-rw-r--r--po/tizen2.3/nb.po6
-rw-r--r--po/tizen2.3/nl.po6
-rw-r--r--po/tizen2.3/pl.po6
-rw-r--r--po/tizen2.3/pt_BR.po6
-rw-r--r--po/tizen2.3/pt_PT.po6
-rw-r--r--po/tizen2.3/ro.po6
-rw-r--r--po/tizen2.3/ru_RU.po6
-rw-r--r--po/tizen2.3/sk.po6
-rw-r--r--po/tizen2.3/sl.po6
-rw-r--r--po/tizen2.3/sr.po6
-rw-r--r--po/tizen2.3/sv.po6
-rw-r--r--po/tizen2.3/tr_TR.po6
-rw-r--r--po/tizen2.3/uk.po6
-rw-r--r--po/tizen2.3/uz.po6
-rw-r--r--po/tizen2.3/zh_CN.po6
-rw-r--r--po/tizen2.3/zh_HK.po6
-rw-r--r--po/tizen2.3/zh_TW.po6
-rwxr-xr-xpo/tr_TR.po3
-rwxr-xr-xpo/uz.po3
-rwxr-xr-xpo/zh_CN.po3
-rwxr-xr-xpo/zh_HK.po3
-rwxr-xr-xpo/zh_SG.po3
-rwxr-xr-xpo/zh_TW.po3
-rwxr-xr-xprovider-interface/CMakeLists.txt7
-rwxr-xr-xprovider-interface/download-provider-interface.c2462
-rw-r--r--provider-interface/download-provider-interface.pc.in2
-rwxr-xr-xprovider-interface/include/download-provider-interface.h72
-rwxr-xr-xprovider/CMakeLists.txt86
-rw-r--r--provider/download-provider-client-manager.c741
-rw-r--r--provider/download-provider-client.c2110
-rwxr-xr-xprovider/download-provider-da-interface.c903
-rwxr-xr-xprovider/download-provider-db.c2917
-rw-r--r--provider/download-provider-ipc.c132
-rwxr-xr-xprovider/download-provider-main.c301
-rwxr-xr-xprovider/download-provider-network.c412
-rw-r--r--provider/download-provider-notification-manager.c573
-rwxr-xr-xprovider/download-provider-notification.c793
-rw-r--r--provider/download-provider-notify.c103
-rw-r--r--provider/download-provider-plugin-download-agent.c989
-rw-r--r--provider/download-provider-pthread.c110
-rw-r--r--provider/download-provider-queue-manager.c315
-rw-r--r--provider/download-provider-queue.c194
-rwxr-xr-xprovider/download-provider-request.c941
-rwxr-xr-xprovider/download-provider-slots.c174
-rw-r--r--provider/download-provider-smack.c165
-rwxr-xr-xprovider/download-provider-socket.c351
-rwxr-xr-xprovider/download-provider-thread-queue.c398
-rwxr-xr-xprovider/download-provider-thread-request.c2158
-rw-r--r--provider/download-provider-utils.c103
-rw-r--r--provider/include/download-provider-client-manager.h35
-rw-r--r--provider/include/download-provider-client.h60
-rwxr-xr-xprovider/include/download-provider-config.h35
-rw-r--r--provider/include/download-provider-db-defs.h157
-rwxr-xr-xprovider/include/download-provider-db.h264
-rwxr-xr-xprovider/include/download-provider-defs.h93
-rw-r--r--[-rwxr-xr-x]provider/include/download-provider-ipc.h (renamed from provider/download-provider-pid.c)38
-rwxr-xr-xprovider/include/download-provider-log.h14
-rwxr-xr-xprovider/include/download-provider-network.h26
-rw-r--r--provider/include/download-provider-notification-manager.h33
-rwxr-xr-xprovider/include/download-provider-notification.h24
-rw-r--r--provider/include/download-provider-notify.h24
-rw-r--r--[-rwxr-xr-x]provider/include/download-provider-plugin-download-agent.h (renamed from provider/include/download-provider-da-interface.h)14
-rwxr-xr-xprovider/include/download-provider-pthread.h82
-rw-r--r--provider/include/download-provider-queue-manager.h25
-rwxr-xr-xprovider/include/download-provider-queue.h18
-rwxr-xr-xprovider/include/download-provider-request.h58
-rwxr-xr-xprovider/include/download-provider-slots.h90
-rw-r--r--provider/include/download-provider-smack.h33
-rwxr-xr-xprovider/include/download-provider-socket.h43
-rw-r--r--[-rwxr-xr-x]provider/include/download-provider-utils.h (renamed from agent/include/download-agent-utils-dl-id-history.h)24
-rwxr-xr-xprovider/include/download-provider.h237
-rw-r--r--res/images/Notification_download_animation.gifbin4631 -> 0 bytes
-rw-r--r--res/images/Q02_Notification_download_complete.pngbin1917 -> 0 bytes
-rw-r--r--res/images/Q02_Notification_download_failed.pngbin2830 -> 0 bytes
-rw-r--r--res/images/redwood/B03_processing_download_complete.pngbin0 -> 3117 bytes
-rw-r--r--res/images/redwood/B03_processing_download_fail.pngbin0 -> 1600 bytes
-rw-r--r--res/images/redwood/U01_icon_broken.pngbin0 -> 4017 bytes
-rw-r--r--res/images/redwood/U01_icon_drm.pngbin0 -> 4077 bytes
-rw-r--r--res/images/redwood/U01_icon_excel.pngbin0 -> 4512 bytes
-rw-r--r--res/images/redwood/U01_icon_html.pngbin0 -> 5063 bytes
-rw-r--r--res/images/redwood/U01_icon_pdf.pngbin0 -> 4686 bytes
-rw-r--r--res/images/redwood/U01_icon_ppt.pngbin0 -> 3946 bytes
-rw-r--r--res/images/redwood/U01_icon_swf.pngbin0 -> 4233 bytes
-rw-r--r--res/images/redwood/U01_icon_text.pngbin0 -> 3832 bytes
-rw-r--r--res/images/redwood/U01_icon_tpk.pngbin0 -> 5319 bytes
-rw-r--r--res/images/redwood/U01_icon_unkown.pngbin0 -> 3888 bytes
-rw-r--r--res/images/redwood/U01_icon_vcs.pngbin0 -> 3835 bytes
-rw-r--r--res/images/redwood/U01_icon_word.pngbin0 -> 4669 bytes
-rw-r--r--res/images/redwood/U01_list_icon_image.pngbin0 -> 4162 bytes
-rw-r--r--res/images/redwood/U01_list_icon_mp3.pngbin0 -> 4154 bytes
-rw-r--r--res/images/redwood/U01_list_icon_mp4.pngbin0 -> 3851 bytes
-rw-r--r--res/images/redwood/noti_download_complete.pngbin0 -> 6935 bytes
-rw-r--r--res/images/redwood/noti_download_failed.pngbin0 -> 8035 bytes
-rw-r--r--res/images/tizen2.3/B03_Processing_download_complete.pngbin0 -> 1268 bytes
-rw-r--r--res/images/tizen2.3/B03_Processing_download_failed.pngbin0 -> 1421 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_date.pngbin0 -> 1606 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_drm.pngbin0 -> 1701 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_html.pngbin0 -> 2359 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_img.pngbin0 -> 1765 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_movie.pngbin0 -> 1640 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_music.pngbin0 -> 1786 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_pdf.pngbin0 -> 2005 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_ppt.pngbin0 -> 1499 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_swf.pngbin0 -> 1878 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_text.pngbin0 -> 1600 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_tpk.pngbin0 -> 2546 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_unknown.pngbin0 -> 1631 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_word.pngbin0 -> 1930 bytes
-rw-r--r--res/images/tizen2.3/download_manager_icon_xls.pngbin0 -> 1854 bytes
-rw-r--r--systemd/download-provider.service1
-rw-r--r--systemd/download-provider.socket6
279 files changed, 13817 insertions, 18759 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2511e8e..67d6e27 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,12 +21,36 @@ IF(DEFINED SUPPORT_LOG_MESSAGE)
ENDIF(SUPPORT_LOG_MESSAGE)
ENDIF(DEFINED SUPPORT_LOG_MESSAGE)
-IF(DEFINED SUPPORT_CHECK_IPC)
- MESSAGE("SUPPORT_CHECK_IPC: ${SUPPORT_CHECK_IPC}")
- IF(SUPPORT_CHECK_IPC)
- ADD_DEFINITIONS(-DSUPPORT_CHECK_IPC)
- ENDIF(SUPPORT_CHECK_IPC)
-ENDIF(DEFINED SUPPORT_CHECK_IPC)
+IF(DEFINED IPC_SOCKET)
+ ADD_DEFINITIONS(-DIPC_SOCKET=\"${IPC_SOCKET}\")
+ENDIF(DEFINED IPC_SOCKET)
+
+IF(DEFINED NOTIFY_DIR)
+ ADD_DEFINITIONS(-DNOTIFY_DIR=\"${NOTIFY_DIR}\")
+ENDIF(DEFINED NOTIFY_DIR)
+
+IF(DEFINED LOCALE_DIR)
+ ADD_DEFINITIONS(-DLOCALE_DIR=\"${LOCALE_DIR}\")
+ENDIF(DEFINED LOCALE_DIR)
+
+IF(DEFINED SUPPORT_SECURITY_PRIVILEGE)
+ MESSAGE("SUPPORT_SECURITY_PRIVILEGE: ${SUPPORT_SECURITY_PRIVILEGE}")
+ IF(SUPPORT_SECURITY_PRIVILEGE)
+ ADD_DEFINITIONS(-DSUPPORT_SECURITY_PRIVILEGE)
+ ENDIF(SUPPORT_SECURITY_PRIVILEGE)
+ENDIF(DEFINED SUPPORT_SECURITY_PRIVILEGE)
+
+IF(DEFINED SUPPORT_COMPANION_MODE)
+ MESSAGE("SUPPORT_COMPANION_MODE: ${SUPPORT_COMPANION_MODE}")
+ IF(SUPPORT_COMPANION_MODE)
+ ADD_DEFINITIONS(-DSUPPORT_COMPANION_MODE)
+ ENDIF(SUPPORT_COMPANION_MODE)
+ENDIF(DEFINED SUPPORT_COMPANION_MODE)
+
+IF (TIZEN_2_3_UX)
+ MESSAGE("TIZEN_2_3_UX:On")
+ ADD_DEFINITIONS("-D_TIZEN_2_3_UX")
+ENDIF(TIZEN_2_3_UX)
# BUILD
@@ -34,7 +58,11 @@ ADD_SUBDIRECTORY(agent)
ADD_SUBDIRECTORY(provider-interface)
ADD_SUBDIRECTORY(provider)
# i18n
-ADD_SUBDIRECTORY(po)
+IF(TIZEN_2_3_UX)
+ADD_SUBDIRECTORY(po/tizen2.3)
+ELSE(TIZEN_2_3_UX)
+ADD_SUBDIRECTORY(po/redwood)
+ENDIF(TIZEN_2_3_UX)
# INSTALL
@@ -47,21 +75,17 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/download-provider.pc DESTINATION ${LIB
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/systemd/download-provider.service DESTINATION /usr/lib/systemd/system)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/systemd/download-provider.socket DESTINATION /usr/lib/systemd/system)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/download-provider-schema.sql DESTINATION ${DATABASE_SCHEMA_DIR})
-
# install images
-INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/images/ DESTINATION ${IMAGE_DIR}
- FILES_MATCHING
- PATTERN "*.png"
- PATTERN "*.gif"
- )
+IF(TIZEN_2_3_UX)
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/images/tizen2.3/ DESTINATION ${IMAGE_DIR})
+ELSE(TIZEN_2_3_UX)
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/images/redwood/ DESTINATION ${IMAGE_DIR})
+ENDIF(TIZEN_2_3_UX)
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)
-IF(DEFINED SMACK_RULE_DIR)
- INSTALL(FILES ${PROJECT_NAME}.rule DESTINATION ${SMACK_RULE_DIR})
-ENDIF(DEFINED SMACK_RULE_DIR)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/dump-download-provider.sh DESTINATION ${CMAKE_LOG_DUMP_SCRIPT_DIR})
diff --git a/agent/CMakeLists.txt b/agent/CMakeLists.txt
index 26f2b34..c92fc48 100755
--- a/agent/CMakeLists.txt
+++ b/agent/CMakeLists.txt
@@ -1,67 +1,27 @@
PROJECT(downloadagent2 C)
-IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
- SET(CMAKE_BUILD_TYPE "Debug")
-ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
-MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+SET(VERSION "0.1.0")
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-SET(VERSION "0.0.1")
FIND_PROGRAM(UNAME NAMES uname)
EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
-
-#DA Engine Include Directory
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include)
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(subpkgs REQUIRED
- libsoup-2.4
- xdgmime
- vconf
- capi-network-connection
- glib-2.0
- dlog
-)
-
-FOREACH(flag ${subpkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -Wall")
-
IF("${ARCH}" MATCHES "^arm.*")
ADD_DEFINITIONS("-D_TARGET")
SET(CMAKE_C_FLAGS_RELEASE "-mabi=aapcs-linux -msoft-float -O2")
ENDIF("${ARCH}" MATCHES "^arm.*")
-ADD_DEFINITIONS("-D_EFL_PLATFORM")
-#allow to install widget, deb pkg and apk for testing
-ADD_DEFINITIONS("-DDA_DEBUG_USING_DLOG")
-#This should be removed when release a target
-ADD_DEFINITIONS("-D_SAMSUNG_MIME_POLICY")
-
-#############################################################################
-#+++++++++++++++++++++++++DA ENGINE+++++++++++++++++++++++++++++++++++++++++++
-#############################################################################
+#DA Engine Include Directory
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include)
SET(SRCS_PATH ".")
-SET(SRCS_DA_ENGINE
- ${SRCS_PATH}/download-agent-debug.c
+SET(SRCS_DA
${SRCS_PATH}/download-agent-interface.c
${SRCS_PATH}/download-agent-client-mgr.c
${SRCS_PATH}/download-agent-dl-mgr.c
- ${SRCS_PATH}/download-agent-dl-info-util.c
- ${SRCS_PATH}/download-agent-http-queue.c
- ${SRCS_PATH}/download-agent-http-misc.c
+ ${SRCS_PATH}/download-agent-dl-info.c
${SRCS_PATH}/download-agent-http-mgr.c
${SRCS_PATH}/download-agent-http-msg-handler.c
${SRCS_PATH}/download-agent-encoding.c
- ${SRCS_PATH}/download-agent-utils.c
- ${SRCS_PATH}/download-agent-utils-dl-id-history.c
- ${SRCS_PATH}/download-agent-basic.c
${SRCS_PATH}/download-agent-file.c
- ${SRCS_PATH}/download-agent-plugin-libsoup.c
${SRCS_PATH}/download-agent-plugin-conf.c
${SRCS_PATH}/download-agent-mime-util.c
)
@@ -71,14 +31,86 @@ SET(HEADERS
include/download-agent-interface.h
)
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS_DA_ENGINE})
-#TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${subpkgs_LDFLAGS} "-ldl")
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${subpkgs_LDFLAGS})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION 0.0.1)
+INCLUDE(FindPkgConfig)
+
+MESSAGE("SUPPORT_SYS_RESOURCE: ${SUPPORT_SYS_RESOURCE}")
+IF (SUPPORT_SYS_RESOURCE)
+pkg_check_modules(subpkgs REQUIRED
+ xdgmime
+ vconf
+ capi-network-connection
+ dlog
+ system-resource
+ storage
+)
+ELSE (SUPPORT_SYS_RESOURCE)
+pkg_check_modules(subpkgs REQUIRED
+ xdgmime
+ vconf
+ capi-network-connection
+ dlog
+ storage
+)
+ENDIF (SUPPORT_SYS_RESOURCE)
+
+IF ("${HTTP_LIB}" MATCHES "libcurl")
+ MESSAGE("HTTP_LIB: ${HTTP_LIB}")
+ pkg_check_modules(httppkgs REQUIRED
+ libcurl
+ )
+ LIST(APPEND SRCS_DA
+ ${SRCS_PATH}/download-agent-plugin-libcurl.c
+ )
+ENDIF ("${HTTP_LIB}" MATCHES "libcurl")
-#############################################################################
-#+++++++++++++++++++++++++INSTALLATION++++++++++++++++++++++++++++++++++++++++
-#############################################################################
+IF (SUPPORT_OMA_DRM)
+ MESSAGE("SUPPORT_OMA_DRM: ${SUPPORT_OMA_DRM}")
+ ADD_DEFINITIONS("-D_ENABLE_OMA_DRM")
+ LIST(APPEND SRCS_DA
+ ${SRCS_PATH}/download-agent-plugin-drm.c
+ )
+ pkg_check_modules(drmpkgs REQUIRED
+ drm-client
+ drm-trusted
+ )
+ENDIF (SUPPORT_OMA_DRM)
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+IF (SUPPORT_SYS_RESOURCE)
+ ADD_DEFINITIONS("-D_ENABLE_SYS_RESOURCE")
+ENDIF (SUPPORT_SYS_RESOURCE)
+
+IF (SUPPORT_DOWNLOAD_BOOSTER)
+ MESSAGE("SUPPORT_DOWNLOAD_BOOSTER:${SUPPORT_DOWNLOAD_BOOSTER}")
+ ADD_DEFINITIONS("-D_RAF_SUPPORT")
+ ADD_DEFINITIONS("-D_DOWNLOAD_BOOSTER_SUPPORT")
+ENDIF (SUPPORT_DOWNLOAD_BOOSTER)
+FOREACH(flag ${subpkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${httppkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+IF (SUPPORT_OMA_DRM)
+ FOREACH(flag ${drmpkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ ENDFOREACH(flag)
+ #This is request of DRM Team.
+ ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64")
+ENDIF (SUPPORT_OMA_DRM)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -Wall")
+
+ADD_DEFINITIONS("-D_ENABLE_DLOG")
+#This should be removed when release a target
+ADD_DEFINITIONS("-D_SAMSUNG_MIME_POLICY")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS_DA})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${subpkgs_LDFLAGS} ${httppkgs_LDFLAGS} ${drmpkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
diff --git a/agent/download-agent-basic.c b/agent/download-agent-basic.c
deleted file mode 100755
index 73fc892..0000000
--- a/agent/download-agent-basic.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-
-#include "download-agent-basic.h"
-#include "download-agent-debug.h"
-#include "download-agent-client-mgr.h"
-#include "download-agent-utils.h"
-#include "download-agent-http-mgr.h"
-#include "download-agent-http-misc.h"
-#include "download-agent-dl-mgr.h"
-#include "download-agent-pthread.h"
-#include "download-agent-file.h"
-
-static void* __thread_start_download(void* data);
-void __thread_clean_up_handler_for_start_download(void *arg);
-
-static da_result_t __make_source_info_basic_download(
- stage_info *stage,
- client_input_t *client_input);
-static da_result_t __download_content(stage_info *stage);
-
-da_result_t start_download(const char *url , int *dl_id)
-{
- DA_LOG_FUNC_LOGD(Default);
- return start_download_with_extension(url, dl_id, NULL);
-}
-
-da_result_t start_download_with_extension(
- const char *url,
- int *dl_id,
- extension_data_t *extension_data)
-{
- da_result_t ret = DA_RESULT_OK;
- int slot_id = 0;
- const char **request_header = DA_NULL;
- const char *install_path = DA_NULL;
- const char *file_name = DA_NULL;
- const char *etag = DA_NULL;
- const char *temp_file_path = DA_NULL;
- const char *pkg_name = DA_NULL;
- int request_header_count = 0;
- void *user_data = DA_NULL;
- client_input_t *client_input = DA_NULL;
- client_input_basic_t *client_input_basic = DA_NULL;
- download_thread_input *thread_info = DA_NULL;
- pthread_attr_t thread_attr;
-
- DA_LOG_FUNC_LOGV(Default);
-
- if (extension_data) {
- request_header = extension_data->request_header;
- if (extension_data->request_header_count)
- request_header_count = extension_data->request_header_count;
- install_path = extension_data->install_path;
- file_name = extension_data->file_name;
- user_data = extension_data->user_data;
- etag = extension_data->etag;
- temp_file_path = extension_data->temp_file_path;
- pkg_name = extension_data->pkg_name;
- }
-
- ret = get_available_slot_id(&slot_id);
- if (DA_RESULT_OK != ret)
- return ret;
-
- *dl_id = GET_DL_ID(slot_id);
-
- client_input = (client_input_t *)calloc(1, sizeof(client_input_t));
- if (!client_input) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- } else {
- client_input->user_data = user_data;
- if (install_path) {
- int install_path_len = strlen(install_path);
- if (install_path[install_path_len-1] == '/')
- install_path_len--;
-
- client_input->install_path = (char *)calloc(install_path_len+1, sizeof(char));
- if (client_input->install_path)
- strncpy(client_input->install_path, install_path, install_path_len);
- }
-
- if (file_name) {
- client_input->file_name = (char *)calloc(strlen(file_name)+1, sizeof(char));
- if (client_input->file_name)
- strncpy(client_input->file_name, file_name, strlen(file_name));
- }
-
- if (etag) {
- client_input->etag = (char *)calloc(strlen(etag)+1, sizeof(char));
- if (client_input->etag)
- strncpy(client_input->etag, etag, strlen(etag));
-
- }
-
- if (temp_file_path) {
- client_input->temp_file_path = (char *)calloc(strlen(temp_file_path)+1, sizeof(char));
- if (client_input->temp_file_path)
- strncpy(client_input->temp_file_path, temp_file_path, strlen(temp_file_path));
- }
-
- if (pkg_name) {
- client_input->pkg_name = (char *)calloc(strlen(pkg_name)+1, sizeof(char));
- if (client_input->pkg_name)
- strncpy(client_input->pkg_name, pkg_name, strlen(pkg_name));
- }
- client_input_basic = &(client_input->client_input_basic);
- client_input_basic->req_url = (char *)calloc(strlen(url)+1, sizeof(char));
- if(DA_NULL == client_input_basic->req_url) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
- strncpy(client_input_basic->req_url ,url,strlen(url));
-
- if (request_header_count > 0) {
- int i = 0;
- client_input_basic->user_request_header =
- (char **)calloc(1, sizeof(char *)*request_header_count);
- if(DA_NULL == client_input_basic->user_request_header) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
- for (i = 0; i < request_header_count; i++)
- {
- client_input_basic->user_request_header[i] = strdup(request_header[i]);
- }
- client_input_basic->user_request_header_count = request_header_count;
- }
- }
-
- thread_info = (download_thread_input *)calloc(1, sizeof(download_thread_input));
- if (!thread_info) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- } else {
- thread_info->slot_id = slot_id;
- thread_info->client_input = client_input;
- }
- if (pthread_attr_init(&thread_attr) != 0) {
- ret = DA_ERR_FAIL_TO_CREATE_THREAD;
- goto ERR;
- }
-
- if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) {
- ret = DA_ERR_FAIL_TO_CREATE_THREAD;
- goto ERR;
- }
-
- if (pthread_create(&GET_DL_THREAD_ID(slot_id), &thread_attr,
- __thread_start_download, thread_info) < 0) {
- DA_LOG_ERR(Thread, "making thread failed..");
- ret = DA_ERR_FAIL_TO_CREATE_THREAD;
- } else {
- if (GET_DL_THREAD_ID(slot_id) < 1) {
- DA_LOG_ERR(Thread, "The thread start is failed before calling this");
-// When http resource is leaked, the thread ID is initialized at error handling section of thread_start_download()
-// Because the thread ID is initialized, the ptrhead_detach should not be called. This is something like timing issue between threads.
-// thread info and basic_dl_input is freed at thread_start_download(). And it should not returns error code in this case.
- goto ERR;
- }
- }
- DA_LOG_DEBUG(Thread, "download thread create slot_id[%d] thread id[%lu]",
- slot_id,GET_DL_THREAD_ID(slot_id));
-
-ERR:
- if (DA_RESULT_OK != ret) {
- if (client_input) {
- clean_up_client_input_info(client_input);
- free(client_input);
- client_input = DA_NULL;
- }
- if (thread_info) {
- free(thread_info);
- thread_info = DA_NULL;
- }
- destroy_download_info(slot_id);
- }
- return ret;
-}
-
-da_result_t __make_source_info_basic_download(
- stage_info *stage,
- client_input_t *client_input)
-{
- da_result_t ret = DA_RESULT_OK;
- client_input_basic_t *client_input_basic = DA_NULL;
- source_info_t *source_info = DA_NULL;
- source_info_basic_t *source_info_basic = DA_NULL;
-
- DA_LOG_FUNC_LOGV(Default);
-
- if (!stage) {
- DA_LOG_ERR(Default, "no stage; DA_ERR_INVALID_ARGUMENT");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- client_input_basic = &(client_input->client_input_basic);
- if (DA_NULL == client_input_basic->req_url) {
- DA_LOG_ERR(Default, "DA_ERR_INVALID_URL");
- ret = DA_ERR_INVALID_URL;
- goto ERR;
- }
-
- source_info_basic = (source_info_basic_t*)calloc(1, sizeof(source_info_basic_t));
- if (DA_NULL == source_info_basic) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
-
- source_info_basic->url = client_input_basic->req_url;
- client_input_basic->req_url = DA_NULL;
-
- if (client_input_basic->user_request_header) {
- source_info_basic->user_request_header =
- client_input_basic->user_request_header;
- source_info_basic->user_request_header_count =
- client_input_basic->user_request_header_count;
- client_input_basic->user_request_header = DA_NULL;
- client_input_basic->user_request_header_count = 0;
- }
-
- source_info = GET_STAGE_SOURCE_INFO(stage);
- memset(source_info, 0, sizeof(source_info_t));
-
- source_info->source_info_type.source_info_basic = source_info_basic;
-
-// DA_SECURE_LOGI("BASIC HTTP STARTED: URL=%s",
-// source_info->source_info_type.source_info_basic->url);
-ERR:
- return ret;
-}
-
-void __thread_clean_up_handler_for_start_download(void *arg)
-{
- DA_LOG_CRITICAL(Default, "cleanup for thread id = %d", pthread_self());
-}
-
-static void *__thread_start_download(void *data)
-{
- da_result_t ret = DA_RESULT_OK;
- download_thread_input *thread_info = DA_NULL;
- client_input_t *client_input = DA_NULL;
- stage_info *stage = DA_NULL;
- download_state_t download_state = 0;
-
- int slot_id = DA_INVALID_ID;
-
- DA_LOG_FUNC_LOGV(Thread);
-
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL);
-
- thread_info = (download_thread_input*)data;
- if (DA_NULL == thread_info) {
- DA_LOG_ERR(Thread, "thread_info is NULL..");
- ret = DA_ERR_INVALID_ARGUMENT;
- return DA_NULL;
- } else {
- slot_id = thread_info->slot_id;
- client_input = thread_info->client_input;
-
- if(thread_info) {
- free(thread_info);
- thread_info = DA_NULL;
- }
- }
-
- pthread_cleanup_push(__thread_clean_up_handler_for_start_download, (void *)NULL);
-
- if (DA_FALSE == is_valid_slot_id(slot_id)) {
- ret = DA_ERR_INVALID_ARGUMENT;
- DA_LOG_ERR(Default, "Invalid Download ID");
- goto ERR;
- }
-
- if (!client_input) {
- ret = DA_ERR_INVALID_ARGUMENT;
- DA_LOG_ERR(Default, "Invalid client_input");
- goto ERR;
- }
-
- stage = Add_new_download_stage(slot_id);
- if (!stage) {
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- DA_LOG_ERR(Default, "STAGE ADDITION FAIL!");
- goto ERR;
- }
- DA_LOG_VERBOSE(Default, "new added Stage : %p", stage);
-
- GET_DL_USER_DATA(slot_id) = client_input->user_data;
- client_input->user_data = DA_NULL;
- GET_DL_USER_INSTALL_PATH(slot_id) = client_input->install_path;
- client_input->install_path = DA_NULL;
- GET_DL_USER_FILE_NAME(slot_id) = client_input->file_name;
- client_input->file_name = DA_NULL;
- GET_DL_USER_ETAG(slot_id) = client_input->etag;
- client_input->etag = DA_NULL;
- GET_DL_USER_TEMP_FILE_PATH(slot_id) = client_input->temp_file_path;
- client_input->temp_file_path = DA_NULL;
-
- ret = __make_source_info_basic_download(stage, client_input);
-
- if (ret == DA_RESULT_OK) {
- /* to save memory */
- if (client_input) {
- clean_up_client_input_info(client_input);
- free(client_input);
- client_input = DA_NULL;
- }
-
- ret = __download_content(stage);
- if (stage != GET_DL_CURRENT_STAGE(slot_id)) {
- DA_LOG_ERR(Default,"Playready download case. The next stage is present stage");
- stage = GET_DL_CURRENT_STAGE(slot_id);
- }
- }
-ERR:
- if (client_input) {
- clean_up_client_input_info(client_input);
- free(client_input);
- client_input = DA_NULL;
- }
-
- if (DA_RESULT_OK == ret) {
- char *installed_path = NULL;
- char *etag = DA_NULL;
- req_dl_info *request_info = NULL;
- file_info *file_storage = NULL;
- DA_LOG_VERBOSE(Default, "Whole download flow is finished.");
- _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
- download_state = GET_DL_STATE_ON_STAGE(stage);
- _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
- if (download_state == DOWNLOAD_STATE_ABORTED) {
- DA_LOG(Default, "Abort case. Do not call client callback");
-#ifdef PAUSE_EXIT
- } else if (download_state == DOWNLOAD_STATE_PAUSED) {
- DA_LOG(Default, "Finish case from paused state");
- destroy_download_info(slot_id);
-#endif
- } else {
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
- etag = GET_REQUEST_HTTP_HDR_ETAG(request_info);
- file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
- installed_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage);
- send_user_noti_and_finish_download_flow(slot_id, installed_path,
- etag);
- }
- } else {
- char *etag = DA_NULL;
- req_dl_info *request_info = NULL;
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
- DA_LOG_CRITICAL(Default, "Download Failed -Return = %d", ret);
- if (request_info) {
- etag = GET_REQUEST_HTTP_HDR_ETAG(request_info);
- send_client_finished_info(slot_id, GET_DL_ID(slot_id),
- DA_NULL, etag, ret, get_http_status(slot_id));
- }
- destroy_download_info(slot_id);
- }
-
- pthread_cleanup_pop(0);
- DA_LOG_CRITICAL(Thread, "==thread_start_download - EXIT==");
- pthread_exit((void *)NULL);
- return DA_NULL;
-}
-
-da_result_t __download_content(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- download_state_t download_state = 0;
- da_bool_t isDownloadComplete = DA_FALSE;
- int slot_id = DA_INVALID_ID;
-
- DA_LOG_FUNC_LOGV(Default);
-
- slot_id = GET_STAGE_DL_ID(stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD, stage);
-
- do {
- stage = GET_DL_CURRENT_STAGE(slot_id);
- _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
- download_state = GET_DL_STATE_ON_STAGE(stage);
- DA_LOG_VERBOSE(Default, "download_state to - [%d] ", download_state);
- _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
-
- switch(download_state) {
- case DOWNLOAD_STATE_NEW_DOWNLOAD:
- ret = requesting_download(stage);
-
- _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
- download_state = GET_DL_STATE_ON_STAGE(stage);
- _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(stage)]);
- if (download_state == DOWNLOAD_STATE_CANCELED ||
- download_state == DOWNLOAD_STATE_ABORTED ||
- download_state == DOWNLOAD_STATE_PAUSED) {
- break;
- } else {
- if (DA_RESULT_OK == ret) {
- ret = handle_after_download(stage);
- }
- }
- break;
- default:
- isDownloadComplete = DA_TRUE;
- break;
- }
- }while ((DA_RESULT_OK == ret) && (DA_FALSE == isDownloadComplete));
-
- return ret;
-}
diff --git a/agent/download-agent-client-mgr.c b/agent/download-agent-client-mgr.c
index b27a2d4..82dd516 100755
--- a/agent/download-agent-client-mgr.c
+++ b/agent/download-agent-client-mgr.c
@@ -14,618 +14,132 @@
* limitations under the License.
*/
-#include <unistd.h>
+#include <stdlib.h>
#include "download-agent-client-mgr.h"
-#include "download-agent-debug.h"
-#include "download-agent-utils.h"
-#include "download-agent-file.h"
-#define IS_CLIENT_Q_HAVING_DATA(QUEUE) (QUEUE->having_data)
-
-static client_app_mgr_t client_app_mgr;
-
-static da_result_t __launch_client_thread(void);
-static void *__thread_for_client_noti(void *data);
-void __thread_clean_up_handler_for_client_thread(void *arg);
-static void __pop_client_noti(client_noti_t **out_client_noti);
-
-void __client_q_goto_sleep_without_lock(void);
-void __client_q_wake_up_without_lock(void);
-void destroy_client_noti(client_noti_t *client_noti);
-
-da_result_t init_client_app_mgr()
-{
- DA_LOG_FUNC_LOGV(ClientNoti);
-
- if(client_app_mgr.is_init)
- return DA_RESULT_OK;
-
- client_app_mgr.is_init = DA_TRUE;
- client_app_mgr.client_app_info.client_user_agent = DA_NULL;
- client_app_mgr.is_thread_init = DA_FALSE;
- client_app_mgr.thread_id = 0;
-
- return DA_RESULT_OK;
-}
-
-da_bool_t is_client_app_mgr_init(void)
-{
- return client_app_mgr.is_init;
-}
-
-da_result_t reg_client_app(
- da_client_cb_t *da_client_callback)
-{
- da_result_t ret = DA_RESULT_OK;
- client_queue_t *queue = DA_NULL;
- client_noti_t *client_noti = DA_NULL;
-
- DA_LOG_FUNC_LOGD(ClientNoti);
-
- memset(&(client_app_mgr.client_app_info.client_callback),
- 0, sizeof(da_client_cb_t));
- memcpy(&(client_app_mgr.client_app_info.client_callback),
- da_client_callback, sizeof(da_client_cb_t));
-
- _da_thread_mutex_init(&(client_app_mgr.mutex_client_mgr), DA_NULL);
-
- /* If some noti is existed at queue, delete all */
- do {
- __pop_client_noti(&client_noti);
- destroy_client_noti(client_noti);
- } while(client_noti != DA_NULL);
-
- queue = &(client_app_mgr.client_queue);
- DA_LOG_VERBOSE(ClientNoti, "client queue = %p", queue);
- _da_thread_mutex_init(&(queue->mutex_client_queue), DA_NULL);
- _da_thread_cond_init(&(queue->cond_client_queue), DA_NULL);
-
- ret = __launch_client_thread();
-
- return ret;
-}
-
-da_result_t dereg_client_app(void)
+da_ret_t send_client_paused_info(da_info_t *da_info)
{
- client_noti_t *client_noti = DA_NULL;
-
- DA_LOG_FUNC_LOGV(ClientNoti);
-
- client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t));
- if (!client_noti) {
- DA_LOG_ERR(ClientNoti, "calloc fail");
- return DA_ERR_FAIL_TO_MEMALLOC;
- }
-
- client_noti->slot_id = DA_INVALID_ID;
- client_noti->noti_type = Q_CLIENT_NOTI_TYPE_TERMINATE;
- client_noti->next = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ NULL_CHECK_RET(da_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
- _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr));
- if (client_app_mgr.is_thread_init != DA_TRUE) {
- DA_LOG_CRITICAL(ClientNoti, "try to cancel client mgr thread id[%lu]",
- client_app_mgr.thread_id);
- if (client_app_mgr.thread_id &&
- pthread_cancel(client_app_mgr.thread_id) < 0) {
- DA_LOG_ERR(ClientNoti, "cancel thread is failed!!!");
- }
- free(client_noti);
+ if (da_info->is_cb_update && da_info->cb_info.paused_cb) {
+ da_info->cb_info.paused_cb(da_info->da_id,
+ req_info->user_req_data, req_info->user_client_data);
+ DA_LOGV("id[%d]", da_info->da_id);
} else {
- void *t_return = NULL;
- DA_LOG_VERBOSE(ClientNoti, "pushing Q_CLIENT_NOTI_TYPE_TERMINATE");
- push_client_noti(client_noti);
- DA_LOG_DEBUG(Thread, "===try to join client mgr thread id[%lu]===",
- client_app_mgr.thread_id);
- if (client_app_mgr.thread_id &&
- pthread_join(client_app_mgr.thread_id, &t_return) < 0) {
- DA_LOG_ERR(Thread, "join client thread is failed!!!");
- }
- DA_LOG_DEBUG(Thread, "===thread join return[%d]===", (char*)t_return);
+ DA_LOGV("No CB:id[%d]", da_info->da_id);
}
- _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr));
- /* ToDo: This clean up should be done at the end of client_thread. */
- if(client_app_mgr.client_app_info.client_user_agent) {
- free(client_app_mgr.client_app_info.client_user_agent);
- client_app_mgr.client_app_info.client_user_agent = DA_NULL;
- }
- _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr));
- client_app_mgr.is_thread_init = DA_FALSE;
- _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr));
- _da_thread_mutex_destroy(&(client_app_mgr.mutex_client_mgr));
return DA_RESULT_OK;
}
-da_result_t send_client_paused_info(int slot_id)
+da_ret_t send_client_update_dl_info(da_info_t *da_info)
{
- client_noti_t *client_noti = DA_NULL;
- user_paused_info_t *paused_info = DA_NULL;
- download_state_t state = GET_DL_STATE_ON_ID(slot_id);
-
- DA_LOG_FUNC_LOGD(ClientNoti);
-
- if (!GET_DL_ENABLE_PAUSE_UPDATE(slot_id)) {
- DA_LOG(ClientNoti, "Do not call pause cb");
- return DA_RESULT_OK;
- }
- if (!is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(ClientNoti, "Download ID is not valid");
- return DA_RESULT_OK;
- }
+ download_info_t *info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ http_info_t *http_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ NULL_CHECK_RET(da_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
- DA_LOG_VERBOSE(ClientNoti, "slot_id[%d]", slot_id);
- if ((DOWNLOAD_STATE_PAUSED != state)) {
- DA_LOG(ClientNoti, "The state is not paused. state:%d", state);
- return DA_ERR_INVALID_STATE;
- }
-
- client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t));
- if (!client_noti) {
- DA_LOG_ERR(ClientNoti, "calloc fail");
- return DA_ERR_FAIL_TO_MEMALLOC;
- }
-
- client_noti->slot_id = slot_id;
- client_noti->user_data = GET_DL_USER_DATA(slot_id);
- client_noti->noti_type = Q_CLIENT_NOTI_TYPE_PAUSED_INFO;
- client_noti->next = DA_NULL;
-
- paused_info = (user_paused_info_t *)&(client_noti->type.paused_info);
- paused_info->download_id= GET_DL_ID(slot_id);
- DA_LOG(ClientNoti, "pushing paused info. slot_id=%d, dl_id=%d",
- slot_id, GET_DL_ID(slot_id));
-
- push_client_noti(client_noti);
-
- return DA_RESULT_OK;
-}
-
-da_result_t send_client_update_progress_info (
- int slot_id,
- int dl_id,
- unsigned long int received_size
- )
-{
- client_noti_t *client_noti = DA_NULL;
- user_progress_info_t *progress_info = DA_NULL;
-
- DA_LOG_FUNC_LOGV(ClientNoti);
-
- if (!is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(ClientNoti, "Download ID is not valid");
- return DA_ERR_INVALID_DL_REQ_ID;
- }
-
- client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t));
- if (!client_noti) {
- DA_LOG_ERR(ClientNoti, "calloc fail");
- return DA_ERR_FAIL_TO_MEMALLOC;
- }
-
- client_noti->slot_id = slot_id;
- client_noti->user_data = GET_DL_USER_DATA(slot_id);
- client_noti->noti_type = Q_CLIENT_NOTI_TYPE_PROGRESS_INFO;
- client_noti->next = DA_NULL;
-
- progress_info = (user_progress_info_t *)&(client_noti->type.update_progress_info);
- progress_info->download_id= dl_id;
- progress_info->received_size = received_size;
-
- DA_LOG_VERBOSE(ClientNoti, "pushing received_size=%lu, slot_id=%d, dl_id=%d",
- received_size, slot_id, dl_id);
-
- push_client_noti(client_noti);
-
- return DA_RESULT_OK;
-}
-
-da_result_t send_client_update_dl_info (
- int slot_id,
- int dl_id,
- char *file_type,
- unsigned long int file_size,
- char *tmp_saved_path,
- char *pure_file_name,
- char *etag,
- char *extension)
-{
- client_noti_t *client_noti = DA_NULL;
- user_download_info_t *update_dl_info = DA_NULL;
- int len = 0;
-
- DA_LOG_FUNC_LOGV(ClientNoti);
-
- if (!is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(ClientNoti, "Download ID is not valid");
- return DA_ERR_INVALID_DL_REQ_ID;
- }
-
- client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t));
- if (!client_noti) {
- DA_LOG_ERR(ClientNoti, "calloc fail");
- return DA_ERR_FAIL_TO_MEMALLOC;
- }
-
- client_noti->slot_id = slot_id;
- client_noti->user_data = GET_DL_USER_DATA(slot_id);
- client_noti->noti_type = Q_CLIENT_NOTI_TYPE_STARTED_INFO;
- client_noti->next = DA_NULL;
-
- update_dl_info = (user_download_info_t *)&(client_noti->type.update_dl_info);
- update_dl_info->download_id = dl_id;
- update_dl_info->file_size = file_size;
- if (pure_file_name && extension) {
- len = strlen(pure_file_name) + strlen(extension) + 1;
- update_dl_info->content_name = (char *)calloc(len + 1, sizeof(char));
- if (!update_dl_info->content_name) {
- free(client_noti);
+ if (da_info->is_cb_update && da_info->cb_info.download_info_cb) {
+ info = (download_info_t *)calloc(1, sizeof(download_info_t));
+ if (!info)
return DA_ERR_FAIL_TO_MEMALLOC;
+ info->download_id = da_info->da_id;
+ info->file_size = http_info->content_len_from_header;
+ if (http_info->content_type_from_header)
+ info->file_type = strdup(http_info->content_type_from_header);
+ if (file_info->file_path)
+ info->tmp_saved_path = strdup(file_info->file_path);
+ if (file_info->pure_file_name)
+ info->content_name = strdup(file_info->pure_file_name);
+ if (http_info->etag_from_header) {
+ info->etag = strdup(http_info->etag_from_header);
+ //DA_SECURE_LOGI("etag[%s]", info->etag);
}
- snprintf(update_dl_info->content_name, len + 1, "%s.%s",
- pure_file_name, extension);
- }
-
- /* These strings MUST be copied to detach __thread_for_client_noti from download_info */
- if (file_type)
- update_dl_info->file_type = strdup(file_type);
-
- if (tmp_saved_path)
- update_dl_info->tmp_saved_path = strdup(tmp_saved_path);
-
- if (etag)
- update_dl_info->etag = strdup(etag);
- DA_LOG_DEBUG(ClientNoti, "pushing slot_id=%d, dl_id=%d", slot_id, dl_id);
-
- push_client_noti(client_noti);
-
- return DA_RESULT_OK;
-}
-
-da_result_t send_client_finished_info (
- int slot_id,
- int dl_id,
- char *saved_path,
- char *etag,
- int error,
- int http_status
- )
-{
- client_noti_t *client_noti = DA_NULL;
- user_finished_info_t *finished_info = DA_NULL;
-
- DA_LOG_FUNC_LOGV(ClientNoti);
-
- if (!is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(ClientNoti, "Download ID is not valid");
- return DA_ERR_INVALID_DL_REQ_ID;
- }
-
- client_noti = (client_noti_t *)calloc(1, sizeof(client_noti_t));
- if (!client_noti) {
- DA_LOG_ERR(ClientNoti, "calloc fail");
- return DA_ERR_FAIL_TO_MEMALLOC;
- }
-
- client_noti->slot_id = slot_id;
- client_noti->user_data = GET_DL_USER_DATA(slot_id);
- client_noti->noti_type = Q_CLIENT_NOTI_TYPE_FINISHED_INFO;
- client_noti->next = DA_NULL;
-
- finished_info = (user_finished_info_t *)&(client_noti->type.finished_info);
- finished_info->download_id = dl_id;
- finished_info->err = error;
- finished_info->http_status = http_status;
-
- if (saved_path) {
- finished_info->saved_path = strdup(saved_path);
- DA_SECURE_LOGD("saved path=%s", saved_path);
- }
- if (etag) {
- finished_info->etag = strdup(etag);
- DA_SECURE_LOGD("pushing finished info. etag[%s]", etag);
- }
- DA_LOG_VERBOSE(ClientNoti, "user_data=%p", client_noti->user_data);
- DA_LOG_VERBOSE(ClientNoti, "http_status=%d", http_status);
- DA_LOG(ClientNoti, "pushing slot_id=%d, dl_id=%d err=%d", slot_id, dl_id, error);
-
- push_client_noti(client_noti);
-
- return DA_RESULT_OK;
-}
-
-da_result_t __launch_client_thread(void)
-{
- pthread_t thread_id = 0;
-
- DA_LOG_FUNC_LOGV(Thread);
-
- if (pthread_create(&thread_id, DA_NULL,
- __thread_for_client_noti,DA_NULL) < 0) {
- DA_LOG_ERR(Thread, "making thread failed..");
- return DA_ERR_FAIL_TO_CREATE_THREAD;
+ da_info->cb_info.download_info_cb(info,
+ req_info->user_req_data, req_info->user_client_data);
+ DA_LOGD("id[%d]", info->download_id);
+ //DA_LOGI("id[%d]total_size[%lu]", info->download_id, info->file_size);
+ //if (http_info->content_type_from_header)
+ //DA_SECURE_LOGI("mime_type[%s]", http_info->content_type_from_header);
+ } else {
+ DA_LOGI("No CB:id[%d]", da_info->da_id);
}
- DA_LOG_VERBOSE(Thread, "client mgr thread id[%d]", thread_id);
- client_app_mgr.thread_id = thread_id;
return DA_RESULT_OK;
}
-void destroy_client_noti(client_noti_t *client_noti)
-{
- if (client_noti) {
- if (client_noti->noti_type == Q_CLIENT_NOTI_TYPE_STARTED_INFO) {
- user_download_info_t *update_dl_info = DA_NULL;
- update_dl_info = (user_download_info_t*)&(client_noti->type.update_dl_info);
- if (update_dl_info->file_type) {
- free(update_dl_info->file_type);
- update_dl_info->file_type = DA_NULL;
- }
- if (update_dl_info->tmp_saved_path) {
- free(update_dl_info->tmp_saved_path);
- update_dl_info->tmp_saved_path = DA_NULL;
- }
- if (update_dl_info->etag) {
- free(update_dl_info->etag);
- update_dl_info->etag = DA_NULL;
- }
- } else if (client_noti->noti_type ==
- Q_CLIENT_NOTI_TYPE_FINISHED_INFO) {
- user_finished_info_t *finished_info = DA_NULL;
- finished_info = (user_finished_info_t*)
- &(client_noti->type.finished_info);
- if (finished_info->saved_path) {
- free(finished_info->saved_path);
- finished_info->saved_path = DA_NULL;
- }
- if (finished_info->etag) {
- free(finished_info->etag);
- finished_info->etag = DA_NULL;
- }
- }
- free(client_noti);
- }
-}
-
-
-void push_client_noti(client_noti_t *client_noti)
+da_ret_t send_client_update_progress_info(da_info_t *da_info)
{
- client_queue_t *queue = DA_NULL;
- client_noti_t *head = DA_NULL;
- client_noti_t *pre = DA_NULL;
- client_noti_t *cur = DA_NULL;
-
- queue = &(client_app_mgr.client_queue);
- _da_thread_mutex_lock (&(queue->mutex_client_queue));
+ file_info_t *file_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ NULL_CHECK_RET(da_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
- head = queue->client_q_head;
- if (!head) {
- queue->client_q_head = client_noti;
- } else {
- cur = head;
- while (cur->next) {
- pre = cur;
- cur = pre->next;
- }
-#if 0
- if (cur->noti_type == Q_CLIENT_NOTI_TYPE_PROGRESS_INFO) {
- /* For UI performance. If the update noti info is existed at queue,
- replace it with new update noti info */
- if (cur->slot_id == client_noti->slot_id) {
- /* DA_LOG(ClientNoti, "exchange queue's tail and pushing item"); */
- if (pre == DA_NULL)
- queue->client_q_head = client_noti;
- else
- pre->next = client_noti;
- destroy_client_noti(cur);
- } else {
- cur->next = client_noti;
- }
- } else {
- cur->next = client_noti;
- }
-#else
- cur->next = client_noti;
-#endif
- }
-
- queue->having_data = DA_TRUE;
+ if (!file_info->is_updated)
+ return DA_RESULT_OK;
- __client_q_wake_up_without_lock();
- if (queue->client_q_head->next) {
- DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti[%p]",
- queue->client_q_head, queue->client_q_head->next);
+ if (da_info->is_cb_update && da_info->cb_info.progress_cb) {
+ da_info->cb_info.progress_cb(da_info->da_id,
+ file_info->bytes_written_to_file,
+ req_info->user_req_data, req_info->user_client_data);
+ DA_LOGV("id[%d],size[%llu]", da_info->da_id,
+ file_info->bytes_written_to_file);
} else {
- DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti is NULL",
- queue->client_q_head);
+ DA_LOGI("No CB:id[%d]", da_info->da_id);
}
-
- _da_thread_mutex_unlock (&(queue->mutex_client_queue));
+ file_info->is_updated = DA_FALSE;
+ return DA_RESULT_OK;
}
-void __pop_client_noti(client_noti_t **out_client_noti)
+da_ret_t send_client_finished_info(da_info_t *da_info, int err)
{
- client_queue_t *queue = DA_NULL;
-
- queue = &(client_app_mgr.client_queue);
+ finished_info_t *info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ http_info_t *http_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ NULL_CHECK_RET(da_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
- _da_thread_mutex_lock (&(queue->mutex_client_queue));
-
- if (queue->client_q_head) {
- *out_client_noti = queue->client_q_head;
- queue->client_q_head = queue->client_q_head->next;
- if (queue->client_q_head) {
- DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti[%p]",
- *out_client_noti, queue->client_q_head);
- } else {
- DA_LOG_VERBOSE(ClientNoti, "client noti[%p] next noti is NULL",
- *out_client_noti);
- }
+ if (da_info->is_cb_update && da_info->cb_info.finished_cb) {
+ info = (finished_info_t *)calloc(1, sizeof(finished_info_t));
+ if (!info)
+ return DA_ERR_FAIL_TO_MEMALLOC;
+ info->download_id = da_info->da_id;
+ if (http_info->http_msg_response)
+ info->http_status = http_info->http_msg_response->status_code;
+ else
+ DA_LOGE("http_msg_response is NULL");
+ if (file_info->file_path)
+ info->saved_path = strdup(file_info->file_path);
+ if (http_info->etag_from_header)
+ info->etag = strdup(http_info->etag_from_header);
+ info->err = err;
+ da_info->cb_info.finished_cb(info,
+ req_info->user_req_data, req_info->user_client_data);
+ DA_LOGD("id[%d]", info->download_id);
+ //DA_LOGI("id[%d],err[%d], http_status[%d]", info->download_id,
+ //info->err, info->http_status);
} else {
- *out_client_noti = DA_NULL;
- }
-
- if (queue->client_q_head == DA_NULL) {
- queue->having_data = DA_FALSE;
+ DA_LOGI("No CB:id[%d]", da_info->da_id);
}
-
- _da_thread_mutex_unlock (&(queue->mutex_client_queue));
-}
-
-void __client_q_goto_sleep_without_lock(void)
-{
- client_queue_t *queue = DA_NULL;
- queue = &(client_app_mgr.client_queue);
- _da_thread_cond_wait(&(queue->cond_client_queue), &(queue->mutex_client_queue));
-}
-
-void __client_q_wake_up_without_lock(void)
-{
- client_queue_t *queue = DA_NULL;
- queue = &(client_app_mgr.client_queue);
- _da_thread_cond_signal(&(queue->cond_client_queue));
-}
-
-void __thread_clean_up_handler_for_client_thread(void *arg)
-{
- DA_LOG_CRITICAL(Thread, "cleanup for thread id = %d", pthread_self());
-}
-
-static void *__thread_for_client_noti(void *data)
-{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t need_wait = DA_TRUE;
- client_queue_t *queue = DA_NULL;
- client_noti_t *client_noti = DA_NULL;
-
- DA_LOG_FUNC_LOGV(Thread);
-
- _da_thread_mutex_lock(&(client_app_mgr.mutex_client_mgr));
- client_app_mgr.is_thread_init = DA_TRUE;
- _da_thread_mutex_unlock(&(client_app_mgr.mutex_client_mgr));
-
- queue = &(client_app_mgr.client_queue);
- DA_LOG_VERBOSE(ClientNoti, "client queue = %p", queue);
-
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL);
- pthread_cleanup_push(__thread_clean_up_handler_for_client_thread, (void *)DA_NULL);
-
- do {
- _da_thread_mutex_lock(&(queue->mutex_client_queue));
- if (DA_FALSE == IS_CLIENT_Q_HAVING_DATA(queue)) {
- DA_LOG_VERBOSE(Thread, "Sleep @ thread_for_client_noti!");
- __client_q_goto_sleep_without_lock();
- DA_LOG_VERBOSE(Thread, "Woke up @ thread_for_client_noti");
- }
- _da_thread_mutex_unlock(&(queue->mutex_client_queue));
-
- do {
- __pop_client_noti(&client_noti);
- if (client_noti == DA_NULL) {
- DA_LOG_ERR(ClientNoti, "There is no data on client queue!");
- ret = DA_ERR_INVALID_STATE;
- need_wait = DA_FALSE;
- } else {
- DA_LOG_VERBOSE(ClientNoti, "noti type[%d]",
- client_noti->noti_type);
- switch (client_noti->noti_type) {
- case Q_CLIENT_NOTI_TYPE_STARTED_INFO:
- {
- user_download_info_t *update_dl_info = DA_NULL;;
- update_dl_info = (user_download_info_t*)(&(client_noti->type.update_dl_info));
- if (client_app_mgr.client_app_info.client_callback.update_dl_info_cb) {
- client_app_mgr.client_app_info.client_callback.update_dl_info_cb(update_dl_info, client_noti->user_data);
- if (update_dl_info->etag)
- DA_SECURE_LOGD("Etag:[%s]", update_dl_info->etag);
- DA_SECURE_LOGD("file size=%lu", update_dl_info->file_size);
- DA_LOG(ClientNoti, "Update download info for slot_id=%d, dl_id=%d- DONE",
- client_noti->slot_id,
- update_dl_info->download_id
- );
- }
- }
- break;
- case Q_CLIENT_NOTI_TYPE_PROGRESS_INFO:
- {
- user_progress_info_t *progress_info = DA_NULL;;
- progress_info = (user_progress_info_t*)(&(client_noti->type.update_progress_info));
- if (client_app_mgr.client_app_info.client_callback.update_progress_info_cb) {
- client_app_mgr.client_app_info.client_callback.update_progress_info_cb(progress_info, client_noti->user_data);
- DA_LOG_VERBOSE(ClientNoti, "Update downloading info for slot_id=%d, dl_id=%d, received size=%lu - DONE",
- client_noti->slot_id,
- progress_info->download_id,
- progress_info->received_size);
- }
- }
- break;
- case Q_CLIENT_NOTI_TYPE_FINISHED_INFO:
- {
- user_finished_info_t *finished_info = DA_NULL;;
- finished_info = (user_finished_info_t*)(&(client_noti->type.finished_info));
- if (client_app_mgr.client_app_info.client_callback.finished_info_cb) {
- client_app_mgr.client_app_info.client_callback.finished_info_cb(
- finished_info, client_noti->user_data);
- DA_LOG(ClientNoti, "Completed info for slot_id=%d, dl_id=%d, err=%d http_state=%d user_data=%p- DONE",
- client_noti->slot_id,
- finished_info->download_id,
- finished_info->err,
- finished_info->http_status,
- client_noti->user_data);
- if (finished_info->etag)
- DA_SECURE_LOGD("Completed info for etag=%s - DONE",
- finished_info->etag);
-
- }
- }
- break;
- case Q_CLIENT_NOTI_TYPE_PAUSED_INFO:
- {
- user_paused_info_t *da_paused_info = DA_NULL;
- da_paused_info = (user_paused_info_t *)(&(client_noti->type.paused_info));
-
- if (client_app_mgr.client_app_info.client_callback.paused_info_cb) {
- DA_LOG(ClientNoti, "User Paused info for slot_id=%d, dl_id=%d - Done",
- client_noti->slot_id,
- da_paused_info->download_id);
- client_app_mgr.client_app_info.client_callback.paused_info_cb(
- da_paused_info, client_noti->user_data);
- }
- }
- break;
- case Q_CLIENT_NOTI_TYPE_TERMINATE:
- DA_LOG_VERBOSE(ClientNoti, "Q_CLIENT_NOTI_TYPE_TERMINATE");
- need_wait = DA_FALSE;
- break;
- }
- destroy_client_noti(client_noti);
- }
-
- if(DA_TRUE == need_wait) {
- _da_thread_mutex_lock(&(queue->mutex_client_queue));
- if (DA_FALSE == IS_CLIENT_Q_HAVING_DATA(queue)) {
- _da_thread_mutex_unlock (&(queue->mutex_client_queue));
- break;
- } else {
- _da_thread_mutex_unlock (&(queue->mutex_client_queue));
- }
- } else {
- break;
- }
- } while (1);
- } while (DA_TRUE == need_wait);
-
- _da_thread_mutex_destroy(&(queue->mutex_client_queue));
- _da_thread_cond_destroy(&(queue->cond_client_queue));
-
- pthread_cleanup_pop(0);
- DA_LOG_DEBUG(Thread, "=====thread_for_client_noti- EXIT=====");
- pthread_exit((void *)NULL);
- return DA_NULL;
+ return DA_RESULT_OK;
}
-char *get_client_user_agent_string(void)
-{
- if (!client_app_mgr.is_init)
- return DA_NULL;
-
- return client_app_mgr.client_app_info.client_user_agent;
-}
diff --git a/agent/download-agent-debug.c b/agent/download-agent-debug.c
deleted file mode 100755
index 07078b3..0000000
--- a/agent/download-agent-debug.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "download-agent-debug.h"
-#include "download-agent-utils.h"
-
-#define STRING_IT(x) #x
-#define TURN_ON_LOG(channel) (DALogBitMap |= (0x1<<(channel)))
-
-int DALogBitMap;
-
-char *__get_log_env(void);
-char **__parsing_log_env(char *in_log_env);
-char *__copying_str(char *source, int length);
-char *__get_channel_name_from_enum(da_log_channel channel_enum);
-
-da_result_t init_log_mgr(void) {
- da_result_t ret = DA_RESULT_OK;
- static da_bool_t did_log_mgr_init = DA_FALSE;
- char *log_env = DA_NULL;
- char **parsed_log_env = DA_NULL;
- char **cur_parsed_log_env = DA_NULL;
- int i = 0;
-
- if (did_log_mgr_init)
- return ret;
-
- did_log_mgr_init = DA_TRUE;
-
- log_env = __get_log_env();
- if (!log_env) {
- /* If no environment values are found, do behave like all logs are turned on except for Soup log */
- DALogBitMap = ~(0x1 << Soup);
- return ret;
- }
-
- TURN_ON_LOG(Default);
-
- parsed_log_env = __parsing_log_env(log_env);
- if (parsed_log_env) {
- char *channel_keyward = DA_NULL;
- for (cur_parsed_log_env = parsed_log_env; *cur_parsed_log_env; cur_parsed_log_env++) {
- if (!*cur_parsed_log_env)
- break;
- for (i = 0; i < DA_LOG_CHANNEL_MAX; i++) {
- channel_keyward = __get_channel_name_from_enum(i);
- if (channel_keyward && !strcmp(*cur_parsed_log_env,
- channel_keyward)) {
- TURN_ON_LOG(i);
- break;
- }
- }
- free(*cur_parsed_log_env);
- }
- free(parsed_log_env);
- }
-
- if (log_env)
- free(log_env);
-
- return ret;
-}
-
-char *__get_log_env(void) {
- char *log_env = DA_NULL;
-
- /* environment value has higher priority than configure file */
- log_env = getenv(DA_DEBUG_ENV_KEY);
- if (log_env && strlen(log_env))
- return strdup(log_env);
-
- if (read_data_from_file(DA_DEBUG_CONFIG_FILE_PATH, &log_env))
- return log_env;
-
- return DA_NULL;
-}
-
-char **__parsing_log_env(char *in_log_env) {
- char **out_parsed_result = DA_NULL;
-
- char **temp_result_array = DA_NULL;
- char **cur_temp_result_array = DA_NULL;
- int how_many_item = 0;
- int how_many_delimeter = 0;
-
- char delimiter = ',';
-
- char *org_str = in_log_env;
- char *cur_char = org_str;
- char *start = org_str;
- char *end = org_str;
- int target_len = 0;
-
- if (!org_str)
- return DA_NULL;
-
- /* counting delimiter to know how many items should be memory allocated.
- * This causes two round of loop (counting delimiter and real operation).
- * But I think it is tolerable, because input parameter is from console.
- * And it is also a reason why we should not use fixed length array.
- * Users are hard to input very long environment, but it is possible. */
- for (cur_char = org_str; *cur_char; cur_char++) {
- if (*cur_char == delimiter)
- how_many_delimeter++;
- }
- how_many_item = how_many_delimeter + 1;
- temp_result_array = (char**) calloc(1, how_many_item + 1);
- if (!(temp_result_array))
- goto ERR;
-
- cur_temp_result_array = temp_result_array;
- cur_char = org_str;
- while (1) {
- if (*cur_char == delimiter) {
- end = cur_char;
- target_len = (int) (end - start);
- *cur_temp_result_array++ = __copying_str(start,
- target_len);
- start = ++cur_char;
- continue;
- } else if (!(*cur_char)) {
- end = cur_char;
- target_len = (int) (end - start);
- *cur_temp_result_array++ = __copying_str(start,
- target_len);
- *cur_temp_result_array = DA_NULL;
- break;
- } else {
- cur_char++;
- }
- }
- out_parsed_result = temp_result_array;
-ERR:
- return out_parsed_result;
-}
-
-char *__copying_str(char *source, int length) {
- char *copied_str = DA_NULL;
- char *cur_pos = DA_NULL;
- char white_space = ' ';
- char end_of_line = 10; /* ASCII for LF */
- int i = 0;
-
- if (!source || !(length > 0))
- return DA_NULL;
-
- copied_str = (char*) calloc(1, length + 1);
- if (copied_str) {
- cur_pos = copied_str;
- for (i = 0; i < length; i++) {
- if ((source[i] != white_space) && (source[i]
- != end_of_line))
- *cur_pos++ = source[i];
- }
- }
-
- return copied_str;
-}
-
-char *__get_channel_name_from_enum(da_log_channel channel_enum) {
- switch (channel_enum) {
- case Soup:
- return STRING_IT(Soup);
- case HTTPManager:
- return STRING_IT(HTTPManager);
- case FileManager:
- return STRING_IT(FileManager);
- case DRMManager:
- return STRING_IT(DRMManager);
- case DownloadManager:
- return STRING_IT(DownloadManager);
- case ClientNoti:
- return STRING_IT(ClientNoti);
- case HTTPMessageHandler:
- return STRING_IT(HTTPMessageHandler);
- case Encoding:
- return STRING_IT(Encoding);
- case QueueManager:
- return STRING_IT(QueueManager);
- case Parsing:
- return STRING_IT(Parsing);
- case Thread:
- return STRING_IT(Thread);
- case Default:
- return STRING_IT(Default);
- default:
- return DA_NULL;
- }
-}
diff --git a/agent/download-agent-dl-info-util.c b/agent/download-agent-dl-info-util.c
deleted file mode 100755
index 2b66357..0000000
--- a/agent/download-agent-dl-info-util.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string.h>
-
-#include "download-agent-client-mgr.h"
-#include "download-agent-dl-info-util.h"
-#include "download-agent-debug.h"
-#include "download-agent-utils.h"
-#include "download-agent-file.h"
-#include "download-agent-http-mgr.h"
-#include "download-agent-plugin-conf.h"
-
-pthread_mutex_t mutex_download_state[DA_MAX_DOWNLOAD_ID];
-static pthread_mutex_t mutex_download_mgr = PTHREAD_MUTEX_INITIALIZER;
-download_mgr_t download_mgr;
-
-void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic);
-void cleanup_req_dl_info_http(req_dl_info *http_download);
-void destroy_file_info(file_info *file);
-
-da_result_t init_download_mgr() {
- da_result_t ret = DA_RESULT_OK;
- int i = 0;
-
- DA_LOG_FUNC_LOGV(Default);
-
- _da_thread_mutex_lock(&mutex_download_mgr);
-
- if (download_mgr.is_init == DA_FALSE) {
- download_mgr.is_init = DA_TRUE;
-
- for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
- _da_thread_mutex_init(&mutex_download_state[i], DA_NULL);
- init_download_info(i);
- }
- init_dl_id_history(&(download_mgr.dl_id_history));
- }
-
- _da_thread_mutex_unlock(&mutex_download_mgr);
-
- return ret;
-}
-
-da_result_t deinit_download_mgr(void) {
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGV(Default);
-
- _da_thread_mutex_lock(&mutex_download_mgr);
- if (download_mgr.is_init == DA_TRUE) {
- int i = 0;
- dl_info_t *dl_info = DA_NULL;
- void *t_return = NULL;
- for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
- dl_info = &(download_mgr.dl_info[i]);
- if (dl_info && dl_info->is_using) {
- request_to_abort_http_download(GET_DL_CURRENT_STAGE(i));
- DA_LOG_CRITICAL(Thread, "===download id[%d] thread id[%lu] join===",i, GET_DL_THREAD_ID(i));
-/* Because the download daemon can call the deinit function, the resources of pthread are not freed
- FIXME later : It is needed to change the termination flow again.
- if (pthread_join(GET_DL_THREAD_ID(i), &t_return) < 0) {
- DA_LOG_ERR(Thread, "join client thread is failed!!!");
- }
-*/
- DA_LOG_CRITICAL(Thread, "===download id[%d] thread join return[%d]===",i, (char*)t_return);
- }
- }
- download_mgr.is_init = DA_FALSE;
- deinit_dl_id_history(&(download_mgr.dl_id_history));
- }
- _da_thread_mutex_unlock(&mutex_download_mgr);
- return ret;
-}
-
-void init_download_info(int slot_id)
-{
- dl_info_t *dl_info = DA_NULL;
-
- DA_LOG_FUNC_LOGV(Default);
-
- _da_thread_mutex_lock(&mutex_download_state[slot_id]);
- dl_info = &(download_mgr.dl_info[slot_id]);
- dl_info->is_using = DA_FALSE;
- dl_info->state = DOWNLOAD_STATE_IDLE;
- dl_info->download_stage_data = DA_NULL;
- dl_info->dl_id = 0;
- dl_info->http_status = 0;
- dl_info->enable_pause_update = DA_FALSE;
- dl_info->user_install_path = DA_NULL;
- dl_info->user_file_name = DA_NULL;
- dl_info->user_etag = DA_NULL;
- dl_info->user_temp_file_path = DA_NULL;
- dl_info->user_data = DA_NULL;
-
- Q_init_queue(&(dl_info->queue));
-
- DA_LOG_VERBOSE(Default, "Init slot_id [%d] Info END", slot_id);
- _da_thread_mutex_unlock(&mutex_download_state[slot_id]);
-
- return;
-}
-
-void destroy_download_info(int slot_id)
-{
- dl_info_t *dl_info = DA_NULL;
-
- DA_LOG_VERBOSE(Default, "Destroying slot_id [%d] Info", slot_id);
-
- if (slot_id == DA_INVALID_ID) {
- DA_LOG_ERR(Default, "invalid slot_id");
- return;
- }
-
- dl_info = &(download_mgr.dl_info[slot_id]);
- if (DA_FALSE == dl_info->is_using) {
- return;
- }
-
- _da_thread_mutex_lock (&mutex_download_state[slot_id]);
- dl_info->state = DOWNLOAD_STATE_IDLE;
- dl_info->active_dl_thread_id = 0;
-
- if (dl_info->download_stage_data != DA_NULL) {
- remove_download_stage(slot_id, dl_info->download_stage_data);
- dl_info->download_stage_data = DA_NULL;
- }
- dl_info->dl_id = 0;
- dl_info->enable_pause_update = DA_FALSE;
- if (dl_info->user_install_path) {
- free(dl_info->user_install_path);
- dl_info->user_install_path = DA_NULL;
- }
-
- if (dl_info->user_file_name) {
- free(dl_info->user_file_name);
- dl_info->user_file_name = DA_NULL;
- }
-
- if (dl_info->user_etag) {
- free(dl_info->user_etag);
- dl_info->user_etag = DA_NULL;
- }
-
- if (dl_info->user_temp_file_path) {
- free(dl_info->user_temp_file_path);
- dl_info->user_temp_file_path = DA_NULL;
- }
-
- dl_info->user_data = DA_NULL;
-
- Q_destroy_queue(&(dl_info->queue));
- dl_info->http_status = 0;
-
- dl_info->is_using = DA_FALSE;
-
- DA_LOG_DEBUG(Default, "Destroying slot_id [%d] Info END", slot_id);
- _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
- return;
-}
-
-void *Add_new_download_stage(int slot_id)
-{
- stage_info *download_stage_data = NULL;
- stage_info *new_download_stage_data = NULL;
-
- DA_LOG_FUNC_LOGV(Default);
-
- new_download_stage_data = (stage_info*)calloc(1, sizeof(stage_info));
- if (!new_download_stage_data)
- goto ERR;
-
- new_download_stage_data->dl_id = slot_id;
- download_stage_data = GET_DL_CURRENT_STAGE(slot_id);
- if (download_stage_data) {
- while (download_stage_data->next_stage_info) {
- download_stage_data
- = download_stage_data->next_stage_info;
- };
- download_stage_data->next_stage_info = new_download_stage_data;
- } else {
- GET_DL_CURRENT_STAGE(slot_id) = new_download_stage_data;
- }
- DA_LOG_VERBOSE(Default, "NEW STAGE ADDED FOR DOWNLOAD ID[%d] new_stage[%p]", slot_id,new_download_stage_data);
-
-ERR:
- return new_download_stage_data;
-}
-
-void remove_download_stage(int slot_id, stage_info *in_stage)
-{
- stage_info *stage = DA_NULL;
-
- DA_LOG_FUNC_LOGV(Default);
-
- stage = GET_DL_CURRENT_STAGE(slot_id);
- if (DA_NULL == stage) {
- DA_LOG_VERBOSE(Default, "There is no stage field on slot_id = %d", slot_id);
- goto ERR;
- }
-
- if (DA_NULL == in_stage) {
- DA_LOG_VERBOSE(Default, "There is no in_stage to remove.");
- goto ERR;
- }
-
- if (in_stage == stage) {
- DA_LOG_VERBOSE(Default, "Base stage will be removed. in_stage[%p]",in_stage);
- DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info);
- GET_DL_CURRENT_STAGE(slot_id) = stage->next_stage_info;
- empty_stage_info(in_stage);
- free(in_stage);
- in_stage = DA_NULL;
- } else {
- while (in_stage != stage->next_stage_info) {
- stage = stage->next_stage_info;
- }
- if (in_stage == stage->next_stage_info) {
- stage->next_stage_info
- = stage->next_stage_info->next_stage_info;
- DA_LOG_VERBOSE(Default, "Stage will be removed. in_stage[%p]",in_stage);
- DA_LOG_VERBOSE(Default, "next stage[%p]",stage->next_stage_info);
- empty_stage_info(in_stage);
- free(in_stage);
- in_stage = DA_NULL;
- }
- }
-
-ERR:
- return;
-}
-
-void empty_stage_info(stage_info *in_stage)
-{
- source_info_t *source_information = NULL;
- req_dl_info *request_download_info = NULL;
- file_info *file_information = NULL;
-
- DA_LOG_VERBOSE(Default, "Stage to Remove:[%p]", in_stage);
- source_information = GET_STAGE_SOURCE_INFO(in_stage);
-
- cleanup_source_info_basic_download(
- GET_SOURCE_BASIC(source_information));
-
- request_download_info = GET_STAGE_TRANSACTION_INFO(in_stage);
-
- cleanup_req_dl_info_http(request_download_info);
-
- file_information = GET_STAGE_CONTENT_STORE_INFO(in_stage);
- destroy_file_info(file_information);
-}
-
-void cleanup_source_info_basic_download(source_info_basic_t *source_info_basic)
-{
- if (NULL == source_info_basic)
- goto ERR;
-
- DA_LOG_FUNC_LOGV(Default);
-
- if (NULL != source_info_basic->url) {
- free(source_info_basic->url);
- source_info_basic->url = DA_NULL;
- }
-
-ERR:
- return;
-
-}
-
-void cleanup_req_dl_info_http(req_dl_info *http_download)
-{
- DA_LOG_FUNC_LOGV(Default);
-
- if (http_download->http_info.http_msg_request) {
- http_msg_request_destroy(
- &(http_download->http_info.http_msg_request));
- http_download->http_info.http_msg_request = DA_NULL;
- }
-
- if (http_download->http_info.http_msg_response) {
- http_msg_response_destroy(
- &(http_download->http_info.http_msg_response));
- http_download->http_info.http_msg_response = DA_NULL;
- }
-
- if (DA_NULL != http_download->location_url) {
- free(http_download->location_url);
- http_download->location_url = DA_NULL;
- }
- if (DA_NULL != http_download->content_type_from_header) {
- free(http_download->content_type_from_header);
- http_download->content_type_from_header = DA_NULL;
- }
-
- if (DA_NULL != http_download->etag_from_header) {
- free(http_download->etag_from_header);
- http_download->etag_from_header = DA_NULL;
- }
-
- http_download->invloved_transaction_id = DA_INVALID_ID;
- http_download->content_len_from_header = 0;
- http_download->downloaded_data_size = 0;
-
- _da_thread_mutex_destroy(&(http_download->mutex_http_state));
-
- return;
-}
-
-void destroy_file_info(file_info *file_information)
-{
- DA_LOG_FUNC_LOGV(Default);
-
- if (!file_information)
- return;
-
- if (file_information->file_name_final) {
- free(file_information->file_name_final);
- file_information->file_name_final = NULL;
- }
-
- if (file_information->content_type) {
- free(file_information->content_type);
- file_information->content_type = NULL;
- }
-
- if (file_information->pure_file_name) {
- free(file_information->pure_file_name);
- file_information->pure_file_name = NULL;
- }
-
- if (file_information->extension) {
- free(file_information->extension);
- file_information->extension = NULL;
- }
- return;
-}
-
-void clean_up_client_input_info(client_input_t *client_input)
-{
- DA_LOG_FUNC_LOGV(Default);
-
- if (client_input) {
- client_input->user_data = NULL;
-
- if (client_input->install_path) {
- free(client_input->install_path);
- client_input->install_path = DA_NULL;
- }
-
- if (client_input->file_name) {
- free(client_input->file_name);
- client_input->file_name = DA_NULL;
- }
-
- if (client_input->etag) {
- free(client_input->etag);
- client_input->etag = DA_NULL;
- }
-
- if (client_input->temp_file_path) {
- free(client_input->temp_file_path);
- client_input->temp_file_path = DA_NULL;
- }
-
- if (client_input->pkg_name) {
- free(client_input->pkg_name);
- client_input->pkg_name = DA_NULL;
- }
-
- client_input_basic_t *client_input_basic =
- &(client_input->client_input_basic);
-
- if (client_input_basic && client_input_basic->req_url) {
- free(client_input_basic->req_url);
- client_input_basic->req_url = DA_NULL;
- }
-
- if (client_input_basic && client_input_basic->user_request_header) {
- int i = 0;
- int count = client_input_basic->user_request_header_count;
- for (i = 0; i < count; i++)
- {
- if (client_input_basic->user_request_header[i]) {
- free(client_input_basic->user_request_header[i]);
- client_input_basic->user_request_header[i] = DA_NULL;
- }
- }
-
- free(client_input_basic->user_request_header);
- client_input_basic->user_request_header = DA_NULL;
- client_input_basic->user_request_header_count = 0;
- }
- } else {
- DA_LOG_ERR(Default, "client_input is NULL.");
- }
-
- return;
-}
-
-da_result_t get_slot_id_for_dl_id(
- int dl_id,
- int* slot_id)
-{
- da_result_t ret = DA_ERR_INVALID_DL_REQ_ID;
- int iter = 0;
-
- if (dl_id < 0) {
- DA_LOG_ERR(Default, "dl_id is less than 0 - %d", dl_id);
- return DA_ERR_INVALID_DL_REQ_ID;
- }
-
- _da_thread_mutex_lock(&mutex_download_mgr);
- for (iter = 0; iter < DA_MAX_DOWNLOAD_ID; iter++) {
- if (download_mgr.dl_info[iter].is_using == DA_TRUE) {
- if (download_mgr.dl_info[iter].dl_id ==
- dl_id) {
- *slot_id = iter;
- ret = DA_RESULT_OK;
- break;
- }
- }
- }
- _da_thread_mutex_unlock(&mutex_download_mgr);
-
- return ret;
-}
-
-
-da_result_t get_available_slot_id(int *available_id)
-{
- da_result_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
- int i;
-
- _da_thread_mutex_lock(&mutex_download_mgr);
- for (i = 0; i < DA_MAX_DOWNLOAD_ID; i++) {
- if (download_mgr.dl_info[i].is_using == DA_FALSE) {
- init_download_info(i);
-
- download_mgr.dl_info[i].is_using = DA_TRUE;
-
- download_mgr.dl_info[i].dl_id
- = get_available_dl_id(&(download_mgr.dl_id_history));
-
- *available_id = i;
- DA_LOG_VERBOSE(Default, "available download id = %d", *available_id);
- ret = DA_RESULT_OK;
-
- break;
- }
- }
- _da_thread_mutex_unlock(&mutex_download_mgr);
-
- return ret;
-}
-
-da_bool_t is_valid_slot_id(int slot_id)
-{
- da_bool_t ret = DA_FALSE;
-
- if (slot_id >= 0 && slot_id < DA_MAX_DOWNLOAD_ID) {
- if (download_mgr.dl_info[slot_id].is_using == DA_TRUE)
- ret = DA_TRUE;
- }
-
- return ret;
-}
-
-void store_http_status(int dl_id, int status)
-{
- if (status < 100 || status > 599) {
- DA_LOG_ERR(Default, "Invalid status code [%d]", status);
- return;
- }
- DA_LOG_VERBOSE(Default, "store_http_status id[%d]status[%d] ",dl_id, status);
- download_mgr.dl_info[dl_id].http_status = status;
-}
-
-int get_http_status(int slot_id)
-{
- if (!download_mgr.dl_info[slot_id].is_using) {
- DA_LOG_ERR(Default, "Invalid slot_id [%d]", slot_id);
- return 0;
- }
- return download_mgr.dl_info[slot_id].http_status;
-}
diff --git a/agent/download-agent-dl-info.c b/agent/download-agent-dl-info.c
new file mode 100644
index 0000000..6e49145
--- /dev/null
+++ b/agent/download-agent-dl-info.c
@@ -0,0 +1,462 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "download-agent-dl-info.h"
+#include "download-agent-http-mgr.h"
+#include "download-agent-http-msg-handler.h"
+
+static pthread_mutex_t mutex_da_info_list = PTHREAD_MUTEX_INITIALIZER;
+
+static void __init_da_info(int id)
+{
+ da_info_t *da_info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ http_info_t *http_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+
+ da_info = (da_info_t *)calloc(1, sizeof(da_info_t));
+ if (!da_info) {
+ DA_LOGE("Fail to calloc. id[%d]",id);
+ da_info_list[id] = DA_NULL;
+ return;
+ }
+ file_info = (file_info_t *)calloc(1, sizeof(file_info_t));
+ if (!file_info) {
+ DA_LOGE("Fail to calloc. id[%d]",id);
+ free(da_info);
+ da_info_list[id] = DA_NULL;
+ return;
+ }
+ http_info = (http_info_t *)calloc(1, sizeof(http_info_t));
+ if (!http_info) {
+ DA_LOGE("Fail to calloc. id[%d]",id);
+ free(da_info);
+ free(file_info);
+ da_info_list[id] = DA_NULL;
+ return;
+ }
+ req_info = (req_info_t *)calloc(1, sizeof(req_info_t));
+ if (!req_info) {
+ DA_LOGE("Fail to calloc. id[%d]",id);
+ free(da_info);
+ free(file_info);
+ free(http_info);
+ da_info_list[id] = DA_NULL;
+ return;
+ }
+
+ da_info->da_id = DA_INVALID_ID;
+ da_info->tid = DA_INVALID_ID;
+ memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t));
+ da_info->is_cb_update = DA_FALSE;
+ da_info->http_info = http_info;
+ da_info->file_info = file_info;
+ da_info->req_info = req_info;
+ da_info->update_time = 0;
+ da_info_list[id] = da_info;
+}
+
+da_ret_t init_http_msg_t(http_msg_t **http_msg)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_msg_t *temp = DA_NULL;
+ temp = (http_msg_t *)calloc(1, sizeof(http_msg_t));
+ if (!temp) {
+ DA_LOGE("Fail to calloc. id");
+ return DA_ERR_FAIL_TO_MEMALLOC;
+ }
+ *http_msg = temp;
+ return ret;
+}
+
+void destroy_http_msg_t(http_msg_t *http_msg)
+{
+ if (http_msg)
+ free(http_msg);
+ http_msg = DA_NULL;
+ return;
+}
+
+da_ret_t get_available_da_id(int *available_id)
+{
+ da_ret_t ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
+ int i = 0;
+
+ DA_MUTEX_LOCK(&mutex_da_info_list);
+ for (i = 0; i < DA_MAX_ID; i++) {
+ if (da_info_list[i] == DA_NULL) {
+ *available_id = i;
+ DA_LOGV("available download id[%d]", *available_id);
+ __init_da_info(i);
+ ret = DA_RESULT_OK;
+ break;
+ }
+ }
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+
+ return ret;
+}
+
+da_ret_t get_da_info_with_da_id(int id, da_info_t **out_info)
+{
+ da_ret_t ret = DA_ERR_INVALID_ARGUMENT;
+ int i = 0;
+
+ DA_MUTEX_LOCK(&mutex_da_info_list);
+ for (i = 0; i < DA_MAX_ID; i++) {
+ if (DA_NULL != da_info_list[i] && da_info_list[i]->da_id == id) {
+ *out_info = da_info_list[i];
+ ret = DA_RESULT_OK;
+ break;
+ }
+ }
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+
+ return ret;
+}
+
+da_ret_t __is_supporting_protocol(const char *url)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ int wanted_str_len = 0;
+ char *protocol = NULL;
+ char *wanted_str_start = NULL;
+ char *wanted_str_end = NULL;
+
+ if (DA_NULL == url || strlen(url) < 1)
+ return DA_ERR_INVALID_URL;
+
+ wanted_str_start = (char*)url;
+ wanted_str_end = strstr(url, "://");
+ if (!wanted_str_end) {
+ DA_LOGE("No protocol on this url");
+ return DA_ERR_INVALID_URL;
+ }
+
+ wanted_str_len = wanted_str_end - wanted_str_start;
+ protocol = (char*)calloc(1, wanted_str_len + 1);
+ if (!protocol) {
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
+ return DA_ERR_FAIL_TO_MEMALLOC;
+ }
+ strncpy(protocol, wanted_str_start, wanted_str_len);
+
+ if (strlen(protocol) < 1)
+ ret = DA_ERR_UNSUPPORTED_PROTOCAL;
+ else if (strcasecmp(protocol, "http") != 0 &&
+ strcasecmp(protocol, "https") != 0)
+ ret = DA_ERR_UNSUPPORTED_PROTOCAL;
+
+ free(protocol);
+ return ret;
+}
+
+da_ret_t copy_user_input_data(da_info_t *da_info, const char *url,
+ req_data_t *ext_data, da_cb_t *da_cb_data)
+{
+ da_ret_t ret = DA_RESULT_OK;
+
+ if (!url || !da_info) {
+ DA_LOGE("Invalid Param");
+ return DA_ERR_INVALID_ARGUMENT;
+ }
+
+ ret = __is_supporting_protocol(url);
+ if (ret != DA_RESULT_OK) {
+ DA_SECURE_LOGE("url[%s]", url);
+ return ret;
+ }
+
+ if (ext_data) {
+ req_info_t *req_info = da_info->req_info;
+
+ if (ext_data->request_header_count > 0) {
+ int i = 0;
+ int count = ext_data->request_header_count;
+ req_info->req_header = (char **)calloc(count, sizeof(char *));
+ if(DA_NULL == req_info->req_header) {
+ DA_LOGE("Fail to calloc");
+ free(req_info);
+ da_info->req_info = DA_NULL;
+ return DA_ERR_FAIL_TO_MEMALLOC;
+ }
+ for (i = 0; i < count; i++) {
+ if (ext_data->request_header[i])
+ req_info->req_header[i] =
+ strdup(ext_data->request_header[i]);
+ }
+ req_info->req_header_count = count;
+ }
+
+ if (url)
+ req_info->url = strdup(url);
+ if (ext_data->install_path)
+ req_info->install_path = strdup(ext_data->install_path);
+ if (ext_data->file_name)
+ req_info->file_name = strdup(ext_data->file_name);
+ if (ext_data->etag)
+ req_info->etag = strdup(ext_data->etag);
+ if (ext_data->temp_file_path)
+ req_info->temp_file_path = strdup(ext_data->temp_file_path);
+ if (ext_data->pkg_name)
+ req_info->pkg_name = strdup(ext_data->pkg_name);
+ req_info->network_bonding = ext_data->network_bonding;
+ if (ext_data->user_req_data)
+ req_info->user_req_data = ext_data->user_req_data;
+ if (ext_data->user_client_data)
+ req_info->user_client_data = ext_data->user_client_data;
+ da_info->req_info = req_info;
+ }
+ if (da_cb_data) {
+ da_info->is_cb_update = DA_TRUE;
+ memcpy(&(da_info->cb_info), da_cb_data, sizeof(da_cb_t));
+ }
+ return ret;
+}
+
+static void __destroy_http_msg(http_msg_t *msg)
+{
+ msg->curl = DA_NULL;
+ free(msg);
+}
+
+static void __destroy_http_msg_request(http_msg_request_t *msg)
+{
+ if (msg) {
+ http_msg_request_destroy(&msg);
+ free(msg);
+ }
+}
+
+static void __destroy_http_msg_response(http_msg_response_t *msg)
+{
+ if (msg) {
+ http_msg_response_destroy(&msg);
+ free(msg);
+ }
+}
+
+static void __destroy_req_info(req_info_t *req_info)
+{
+ if (req_info) {
+ free(req_info->url);
+ if (req_info->req_header && req_info->req_header_count > 0) {
+ int i = 0;
+ int count = req_info->req_header_count;
+ for (i = 0; i < count; i++) {
+ free(req_info->req_header[i]);
+ req_info->req_header[i] = DA_NULL;
+ }
+ free(req_info->req_header);
+ req_info->req_header = DA_NULL;
+ req_info->req_header_count = 0;
+ }
+ free(req_info->install_path);
+ free(req_info->file_name);
+ free(req_info->etag);
+ free(req_info->temp_file_path);
+ free(req_info->pkg_name);
+ req_info->user_req_data = DA_NULL;
+ req_info->user_client_data = DA_NULL;
+ free(req_info);
+ }
+}
+
+void destroy_http_info(http_info_t *http_info)
+{
+ if (http_info) {
+ DA_LOGI("[TEST] location_url[%p]",http_info->location_url);
+ free(http_info->location_url);
+ free(http_info->proxy_addr);
+ free(http_info->content_type_from_header);
+ free(http_info->etag_from_header);
+ free(http_info->file_name_from_header);
+ if (http_info->http_msg_request) {
+ __destroy_http_msg_request(http_info->http_msg_request);
+ http_info->http_msg_request = DA_NULL;
+ }
+ if (http_info->http_msg_response) {
+ __destroy_http_msg_response(http_info->http_msg_response);
+ http_info->http_msg_response = DA_NULL;
+ }
+ if (http_info->http_msg) {
+ __destroy_http_msg(http_info->http_msg);
+ http_info->http_msg = DA_NULL;
+ }
+ DA_MUTEX_DESTROY(&(http_info->mutex_state));
+ DA_MUTEX_DESTROY(&(http_info->mutex_http));
+ DA_COND_DESTROY(&(http_info->cond_http));
+ http_info->state = HTTP_STATE_READY_TO_DOWNLOAD;
+ http_info->http_method = HTTP_METHOD_GET;
+ http_info->content_len_from_header = 0;
+ http_info->total_size = 0;
+ http_info->error_code = 0;
+ free(http_info);
+ }
+}
+
+void destroy_file_info(file_info_t *file_info)
+{
+ if (file_info) {
+ file_info->file_handle = DA_NULL;
+ free(file_info->pure_file_name);
+ free(file_info->extension);
+ free(file_info->file_path);
+ free(file_info->mime_type);
+ free(file_info->buffer);
+ file_info->buffer_len = 0;
+ file_info->file_size = 0;
+#ifdef _RAF_SUPPORT
+ file_info->file_size_of_temp_file = 0;
+#endif
+ file_info->bytes_written_to_file = 0;
+ file_info->is_updated = DA_FALSE;
+ free(file_info);
+ }
+}
+
+// For pause and resume case
+void reset_http_info_for_resume(http_info_t *http_info)
+{
+ if (http_info) {
+ DA_LOGI("[TEST] location_url[%p]",http_info->location_url);
+ free(http_info->location_url);
+ http_info->location_url = DA_NULL;
+ free(http_info->proxy_addr);
+ http_info->proxy_addr = DA_NULL;
+ free(http_info->content_type_from_header);
+ http_info->content_type_from_header = DA_NULL;
+ if (http_info->http_msg_response) {
+ __destroy_http_msg_response(http_info->http_msg_response);
+ http_info->http_msg_response = DA_NULL;
+ }
+ if (http_info->http_msg) {
+ __destroy_http_msg(http_info->http_msg);
+ http_info->http_msg = DA_NULL;
+ }
+ http_info->http_method = HTTP_METHOD_GET;
+ http_info->content_len_from_header = 0;
+ http_info->total_size = 0;
+ }
+}
+
+void reset_http_info(http_info_t *http_info)
+{
+ if (http_info) {
+ DA_LOGI("[TEST] location_url[%p]",http_info->location_url);
+ free(http_info->location_url);
+ http_info->location_url = DA_NULL;
+ free(http_info->proxy_addr);
+ http_info->proxy_addr = DA_NULL;
+ free(http_info->content_type_from_header);
+ http_info->content_type_from_header = DA_NULL;
+ if (http_info->http_msg_request) {
+ __destroy_http_msg_request(http_info->http_msg_request);
+ http_info->http_msg_request = DA_NULL;
+ }
+ if (http_info->http_msg_response) {
+ __destroy_http_msg_response(http_info->http_msg_response);
+ http_info->http_msg_response = DA_NULL;
+ }
+ if (http_info->http_msg) {
+ __destroy_http_msg(http_info->http_msg);
+ http_info->http_msg = DA_NULL;
+ }
+ http_info->http_method = HTTP_METHOD_GET;
+ http_info->content_len_from_header = 0;
+ http_info->total_size = 0;
+ }
+}
+
+da_bool_t is_valid_download_id(int download_id)
+{
+ da_ret_t ret = DA_RESULT_OK;
+
+ DA_LOGV("");
+ DA_MUTEX_LOCK(&mutex_da_info_list);
+ if (DA_NULL == da_info_list[download_id]) {
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+ return DA_FALSE;
+ }
+ if (is_stopped_state(da_info_list[download_id])) {
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+ return DA_TRUE;
+ }
+ if (da_info_list[download_id]->da_id != DA_INVALID_ID) {
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+ return DA_TRUE;
+ } else {
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+ return DA_FALSE;
+ }
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+ return ret;
+}
+
+void destroy_da_info_list()
+{
+ int i = 0;
+ DA_MUTEX_LOCK(&mutex_da_info_list);
+ for (i = 0; i < DA_MAX_ID; i++) {
+ if(DA_NULL != da_info_list[i]) {
+ if (da_info_list[i]->req_info) {
+ __destroy_req_info(da_info_list[i]->req_info);
+ da_info_list[i]->req_info = DA_NULL;
+ }
+ if (da_info_list[i]->http_info) {
+ destroy_http_info(da_info_list[i]->http_info);
+ da_info_list[i]->http_info = DA_NULL;
+ }
+ if (da_info_list[i]->file_info) {
+ destroy_file_info(da_info_list[i]->file_info);
+ da_info_list[i]->file_info = DA_NULL;
+ }
+ free(da_info_list[i]);
+ da_info_list[i] = DA_NULL;
+ }
+ }
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+}
+
+void destroy_da_info(int id)
+{
+ da_info_t *da_info = DA_NULL;
+ DA_MUTEX_LOCK(&mutex_da_info_list);
+ da_info = da_info_list[id];
+ if (da_info) {
+ if (da_info->req_info) {
+ __destroy_req_info(da_info->req_info);
+ da_info->req_info = DA_NULL;
+ }
+ if (da_info->http_info) {
+ destroy_http_info(da_info->http_info);
+ da_info->http_info = DA_NULL;
+ }
+ if (da_info->file_info) {
+ destroy_file_info(da_info->file_info);
+ da_info->file_info = DA_NULL;
+ }
+ da_info->da_id = DA_INVALID_ID;
+ da_info->tid = DA_INVALID_ID;
+ memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t));
+ free(da_info);
+ da_info_list[id] = DA_NULL;
+ }
+ DA_MUTEX_UNLOCK(&mutex_da_info_list);
+}
diff --git a/agent/download-agent-dl-mgr.c b/agent/download-agent-dl-mgr.c
index 7a2ce0d..e57f3f3 100755
--- a/agent/download-agent-dl-mgr.c
+++ b/agent/download-agent-dl-mgr.c
@@ -14,301 +14,173 @@
* limitations under the License.
*/
-#include "download-agent-client-mgr.h"
-#include "download-agent-debug.h"
-#include "download-agent-dl-mgr.h"
-#include "download-agent-utils.h"
-#include "download-agent-http-mgr.h"
-#include "download-agent-file.h"
-#include "download-agent-plugin-conf.h"
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <signal.h>
+#ifdef _ENABLE_SYS_RESOURCE
+#include "resourced.h"
+#endif
-static da_result_t __cancel_download_with_slot_id(int slot_id);
-static da_result_t __suspend_download_with_slot_id(int slot_id);
-
+#include "download-agent-dl-mgr.h"
+#include "download-agent-dl-info.h"
+#include "download-agent-http-mgr.h"
-da_result_t requesting_download(stage_info *stage)
+void __thread_clean_up_handler_for_start_download(void *arg)
{
- da_result_t ret = DA_RESULT_OK;
- req_dl_info *request_session = DA_NULL;
+ DA_LOGI("cleanup for thread id[%lu]", pthread_self());
+}
- DA_LOG_FUNC_LOGV(Default);
+da_ret_t __download_content(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
- if (!stage) {
- DA_LOG_ERR(Default, "stage is null..");
+ DA_LOGV("");
+ if (!da_info) {
+ DA_LOGE("NULL CHECK!: da_info");
ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
+ return ret;
}
- ret = make_req_dl_info_http(stage, GET_STAGE_TRANSACTION_INFO(stage));
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- request_session = GET_STAGE_TRANSACTION_INFO(stage);
- ret = request_http_download(stage);
- if (DA_RESULT_OK == ret) {
- DA_LOG_VERBOSE(Default, "Http download is complete.");
- } else {
- DA_LOG_ERR(Default, "Http download is failed. ret = %d", ret);
- goto ERR;
- }
-ERR:
+ ret = request_http_download(da_info);
return ret;
}
-da_result_t handle_after_download(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- da_mime_type_id_t mime_type = DA_MIME_TYPE_NONE;
-
- DA_LOG_FUNC_LOGV(Default);
- mime_type = get_mime_type_id(
- GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)));
-
- switch (mime_type) {
- case DA_MIME_TYPE_NONE:
- DA_LOG(Default, "DA_MIME_TYPE_NONE");
- ret = DA_ERR_MISMATCH_CONTENT_TYPE;
- break;
- default:
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_FINISH, stage);
- break;
- } /* end of switch */
-
- return ret;
-}
-
-static da_result_t __cancel_download_with_slot_id(int slot_id)
+static void *__thread_start_download(void *data)
{
- da_result_t ret = DA_RESULT_OK;
- download_state_t download_state;
- stage_info *stage = DA_NULL;
-
- DA_LOG_FUNC_LOGD(Default);
-
- _da_thread_mutex_lock (&mutex_download_state[slot_id]);
- download_state = GET_DL_STATE_ON_ID(slot_id);
- DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id));
-
- if (download_state == DOWNLOAD_STATE_FINISH ||
- download_state == DOWNLOAD_STATE_CANCELED) {
- DA_LOG_CRITICAL(Default, "Already download is finished. Do not send cancel request");
- _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
- return ret;
+ da_info_t *da_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ int da_id = DA_INVALID_ID;
+
+// DA_LOGV("");
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, DA_NULL);
+
+ da_info = (da_info_t *)data;
+ NULL_CHECK_RET_OPT(da_info, DA_NULL);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET_OPT(req_info, DA_NULL);
+
+ da_id = da_info->da_id;
+ pthread_cleanup_push(__thread_clean_up_handler_for_start_download, DA_NULL);
+#ifdef _ENABLE_SYS_RESOURCE
+ if (req_info->pkg_name) {
+ pid_t tid = (pid_t) syscall(SYS_gettid);
+ da_info->tid = (pid_t) syscall(SYS_gettid);
+ DA_SECURE_LOGI("pkg_name[%s] threadid[%lu]",
+ req_info->pkg_name,pthread_self());
+ if (join_app_performance(req_info->pkg_name, tid) !=
+ RESOURCED_ERROR_OK) {
+ DA_LOGE("Can not put app to network performance id[%d]", da_id);
+ }
}
- _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
-
- stage = GET_DL_CURRENT_STAGE(slot_id);
- if (!stage)
- return DA_RESULT_OK;
-
- ret = request_to_cancel_http_download(stage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- DA_LOG(Default, "Download cancel Successful for download id - %d", slot_id);
-ERR:
- return ret;
+#endif
+ __download_content(da_info);
+ destroy_da_info(da_id);
+ pthread_cleanup_pop(0);
+ DA_LOGI("=====EXIT thread : da_id[%d]=====", da_id);
+ pthread_exit((void *)DA_NULL);
+ return DA_NULL;
}
-da_result_t cancel_download(int dl_id)
+da_ret_t start_download(da_info_t *da_info)
{
- da_result_t ret = DA_RESULT_OK;
-
- int slot_id = DA_INVALID_ID;
-
- DA_LOG_FUNC_LOGD(Default);
-
- ret = get_slot_id_for_dl_id(dl_id, &slot_id);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(Default, "dl req ID is not Valid");
+ da_ret_t ret = DA_RESULT_OK;
+ pthread_attr_t thread_attr;
+ pthread_t tid;
+ if (pthread_attr_init(&thread_attr) != 0) {
+ ret = DA_ERR_FAIL_TO_CREATE_THREAD;
goto ERR;
}
- if (DA_FALSE == is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(Default, "Download ID is not Valid");
- ret = DA_ERR_INVALID_ARGUMENT;
+ if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) {
+ ret = DA_ERR_FAIL_TO_CREATE_THREAD;
goto ERR;
}
- ret = __cancel_download_with_slot_id(slot_id);
-
-ERR:
- return ret;
-
-}
-
-static da_result_t __suspend_download_with_slot_id(int slot_id)
-{
- da_result_t ret = DA_RESULT_OK;
- download_state_t download_state;
- stage_info *stage = DA_NULL;
-
- DA_LOG_FUNC_LOGD(Default);
-
- _da_thread_mutex_lock (&mutex_download_state[slot_id]);
- download_state = GET_DL_STATE_ON_ID(slot_id);
- DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id));
- _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
-
- stage = GET_DL_CURRENT_STAGE(slot_id);
- if (!stage)
- return DA_ERR_CANNOT_SUSPEND;
-
- ret = request_to_suspend_http_download(stage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- DA_LOG(Default, "Download Suspend Successful for download id-%d", slot_id);
-ERR:
- return ret;
-}
-
-da_result_t suspend_download(int dl_id, da_bool_t is_enable_cb)
-{
- da_result_t ret = DA_RESULT_OK;
- int slot_id = DA_INVALID_ID;
-
- DA_LOG_FUNC_LOGD(Default);
-
- ret = get_slot_id_for_dl_id(dl_id, &slot_id);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(Default, "dl req ID is not Valid");
- goto ERR;
- }
- GET_DL_ENABLE_PAUSE_UPDATE(slot_id) = is_enable_cb;
- if (DA_FALSE == is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(Default, "Download ID is not Valid");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
+ if (pthread_create(&(tid), &thread_attr,
+ __thread_start_download, da_info) < 0) {
+ DA_LOGE("Fail to make thread:id[%d]", da_info->da_id);
+ ret = DA_ERR_FAIL_TO_CREATE_THREAD;
+ } else {
+ if (tid < 1) {
+ DA_LOGE("The thread start is failed before calling this");
+// When http resource is leaked, the thread ID is initialized at error handling section of thread_start_download()
+// Because the thread ID is initialized, the ptrhead_detach should not be called. This is something like timing issue between threads.
+// thread info and basic_dl_input is freed at thread_start_download(). And it should not returns error code in this case.
+ ret = DA_ERR_FAIL_TO_CREATE_THREAD;
+ goto ERR;
+ }
}
-
- ret = __suspend_download_with_slot_id(slot_id);
-
+ da_info->thread_id = tid;
+ DA_LOGI("Thread create:thread id[%lu]", da_info->thread_id);
ERR:
+ if (DA_RESULT_OK != ret) {
+ destroy_da_info(da_info->da_id);
+ }
return ret;
-
}
-static da_result_t __resume_download_with_slot_id(int slot_id)
+da_ret_t cancel_download(int dl_id, da_bool_t is_enable_cb)
{
- da_result_t ret = DA_RESULT_OK;
- download_state_t download_state;
- stage_info *stage = DA_NULL;
-
- DA_LOG_FUNC_LOGD(Default);
+ da_ret_t ret = DA_RESULT_OK;
+ da_info_t *da_info = DA_NULL;
- _da_thread_mutex_lock (&mutex_download_state[slot_id]);
- download_state = GET_DL_STATE_ON_ID(slot_id);
- DA_LOG(Default, "download_state = %d", GET_DL_STATE_ON_ID(slot_id));
- _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
+ DA_LOGV("");
- stage = GET_DL_CURRENT_STAGE(slot_id);
-
- ret = request_to_resume_http_download(stage);
+ ret = get_da_info_with_da_id(dl_id, &da_info);
+ if (ret != DA_RESULT_OK || !da_info) {
+ return DA_ERR_INVALID_ARGUMENT;
+ }
+ da_info->is_cb_update = is_enable_cb;
+ ret = request_to_cancel_http_download(da_info);
if (ret != DA_RESULT_OK)
goto ERR;
- DA_LOG(Default, "Download Resume Successful for download id-%d", slot_id);
+ DA_LOGI("Download cancel Successful for download id[%d]", da_info->da_id);
+
ERR:
return ret;
}
-da_result_t resume_download(int dl_id)
+da_ret_t suspend_download(int dl_id, da_bool_t is_enable_cb)
{
- da_result_t ret = DA_RESULT_OK;
- int slot_id = DA_INVALID_ID;
+ da_ret_t ret = DA_RESULT_OK;
+ da_info_t *da_info = DA_NULL;
- DA_LOG_FUNC_LOGD(Default);
+ DA_LOGV("");
- ret = get_slot_id_for_dl_id(dl_id, &slot_id);
+ ret = get_da_info_with_da_id(dl_id, &da_info);
+ if (ret != DA_RESULT_OK || !da_info) {
+ return DA_ERR_INVALID_ARGUMENT;
+ }
+ da_info->is_cb_update = is_enable_cb;
+ ret = request_to_suspend_http_download(da_info);
if (ret != DA_RESULT_OK)
goto ERR;
-
- if (DA_FALSE == is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(Default, "Download ID is not Valid");
- ret = DA_ERR_INVALID_DL_REQ_ID;
- goto ERR;
- }
-
- ret = __resume_download_with_slot_id(slot_id);
-
+ DA_LOGV("Download Suspend Successful for download id[%d]", da_info->da_id);
ERR:
return ret;
-}
-
-da_result_t send_user_noti_and_finish_download_flow(
- int slot_id, char *installed_path, char *etag)
-{
- da_result_t ret = DA_RESULT_OK;
- download_state_t download_state = HTTP_STATE_READY_TO_DOWNLOAD;
- da_bool_t need_destroy_download_info = DA_FALSE;
-
- DA_LOG_FUNC_LOGV(Default);
- _da_thread_mutex_lock (&mutex_download_state[slot_id]);
- download_state = GET_DL_STATE_ON_ID(slot_id);
- DA_LOG_DEBUG(Default, "state = %d", download_state);
- _da_thread_mutex_unlock (&mutex_download_state[slot_id]);
-
- switch (download_state) {
- case DOWNLOAD_STATE_FINISH:
- send_client_finished_info(slot_id, GET_DL_ID(slot_id),
- installed_path, DA_NULL, DA_RESULT_OK,
- get_http_status(slot_id));
- need_destroy_download_info = DA_TRUE;
- break;
- case DOWNLOAD_STATE_CANCELED:
- send_client_finished_info(slot_id, GET_DL_ID(slot_id),
- installed_path, etag, DA_RESULT_USER_CANCELED,
- get_http_status(slot_id));
- need_destroy_download_info = DA_TRUE;
- break;
-#ifdef PAUSE_EXIT
- case DOWNLOAD_STATE_PAUSED:
- need_destroy_download_info = DA_TRUE;
- break;
-#endif
- default:
- DA_LOG(Default, "download state = %d", download_state);
- break;
- }
-
- if (need_destroy_download_info == DA_TRUE) {
- destroy_download_info(slot_id);
- } else {
- DA_LOG_CRITICAL(Default, "download info is not destroyed");
- }
-
- return ret;
}
-da_bool_t is_valid_download_id(int dl_id)
+da_ret_t resume_download(int dl_id)
{
+ da_ret_t ret = DA_RESULT_OK;
+ da_info_t *da_info = DA_NULL;
- da_bool_t ret = DA_TRUE;
- int slot_id = DA_INVALID_ID;
-
- DA_LOG_VERBOSE(Default, "[is_valid_download_id]download_id : %d", dl_id);
-
- ret = get_slot_id_for_dl_id(dl_id, &slot_id);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(Default, "dl req ID is not Valid");
- ret = DA_FALSE;
- goto ERR;
- } else {
- ret = DA_TRUE;
- }
+ DA_LOGV("");
- if (DA_FALSE == is_valid_slot_id(slot_id)) {
- DA_LOG_ERR(Default, "Download ID is not Valid");
- ret = DA_FALSE;
- goto ERR;
+ ret = get_da_info_with_da_id(dl_id, &da_info);
+ if (ret != DA_RESULT_OK || !da_info) {
+ return DA_ERR_INVALID_ARGUMENT;
}
- if (GET_DL_THREAD_ID(slot_id) < 1) {
- DA_LOG_ERR(Default, "Download thread is not alive");
- ret = DA_FALSE;
+ da_info->is_cb_update = DA_TRUE;
+ ret = request_to_resume_http_download(da_info);
+ if (ret != DA_RESULT_OK)
goto ERR;
- }
-
+ DA_LOGV("Download Resume Successful for download id[%d]", da_info->da_id);
ERR:
return ret;
}
+
diff --git a/agent/download-agent-encoding.c b/agent/download-agent-encoding.c
index 1955fcd..3f14fca 100755
--- a/agent/download-agent-encoding.c
+++ b/agent/download-agent-encoding.c
@@ -16,12 +16,12 @@
#include <string.h>
#include <stdlib.h>
-#include <glib.h>
+#include "glib.h"
-#include "download-agent-encoding.h"
#include "download-agent-debug.h"
+#include "download-agent-encoding.h"
-da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
+da_ret_t _parsing_base64_encoded_str(const char *in_encoded_str,
char **out_charset_type,
char *out_encoding_type,
char **out_raw_encoded_str);
@@ -34,7 +34,7 @@ da_bool_t is_base64_encoded_word(const char *in_str)
char *found_str = DA_NULL;
if (!in_str) {
- DA_LOG_ERR(Default, "input string is NULL");
+ DA_LOGE("input string is NULL");
return DA_FALSE;
}
@@ -47,14 +47,10 @@ da_bool_t is_base64_encoded_word(const char *in_str)
snprintf(second_needle, sizeof(second_needle), "%s", "?="); // ?=
}
-// DA_SECURE_LOGD("needle = [%s], haystack = [%s]", first_needle, haystack);
-
found_str = strstr(haystack, first_needle);
if (found_str) {
if (found_str == haystack) {
-// DA_SECURE_LOGD("Input string is starting with %s", needle);
haystack = haystack + strlen(haystack) - strlen(second_needle);
-// DA_SECURE_LOGD("second haystack is [%s]", haystack);
if(!strcmp(haystack, second_needle))
return DA_TRUE;
}
@@ -62,11 +58,10 @@ da_bool_t is_base64_encoded_word(const char *in_str)
return DA_FALSE;
}
-da_result_t decode_base64_encoded_str(const char *in_encoded_str,
+da_ret_t decode_base64_encoded_str(const char *in_encoded_str,
char **out_decoded_ascii_str)
{
- da_result_t ret = DA_RESULT_OK;
-
+ da_ret_t ret = DA_RESULT_OK;
const char *org_str = DA_NULL;
char *charset_type = NULL;
char encoding_type = '\0';
@@ -80,7 +75,7 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str,
org_str = in_encoded_str;
if(!org_str) {
- DA_LOG_ERR(Default, "Input string is NULL");
+ DA_LOGE("Input string is NULL");
ret = DA_ERR_INVALID_ARGUMENT;
goto ERR;
}
@@ -91,10 +86,8 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str,
goto ERR;
}
-// DA_SECURE_LOGD("charset = [%s], encoding = [%c], raw = [%s]", charset_type, encoding_type, raw_encoded_str);
-
if(encoding_type != 'B') {
- DA_LOG_ERR(Default, "Encoded Word is not encoded with Base64, but %c. We can only handle Base64.", encoding_type);
+ DA_LOGE("Encoded Word is not encoded with Base64, but %c. We can only handle Base64.", encoding_type);
ret = DA_ERR_INVALID_ARGUMENT;
goto ERR;
}
@@ -112,7 +105,7 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str,
DA_SECURE_LOGD("g_decoded_text = [%s]", g_decoded_text);
decoded_str = (char*)calloc(1, g_decoded_text_len+1);
if(!decoded_str) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
ret = DA_ERR_FAIL_TO_MEMALLOC;
goto ERR;
} else {
@@ -123,40 +116,32 @@ da_result_t decode_base64_encoded_str(const char *in_encoded_str,
ERR:
*out_decoded_ascii_str = decoded_str;
-
if(charset_type) {
free(charset_type);
charset_type = NULL;
}
-
if(raw_encoded_str) {
free(raw_encoded_str);
raw_encoded_str = NULL;
}
-
if(g_decoded_text) {
g_free(g_decoded_text);
}
-
return ret;
}
-
-da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
+da_ret_t _parsing_base64_encoded_str(const char *in_encoded_str,
char **out_charset_type,
char *out_encoding_type,
char **out_raw_encoded_str)
{
- da_result_t ret = DA_RESULT_OK;
-
+ da_ret_t ret = DA_RESULT_OK;
const char *org_str = DA_NULL; // e.g. =?UTF-8?B?7Jew7JWE7JmA7IKs7J6QLmpwZw==?=
char *charset_type = NULL; // e.g. UTF-8
char encoding_type = '\0'; // e.g. B (means Base64)
char *raw_encoded_str = NULL; // e.g. 7Jew7JWE7JmA7IKs7J6QLmpwZw==
-
char *haystack = DA_NULL;
char needle[8] = {0,};
-
char *wanted_str = DA_NULL;
int wanted_str_len = 0;
char *wanted_str_start = DA_NULL;
@@ -164,7 +149,7 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
org_str = in_encoded_str;
if (!org_str) {
- DA_LOG_ERR(Default, "Input string is NULL");
+ DA_LOGE("Input string is NULL");
ret = DA_ERR_INVALID_ARGUMENT;
goto ERR;
}
@@ -174,12 +159,11 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
snprintf(needle, sizeof(needle), "=?");
wanted_str_end = strstr(haystack, needle);
if (!wanted_str_end) {
- DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("DA_ERR_INVALID_ARGUMENT");
ret = DA_ERR_INVALID_ARGUMENT;
goto ERR;
} else {
wanted_str = wanted_str_end + strlen(needle);
- DA_SECURE_LOGD("strip [%s]", wanted_str);
}
// for charset
@@ -187,14 +171,14 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
needle[0] = '?';
wanted_str_end = strchr(haystack, needle[0]);
if (!wanted_str_end) {
- DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("DA_ERR_INVALID_ARGUMENT");
ret = DA_ERR_INVALID_ARGUMENT;
goto ERR;
} else {
wanted_str_len = wanted_str_end - wanted_str_start + 1;
wanted_str = (char*)calloc(1, wanted_str_len+1);
if (!wanted_str) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
ret = DA_ERR_FAIL_TO_MEMALLOC;
goto ERR;
} else {
@@ -203,27 +187,26 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
wanted_str = DA_NULL;
}
- DA_LOG(Default, "charset [%s]", charset_type);
+ DA_LOGV("charset [%s]", charset_type);
}
-
// for encoding
encoding_type = *(++wanted_str_end);
- DA_LOG(Default, "encoding [%c]", encoding_type);
+ DA_LOGV("encoding [%c]", encoding_type);
// for raw encoded str
haystack = wanted_str_start = wanted_str_end + 1;
snprintf(needle, sizeof(needle), "?=");
wanted_str_end = strstr(haystack, needle);
if (!wanted_str_end) {
- DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("DA_ERR_INVALID_ARGUMENT");
ret = DA_ERR_INVALID_ARGUMENT;
goto ERR;
} else {
wanted_str_len = wanted_str_end - wanted_str_start + 1;
wanted_str = (char*)calloc(1, wanted_str_len+1);
if (!wanted_str) {
- DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
ret = DA_ERR_FAIL_TO_MEMALLOC;
goto ERR;
} else {
@@ -234,7 +217,6 @@ da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
DA_SECURE_LOGD("raw encoded str [%s]", raw_encoded_str);
}
-
ERR:
if (ret != DA_RESULT_OK) {
if (charset_type) {
@@ -242,17 +224,15 @@ ERR:
charset_type = NULL;
}
}
-
*out_charset_type = charset_type;
*out_encoding_type = encoding_type;
*out_raw_encoded_str = raw_encoded_str;
-
return ret;
}
void decode_url_encoded_str(const char *in_encoded_str, char **out_str)
{
- char *in = NULL;
+ char *in = NULL;
char *out = NULL;
*out_str = calloc(1, strlen(in_encoded_str) + 1);
if (*out_str == NULL)
@@ -279,4 +259,3 @@ void decode_url_encoded_str(const char *in_encoded_str, char **out_str)
out++;
}
}
-
diff --git a/agent/download-agent-file.c b/agent/download-agent-file.c
index 0da5445..ea901e2 100755
--- a/agent/download-agent-file.c
+++ b/agent/download-agent-file.c
@@ -14,593 +14,69 @@
* limitations under the License.
*/
-#include <stdio.h>
+#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
+#include <string.h>
+#include <sys/vfs.h>
#include <math.h>
#include <errno.h>
-#include "download-agent-client-mgr.h"
+
#include "download-agent-debug.h"
-#include "download-agent-utils.h"
-#include "download-agent-dl-mgr.h"
#include "download-agent-file.h"
#include "download-agent-mime-util.h"
-#include "download-agent-http-mgr.h"
+/* FIXME Later */
+#include "download-agent-http-msg-handler.h"
+#include "download-agent-plugin-drm.h"
#include "download-agent-plugin-conf.h"
+#include <storage.h>
-#define NO_NAME_TEMP_STR "No name"
-
-static da_result_t __set_file_size(stage_info *stage);
-static da_result_t __saved_file_open(stage_info *stage);
-
-static char *__derive_extension(stage_info *stage);
-static da_result_t __divide_file_name_into_pure_name_N_extesion(
- const char *in_file_name,
- char **out_pure_file_name,
- char **out_extension);
-static da_result_t __get_candidate_file_name(stage_info *stage,
- char **out_pure_file_name, char **out_extension);
-
-static da_result_t __file_write_buf_make_buf(file_info *file_storage);
-static da_result_t __file_write_buf_destroy_buf(file_info *file_storage);
-static da_result_t __file_write_buf_flush_buf(stage_info *stage,
- file_info *file_storage);
-static da_result_t __file_write_buf_copy_to_buf(file_info *file_storage,
- char *body, int body_len);
-static da_result_t __file_write_buf_directly_write(stage_info *stage,
- file_info *file_storage, char *body, int body_len);
-
-da_result_t clean_files_from_dir(char *dir_path)
-{
- da_result_t ret = DA_RESULT_OK;
- struct dirent *d = DA_NULL;
- DIR *dir;
- char file_path[DA_MAX_FULL_PATH_LEN] = { 0, };
-
- DA_LOG_FUNC_LOGD(FileManager);
-
- if (dir_path == DA_NULL)
- return DA_ERR_INVALID_ARGUMENT;
-
- if (is_dir_exist(dir_path)) {
- dir = opendir(dir_path);
- if (DA_NULL == dir) {
- DA_LOG_ERR(FileManager, "opendir() is failed.");
- ret = DA_ERR_INVALID_INSTALL_PATH;
- } else {
- while (DA_NULL != (d = readdir(dir))) {
- DA_SECURE_LOGD("%s",d->d_name);
- if (0 == strncmp(d->d_name, ".", strlen("."))
- || 0 == strncmp(d->d_name,
- "..",
- strlen(".."))) {
- continue;
- }
-
- memset(file_path, 0x00, DA_MAX_FULL_PATH_LEN);
- snprintf(file_path, DA_MAX_FULL_PATH_LEN,
- "%s/%s", dir_path, d->d_name);
- if (remove(file_path) < 0) {
- DA_LOG_ERR(FileManager, "fail to remove file");
- }
- }
-
- closedir(dir);
- if (remove(dir_path) < 0) {
- DA_LOG_ERR(FileManager, "fail to remove dir");
- }
- }
- }
- return ret;
-}
-
-/* Priority to obtain MIME Type
- * 1. HTTP response header's <Content-Type> field
- * 2. from OMA descriptor file's <content-type> attribute (mandatory field)
- * 3. Otherwise, leave blank for MIME Type
- */
-da_result_t get_mime_type(stage_info *stage, char **out_mime_type)
-{
- char *mime_type = DA_NULL;
-
- if (!GET_STAGE_SOURCE_INFO(stage))
- return DA_ERR_INVALID_ARGUMENT;
-
- /* Priority 1 */
- if (GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage))) {
- mime_type = GET_REQUEST_HTTP_HDR_CONT_TYPE(GET_STAGE_TRANSACTION_INFO(stage));
-// DA_SECURE_LOGI("content type from HTTP response header [%s]", mime_type);
- }
-
- if (!mime_type) {
- DA_LOG(FileManager, "no content type derived");
- return DA_RESULT_OK;
- }
-
- /* FIXME really need memory allocation? */
- *out_mime_type = (char *)calloc(1, strlen(mime_type) + 1);
- if (*out_mime_type) {
- strncpy(*out_mime_type, mime_type, strlen(mime_type));
-// DA_SECURE_LOGD("out_mime_type str[%s] ptr[%p] len[%d]",
-// *out_mime_type,*out_mime_type,strlen(*out_mime_type));
- } else {
- DA_LOG_ERR(FileManager, "fail to allocate memory");
- return DA_ERR_FAIL_TO_MEMALLOC;
- }
-
-// DA_SECURE_LOGD("mime type = %s", *out_mime_type);
- return DA_RESULT_OK;
-}
-
-da_bool_t is_file_exist(const char *file_path)
-{
- struct stat dir_state;
- int stat_ret;
-
- if (file_path == DA_NULL) {
- DA_LOG_ERR(FileManager, "file path is DA_NULL");
- return DA_FALSE;
- }
-
- stat_ret = stat(file_path, &dir_state);
-
- if (stat_ret == 0) {
- if (dir_state.st_mode & S_IFREG) {
- DA_SECURE_LOGD("Exist! %s is a regular file & its size = %lu", file_path, dir_state.st_size);
- return DA_TRUE;
- }
-
- return DA_FALSE;
- }
- return DA_FALSE;
-
-}
-
-da_bool_t is_dir_exist(const char *file_path)
-{
- struct stat dir_state;
- int stat_ret;
-
- if (file_path == DA_NULL) {
- DA_LOG_ERR(FileManager, "file path is DA_NULL");
- return DA_FALSE;
- }
-
- stat_ret = stat(file_path, &dir_state);
-
- if (stat_ret == 0) {
- if (dir_state.st_mode & S_IFDIR) {
- DA_LOG_VERBOSE(FileManager, "Existed directory.");
- return DA_TRUE;
- }
-
- return DA_FALSE;
- }
- return DA_FALSE;
-}
-
-void get_file_size(char *file_path, unsigned long long *out_file_size)
-{
- struct stat dir_state;
- int stat_ret;
-
- *out_file_size = -1;
-
- if (file_path == DA_NULL) {
- DA_LOG_ERR(FileManager, "file path is DA_NULL");
- return;
- }
- /* Please do not use ftell() to obtain file size, use stat instead.
- * This is a guide from www.securecoding.cert.org
- * : FIO19-C. Do not use fseek() and ftell() to compute the size of a file
- */
- stat_ret = stat(file_path, &dir_state);
- if (stat_ret == 0) {
- if (dir_state.st_mode & S_IFREG) {
- DA_LOG(FileManager, "size = %lu", dir_state.st_size);
- *out_file_size = dir_state.st_size;
- }
- }
- return;
-}
+#define NO_NAME_TEMP_STR "No name"
+#define MAX_SUFFIX_COUNT 1000000000
-da_result_t __saved_file_open(stage_info *stage)
+da_ret_t __saved_file_open(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
- file_info *file_storage = DA_NULL;
+ da_ret_t ret = DA_RESULT_OK;
char *actual_file_path = DA_NULL;
void *fd = DA_NULL;
- DA_LOG_FUNC_LOGV(FileManager);
-
- file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
- if (!file_storage)
- return DA_ERR_INVALID_ARGUMENT;
+ DA_LOGV("");
- actual_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage);
+ actual_file_path = file_info->file_path;
if (!actual_file_path)
return DA_ERR_INVALID_ARGUMENT;
fd = fopen(actual_file_path, "a+"); // for resume
if (fd == DA_NULL) {
- DA_LOG_ERR(FileManager, "File open failed");
+ DA_LOGE("File open failed");
if (errno == ENOSPC)
ret = DA_ERR_DISK_FULL;
else
ret = DA_ERR_FAIL_TO_ACCESS_FILE;
goto ERR;
}
- GET_CONTENT_STORE_FILE_HANDLE(file_storage) = fd;
-// DA_SECURE_LOGD("file path for saving = %s",
-// GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage));
+ file_info->file_handle = fd;
+ //DA_SECURE_LOGD("file path for saving[%s]", file_info->file_path);
ERR:
if (DA_RESULT_OK != ret) {
- GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL;
+ file_info->file_handle = DA_NULL;
}
return ret;
}
-da_result_t __set_file_size(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- req_dl_info *stage_req_info = DA_NULL;
- file_info *file_storage = DA_NULL;
-
- DA_LOG_FUNC_LOGV(FileManager);
-
- if (!stage) {
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- stage_req_info = GET_STAGE_TRANSACTION_INFO(stage);
-
- file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
- if (!file_storage)
- goto ERR;
-
- if (GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info) != 0) {
- GET_CONTENT_STORE_FILE_SIZE(file_storage)
- = GET_REQUEST_HTTP_HDR_CONT_LEN(stage_req_info);
- } else {
- GET_CONTENT_STORE_FILE_SIZE(file_storage) = 0;
- }
- DA_LOG_VERBOSE(FileManager, "file size = %d", GET_CONTENT_STORE_FILE_SIZE(file_storage));
-ERR:
- return ret;
-
-}
-
-/* Priority to derive extension
- * 1. according to MIME-Type
- * 2. if MIME-Type is ambiguous or blank,
- * 2-1. derived from <Content-Disposition> field's "filename" attribute
- * 2-2. derived from url
- * 3. if url does not have extension, leave blank for extension
- */
-char *__derive_extension(stage_info *stage)
-{
- if (!stage)
- return DA_NULL;
-
- source_info_t *source_info = GET_STAGE_SOURCE_INFO(stage);
- req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage);
- file_info *file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
- char *extension = DA_NULL;
- char *url = DA_NULL;
-
- /* Priority 1 */
- char *mime_type = DA_NULL;
- mime_type = GET_CONTENT_STORE_CONTENT_TYPE(file_info_data);
- if (mime_type && !is_ambiguous_MIME_Type(mime_type)) {
- char *extension = DA_NULL;
- da_result_t ret = get_extension_from_mime_type(mime_type, &extension);
- if (ret == DA_RESULT_OK && extension)
- return extension;
- }
-
- /* Priority 2-1 */
- http_msg_response_t *http_msg_response = DA_NULL;
- http_msg_response = request_info->http_info.http_msg_response;
- if (http_msg_response) {
- char *file_name = DA_NULL;
- da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response,
- DA_NULL, &file_name);
- if (b_ret && file_name) {
- char *extension = DA_NULL;
- DA_SECURE_LOGD("Name from Content-Disposition :[%s]", file_name);
- __divide_file_name_into_pure_name_N_extesion(file_name, DA_NULL, &extension);
- if (file_name) {
- free(file_name);
- file_name = DA_NULL;
- }
- if (extension)
- return extension;
- }
- }
- /* Priority 2-2 */
- /* If there is location url from response header in case of redirection,
- * it try to parse the extention name from the location url */
- if (GET_REQUEST_HTTP_REQ_LOCATION(request_info))
- url = GET_REQUEST_HTTP_REQ_LOCATION(request_info);
- else
- url = GET_SOURCE_BASIC_URL(source_info);
- if (url) {
- DA_SECURE_LOGD("url:[%s]", url);
- da_bool_t b_ret = da_get_extension_name_from_url(url, &extension);
- if (b_ret && extension)
- return extension;
- }
-
- return DA_NULL;
-}
-
-/** Priority for deciding file name
- * 1. what client wants, which is conveyed by DA_FEATURE_FILE_NAME
- * 2. 'filename' option on HTTP response header's Content-Disposition field
- * 3. requesting URL
- * 4. Otherwise, define it as "No name"
- */
-da_result_t __get_candidate_file_name(stage_info *stage, char **out_pure_file_name, char **out_extension)
-{
- da_result_t ret = DA_RESULT_OK;
- source_info_t *source_info = DA_NULL;
- char *pure_file_name = DA_NULL;
- char *extension = DA_NULL;
-
- DA_LOG_FUNC_LOGV(FileManager);
-
- if (!stage || !out_pure_file_name)
- return DA_ERR_INVALID_ARGUMENT;
-
- source_info = GET_STAGE_SOURCE_INFO(stage);
- if (!source_info)
- return DA_ERR_INVALID_ARGUMENT;
-
- /* Priority 1 */
- if (!pure_file_name && GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage))) {
- __divide_file_name_into_pure_name_N_extesion(
- GET_DL_USER_FILE_NAME(GET_STAGE_DL_ID(stage)),
- &pure_file_name, &extension);
- }
-
- /* Priority 2 */
- if (!pure_file_name) {
- req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage);
- http_msg_response_t *http_msg_response = DA_NULL;
- http_msg_response = request_info->http_info.http_msg_response;
- if (http_msg_response) {
- char *file_name = DA_NULL;
- da_bool_t b_ret = http_msg_response_get_content_disposition(http_msg_response,
- DA_NULL, &file_name);
- if (b_ret && file_name) {
- DA_SECURE_LOGD("Name from Content-Disposition :[%s]", file_name);
- __divide_file_name_into_pure_name_N_extesion(file_name, &pure_file_name, &extension);
- if (file_name) {
- free(file_name);
- file_name = DA_NULL;
- }
- }
- }
- }
-
- /* Priority 3 */
- if (!pure_file_name) {
- char *url = DA_NULL;
- req_dl_info *request_info = GET_STAGE_TRANSACTION_INFO(stage);
- /* If there is location url from response header in case of redirection,
- * it try to parse the file name from the location url */
- if (GET_REQUEST_HTTP_REQ_LOCATION(request_info))
- url = GET_REQUEST_HTTP_REQ_LOCATION(request_info);
- else
- url = GET_SOURCE_BASIC_URL(source_info);
- if (url) {
- DA_SECURE_LOGD("url: [%s]", url);
- da_get_file_name_from_url(url, &pure_file_name);
- }
- }
-
- /* Priority 4 */
- if (!pure_file_name) {
- pure_file_name = strdup(NO_NAME_TEMP_STR);
- if (!pure_file_name) {
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
- }
-
- *out_pure_file_name = pure_file_name;
- pure_file_name = DA_NULL;
- DA_SECURE_LOGD("candidate file name [%s]", *out_pure_file_name);
-
- if (out_extension) {
- if (extension) {
- *out_extension = extension;
- extension = DA_NULL;
- } else {
- *out_extension = __derive_extension(stage);
- DA_SECURE_LOGD("candidate extension [%s]", *out_extension);
- }
- }
-
- if (extension)
- free(extension);
-
- return DA_RESULT_OK;
-
-ERR:
- if (extension)
- free(extension);
-
- return ret;
-}
-
-da_result_t __decide_file_path(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- char *temp_dir = DA_NULL;
- char *extension = DA_NULL;
- char *file_name_without_extension = DA_NULL;
- char *tmp_file_path = DA_NULL;
- char *user_install_path = DA_NULL;
- file_info *file_info_data = DA_NULL;
- int len = 0;
- DA_LOG_FUNC_LOGV(FileManager);
-
- file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
- if (!file_info_data)
- return DA_ERR_INVALID_ARGUMENT;
-
-
- /* If the installed path which user want is set, the temporary directory is same to the installation directory.
- * Otherwise, the default temporary directory is used.
- */
- user_install_path = GET_DL_USER_INSTALL_PATH(GET_STAGE_DL_ID(stage));
- if (user_install_path) {
- len = strlen(user_install_path);
- temp_dir = (char *)calloc(len + 1, sizeof(char));
- if (!temp_dir) {
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
- memcpy(temp_dir, user_install_path, len);
- temp_dir[len] = '\0';
-
- } else {
- ret = get_default_install_dir(&temp_dir);
- if (DA_RESULT_OK != ret || DA_NULL == temp_dir) {
- goto ERR;
- }
- }
-
- ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension);
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- // for resume
- tmp_file_path = get_full_path_avoided_duplication(temp_dir, file_name_without_extension, extension);
- if (tmp_file_path) {
- GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage))
- = tmp_file_path;
- tmp_file_path = DA_NULL;
- } else {
- ret = DA_ERR_FAIL_TO_ACCESS_FILE;
- goto ERR;
- }
-
- if (file_name_without_extension && !GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data)) {
- GET_CONTENT_STORE_PURE_FILE_NAME(file_info_data) = file_name_without_extension;
- file_name_without_extension = DA_NULL;
- }
-
- if (extension && !GET_CONTENT_STORE_EXTENSION(file_info_data)) {
- GET_CONTENT_STORE_EXTENSION(file_info_data) = extension;
- extension = DA_NULL;
- }
-
-ERR:
- DA_SECURE_LOGI("decided file path = %s", GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data));
- if (temp_dir) {
- free(temp_dir);
- temp_dir = DA_NULL;
- }
- if (file_name_without_extension) {
- free(file_name_without_extension);
- file_name_without_extension = DA_NULL;
- }
- if (extension) {
- free(extension);
- extension = DA_NULL;
- }
- return ret;
-}
-
-char *get_full_path_avoided_duplication(char *in_dir, char *in_candidate_file_name, char *in_extension)
-{
- char *dir = in_dir;
- char *file_name = in_candidate_file_name;
- char *extension = in_extension;
- char *final_path = DA_NULL;
-
- int final_path_len = 0;
- int extension_len = 0;
-
- int suffix_count = 0; /* means suffix on file name. up to "_1000000000" */
- const int max_suffix_count = 1000000000;
- int suffix_len = (int)log10(max_suffix_count+1) + 1; /* 1 means "_" */
-
- if (!in_dir || !in_candidate_file_name)
- return DA_NULL;
-
-// DA_SECURE_LOGD("in_candidate_file_name=[%s], in_extension=[%s]", in_candidate_file_name, in_extension);
-
- if (extension)
- extension_len = strlen(extension);
-
- /* first 1 for "/", second 1 for ".", last 1 for DA_NULL */
- final_path_len = strlen(dir) + 1 + strlen(file_name) + 1
- + suffix_len + extension_len + 1;
-
- final_path = (char*)calloc(1, final_path_len);
- if (!final_path) {
- DA_LOG_ERR(FileManager, "DA_ERR_FAIL_TO_MEMALLOC");
- return DA_NULL;
- }
-
- do {
- /* e.g) /tmp/abc.jpg
- * if there is no extension name, just make a file name without extension */
- if (0 == extension_len) {
- if (suffix_count == 0) {
- snprintf(final_path, final_path_len,
- "%s/%s", dir, file_name);
- } else {
- snprintf(final_path, final_path_len,
- "%s/%s_%d", dir, file_name, suffix_count);
- }
- } else {
- if (suffix_count == 0) {
- snprintf(final_path, final_path_len,
- "%s/%s.%s", dir, file_name, extension);
- } else {
- snprintf(final_path, final_path_len,
- "%s/%s_%d.%s",
- dir, file_name, suffix_count, extension);
- }
- }
-
- if (is_file_exist(final_path)) {
- suffix_count++;
- if (suffix_count > max_suffix_count) {
- free(final_path);
- final_path = DA_NULL;
- break;
- } else {
- memset(final_path, 0x00, final_path_len);
- continue;
- }
- }
-
- break;
- } while (1);
-
-// DA_SECURE_LOGD("decided path = [%s]", final_path);
- return final_path;
-}
-
-da_result_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_name, char **out_pure_file_name, char **out_extension)
+da_ret_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_name, char **out_pure_file_name, char **out_extension)
{
char *file_name = DA_NULL;
char *tmp_ptr = DA_NULL;
char temp_file[DA_MAX_FILE_PATH_LEN] = {0,};
char tmp_ext[DA_MAX_STR_LEN] = {0,};
int len = 0;
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
- DA_LOG_FUNC_LOGD(FileManager);
+ DA_LOGV("");
if (!in_file_name)
return DA_ERR_INVALID_ARGUMENT;
@@ -639,553 +115,794 @@ da_result_t __divide_file_name_into_pure_name_N_extesion(const char *in_file_nam
(const char*) temp_file);
}
- DA_SECURE_LOGD("pure file name [%s]", *out_pure_file_name);
+ DA_LOGV( "pure file name [%s]", *out_pure_file_name);
return ret;
}
-da_result_t __file_write_buf_make_buf(file_info *file_storage)
+da_ret_t __file_write_buf_make_buf(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
char *buffer = DA_NULL;
- DA_LOG_FUNC_LOGV(FileManager);
+ DA_LOGV("");
- buffer = (char*) calloc(DOWNLOAD_NOTIFY_LIMIT, 1);
+ buffer = (char*) calloc(1, DA_FILE_BUF_SIZE);
if (DA_NULL == buffer) {
- DA_LOG_ERR(FileManager, "Calloc failure ");
+ DA_LOGE("Calloc failure ");
ret = DA_ERR_FAIL_TO_MEMALLOC;
} else {
- GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
- GET_CONTENT_STORE_FILE_BUFFER(file_storage) = buffer;
+ file_info->buffer_len = 0;
+ file_info->buffer = buffer;
}
return ret;
}
-da_result_t __file_write_buf_destroy_buf(file_info *file_storage)
+da_ret_t __file_write_buf_destroy_buf(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGV(FileManager);
+ da_ret_t ret = DA_RESULT_OK;
- if (GET_CONTENT_STORE_FILE_BUFFER(file_storage))
- free(GET_CONTENT_STORE_FILE_BUFFER(file_storage));
+ DA_LOGV("");
+ NULL_CHECK_RET(file_info);
- GET_CONTENT_STORE_FILE_BUFFER(file_storage) = DA_NULL;
- GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
+ free(file_info->buffer);
+ file_info->buffer = DA_NULL;
+ file_info->buffer_len = 0;
return ret;
}
-da_result_t __file_write_buf_flush_buf(stage_info *stage, file_info *file_storage)
+da_ret_t __file_write_buf_flush_buf(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
char *buffer = DA_NULL;
int buffer_size = 0;
int write_success_len = 0;
void *fd = DA_NULL;
- DA_LOG_FUNC_LOGV(FileManager);
+ // DA_LOGV("");
- buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
- buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
+ buffer = file_info->buffer;
+ buffer_size = file_info->buffer_len;
if (buffer_size == 0) {
- DA_LOG_ERR(FileManager, "no data on buffer..");
+ DA_LOGE("no data on buffer..");
return ret;
}
- fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
+ fd = file_info->file_handle;
if (DA_NULL == fd) {
- DA_LOG_ERR(FileManager, "There is no file handle.");
+ DA_LOGE("There is no file handle.");
ret = DA_ERR_FAIL_TO_ACCESS_FILE;
goto ERR;
}
+
write_success_len = fwrite(buffer, sizeof(char), buffer_size,
(FILE *) fd);
/* FIXME : This can be necessary later due to progressive download.
* The solution for reducing fflush is needed */
//fflush((FILE *) fd);
if (write_success_len != buffer_size) {
- DA_LOG_ERR(FileManager, "write fails ");
+ DA_LOGE("write fails ");
if (errno == ENOSPC)
ret = DA_ERR_DISK_FULL;
else
ret = DA_ERR_FAIL_TO_ACCESS_FILE;
goto ERR;
}
- GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
- += write_success_len;
- DA_LOG_VERBOSE(FileManager, "write %d bytes", write_success_len);
- IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE;
- GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
-
+ file_info->bytes_written_to_file += write_success_len;
+ file_info->is_updated = DA_TRUE;
+ file_info->buffer_len = 0;
ERR:
return ret;
}
-da_result_t __file_write_buf_copy_to_buf(file_info *file_storage, char *body,
+da_ret_t __file_write_buf_copy_to_buf(file_info_t *file_info, char *body,
int body_len)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
char *buffer = DA_NULL;
int buffer_size = 0;
- DA_LOG_FUNC_LOGV(FileManager);
+ DA_LOGV("");
- buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
- buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
+ NULL_CHECK_RET(file_info->buffer);
+ buffer = file_info->buffer;
+ buffer_size = file_info->buffer_len;
memcpy(buffer + buffer_size, body, body_len);
- GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) += body_len;
+ file_info->buffer_len += body_len;
return ret;
}
-da_result_t __file_write_buf_directly_write(stage_info *stage,
- file_info *file_storage, char *body, int body_len)
+da_ret_t __file_write_buf_directly_write(file_info_t *file_info,
+ char *body, int body_len)
{
- da_result_t ret = DA_RESULT_OK;
- int write_success_len = 0;
+ da_ret_t ret = DA_RESULT_OK;
+ size_t write_success_len = 0;
void *fd = DA_NULL;
- DA_LOG_FUNC_LOGV(FileManager);
+ // DA_LOGV("");
- fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
+ fd = file_info->file_handle;
if (DA_NULL == fd) {
- DA_LOG_ERR(FileManager, "There is no file handle.");
-
+ DA_LOGE("There is no file handle.");
ret = DA_ERR_FAIL_TO_ACCESS_FILE;
goto ERR;
}
- write_success_len = fwrite(body, sizeof(char), body_len,
+
+ write_success_len = fwrite(body, sizeof(char), (size_t)body_len,
(FILE *) fd);
/* FIXME : This can be necessary later due to progressive download.
* The solution for reducing fflush is needed */
//fflush((FILE *) fd);
- if (write_success_len != body_len) {
- DA_LOG_ERR(FileManager, "write fails ");
+ if (write_success_len != (size_t)body_len) {
+ DA_LOGE("write fails ");
if (errno == ENOSPC)
ret = DA_ERR_DISK_FULL;
else
ret = DA_ERR_FAIL_TO_ACCESS_FILE;
goto ERR;
}
- GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
- += write_success_len;
- DA_LOG(FileManager, "write %d bytes", write_success_len);
- IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_TRUE;
+ file_info->bytes_written_to_file += write_success_len;
+ DA_LOGV( "write %llu bytes", write_success_len);
+ file_info->is_updated = DA_TRUE;
ERR:
return ret;
}
-da_result_t file_write_ongoing(stage_info *stage, char *body, int body_len)
+/* Priority to derive extension
+ * 1. extension name which client set
+ * 2. according to MIME-Type
+ * 3. if MIME-Type is ambiguous or blank,
+ * 3-1. derived from <Content-Disposition> field's "filename" attribute
+ * 3-2. derived from url
+ * 4. if url does not have extension, leave blank for extension
+ */
+char *__get_extension_name(char *mime_type,
+ char *file_name_from_header, char *url)
{
- da_result_t ret = DA_RESULT_OK;
- file_info *file_storage = DA_NULL;
- int buffer_size = 0;
- char *buffer = DA_NULL;
-
- DA_LOG_FUNC_LOGV(FileManager);
+ char *extension = DA_NULL;
- file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
- if (!file_storage) {
- DA_LOG_ERR(FileManager, "file_info is empty.");
- ret = DA_ERR_FAIL_TO_ACCESS_FILE;
- goto ERR;
+ /* Priority 1 */
+ if (mime_type && !is_ambiguous_MIME_Type(mime_type)) {
+ char *extension = DA_NULL;
+ da_ret_t ret = get_extension_from_mime_type(mime_type, &extension);
+ if (ret == DA_RESULT_OK && extension)
+ return extension;
}
+ /* Priority 2-1 */
+ if (file_name_from_header) {
+ char *extension = DA_NULL;
+ DA_SECURE_LOGI("Content-Disposition :[%s]", file_name_from_header);
+ __divide_file_name_into_pure_name_N_extesion(file_name_from_header,
+ DA_NULL, &extension);
+ if (extension)
+ return extension;
+ }
+ /* Priority 2-2 */
+ if (url) {
+ DA_LOGV("Get extension from url");
+ da_bool_t b_ret = da_get_extension_name_from_url(url, &extension);
+ if (b_ret && extension)
+ return extension;
+ }
+ return DA_NULL;
+}
- buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
- buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
- IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(file_storage) = DA_FALSE;
-
- if (DA_NULL == buffer) {
- if (body_len < DOWNLOAD_NOTIFY_LIMIT) {
- ret = __file_write_buf_make_buf(file_storage);
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- __file_write_buf_copy_to_buf(file_storage, body, body_len);
- } else {
- ret = __file_write_buf_directly_write(stage,
- file_storage, body, body_len);
- if (ret != DA_RESULT_OK)
- goto ERR;
- }
- } else {
- if (DOWNLOAD_NOTIFY_LIMIT <= body_len) {
- ret = __file_write_buf_flush_buf(stage, file_storage);
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- ret = __file_write_buf_directly_write(stage,
- file_storage, body, body_len);
- if (ret != DA_RESULT_OK)
- goto ERR;
+/** Priority for deciding file name
+ * 1. file name which client set
+ * 2. 'filename' option on HTTP response header's Content-Disposition field
+ * 3. requesting URL
+ * 4. Otherwise, define it as "No name"
+ */
+da_ret_t __get_candidate_file_name(char *user_file_name, char *url,
+ char *file_name_from_header,
+ char **out_pure_file_name, char **out_extension)
+{
+ da_ret_t ret = DA_RESULT_OK;
- } else if ((DOWNLOAD_NOTIFY_LIMIT - buffer_size) <= body_len) {
- ret = __file_write_buf_flush_buf(stage, file_storage);
- if (ret != DA_RESULT_OK)
- goto ERR;
+ DA_LOGV("");
- __file_write_buf_copy_to_buf(file_storage, body, body_len);
- } else {
- __file_write_buf_copy_to_buf(file_storage, body, body_len);
- }
+ /* Priority 1 */
+ if (user_file_name) {
+ __divide_file_name_into_pure_name_N_extesion(
+ user_file_name, out_pure_file_name, out_extension);
}
-
-ERR:
- if (ret != DA_RESULT_OK) {
- if (file_storage) {
- GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage) = 0;
- if (GET_CONTENT_STORE_FILE_BUFFER(file_storage)) {
- free(
- GET_CONTENT_STORE_FILE_BUFFER(file_storage));
- GET_CONTENT_STORE_FILE_BUFFER(file_storage)
- = DA_NULL;
- }
- }
+ if (*out_pure_file_name)
+ return ret;
+ /* Priority 2 */
+ if (file_name_from_header) {
+ DA_SECURE_LOGI("Content-Disposition:[%s]", file_name_from_header);
+ __divide_file_name_into_pure_name_N_extesion(file_name_from_header,
+ out_pure_file_name, DA_NULL);
}
+ if (*out_pure_file_name)
+ return ret ;
+ /* Priority 3 */
+ if (url) {
+ DA_LOGV("Get file name from url");
+ da_get_file_name_from_url(url, out_pure_file_name);
+ }
+ if (*out_pure_file_name)
+ return ret ;
+ /* Priority 4 */
+ *out_pure_file_name = strdup(NO_NAME_TEMP_STR);
+ if (*out_pure_file_name == DA_NULL)
+ ret = DA_ERR_FAIL_TO_MEMALLOC;
return ret;
}
-da_result_t file_write_complete(stage_info *stage)
+da_ret_t __decide_file_path(da_info_t *da_info)
{
- da_result_t ret = DA_RESULT_OK;
- file_info*file_storage = DA_NULL;
- char *buffer = DA_NULL;
- unsigned int buffer_size = 0;
- void *fd = DA_NULL;
+ da_ret_t ret = DA_RESULT_OK;
+ char *extension = DA_NULL;
+ char *file_name = DA_NULL;
+ char *tmp_file_path = DA_NULL;
+ char *install_dir = DA_DEFAULT_INSTALL_PATH_FOR_PHONE;
+ char *user_file_name = DA_NULL;
+ char *file_name_from_header = DA_NULL;
+ char *url = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ http_info_t *http_info = DA_NULL;
+
+ DA_LOGV("");
+
+ NULL_CHECK_RET(da_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+
+ if (req_info->install_path)
+ install_dir = req_info->install_path;
+ user_file_name = req_info->file_name;
+ /* If there is location url from response header in case of redirection,
+ * it try to parse the file name from the location url */
+ if (http_info->location_url) {
+ url = http_info->location_url;
+ DA_LOGI("[TEST] location_url[%s][%p]",http_info->location_url, http_info->location_url);
+ } else
+ url = req_info->url;
+
+ file_name_from_header = http_info->file_name_from_header;
+
+ /* extension is extracted only if User set specific name */
+ ret = __get_candidate_file_name(user_file_name, url, file_name_from_header,
+ &file_name, &extension);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
- DA_LOG_FUNC_LOGV(FileManager);
+ if (file_name && strpbrk(file_name, DA_INVALID_PATH_STRING) != NULL) {
+ DA_LOGI("Invalid string at file name");
+ free(file_name);
+ file_name = strdup(NO_NAME_TEMP_STR);
+ if (!file_name) {
+ ret = DA_ERR_FAIL_TO_MEMALLOC;
+ goto ERR;
+ }
- file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
- if (!file_storage) {
- DA_LOG_ERR(FileManager, "file_info is DA_NULL.");
- ret = DA_ERR_FAIL_TO_ACCESS_FILE;
- goto ERR;
}
- buffer = GET_CONTENT_STORE_FILE_BUFFER(file_storage);
- buffer_size = GET_CONTENT_STORE_FILE_BUFF_LEN(file_storage);
+ DA_SECURE_LOGI("candidate file name [%s]", file_name);
- if (DA_NULL == buffer) {
- DA_LOG_ERR(FileManager, "file buffer is DA_NULL");
- } else {
- if (buffer_size != 0) {
- ret = __file_write_buf_flush_buf(stage, file_storage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- }
- __file_write_buf_destroy_buf(file_storage);
+ if (!extension) {
+ extension = __get_extension_name(file_info->mime_type,
+ file_name_from_header, url);
+ }
+ if (file_name && !file_info->pure_file_name) {
+ file_info->pure_file_name = file_name;
+ file_name = DA_NULL;
+ }
+ if (extension && !file_info->extension) {
+ DA_LOGV("candidate extension [%s]", extension);
+ file_info->extension = extension;
+ extension = DA_NULL;
}
- fd = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
- if (fd) {
- fclose(fd);
- fd = DA_NULL;
+ // for resume
+ tmp_file_path = get_full_path_avoided_duplication(install_dir,
+ file_info->pure_file_name, file_info->extension);
+ if (tmp_file_path) {
+ file_info->file_path = tmp_file_path;
+ tmp_file_path = DA_NULL;
+ } else {
+ ret = DA_ERR_FAIL_TO_ACCESS_FILE;
+ goto ERR;
}
- GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL;
+
ERR:
+ DA_SECURE_LOGI("decided file path [%s]", file_info->file_path);
+ free(file_name);
+ free(extension);
return ret;
}
-da_result_t start_file_writing(stage_info *stage)
+// for resume with new download request
+da_ret_t __decide_file_path_for_resume(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
- file_info *file_info_data = DA_NULL;
+ da_ret_t ret = DA_RESULT_OK;
+ char *extension = DA_NULL;
+ char *file_name = DA_NULL;
+ char *file_path = DA_NULL;
+ char *ptr = DA_NULL;
+ char *ptr2 = DA_NULL;
+
+ DA_LOGV("");
+
+ NULL_CHECK_RET(file_info);
+
+ file_path = file_info->file_path;
+ ptr = strrchr(file_path, '/');
+ if (ptr) {
+ ptr++;
+ ptr2 = strrchr(ptr, '.');
+ if (ptr2) {
+ int len = 0;
+ len = ptr2 - ptr;
+ ptr2++;
+ extension = strdup(ptr2);
+ file_name = calloc(1, len + 1);
+ if (file_name)
+ snprintf(file_name, len + 1, "%s", ptr);
+ } else {
+ file_name = strdup(ptr);
+ }
+ }
- DA_LOG_FUNC_LOGV(FileManager);
+ if (file_name && !file_info->pure_file_name) {
+ file_info->pure_file_name = file_name;
+ file_name = DA_NULL;
+ } else {
+ free(file_name);
+ }
+ if (extension && !file_info->extension) {
+ DA_LOGV( "candidate extension [%s]", extension);
+ file_info->extension = extension;
+ extension = DA_NULL;
+ } else {
+ free(extension);
+ }
+ return ret;
+}
- file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
- ret = get_mime_type(stage,
- &GET_CONTENT_STORE_CONTENT_TYPE(file_info_data));
- if (ret != DA_RESULT_OK)
- goto ERR;
+da_ret_t start_file_writing(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ file_info_t *file_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+
+ DA_LOGV("");
+
+ NULL_CHECK_RET(da_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+
+ /* resume case */
+ if (req_info->etag || req_info->temp_file_path) {
+ char *file_path = DA_NULL;
+ char *origin_path = DA_NULL;
+ file_path = req_info->temp_file_path;
+ if (!file_path)
+ return DA_ERR_INVALID_ARGUMENT;
+ origin_path = file_info->file_path;
+ file_info->file_path = strdup(file_path);
+ free(origin_path);
+ ret = __decide_file_path_for_resume(file_info);
+ } else {
+ ret = __decide_file_path(da_info);
+ }
- ret = __decide_file_path(stage);
if (ret != DA_RESULT_OK)
goto ERR;
- ret = __set_file_size(stage);
- if (DA_RESULT_OK != ret)
- goto ERR;
-
- GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
- = 0;
-
- ret = __saved_file_open(stage);
-
+ if (req_info->etag || req_info->temp_file_path) {
+ da_size_t file_size = 0;
+ get_file_size(req_info->temp_file_path, &file_size);
+ if (file_size < 1)
+ goto ERR;
+#ifdef _RAF_SUPPORT
+ file_info->file_size_of_temp_file = file_size;
+#endif
+ file_info->bytes_written_to_file = file_size;
+ } else {
+ file_info->bytes_written_to_file = 0;
+ }
+ ret = __saved_file_open(file_info);
ERR:
return ret;
}
-
-da_result_t start_file_writing_append(stage_info *stage)
+da_ret_t start_file_append(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
- DA_LOG_FUNC_LOGD(FileManager);
+ DA_LOGV("");
- ret = __saved_file_open(stage);
+ NULL_CHECK_RET(file_info);
+ ret = __saved_file_open(file_info);
return ret;
}
-// for resume with new download request
-da_result_t start_file_writing_append_with_new_download(stage_info *stage)
+da_ret_t file_write_ongoing(file_info_t *file_info, char *body, int body_len)
{
- da_result_t ret = DA_RESULT_OK;
- file_info *file_storage = DA_NULL;
- char *original_file_path = DA_NULL;
- char *temp_file_path = DA_NULL;
- char *extension = DA_NULL;
- char *file_name_without_extension = DA_NULL;
- req_dl_info *request_info = DA_NULL;
- unsigned long long temp_file_size = 0;
-
- DA_LOG_FUNC_LOGD(FileManager);
-
- file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
- if (!file_storage)
- return DA_ERR_INVALID_ARGUMENT;
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
- if (!request_info)
- return DA_ERR_INVALID_ARGUMENT;
- temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(request_info);
- if (!temp_file_path)
- return DA_ERR_INVALID_ARGUMENT;
- original_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage);
-
- GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_storage) = strdup(temp_file_path);
-
- if (original_file_path)
- free(original_file_path);
+ da_ret_t ret = DA_RESULT_OK;
+ int buffer_size = 0;
+ char *buffer = DA_NULL;
- ret = get_mime_type(stage,
- &GET_CONTENT_STORE_CONTENT_TYPE(file_storage));
- if (ret != DA_RESULT_OK)
- goto ERR;
+ DA_LOGV("");
- ret = __get_candidate_file_name(stage, &file_name_without_extension, &extension);
- if (ret != DA_RESULT_OK)
- goto ERR;
+ buffer = file_info->buffer;
+ buffer_size = file_info->buffer_len;
- if (file_name_without_extension) {
- if (!GET_CONTENT_STORE_PURE_FILE_NAME(file_storage)) {
- GET_CONTENT_STORE_PURE_FILE_NAME(file_storage) = file_name_without_extension;
- file_name_without_extension = DA_NULL;
+ if (DA_NULL == buffer) {
+ if (body_len < DA_FILE_BUF_SIZE) {
+ ret = __file_write_buf_make_buf(file_info);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ __file_write_buf_copy_to_buf(file_info, body, body_len);
+ } else {
+ ret = __file_write_buf_directly_write(file_info,
+ body, body_len);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ }
+ } else {
+ if (DA_FILE_BUF_SIZE <= body_len) {
+ ret = __file_write_buf_flush_buf(file_info);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ ret = __file_write_buf_directly_write(file_info,
+ body, body_len);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ } else if ((DA_FILE_BUF_SIZE - buffer_size) <= body_len) {
+ ret = __file_write_buf_flush_buf(file_info);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ __file_write_buf_copy_to_buf(file_info, body, body_len);
} else {
- free(file_name_without_extension);
- file_name_without_extension = DA_NULL;
+ __file_write_buf_copy_to_buf(file_info, body, body_len);
}
}
+ERR:
+ if (ret != DA_RESULT_OK) {
+ file_info->buffer_len = 0;
+ free(file_info->buffer);
+ file_info->buffer = DA_NULL;
+ }
+ return ret;
+}
- if (extension) {
- if (!GET_CONTENT_STORE_EXTENSION(file_storage)) {
- GET_CONTENT_STORE_EXTENSION(file_storage) = extension;
- extension = DA_NULL;
- } else {
- free(extension);
- extension = DA_NULL;
+#ifdef _RAF_SUPPORT
+da_ret_t file_write_complete_for_raf(file_info_t *file_info) {
+ da_ret_t ret = DA_RESULT_OK;
+ char *buffer = DA_NULL;
+ da_size_t wrriten_size = 0;
+ da_size_t file_size = 0;
+ void *fd = DA_NULL;
+
+ DA_LOGV("");
+ fd = file_info->file_handle;
+
+ wrriten_size = file_info->bytes_written_to_file;
+ // test code
+ get_file_size(file_info->file_path, &file_size);
+ DA_LOGI("wrriten_size:%llu file_size:%llu file[%s]",
+ wrriten_size, file_size, file_info->file_path);
+ if (fd) {
+ fclose(fd);
+ fd = DA_NULL;
+ }
+ file_info->file_handle = DA_NULL;
+ if (wrriten_size < file_size) {
+ DA_LOGD("Try truncate");
+ if (truncate(file_info->file_path, wrriten_size) < 0) {
+ DA_LOGE("Fail to ftruncate: errno[%d,%s]", errno, strerror(errno));
}
+ DA_LOGD("Try truncate done");
}
- ret = __set_file_size(stage);
- if (DA_RESULT_OK != ret)
- goto ERR;
- get_file_size(temp_file_path, &temp_file_size);
- if (temp_file_size < 1)
- goto ERR;
+ ERR:
+ return ret;
+}
+#endif
- GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
- = temp_file_size;
+da_ret_t file_write_complete(file_info_t *file_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ char *buffer = DA_NULL;
+ unsigned int buffer_size = 0;
+ void *fd = DA_NULL;
- ret = __saved_file_open(stage);
- return ret;
-ERR:
- if (file_name_without_extension) {
- free(file_name_without_extension);
- file_name_without_extension = DA_NULL;
+ DA_LOGV("");
+
+ buffer = file_info->buffer;
+ buffer_size = file_info->buffer_len;
+
+ if (DA_NULL == buffer) {
+ DA_LOGE("file buffer is NULL");
+ } else {
+ if (buffer_size != 0) {
+ ret = __file_write_buf_flush_buf(file_info);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ }
+ __file_write_buf_destroy_buf(file_info);
}
+ fd = file_info->file_handle;
- if (extension) {
- free(extension);
- extension = DA_NULL;
+ if (fd) {
+ fclose(fd);
+ fd = DA_NULL;
}
+ file_info->file_handle = DA_NULL;
+ERR:
return ret;
}
-da_result_t discard_download(stage_info *stage)
+da_ret_t discard_download(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
- file_info *file_storage = DA_NULL;
+ da_ret_t ret = DA_RESULT_OK;
FILE *f_handle = DA_NULL;
- DA_LOG_FUNC_LOGD(FileManager);
-
- file_storage = GET_STAGE_CONTENT_STORE_INFO(stage);
+ DA_LOGV("");
- f_handle = GET_CONTENT_STORE_FILE_HANDLE(file_storage);
+ f_handle = file_info->file_handle;
if (f_handle) {
fclose(f_handle);
- GET_CONTENT_STORE_FILE_HANDLE(file_storage) = DA_NULL;
+ file_info->file_handle = DA_NULL;
}
return ret;
}
-void clean_paused_file(stage_info *stage)
+void clean_paused_file(file_info_t *file_info)
{
- file_info *file_info_data = DA_NULL;
char *paused_file_path = DA_NULL;
FILE *fd = DA_NULL;
- DA_LOG_FUNC_LOGD(FileManager);
+ DA_LOGV("");
- file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
-
- fd = GET_CONTENT_STORE_FILE_HANDLE(file_info_data);
+ fd = file_info->file_handle;
if (fd) {
fclose(fd);
- GET_CONTENT_STORE_FILE_HANDLE(file_info_data) = DA_NULL;
+ file_info->file_handle = DA_NULL;
}
- paused_file_path = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data);
+ paused_file_path = file_info->file_path;
+ file_info->bytes_written_to_file = 0; // Ignore resume flow after failed or cancled.
remove_file((const char*) paused_file_path);
return;
}
-da_result_t replace_content_file_in_stage(stage_info *stage,
- const char *dest_dd_file_path)
+da_bool_t is_file_exist(const char *file_path)
{
- da_result_t ret = DA_RESULT_OK;
- char *dd_file_path = DA_NULL;
- int len;
+ struct stat dir_state;
+ int stat_ret;
- DA_LOG_FUNC_LOGD(FileManager);
+ if (file_path == DA_NULL) {
+ DA_LOGE("file path is DA_NULL");
+ return DA_FALSE;
+ }
+ stat_ret = stat(file_path, &dir_state);
+ if (stat_ret == 0) {
+ if (dir_state.st_mode & S_IFREG) {
+ //DA_SECURE_LOGD("Exist! %s is a regular file & its size = %lu", file_path, dir_state.st_size);
+ return DA_TRUE;
+ }
- if (!dest_dd_file_path
- && (DA_FALSE == is_file_exist(dest_dd_file_path))) {
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
+ return DA_FALSE;
}
+ return DA_FALSE;
- dd_file_path
- =GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage));
+}
- if (DA_NULL != dd_file_path) {
- remove_file((const char*) dd_file_path);
- free(dd_file_path);
- }
- len = strlen(dest_dd_file_path);
- dd_file_path = calloc(1, len + 1);
- if (!dd_file_path) {
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
- strncpy(dd_file_path, dest_dd_file_path, len);
- GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage))
- = dd_file_path;
+void get_file_size(char *file_path, da_size_t *out_file_size)
+{
+ struct stat dir_state;
+ int stat_ret;
-ERR:
- return ret;
+ *out_file_size = -1;
+ if (file_path == DA_NULL) {
+ DA_LOGE("file path is DA_NULL");
+ return;
+ }
+ /* Please do not use ftell() to obtain file size, use stat instead.
+ * This is a guide from www.securecoding.cert.org
+ * : FIO19-C. Do not use fseek() and ftell() to compute the size of a file
+ */
+ stat_ret = stat(file_path, &dir_state);
+ if (stat_ret == 0) {
+ if (dir_state.st_mode & S_IFREG) {
+ DA_LOGV( "size = %lu", dir_state.st_size);
+ *out_file_size = dir_state.st_size;
+ }
+ }
+ return;
}
-da_result_t copy_file(const char *src, const char *dest)
+char *get_full_path_avoided_duplication(char *in_dir,
+ char *in_candidate_file_name, char *in_extension)
{
- FILE *fs = DA_NULL;
- FILE *fd = DA_NULL;
- int freadnum = 0;
- int fwritenum = 0;
- char buff[4096] = { 0, };
+ char *dir = in_dir;
+ char *file_name = in_candidate_file_name;
+ char *extension = in_extension;
+ char *final_path = DA_NULL;
+
+ int dir_path_len = 0;
+ int final_path_len = 0;
+ int extension_len = 0;
- DA_LOG_FUNC_LOGD(FileManager);
+ int suffix_count = 0; /* means suffix on file name. up to "_99" */
+ int suffix_len = (int)log10(MAX_SUFFIX_COUNT + 1) + 1; /* 1 means "_" */
- /* open files to copy */
- fs = fopen(src, "rb");
- if (!fs) {
- DA_LOG_ERR(FileManager, "Fail to open src file");
- return DA_ERR_FAIL_TO_ACCESS_FILE;
+ if (!in_dir || !in_candidate_file_name)
+ return DA_NULL;
+
+ //DA_SECURE_LOGI("in_candidate_file_name=[%s],in_extension=[%s]",
+ //in_candidate_file_name, in_extension);
+
+ if (extension)
+ extension_len = strlen(extension);
+
+ // to remove trailing slash from dir path
+ dir_path_len = strlen(dir);
+ if (dir[dir_path_len - 1] == '/') {
+ dir[dir_path_len - 1] = '\0';
+ --dir_path_len;
}
- fd = fopen(dest, "wb");
- if (!fd) {
- DA_LOG_ERR(FileManager, "Fail to open dest file");
+ /* first 1 for "/", second 1 for ".", last 1 for DA_NULL */
+ final_path_len = dir_path_len + 1 + strlen(file_name) + 1
+ + suffix_len + extension_len + 1;
- fclose(fs);
- return DA_ERR_FAIL_TO_ACCESS_FILE;
+ final_path = (char*)calloc(1, final_path_len);
+ if (!final_path) {
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
+ return DA_NULL;
}
- /* actual copy */
- while (!feof(fs)) {
- memset(buff, 0x00, 4096);
- freadnum = fread(buff, sizeof(char), sizeof(buff), fs);
- if (freadnum > 0) {
- fwritenum = fwrite(buff, sizeof(char), freadnum, fd);
- if (fwritenum <= 0) {
- DA_LOG(FileManager, "written = %d",fwritenum);
- break;
+ do {
+ /* e.g) /tmp/abc.jpg
+ * if there is no extension name, just make a file name without extension */
+ if (0 == extension_len) {
+ if (suffix_count == 0) {
+ snprintf(final_path, final_path_len,
+ "%s/%s", dir, file_name);
+ } else {
+ snprintf(final_path, final_path_len,
+ "%s/%s_%d", dir, file_name, suffix_count);
}
} else {
- DA_LOG(FileManager, "read = %d",freadnum);
- break;
+ if (suffix_count == 0) {
+ snprintf(final_path, final_path_len,
+ "%s/%s.%s", dir, file_name, extension);
+ } else {
+ snprintf(final_path, final_path_len,
+ "%s/%s_%d.%s",
+ dir, file_name, suffix_count, extension);
+ }
}
- }
-
- fclose(fd);
- fclose(fs);
+ if (is_file_exist(final_path)) {
+ suffix_count++;
+ if (suffix_count > MAX_SUFFIX_COUNT) {
+ free(final_path);
+ final_path = DA_NULL;
+ break;
+ } else {
+ memset(final_path, 0x00, final_path_len);
+ continue;
+ }
+ }
+ break;
+ } while (1);
- return DA_RESULT_OK;
+ //DA_SECURE_LOGD("decided path = [%s]", final_path);
+ return final_path;
}
-da_result_t create_dir(const char *install_dir)
+
+da_ret_t check_drm_convert(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
- /* read/write/search permissions for owner and group,
- * and with read/search permissions for others. */
- if (mkdir(install_dir, S_IRWXU | S_IRWXG | S_IRWXO)) {
- DA_LOG_ERR(FileManager, "Fail to creaate directory");
- ret = DA_ERR_FAIL_TO_ACCESS_STORAGE;
+ da_ret_t ret = DA_RESULT_OK;
+ da_bool_t ret_b = DA_TRUE;
+
+ DA_LOGD("");
+
+ NULL_CHECK_RET(file_info);
+
+#ifdef _ENABLE_OMA_DRM
+
+ /* In case of OMA DRM 1.0 SD, it is not necessary to call DRM convert API.
+ * Because it is already converted itself.
+ * And, the case will return fail because The SD is not supported now.
+ */
+ if (is_content_drm_dcf(file_info->mime_type)) {
+ DA_LOGI("DRM SD case");
+ unlink(file_info->file_path);
+ free(file_info->file_path);
+ file_info->file_path = DA_NULL;
+ return DA_ERR_DRM_FAIL;
+ }
+ if (is_content_drm_dm(file_info->mime_type)) {
+ char *actual_file_path = DA_NULL;
+ char *out_file_path = DA_NULL;
+
+ actual_file_path = file_info->file_path;
+ DA_SECURE_LOGD("actual_file_path = %s", actual_file_path);
+ if (!actual_file_path)
+ return DA_ERR_INVALID_ARGUMENT;
+ ret_b = EDRM_convert(actual_file_path, &out_file_path);
+ unlink(actual_file_path);
+ free(actual_file_path);
+ if (!ret_b)
+ ret = DA_ERR_DRM_FAIL;
+ file_info->file_path = out_file_path;
} else {
- DA_SECURE_LOGD("[%s] is created!", install_dir);
- if (chown(install_dir, 5000, 5000) < 0) {
- DA_LOG_ERR(FileManager, "Fail to chown");
- ret = DA_ERR_FAIL_TO_ACCESS_STORAGE;
- }
+ return ret;
}
+#endif
+
return ret;
}
-da_result_t get_default_install_dir(char **out_path)
+void remove_file(const char *file_path)
{
- char *default_path = DA_NULL;
- da_result_t ret = DA_RESULT_OK;
- int len = 0;
+ DA_LOGV("");
- if (!out_path) {
- DA_LOG_ERR(ClientNoti, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
+ if (file_path && is_file_exist(file_path)) {
+ DA_SECURE_LOGD("remove file [%s]", file_path);
+ if (unlink(file_path) < 0) {
+ DA_LOGE("file removing failed.");
+ }
}
+}
- len = strlen(DA_DEFAULT_INSTALL_PATH_FOR_PHONE);
+da_ret_t get_available_memory(char *dir_path, da_size_t len)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ int fs_ret = 0;
+ //struct statfs filesys_info = {0, };
+ struct statvfs filesys_info;
- default_path = calloc(len + 1, sizeof(char));
- if (!default_path) {
- return DA_ERR_FAIL_TO_MEMALLOC;
- }
+ DA_LOGV("");
- memcpy(default_path, DA_DEFAULT_INSTALL_PATH_FOR_PHONE, len);
- default_path[len] = '\0';
+ if (!dir_path)
+ return DA_ERR_INVALID_INSTALL_PATH;
- *out_path = default_path;
+ //fs_ret = statfs(dir_path, &filesys_info);
+ // Using this as it considers FOTA memory while returning available memory
+ fs_ret = storage_get_internal_memory_size(&filesys_info);
- if (!is_dir_exist(default_path)) {
- ret = create_dir(default_path);
+ if (fs_ret != 0) {
+ // DA_LOGE("statfs error[%s]", strerror(errno));
+ return DA_ERR_INVALID_ARGUMENT;
+ // return DA_ERR_INVALID_INSTALL_PATH;
}
- DA_SECURE_LOGD("default temp path = [%s]", *out_path);
- return DA_RESULT_OK;
+
+ double available_size = (double)filesys_info.f_bsize * filesys_info.f_bavail;
+ double total_size = (double)filesys_info.f_frsize * filesys_info.f_blocks;
+ DA_SECURE_LOGI(" total = %lf ", total_size);
+ DA_SECURE_LOGI(" available = %lf ",available_size);
+
+ DA_LOGV("Available Memory(f_bavail) : %lu", filesys_info.f_bavail);
+ DA_LOGV("Available Memory(f_bsize) : %d", filesys_info.f_bsize);
+ DA_LOGD("Available Memory(kbytes) : %d", (filesys_info.f_bavail/1024)*filesys_info.f_bsize);
+ DA_LOGV("Content: %llu", len);
+ if (available_size < (len
+ + SAVE_FILE_BUFFERING_SIZE_50KB)) /* 50KB buffering */
+ ret = DA_ERR_DISK_FULL;
+
+ return ret;
}
diff --git a/agent/download-agent-http-mgr.c b/agent/download-agent-http-mgr.c
index bbc69f0..3a2feb9 100755
--- a/agent/download-agent-http-mgr.c
+++ b/agent/download-agent-http-mgr.c
@@ -14,376 +14,200 @@
* limitations under the License.
*/
-#include "download-agent-utils.h"
-#include "download-agent-debug.h"
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include "download-agent-dl-info.h"
+#include "download-agent-file.h"
+#include "download-agent-mime-util.h"
#include "download-agent-client-mgr.h"
-#include "download-agent-http-mgr.h"
-#include "download-agent-http-misc.h"
#include "download-agent-http-msg-handler.h"
-#include "download-agent-file.h"
#include "download-agent-plugin-conf.h"
-#include "download-agent-plugin-http-interface.h"
-
-da_result_t make_default_http_request_hdr(const char *url,
- char **user_request_header,
- int user_request_heaer_count,
- http_msg_request_t **out_http_msg_request,
- char *user_request_etag,
- char *user_request_temp_file_path);
-da_result_t create_resume_http_request_hdr(stage_info *stage,
- http_msg_request_t **out_resume_request);
-
-da_result_t start_new_transaction(stage_info *stage);
-da_result_t set_http_request_hdr(stage_info *stage);
-da_result_t make_transaction_info_and_start_transaction(stage_info *stage);
-
-da_result_t pause_for_flow_control(stage_info *stage);
-da_result_t unpause_for_flow_control(stage_info *stage);
-
-da_result_t handle_any_input(stage_info *stage);
-da_result_t handle_event_control(stage_info *stage, q_event_t *event);
-da_result_t handle_event_http(stage_info *stage, q_event_t *event);
-da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event);
-da_result_t handle_event_http_final(stage_info *stage, q_event_t *event);
-da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event);
-
-da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
- http_msg_response_t *http_msg_response);
-
-da_result_t handle_event_abort(stage_info *stage);
-da_result_t handle_event_cancel(stage_info *stage);
-da_result_t handle_event_suspend(stage_info *stage);
-da_result_t handle_event_resume(stage_info *stage);
-da_result_t handle_http_hdr(stage_info *stage,
- http_msg_response_t *http_msg_response, int http_status);
-da_result_t handle_http_status_code(stage_info *stage,
- http_msg_response_t *http_msg_response, int http_status);
-da_result_t handle_http_body(stage_info *stage, char *body, int body_len);
-
-da_result_t set_hdr_fields_on_download_info(stage_info *stage);
-
-da_result_t _check_content_type_is_matched(stage_info *stage);
-da_result_t _check_enough_memory_for_this_download(stage_info *stage);
-da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
- stage_info *stage);
-
-da_result_t _check_resume_download_is_available(stage_info *stage,
- http_msg_response_t *new_http_msg_response);
-da_result_t _check_this_partial_download_is_available(stage_info *stage,
- http_msg_response_t *new_http_msg_response);
-
-da_result_t _cancel_transaction(stage_info *stage);
-da_result_t _disconnect_transaction(stage_info *stage);
-
-void __parsing_user_request_header(char *user_request_header,
- char **out_field, char **out_value);
-
-http_mgr_t http_mgr;
-
-da_result_t init_http_mgr(void)
-{
- da_result_t ret = DA_RESULT_OK;
+#include "download-agent-plugin-drm.h"
+#include "download-agent-plugin-libcurl.h"
- DA_LOG_FUNC_LOGV(HTTPManager);
+void __http_update_cb(http_raw_data_t *data, void *user_param);
- if (http_mgr.is_http_init == DA_FALSE) {
- http_mgr.is_http_init = DA_TRUE;
- ret = PI_http_init();
- }
-
- return ret;
-}
+#define CONVERT_STR(NAME) (#NAME)
-
-da_result_t request_to_abort_http_download(stage_info *stage)
+static const char *__get_state_str(http_state_t state)
{
- da_result_t ret = DA_RESULT_OK;
- q_event_t *q_event = DA_NULL;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
- if (!stage) {
- DA_LOG_ERR(HTTPManager, "Stage is NULL. download info is already destroyed");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT");
- ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_ABORT, &q_event);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
- goto ERR;
- } else {
- DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
- Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), q_event);
+ char *str = NULL;
+ switch(state) {
+ case HTTP_STATE_READY_TO_DOWNLOAD:
+ str = CONVERT_STR(HTTP_STATE_READY_TO_DOWNLOAD);
+ break;
+ case HTTP_STATE_REDIRECTED:
+ str = CONVERT_STR(HTTP_STATE_REDIRECTED);
+ break;
+ case HTTP_STATE_DOWNLOAD_REQUESTED:
+ str = CONVERT_STR(HTTP_STATE_DOWNLOAD_REQUESTED);
+ break;
+ case HTTP_STATE_DOWNLOAD_STARTED:
+ str = CONVERT_STR(HTTP_STATE_DOWNLOAD_STARTED);
+ break;
+ case HTTP_STATE_DOWNLOADING:
+ str = CONVERT_STR(HTTP_STATE_DOWNLOADING);
+ break;
+ case HTTP_STATE_DOWNLOAD_FINISH:
+ str = CONVERT_STR(HTTP_STATE_DOWNLOAD_FINISH);
+ break;
+ case HTTP_STATE_REQUEST_CANCEL:
+ str = CONVERT_STR(HTTP_STATE_REQUEST_CANCEL);
+ break;
+ case HTTP_STATE_REQUEST_PAUSE:
+ str = CONVERT_STR(HTTP_STATE_REQUEST_PAUSE);
+ break;
+ case HTTP_STATE_REQUEST_RESUME:
+ str = CONVERT_STR(HTTP_STATE_REQUEST_RESUME);
+ break;
+ case HTTP_STATE_CANCELED:
+ str = CONVERT_STR(HTTP_STATE_CANCELED);
+ break;
+ case HTTP_STATE_FAILED:
+ str = CONVERT_STR(HTTP_STATE_FAILED);
+ break;
+ case HTTP_STATE_PAUSED:
+ str = CONVERT_STR(HTTP_STATE_PAUSED);
+ break;
+ case HTTP_STATE_RESUMED:
+ str = CONVERT_STR(HTTP_STATE_RESUMED);
+ break;
+ case HTTP_STATE_ABORTED:
+ str = CONVERT_STR(HTTP_STATE_ABORTED);
+ break;
+ case HTTP_STATE_WAIT_FOR_NET_ERR:
+ str = CONVERT_STR(HTTP_STATE_WAIT_FOR_NET_ERR);
+ break;
+ default:
+ str = "Unknown State";
+ break;
}
-
-ERR:
- return ret;
+ return str;
}
-void deinit_http_mgr(void)
+void __init_http_info(http_info_t *http_info)
{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (http_mgr.is_http_init == DA_TRUE) {
- http_mgr.is_http_init = DA_FALSE;
- PI_http_deinit();
- }
+ DA_LOGV("");
- return;
+ http_info->state = HTTP_STATE_READY_TO_DOWNLOAD;
+ http_info->update_cb = __http_update_cb;
+ DA_MUTEX_INIT(&(http_info->mutex_state), DA_NULL);
+ DA_MUTEX_INIT(&(http_info->mutex_http), DA_NULL);
+ DA_COND_INIT(&(http_info->cond_http), DA_NULL);
}
-da_result_t request_http_download(stage_info *stage)
+void __parsing_user_request_header(char *user_request_header,
+ char **out_field, char **out_value)
{
- da_result_t ret = DA_RESULT_OK;
-
- int slot_id = DA_INVALID_ID;
- http_state_t http_state = 0;
- da_bool_t need_wait = DA_TRUE;
-
- queue_t *queue = DA_NULL;
- req_dl_info *req_info = DA_NULL;
-
- slot_id = GET_STAGE_DL_ID(stage);
- queue = GET_DL_QUEUE(slot_id);
- req_info = GET_STAGE_TRANSACTION_INFO(stage);
-
- DA_LOG_VERBOSE(HTTPManager, "queue = %p", GET_DL_QUEUE(slot_id));
-
- CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD, stage);
-
- do {
- ret = handle_any_input(stage);
- if (ret != DA_RESULT_OK) {
- if (DA_RESULT_OK == GET_REQUEST_HTTP_RESULT(req_info)) {
- GET_REQUEST_HTTP_RESULT(req_info) = ret;
- DA_LOG_CRITICAL(HTTPManager, "setting internal error [%d]", ret);
- }
- _cancel_transaction(stage);
- }
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG_VERBOSE(HTTPManager, "http_state = %d", http_state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- switch (http_state) {
- case HTTP_STATE_READY_TO_DOWNLOAD:
- ret = start_new_transaction(stage);
- if (ret != DA_RESULT_OK) {
- if (DA_RESULT_OK == GET_REQUEST_HTTP_RESULT(req_info)) {
- GET_REQUEST_HTTP_RESULT(req_info) = ret;
- DA_LOG_CRITICAL(HTTPManager, "setting internal error [%d]", ret);
- }
- DA_LOG(HTTPManager, "exiting with error...");
- need_wait = DA_FALSE;
- break;
- }
+ int len = 0;
+ char *pos = NULL;
+ char *temp_pos = NULL;
+ char *field = NULL;
+ char *value = NULL;
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_REQUESTED, stage);
- break;
+ DA_LOGV("");
- case HTTP_STATE_CANCELED:
- case HTTP_STATE_DOWNLOAD_FINISH:
- case HTTP_STATE_ABORTED:
-#ifdef PAUSE_EXIT
- case HTTP_STATE_PAUSED:
-#endif
- DA_LOG_VERBOSE(HTTPManager, "exiting...");
- need_wait = DA_FALSE;
- break;
+ if (!user_request_header) {
+ DA_LOGE("NULL CHECK!: user_request_header");
+ goto ERR;
+ }
- default:
+ pos = strchr(user_request_header, ':');
+ if (!pos) {
+ DA_LOGE("Fail to parse");
+ goto ERR;
+ }
+ temp_pos = (char *)user_request_header;
+ while (*temp_pos)
+ {
+ if (temp_pos == pos || *temp_pos == ' ') {
+ len = temp_pos - user_request_header;
break;
}
-
- if (need_wait == DA_TRUE) {
- _da_thread_mutex_lock(&(queue->mutex_queue));
- if (DA_FALSE == GET_IS_Q_HAVING_DATA(queue)) {
- unpause_for_flow_control(stage);
-
-// DA_LOG_VERBOSE(HTTPManager, "Waiting for input");
- Q_goto_sleep(queue);
-// DA_LOG_VERBOSE(HTTPManager, "Woke up to receive new packet or control event");
- }
- _da_thread_mutex_unlock (&(queue->mutex_queue));
-
- }
-
- } while (need_wait == DA_TRUE);
-
- ret = GET_REQUEST_HTTP_RESULT(req_info);
- DA_LOG_DEBUG(HTTPManager, "Exit request_http_download! ret[%d]slot_id[%d]",
- ret, slot_id);
- return ret;
-}
-
-da_result_t request_to_cancel_http_download(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- q_event_t *q_event = DA_NULL;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL");
- ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_CANCEL, &q_event);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
+ temp_pos++;
+ }
+ if (len < 1) {
+ DA_LOGE("Wrong field name");
goto ERR;
- } else {
- DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
- Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)), q_event);
}
-
-ERR:
- return ret;
-}
-
-da_result_t request_to_suspend_http_download(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- http_state_t http_state = 0;
- q_event_t *q_event = DA_NULL;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG(HTTPManager, "http_state = %d", http_state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- switch (http_state) {
- case HTTP_STATE_PAUSED:
- case HTTP_STATE_REQUEST_PAUSE:
- DA_LOG_CRITICAL(HTTPManager, "Already paused. http_state = %d", http_state);
- ret = DA_ERR_ALREADY_SUSPENDED;
- break;
-
- default:
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
- ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_SUSPEND,
- &q_event);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
- goto ERR;
- } else {
- DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
- Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)),
- q_event);
- }
-
- break;
+ field = (char *)calloc(1, len + 1);
+ if (!field) {
+ DA_LOGE("Fail to calloc");
+ goto ERR;
}
-
-ERR:
- return ret;
-}
-
-da_result_t request_to_resume_http_download(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- http_state_t http_state = 0;
- q_event_t *q_event = DA_NULL;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG(HTTPManager, "[%d] http_state = %d", GET_STAGE_DL_ID(stage), http_state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- switch (http_state) {
- case HTTP_STATE_PAUSED:
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME");
- ret = Q_make_control_event(Q_EVENT_TYPE_CONTROL_RESUME,
- &q_event);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(HTTPManager, "fail to make q_control_event");
- goto ERR;
- } else {
- DA_LOG(HTTPManager, "queue = %p", GET_DL_QUEUE(GET_STAGE_DL_ID(stage)));
- Q_push_event(GET_DL_QUEUE(GET_STAGE_DL_ID(stage)),
- q_event);
- }
-
- break;
-
- case HTTP_STATE_REQUEST_PAUSE:
- DA_LOG_ERR(HTTPManager, "[%d] Fail to resume. Previous pause is not finished. http_state = %d", GET_STAGE_DL_ID(stage), http_state);
- ret = DA_ERR_INVALID_STATE;
-
- break;
-
- case HTTP_STATE_RESUMED:
- ret = DA_ERR_ALREADY_RESUMED;
-
- break;
-
- default:
- DA_LOG_ERR(HTTPManager, "[%d] Fail to resume. This is not a paused ID. http_state = %d", GET_STAGE_DL_ID(stage), http_state);
- ret = DA_ERR_INVALID_STATE;
-
- break;
+ strncpy(field, user_request_header, len);
+ pos++;
+ while (*pos)
+ {
+ if (*pos != ' ')
+ break;
+ pos++;
+ }
+ len = strlen(pos) + 1;
+ value = (char *)calloc(1, len + 1);
+ if (!value) {
+ DA_LOGE("Fail to calloc");
+ goto ERR;
}
+ strncpy(value, pos, len);
+ *out_field = field;
+ *out_value = value;
+ DA_SECURE_LOGD("field[%s], value[%s]", field, value);
+ return;
ERR:
- return ret;
+ if (field) {
+ free(field);
+ field = NULL;
+ }
+ return;
}
-da_result_t start_new_transaction(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
-
- ret = set_http_request_hdr(stage);
- if (ret != DA_RESULT_OK)
- return ret;
- ret = make_transaction_info_and_start_transaction(stage);
- return ret;
-}
-
-da_result_t make_default_http_request_hdr(const char *url,
- char **user_request_header,
- int user_request_header_count,
- http_msg_request_t **out_http_msg_request,
- char *user_request_etag,
- char *user_request_temp_file_path)
+da_ret_t __set_http_request_hdr(req_info_t *req_info, http_info_t *http_info, file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
-
+ da_ret_t ret = DA_RESULT_OK;
http_msg_request_t *http_msg_request = NULL;
char *user_agent = NULL;
+ int count = 0;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
- if (!url) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
- ret = DA_ERR_INVALID_URL;
- goto ERR;
- }
+ NULL_CHECK_RET(req_info);
+ NULL_CHECK_RET(http_info);
+ NULL_CHECK_RET(file_info);
+ NULL_CHECK_RET_OPT(req_info->url, DA_ERR_INVALID_URL);
+ count = req_info->req_header_count;
ret = http_msg_request_create(&http_msg_request);
if (ret != DA_RESULT_OK)
goto ERR;
- ret = http_msg_request_set_url(http_msg_request, url);
+ ret = http_msg_request_set_url(http_msg_request, req_info->url);
if (ret != DA_RESULT_OK)
goto ERR;
- user_agent = get_user_agent();
- if (user_agent)
- http_msg_request_add_field(http_msg_request, HTTP_FIELD_UAGENT,
- user_agent);
+ ret = get_user_agent_string(&user_agent);
+ if (user_agent && ret == DA_RESULT_OK)
+ http_msg_request_add_field(http_msg_request,
+ HTTP_FIELD_UAGENT, user_agent);
+
- http_msg_request_add_field(http_msg_request, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
- http_msg_request_add_field(http_msg_request, HTTP_FIELD_ACCEPT_CHARSET, "utf-8");
+ http_msg_request_add_field(http_msg_request,
+ HTTP_FIELD_ACCEPT_LANGUAGE, "en");
+ http_msg_request_add_field(http_msg_request,
+ HTTP_FIELD_ACCEPT_CHARSET, "utf-8");
- if (user_request_header && user_request_header_count > 0) {
+ if (req_info->req_header && count > 0) {
int i = 0;
- for (i = 0; i < user_request_header_count; i++)
- {
+ for (i = 0; i < count; i++) {
char *field = NULL;
char *value = NULL;
- __parsing_user_request_header(user_request_header[i],
- &field, &value);
+ __parsing_user_request_header(req_info->req_header[i],
+ &field, &value);
if (field && value) {
http_msg_request_add_field(http_msg_request, field, value);
if (field) {
@@ -403,204 +227,348 @@ da_result_t make_default_http_request_hdr(const char *url,
free(value);
value= NULL;
}
- DA_LOG_ERR(HTTPManager, "Fail to parse user request header");
+ DA_LOGE("Fail to parse user request header");
}
}
- } else
- DA_LOG(HTTPManager, "no user reqeust header inserted");
-
- if (user_request_etag) {
+ }
+ if (req_info->etag) {
char buff[64] = {0,};
- unsigned long long size = 0;
+ da_size_t size = 0;
http_msg_request_add_field(http_msg_request,
- HTTP_FIELD_IF_RANGE, user_request_etag);
- get_file_size(user_request_temp_file_path, &size);
+ HTTP_FIELD_IF_RANGE, req_info->etag);
+ get_file_size(req_info->temp_file_path, &size);
+#ifdef _RAF_SUPPORT
+ file_info->file_size_of_temp_file = size;
+#endif
snprintf(buff, sizeof(buff)-1, "bytes=%llu-", size);
http_msg_request_add_field(http_msg_request,
- HTTP_FIELD_RANGE, buff);
+ HTTP_FIELD_RANGE, buff);
}
- *out_http_msg_request = http_msg_request;
-
+ http_info->http_msg_request = http_msg_request;
+ free(user_agent);
+ return ret;
ERR:
- if (ret != DA_RESULT_OK)
+ if (http_msg_request)
http_msg_request_destroy(&http_msg_request);
- if (user_agent)
- free(user_agent);
+
return ret;
+
}
-da_result_t set_http_request_hdr(stage_info *stage)
+da_ret_t __create_http_resume_hdr(req_info_t *req_info, http_info_t *http_info,
+ file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
- req_dl_info *request_info = DA_NULL;
-
- char *url = DA_NULL;
- char **user_request_header = DA_NULL;
- int user_request_header_count = 0;
- char *user_request_etag = DA_NULL;
- char *user_request_temp_file_path = DA_NULL;
- http_msg_request_t* http_msg_request = NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
+ da_ret_t ret = DA_RESULT_OK;
+ da_bool_t b_ret = DA_FALSE;
+ char *value = NULL;
+ char temp_size_str[32] = { 0, };
+ char *etag_from_response = NULL;
+ char *date_from_response = NULL;
+ http_msg_response_t *first_response = NULL;
+ http_msg_request_t *resume_request = NULL;
+ http_msg_request_t *old_request = NULL;
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
+ DA_LOGV("");
- if (DA_NULL ==
- (url = GET_REQUEST_HTTP_REQ_URL(request_info))) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
- ret = DA_ERR_INVALID_URL;
+ first_response = http_info->http_msg_response;
+ if (first_response) {
+ b_ret = http_msg_response_get_ETag(first_response, &value);
+ if (b_ret) {
+ etag_from_response = value;
+ value = NULL;
+ DA_SECURE_LOGD("[ETag][%s]", etag_from_response);
+ }
+ b_ret = http_msg_response_get_date(first_response, &value);
+ if (b_ret) {
+ date_from_response = value;
+ value = NULL;
+ DA_LOGV("[Date][%s]", date_from_response);
+ }
+ DA_SECURE_LOGD("downloaded_size[%u]", file_info->bytes_written_to_file);
+ snprintf(temp_size_str, sizeof(temp_size_str), "bytes=%llu-",
+ file_info->bytes_written_to_file);
+ DA_SECURE_LOGD("size str[%s]", temp_size_str);
+ free(first_response);
+ http_info->http_msg_response = DA_NULL;
+ }
+ old_request = http_info->http_msg_request;
+ free(old_request);
+ http_info->http_msg_request = DA_NULL;
+
+ ret = __set_http_request_hdr(req_info, http_info, file_info);
+ if (ret != DA_RESULT_OK)
goto ERR;
- }
- user_request_header = GET_REQUEST_HTTP_USER_REQUEST_HEADER(
- request_info);
- user_request_header_count = GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(
- request_info);
- user_request_etag = GET_REQUEST_HTTP_USER_REQUEST_ETAG(
- request_info);
- user_request_temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(
- request_info);
- if (user_request_etag) {
- DA_SECURE_LOGD("user_request_etag[%s]",user_request_etag);
+ resume_request = http_info->http_msg_request;
+ if (etag_from_response) {
+ http_msg_request_add_field(resume_request, HTTP_FIELD_IF_RANGE,
+ etag_from_response);
} else {
- DA_LOG_VERBOSE(HTTPManager, "user_request_etag is NULL");
+ if (date_from_response) {
+ http_msg_request_add_field(resume_request,
+ HTTP_FIELD_IF_RANGE, date_from_response);
+ }
}
- ret = make_default_http_request_hdr(url, user_request_header,
- user_request_header_count, &http_msg_request,
- user_request_etag, user_request_temp_file_path);
- if (ret == DA_RESULT_OK)
- request_info->http_info.http_msg_request = http_msg_request;
+
+ if (strlen(temp_size_str) > 0)
+ http_msg_request_add_field(resume_request, HTTP_FIELD_RANGE,
+ temp_size_str);
ERR:
+ if (etag_from_response) {
+ free(etag_from_response);
+ etag_from_response = NULL;
+ }
+ if (date_from_response) {
+ free(date_from_response);
+ date_from_response = NULL;
+ }
return ret;
-
}
-da_result_t make_transaction_info_and_start_transaction(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- int slot_id = DA_INVALID_ID;
- req_dl_info *request_info = DA_NULL;
+da_ret_t __start_transaction(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_info_t *http_info;
+ DA_LOGV("");
- input_for_tranx_t *input_for_tranx = DA_NULL;
+ if (!da_info) {
+ DA_LOGE("NULL CHECK!: da_info");
+ return DA_ERR_INVALID_ARGUMENT;
+ }
+ http_info = da_info->http_info;
+ if (!http_info) {
+ DA_LOGE("NULL CHECK!: http_info");
+ return DA_ERR_INVALID_ARGUMENT;
+ }
+ http_info->http_method = HTTP_METHOD_GET;
+ http_info->proxy_addr = get_proxy_address();
- DA_LOG_FUNC_LOGV(HTTPManager);
+ ret = PI_http_start(da_info);
- slot_id = GET_STAGE_DL_ID(stage);
+ return ret;
+}
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
+da_ret_t __start_resume_transaction(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_info_t *http_info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+
+ ret = __create_http_resume_hdr(req_info, http_info,
+ file_info);
+ if (ret != DA_RESULT_OK)
+ return ret;
- if (GET_REQUEST_HTTP_REQ_URL(request_info) == DA_NULL) {
- DA_LOG_ERR(HTTPManager, "url is NULL");
- ret = DA_ERR_INVALID_URL;
- goto ERR;
+ reset_http_info_for_resume(http_info);
+ if (file_info->file_path) {
+ req_info->temp_file_path = strdup(file_info->file_path);
+ } else {
+ DA_LOGE("file_path cannot be NULL in resume case");
+ return DA_ERR_INVALID_ARGUMENT;
}
+ ret = __start_transaction(da_info);
+ return ret;
+}
- input_for_tranx = (input_for_tranx_t*) calloc(1,
- sizeof(input_for_tranx_t));
- if (input_for_tranx == DA_NULL) {
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- } else {
- input_for_tranx->proxy_addr = get_proxy_address();
- input_for_tranx->queue = GET_DL_QUEUE(slot_id);
- input_for_tranx->http_method = PI_HTTP_METHOD_GET;
- input_for_tranx->http_msg_request
- = request_info->http_info.http_msg_request;
+da_ret_t __start_new_transaction(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+
+ if (!da_info) {
+ DA_LOGE("NULL CHECK!: da_info");
+ return DA_ERR_INVALID_ARGUMENT;
}
- ret = PI_http_start_transaction(input_for_tranx,
- &(GET_REQUEST_HTTP_TRANS_ID(request_info)));
+ ret = __set_http_request_hdr(da_info->req_info, da_info->http_info, da_info->file_info);
if (ret != DA_RESULT_OK)
- goto ERR;
-
-ERR:
- if (input_for_tranx) {
- free(input_for_tranx);
- input_for_tranx = DA_NULL;
- }
+ return ret;
+ ret = __start_transaction(da_info);
return ret;
}
-da_result_t make_req_dl_info_http(stage_info *stage, req_dl_info *out_info)
+int __check_wait_for_auto_retry(http_info_t *http_info)
{
- char *url = DA_NULL;
- char **user_request_header = DA_NULL;
- int user_request_header_count = 0;
- char *user_request_etag = DA_NULL;
- char *user_request_temp_file_path = DA_NULL;
- int dl_id = -1;
- source_info_t *source_info = DA_NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!stage) {
- DA_LOG_ERR(HTTPManager, "stage is NULL");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- source_info = GET_STAGE_SOURCE_INFO(stage);
-
- url = source_info->source_info_type.source_info_basic->url;
- user_request_header =
- source_info->source_info_type.source_info_basic->user_request_header;
- user_request_header_count =
- source_info->source_info_type.source_info_basic->user_request_header_count;
- dl_id = source_info->source_info_type.source_info_basic->dl_id;
- user_request_etag = GET_DL_USER_ETAG(GET_STAGE_DL_ID(stage));
- user_request_temp_file_path = GET_DL_USER_TEMP_FILE_PATH(GET_STAGE_DL_ID(stage));
-
- DA_SECURE_LOGD("url [%s]", url);
-
- if (url) {
- GET_REQUEST_HTTP_REQ_URL(out_info) = url;
- GET_REQUEST_HTTP_USER_REQUEST_HEADER(out_info) = user_request_header;
- GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(out_info) =
- user_request_header_count;
- GET_REQUEST_HTTP_USER_REQUEST_ETAG(out_info) =
- user_request_etag;
- GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(out_info) =
- user_request_temp_file_path;
+ da_ret_t ret = DA_RESULT_OK;
+ struct timespec ts;
+ struct timeval tp;
+ NULL_CHECK_RET_OPT(http_info, 0);
+ gettimeofday(&tp, NULL);
+ ts.tv_sec = tp.tv_sec + DA_MAX_TIME_OUT;
+ ts.tv_nsec = tp.tv_usec * 1000;
+ DA_LOGI("Network Fail case, wait for a while");
+
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_WAIT_FOR_NET_ERR;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_MUTEX_LOCK(&(http_info->mutex_http));
+ ret = pthread_cond_timedwait(&(http_info->cond_http),
+ &(http_info->mutex_http), &ts);
+ DA_MUTEX_UNLOCK(&(http_info->mutex_http));
+ if (ret == ETIMEDOUT) {
+ DA_LOGI("Waiting is done by timeout");
+ } else if (ret != 0) {
+ DA_LOGE("fail to pthread_cond_waittime[%d][%s]",ret, strerror(ret));
} else {
- DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
- return DA_ERR_INVALID_URL;
+ DA_LOGI("Waiting is done by control");
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ DA_LOGI("http_state[%s]", __get_state_str(http_info->state));
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ return 1;
}
- _da_thread_mutex_init(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)), NULL);
-
- return DA_RESULT_OK;
+ return 0;
}
-da_result_t pause_for_flow_control(stage_info *stage)
+// In download thread
+da_ret_t request_http_download(da_info_t *da_info)
{
- return DA_RESULT_OK;
-}
+ da_ret_t ret = DA_RESULT_OK;
+ req_info_t *req_info = DA_NULL;
+ http_info_t *http_info = DA_NULL;
+ http_state_t http_state = 0;
+ da_bool_t need_wait = DA_TRUE;
-da_result_t unpause_for_flow_control(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
+ DA_LOGV("");
+
+ NULL_CHECK_RET(da_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+ __init_http_info(http_info);
- DA_LOG_FUNC_LOGV(HTTPManager);
+ do {
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("http_state[%s][%d]",__get_state_str(http_info->state), da_info->da_id);
+ switch (http_state) {
+ case HTTP_STATE_READY_TO_DOWNLOAD:
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_REQUESTED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ ret = __start_new_transaction(da_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_LOGD("http_state[%s][%d]",__get_state_str(http_info->state), da_info->da_id);
+ http_info->error_code = ret;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ if (ret == DA_ERR_NETWORK_FAIL && http_state != HTTP_STATE_PAUSED) {
+ DA_LOGE("Network failed");
+ if (__check_wait_for_auto_retry(http_info) == 1)
+ need_wait = DA_TRUE;
+ else
+ need_wait = DA_FALSE;
+ }
+ break;
+ case HTTP_STATE_REDIRECTED:
+ case HTTP_STATE_DOWNLOAD_REQUESTED:
+ case HTTP_STATE_DOWNLOAD_STARTED:
+ case HTTP_STATE_DOWNLOADING:
+ case HTTP_STATE_REQUEST_PAUSE:
+ DA_LOGE("Cannot enter here:[%s][id]",
+ __get_state_str(http_info->state), da_info->da_id);
+ break;
+ case HTTP_STATE_REQUEST_CANCEL:
+ break;
+ case HTTP_STATE_REQUEST_RESUME:
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_READY_TO_DOWNLOAD;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ need_wait = DA_TRUE;
+ break;
+ case HTTP_STATE_CANCELED:
+ need_wait = DA_FALSE;
+ ret = DA_RESULT_USER_CANCELED;
+ break;
+ case HTTP_STATE_PAUSED:
+ DA_LOGD("error_code[%d]", http_info->error_code);
+ send_client_paused_info(da_info);
+ DA_LOGD("Waiting thread for paused state");
+ DA_MUTEX_LOCK(&(http_info->mutex_http));
+ pthread_cond_wait(&(http_info->cond_http),&(http_info->mutex_http));
+ DA_MUTEX_UNLOCK(&(http_info->mutex_http));
+ DA_LOGD("Wake up thread due to resume");
+ break;
+ case HTTP_STATE_RESUMED:
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_REQUESTED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ ret = __start_resume_transaction(da_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ if (ret == DA_ERR_NETWORK_FAIL && http_state != HTTP_STATE_PAUSED) {
+ DA_LOGE("Network failed");
+ if (__check_wait_for_auto_retry(http_info) == 1)
+ need_wait = DA_TRUE;
+ else
+ need_wait = DA_FALSE;
+ }
+ break;
+ case HTTP_STATE_DOWNLOAD_FINISH:
+ need_wait = DA_FALSE;
+ if (ret == DA_RESULT_OK)
+ ret = check_drm_convert(da_info->file_info);
+ break;
+ case HTTP_STATE_FAILED:
+ if (ret == DA_ERR_NETWORK_FAIL) {
+ if (__check_wait_for_auto_retry(http_info) == 1)
+ need_wait = DA_TRUE;
+ else
+ need_wait = DA_FALSE;
+ } else {
+ need_wait = DA_FALSE;
+ }
+ break;
+ case HTTP_STATE_ABORTED:
+ need_wait = DA_FALSE;
+ break;
+ default:
+ break;
+ }
+ } while (need_wait == DA_TRUE);
+ DA_LOGD("Final http_state[%s][%d] err[%d]",__get_state_str(http_info->state), da_info->da_id, ret);
+ if (http_info->state != HTTP_STATE_PAUSED)
+ send_client_finished_info(da_info ,ret);
+ DA_LOGI("=== Exiting http_download ret[%d] ===", ret);
+ return ret;
+}
- PI_http_unpause_transaction(
- GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage)));
+da_ret_t __disconnect_transaction(http_info_t *http_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ DA_LOGD("");
+ ret = PI_http_disconnect(http_info);
return ret;
}
-da_result_t handle_event_abort(stage_info *stage)
+
+da_ret_t __handle_event_abort(http_info_t *http_info)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
http_state_t state = 0;
- DA_LOG_FUNC_LOGD(HTTPManager);
+ DA_LOGD("");
+
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGV("http_state[%s]", __get_state_str(state));
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG(HTTPManager, "http_state = %d", state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
switch (state) {
case HTTP_STATE_READY_TO_DOWNLOAD:
case HTTP_STATE_REDIRECTED:
@@ -614,632 +582,406 @@ da_result_t handle_event_abort(stage_info *stage)
case HTTP_STATE_PAUSED:
case HTTP_STATE_RESUMED:
case HTTP_STATE_ABORTED:
+ case HTTP_STATE_WAIT_FOR_NET_ERR:
/* IF the network session is terminated due to some error,
* the state can be aborted.(data aborted case) */
- CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_ABORTED, stage);
- _disconnect_transaction(stage);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_ABORTED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ __disconnect_transaction(http_info);
break;
case HTTP_STATE_DOWNLOAD_FINISH:
break;
default:
- DA_LOG_ERR(HTTPManager, "have to check the flow for this case");
+ DA_LOGE("Cannot enter here");
break;
}
return ret;
}
-da_result_t handle_event_cancel(stage_info *stage)
+da_ret_t __check_enough_memory(http_info_t *http_info, char *user_install_path)
{
- da_result_t ret = DA_RESULT_OK;
- http_state_t state = 0;
+ da_ret_t ret = DA_RESULT_OK;
+ da_size_t cont_len = 0;
+ char *dir_path = DA_DEFAULT_INSTALL_PATH_FOR_PHONE;
+
+ DA_LOGV("");
+ NULL_CHECK_RET(http_info);
+ cont_len = http_info->content_len_from_header;
+ if (cont_len > 0) {
+ if (user_install_path)
+ dir_path = user_install_path;
+ ret = get_available_memory(dir_path, cont_len);
+ }
+ return ret;
+}
- DA_LOG_FUNC_LOGD(HTTPManager);
+da_ret_t request_to_abort_http_download(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ ret = __handle_event_abort(da_info->http_info);
+ return ret;
+}
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG(HTTPManager, "http_state = %d", state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- switch (state) {
+da_ret_t request_to_cancel_http_download(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_info_t *http_info = DA_NULL;
+ http_state_t http_state = 0;
+ DA_LOGV("");
+
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("http_state[%s]", __get_state_str(http_state));
+ switch (http_state) {
case HTTP_STATE_READY_TO_DOWNLOAD:
- CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
+ ret = PI_http_cancel(http_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_CANCELED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ if (da_info->thread_id > 0) {
+ if (pthread_cancel(da_info->thread_id) != 0) {
+ DA_LOGE("Fail to cancel thread id[%d] err[%s]",
+ da_info->thread_id, strerror(errno));
+ } else {
+ DA_LOGI("====Exit thread with cancel:da_id[%d]===",
+ da_info->da_id);
+ }
+ }
+ break;
+ case HTTP_STATE_WAIT_FOR_NET_ERR:
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_CANCELED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_MUTEX_LOCK(&(http_info->mutex_http));
+ DA_COND_SIGNAL(&(http_info->cond_http));
+ DA_MUTEX_UNLOCK(&(http_info->mutex_http));
break;
-
case HTTP_STATE_PAUSED:
- discard_download(stage);
- CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
+ reset_http_info(http_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_CANCELED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
break;
-
case HTTP_STATE_DOWNLOAD_REQUESTED:
case HTTP_STATE_DOWNLOAD_STARTED:
case HTTP_STATE_DOWNLOADING:
case HTTP_STATE_REQUEST_RESUME:
case HTTP_STATE_RESUMED:
- _cancel_transaction(stage);
- CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_CANCEL, stage);
+ ret = PI_http_cancel(http_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_REQUEST_CANCEL;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
break;
-
case HTTP_STATE_DOWNLOAD_FINISH:
+ ret = DA_ERR_INVALID_STATE;
break;
-
case HTTP_STATE_REQUEST_CANCEL:
- DA_LOG(HTTPManager, "HTTP_STATE_REQUEST_CANCEL : cancel is already in progress... ");
+ DA_LOGV("cancel is already in progress... ");
+ ret = DA_ERR_INVALID_STATE;
break;
-
default:
- DA_LOG_ERR(HTTPManager, "have to check the flow for this case");
+ ret = DA_ERR_INVALID_STATE;
+ DA_LOGE("Cannot enter here");
break;
}
-
return ret;
}
-da_result_t handle_event_suspend(stage_info *stage)
+da_ret_t request_to_suspend_http_download(da_info_t *da_info)
{
- da_result_t ret = DA_RESULT_OK;
+
+ da_ret_t ret = DA_RESULT_OK;
+ http_info_t *http_info = DA_NULL;
http_state_t http_state = 0;
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
+ DA_LOGV("");
+
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("http_state[%s]", __get_state_str(http_state));
switch (http_state) {
+ case HTTP_STATE_PAUSED:
case HTTP_STATE_REQUEST_PAUSE:
- DA_LOG(HTTPManager, "already requested to pause! do nothing");
+ DA_LOGI("Already paused. http_state[%s]", __get_state_str(http_state));
+ ret = DA_ERR_ALREADY_SUSPENDED;
break;
-
case HTTP_STATE_READY_TO_DOWNLOAD:
- CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
- send_client_paused_info(GET_STAGE_DL_ID(stage));
+ DA_LOGE("Download has not been started yet");
+ ret = DA_ERR_INVALID_STATE;
+ break;
+ case HTTP_STATE_WAIT_FOR_NET_ERR:
+ DA_LOGD("error_code[%d]", http_info->error_code);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_PAUSED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_MUTEX_LOCK(&(http_info->mutex_http));
+ DA_COND_SIGNAL(&(http_info->cond_http));
+ DA_MUTEX_UNLOCK(&(http_info->mutex_http));
break;
-
default:
- //send_client_paused_info(GET_STAGE_DL_ID(stage));
- _cancel_transaction(stage);
- GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)) = DA_RESULT_OK;
- DA_LOG_CRITICAL(HTTPManager, "[%d] cleanup internal error", GET_STAGE_DL_ID(stage));
- CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_PAUSE,stage);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_REQUEST_PAUSE;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("error_code[%d]", http_info->error_code);
+ if (http_info->error_code != DA_ERR_NETWORK_FAIL)
+ ret = PI_http_pause(http_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_PAUSED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+
break;
}
-
return ret;
}
-da_result_t handle_event_resume(stage_info *stage)
+da_ret_t request_to_resume_http_download(da_info_t *da_info)
{
- da_result_t ret = DA_RESULT_OK;
- http_msg_request_t *resume_request = NULL;
-
+ da_ret_t ret = DA_RESULT_OK;
+ http_info_t *http_info = DA_NULL;
http_state_t http_state = 0;
+ int retry_count = 0;
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
+ DA_LOGV("");
- if (http_state != HTTP_STATE_PAUSED) {
- DA_LOG_ERR(HTTPManager, "Not HTTP_STATE_PAUSED! http_state = %d", http_state);
- ret = DA_ERR_INVALID_STATE;
- goto ERR;
- }
-
- GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)) = DA_RESULT_OK;
- DA_LOG_CRITICAL(HTTPManager, "[%d] cleanup internal error", GET_STAGE_DL_ID(stage));
-
- CHANGE_HTTP_STATE(HTTP_STATE_REQUEST_RESUME,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
-
- ret = create_resume_http_request_hdr(stage, &resume_request);
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- if (GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request)
- free(GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request);
-
- GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_request
- = resume_request;
-
- make_transaction_info_and_start_transaction(stage);
-
-ERR:
- return ret;
-
-}
-
-da_result_t create_resume_http_request_hdr(stage_info *stage,
- http_msg_request_t **out_resume_request)
-{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t b_ret = DA_FALSE;
-
- req_dl_info *request_info = NULL;
-
- http_msg_response_t *first_response = NULL;
- http_msg_request_t *resume_request = NULL;
-
- char *value = NULL;
- char *url = NULL;
- unsigned int downloaded_data_size = 0;
- char downloaded_data_size_to_str[32] = { 0, };
-
- char *etag_from_response = NULL;
- char *date_from_response = NULL;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
-
- if (!(url = GET_REQUEST_HTTP_REQ_URL(GET_STAGE_TRANSACTION_INFO(stage)))) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_NO_URL");
- ret = DA_ERR_INVALID_URL;
- goto ERR;
- }
-
- first_response = request_info->http_info.http_msg_response;
- if (first_response) {
- b_ret = http_msg_response_get_ETag(first_response, &value);
- if (b_ret) {
- etag_from_response = value;
- value = NULL;
- DA_SECURE_LOGD("[ETag][%s]", etag_from_response);
- }
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
- b_ret = http_msg_response_get_date(first_response, &value);
- if (b_ret) {
- date_from_response = value;
- value = NULL;
- DA_SECURE_LOGD("[Date][%s]", date_from_response);
- }
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("http_state[%s]", __get_state_str(http_state));
- downloaded_data_size
- = GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage));
- DA_LOG(HTTPManager, "downloaded_data_size = %u", downloaded_data_size);
- snprintf(downloaded_data_size_to_str, sizeof(downloaded_data_size_to_str), "bytes=%u-",
- downloaded_data_size);
- DA_LOG(HTTPManager, "downloaded_data_size_to_str = %s", downloaded_data_size_to_str);
- }
-
- ret = make_default_http_request_hdr(url, NULL, 0, &resume_request, NULL, NULL);
- if (ret != DA_RESULT_OK)
- goto ERR;
+ switch (http_state) {
+ case HTTP_STATE_PAUSED:
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_RESUMED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("Wake up thread for paused state");
+ DA_MUTEX_LOCK(&(http_info->mutex_http));
+ DA_COND_SIGNAL(&(http_info->cond_http));
+ DA_MUTEX_UNLOCK(&(http_info->mutex_http));
+ DA_LOGD("error_code[%d]", http_info->error_code);
+ if (http_info->error_code != DA_ERR_NETWORK_FAIL) {
+ ret = PI_http_unpause(http_info);
+ if (ret != DA_RESULT_OK)
+ PI_http_cancel(http_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOADING;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
- if (etag_from_response) {
- http_msg_request_add_field(resume_request, HTTP_FIELD_IF_RANGE,
- etag_from_response);
- } else {
- if (date_from_response) {
- http_msg_request_add_field(resume_request,
- HTTP_FIELD_IF_RANGE, date_from_response);
}
- }
-
- if (strlen(downloaded_data_size_to_str) > 0)
- http_msg_request_add_field(resume_request, HTTP_FIELD_RANGE,
- downloaded_data_size_to_str);
-
- *out_resume_request = resume_request;
-
-ERR:
- if (etag_from_response) {
- free(etag_from_response);
- etag_from_response = NULL;
- }
-
- if (date_from_response) {
- free(date_from_response);
- date_from_response = NULL;
- }
-
- return ret;
-}
-
-da_result_t handle_any_input(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
-
- int slot_id = GET_STAGE_DL_ID(stage);
-
- queue_t *queue = DA_NULL;
- q_event_t *event = DA_NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- queue = GET_DL_QUEUE(slot_id);
-
- Q_pop_event(queue, &event);
- if (event == DA_NULL) {
- DA_LOG_DEBUG(HTTPManager, "There is no data on the queue!");
- return DA_RESULT_OK;
- }
-
- switch (event->event_type) {
- case Q_EVENT_TYPE_CONTROL:
- ret = handle_event_control(stage, event);
break;
-
- case Q_EVENT_TYPE_DATA_HTTP:
- ret = handle_event_http(stage, event);
+ case HTTP_STATE_REQUEST_PAUSE:
+ DA_LOGD("Waiting to handle pause request");
+ do {
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ if (http_state == HTTP_STATE_PAUSED) {
+ DA_LOGD("Change to paused state");
+ ret = PI_http_unpause(http_info);
+ break;
+ }
+ retry_count++;
+ } while(retry_count < 10000);
+ if (ret != DA_RESULT_OK || retry_count >= 10000)
+ PI_http_cancel(http_info);
break;
-
- case Q_EVENT_TYPE_DATA_DRM:
+ case HTTP_STATE_RESUMED:
+ ret = DA_ERR_ALREADY_RESUMED;
break;
-
default:
+ DA_LOGE("Fail to resume. Invalid state check. http_state[%s]",
+ __get_state_str(http_state));
+ ret = DA_ERR_INVALID_STATE;
+ // If resume is failed due to invalid state, the previous pause should be canceled.
+ PI_http_cancel(http_info);
break;
}
- Q_destroy_q_event(&event);
-
return ret;
}
-da_result_t handle_event_control(stage_info *stage, q_event_t *event)
+da_ret_t __check_resume_download_is_available(
+ req_info_t *req_info, http_info_t *http_info, file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- if (event->event_type == Q_EVENT_TYPE_CONTROL) {
- switch (event->type.q_event_control.control_type) {
- case Q_EVENT_TYPE_CONTROL_CANCEL:
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_CANCEL");
- ret = handle_event_cancel(stage);
- break;
-
- case Q_EVENT_TYPE_CONTROL_SUSPEND:
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_SUSPEND");
- ret = handle_event_suspend(stage);
- break;
-
- case Q_EVENT_TYPE_CONTROL_RESUME:
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_RESUME");
- ret = handle_event_resume(stage);
- break;
- case Q_EVENT_TYPE_CONTROL_ABORT:
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_ABORT");
- ret = handle_event_abort(stage);
- break;
- /* Fixme: need to think how we use this type. For now, this type is not used. */
- case Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED:
- DA_LOG(HTTPManager, "Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED");
- break;
- case Q_EVENT_TYPE_CONTROL_NONE:
- default:
- DA_LOG_ERR(HTTPManager, "Cannot enter here");
- break;
- }
- }
-
- return ret;
-}
+ da_ret_t ret = DA_RESULT_OK;
+ da_bool_t b_ret = DA_FALSE;
+ char *origin_ETag = NULL;
+ char *new_ETag = NULL;
+ da_size_t remained_content_len = 0;
+ char *value = NULL;
+ da_size_t size = 0;
+ char *temp_file_path = DA_NULL;
+ char *dir_path = DA_DEFAULT_INSTALL_PATH_FOR_PHONE;
-da_result_t handle_event_http(stage_info *stage, q_event_t *event)
-{
- da_result_t ret = DA_RESULT_OK;
- q_event_data_http_t *q_event_data_http = DA_NULL;
+ DA_LOGV("");
- DA_LOG_FUNC_LOGV(HTTPManager);
+ origin_ETag = req_info->etag;
- if (event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
- q_event_data_http = &(event->type.q_event_data_http);
- switch (q_event_data_http->data_type) {
- case Q_EVENT_TYPE_DATA_PACKET:
- ret = handle_event_http_packet(stage, event);
- break;
- case Q_EVENT_TYPE_DATA_FINAL:
- DA_LOG_VERBOSE(HTTPManager, "Q_EVENT_TYPE_DATA_FINAL");
- ret = handle_event_http_final(stage, event);
- break;
- case Q_EVENT_TYPE_DATA_ABORT:
- DA_LOG_VERBOSE(HTTPManager, "Q_EVENT_TYPE_DATA_ABORT");
- ret = handle_event_http_abort(stage, event);
- break;
- }
+ b_ret = http_msg_response_get_content_length(http_info->http_msg_response,
+ &size);
+ if (b_ret) {
+ remained_content_len = size;
+ size = 0;
+ DA_SECURE_LOGD("remained_content_len[%llu]", remained_content_len);
}
- return ret;
-}
-
-da_result_t handle_event_http_packet(stage_info *stage, q_event_t *event)
-{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t is_handle_hdr_success = DA_TRUE;
- q_event_data_http_t *received_data = DA_NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- received_data = &(event->type.q_event_data_http);
-
- if (received_data->http_response_msg) {
- ret = handle_http_hdr(stage, received_data->http_response_msg,
- received_data->http_response_msg->status_code);
- if (DA_RESULT_OK != ret) {
- is_handle_hdr_success = DA_FALSE;
- }
-
- received_data->http_response_msg = NULL;
+ b_ret = http_msg_response_get_ETag(http_info->http_msg_response, &value);
+ if (b_ret) {
+ new_ETag = value;
+ value = NULL;
+ DA_SECURE_LOGD("new ETag[%s]", new_ETag);
+ } else {
+ goto ERR;
}
- if (received_data->body_len > 0) {
- if (is_handle_hdr_success == DA_TRUE) {
- ret = handle_http_body(stage, received_data->body_data,
- received_data->body_len);
- }
- /*For all cases body_data should be deleted*/
- free(received_data->body_data);
- received_data->body_data = DA_NULL;
+ if (origin_ETag && new_ETag &&
+ 0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) {
+ DA_LOGE("ETag is not identical! revoke!");
+ /* FIXME Later : Need to detail error exception handling */
+ ret = DA_ERR_NETWORK_FAIL;
+ /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
+ goto ERR;
}
- return ret;
-}
-
-da_result_t handle_event_http_final(stage_info *stage, q_event_t *event)
-{
- da_result_t ret = DA_RESULT_OK;
- http_state_t http_state = 0;
- int slot_id = DA_INVALID_ID;
- int http_status = 0;
- q_event_data_http_t *received_data = DA_NULL;
-
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- slot_id = GET_STAGE_DL_ID(stage);
- _disconnect_transaction(stage);
-
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG(HTTPManager, "http_state = %d", http_state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- switch (http_state) {
- case HTTP_STATE_REDIRECTED:
- CHANGE_HTTP_STATE(HTTP_STATE_READY_TO_DOWNLOAD,stage);
- break;
-
- case HTTP_STATE_DOWNLOAD_REQUESTED:
- DA_LOG(HTTPManager, "case HTTP_STATE_DOWNLOAD_REQUESTED");
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
- /* Most of http status is decided when got headers.
- * But it is ignored for credential url when got headers in case of 401 status code.
- * So, when the download is finished, it means unauthorized error if the status code has still 401.
- */
- received_data = &(event->type.q_event_data_http);
- http_status = received_data->status_code;
- if (http_status == 401) {
- store_http_status(slot_id, http_status);
- ret = DA_ERR_NETWORK_FAIL;
- }
- break;
-
- case HTTP_STATE_DOWNLOADING:
- DA_LOG_VERBOSE(HTTPManager, "case HTTP_STATE_DOWNLOADING");
- ret = file_write_complete(stage);
- if (ret != DA_RESULT_OK) {
- discard_download(stage);
- goto ERR;
- }
- /* Sometimes, the server can send "0" byte package data although whole data are not sent.
- * At that case, the libsoup call finished callback function with 200 Ok.
- * Only if the DA know content size form response header, it can check the error or not
- */
- ret = _check_downloaded_file_size_is_same_with_header_content_size(stage);
- if(ret != DA_RESULT_OK) {
- discard_download(stage) ;
- goto ERR;
- }
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
- send_client_update_progress_info(
- slot_id,
- GET_DL_ID(slot_id),
- GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
- );
- break;
-
- case HTTP_STATE_REQUEST_PAUSE:
- if (GET_CONTENT_STORE_FILE_HANDLE(GET_STAGE_CONTENT_STORE_INFO(stage))) {
- ret = file_write_complete(stage);
-
- IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
- = DA_FALSE;
-
- send_client_update_progress_info(
- slot_id,
- GET_DL_ID(slot_id),
- GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
- );
-
- }
- CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
- send_client_paused_info(GET_STAGE_DL_ID(stage));
- DA_LOG(HTTPManager, "Server Notification code is set to NULL");
- break;
-
- case HTTP_STATE_ABORTED:
- case HTTP_STATE_CANCELED:
- discard_download(stage);
- break;
- case HTTP_STATE_REQUEST_CANCEL:
- ret = file_write_complete(stage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- discard_download(stage);
- CHANGE_HTTP_STATE(HTTP_STATE_CANCELED, stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
- break;
-
- default:
- ret = file_write_complete(stage);
+ if (remained_content_len > 0) {
+ if (req_info->install_path)
+ dir_path = req_info->install_path;
+ ret = get_available_memory(dir_path, remained_content_len);
if (ret != DA_RESULT_OK)
goto ERR;
- discard_download(stage);
- CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
- break;
}
-ERR:
- /* When file complete is failed */
- if (DA_RESULT_OK != ret) {
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_FINISH, stage);
+ if (!http_info->content_type_from_header) {
+ b_ret = http_msg_response_get_content_type(http_info->http_msg_response,
+ &value);
+ if (b_ret) {
+ http_info->content_type_from_header = value;
+ value = NULL;
+ DA_SECURE_LOGD("Content-Type[%s]",
+ http_info->content_type_from_header);
+ }
}
- return ret;
-}
-
-da_result_t handle_event_http_abort(stage_info *stage, q_event_t *event)
-{
- da_result_t ret = DA_RESULT_OK;
- http_state_t http_state = 0;
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))
- = event->type.q_event_data_http.error_type;
- DA_LOG_CRITICAL(HTTPManager, "set internal error code : [%d]", GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
- _disconnect_transaction(stage);
-
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG(HTTPManager, "http_state = %d", http_state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- switch (http_state) {
- case HTTP_STATE_REQUEST_PAUSE:
- CHANGE_HTTP_STATE(HTTP_STATE_PAUSED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_PAUSED, stage);
- send_client_paused_info(GET_STAGE_DL_ID(stage));
- ret = file_write_complete(stage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- break;
-
- case HTTP_STATE_REQUEST_CANCEL:
- CHANGE_HTTP_STATE(HTTP_STATE_CANCELED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_CANCELED, stage);
- ret = file_write_complete(stage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- discard_download(stage);
- break;
-
- default:
- CHANGE_HTTP_STATE(HTTP_STATE_ABORTED,stage);
- ret = file_write_complete(stage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- discard_download(stage);
- break;
+ temp_file_path = req_info->temp_file_path;
+ if (!temp_file_path) {
+ DA_LOGE("Temporary file path cannot be NULL");
+ ret = DA_ERR_INVALID_ARGUMENT;
+ goto ERR;
}
+ get_file_size(temp_file_path, &size);
+ http_info->content_len_from_header = remained_content_len + size;
+ DA_SECURE_LOGD("Content-Length[%llu]", http_info->content_len_from_header);
ERR:
+ if (new_ETag) {
+ free(new_ETag);
+ new_ETag = DA_NULL;
+ }
return ret;
}
-da_result_t handle_http_hdr(stage_info *stage,
- http_msg_response_t *http_msg_response, int http_status)
-{
- da_result_t ret = DA_RESULT_OK;
- int slot_id = DA_INVALID_ID;
- http_state_t http_state = 0;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- slot_id = GET_STAGE_DL_ID(stage);
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG_DEBUG(HTTPManager, "http_state = %d", http_state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- switch (http_state) {
- case HTTP_STATE_DOWNLOAD_REQUESTED:
- case HTTP_STATE_REQUEST_PAUSE:
- case HTTP_STATE_REQUEST_RESUME:
- case HTTP_STATE_REDIRECTED:
- ret = handle_http_status_code(stage, http_msg_response,
- http_status);
- if (ret != DA_RESULT_OK)
- goto ERR;
- break;
+da_ret_t __check_content_type_is_matched(http_info_t *http_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ char *content_type_from_server = DA_NULL;
- case HTTP_STATE_REQUEST_CANCEL:
- DA_LOG(HTTPManager, "Cancel is in progress.. http_state = %d", http_state);
- break;
+ DA_LOGV("");
- default:
- DA_LOG_ERR(HTTPManager, "http_state = %d", http_state);
- goto ERR;
+ content_type_from_server = http_info->content_type_from_header;
+ if (content_type_from_server == DA_NULL) {
+ DA_LOGV("http header has no Content-Type field, no need to compare");
+ return DA_RESULT_OK;
}
-
-ERR:
return ret;
}
-da_result_t handle_http_status_code(stage_info *stage,
- http_msg_response_t *http_msg_response, int http_status)
+da_ret_t __handle_http_status_code(http_info_t *http_info,
+ file_info_t *file_info, req_info_t *req_info)
{
- da_result_t ret = DA_RESULT_OK;
-
- int slot_id = DA_INVALID_ID;
- req_dl_info *request_info = DA_NULL;
+ da_ret_t ret = DA_RESULT_OK;
http_state_t http_state = 0;
+ http_msg_response_t *http_msg_response = DA_NULL;
+ char *location = DA_NULL;
+ char *if_range_str = DA_NULL;
+ char *range_str = DA_NULL;
+ int http_status = 0;
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- slot_id = GET_STAGE_DL_ID(stage);
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
-
- GET_STAGE_TRANSACTION_INFO(stage)->http_info.http_msg_response
- = http_msg_response;
-
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- DA_LOG_VERBOSE(HTTPManager, "http_state = %d", http_state);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- store_http_status(slot_id, http_status);
-
+ NULL_CHECK_RET(http_info);
+ NULL_CHECK_RET(file_info);
+ NULL_CHECK_RET(req_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("http_state[%s]", __get_state_str(http_state));
+ http_msg_response = http_info->http_msg_response;
+ NULL_CHECK_RET(http_msg_response);
+ http_status = http_msg_response->status_code;
switch (http_status) {
case 200:
case 201:
case 202:
case 203:
+// Although expecting 206, 200 response is received. Remove temporary file and reset file info
+ if (http_info->http_msg_request &&
+ http_msg_request_get_if_range(http_info->http_msg_request, &if_range_str) == DA_TRUE &&
+ http_msg_request_get_range(http_info->http_msg_request, &range_str) == DA_TRUE) {
+ DA_LOGI("Server do not support if-range option");
+ clean_paused_file(file_info);
+ }
+ free(if_range_str);
+ free(range_str);
if (http_state == HTTP_STATE_REQUEST_RESUME)
- clean_paused_file(stage);
- ret = set_hdr_fields_on_download_info(stage);
- if (ret != DA_RESULT_OK)
- goto ERR;
- ret = _check_content_type_is_matched(stage);
+ clean_paused_file(file_info);
+ ret = __check_content_type_is_matched(http_info);
if (ret != DA_RESULT_OK)
goto ERR;
- ret = _check_enough_memory_for_this_download(stage);
+ ret = __check_enough_memory(http_info, req_info->install_path);
if (ret != DA_RESULT_OK)
goto ERR;
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage); // ?
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_STARTED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
break;
case 206:
- DA_LOG(HTTPManager, "HTTP Status is %d - Partial download for resume!",http_status);
+ DA_LOGV("HTTP Status is %d - Partial download for resume!", http_status);
/* The resume can be started with start API.
* So the state should be not HTTP_STATE_RESUME_REQUESTED but HTTP_STATE_DOWNLOAD_REQUESTED*/
if (http_state == HTTP_STATE_DOWNLOAD_REQUESTED) {
- ret = _check_resume_download_is_available(stage,
- http_msg_response);
+ ret = __check_resume_download_is_available(req_info, http_info, file_info);
if (ret != DA_RESULT_OK)
goto ERR;
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOAD_STARTED,stage);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_STARTED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
} else if (http_state == HTTP_STATE_REQUEST_RESUME) {
- ret = _check_this_partial_download_is_available(stage,
- http_msg_response);
- if (ret != DA_RESULT_OK)
- goto ERR;
- CHANGE_HTTP_STATE(HTTP_STATE_RESUMED,stage);
+ ///FIXME later : how get previous response header
+ ///ret = __check_this_partial_download_is_available(http_info,
+ /// previous_ http_msg_response);
+ //if (ret != DA_RESULT_OK)
+ //goto ERR;
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_RESUMED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
} else {
- DA_LOG_ERR(HTTPManager, "This download is not resumed, revoke");
+ DA_LOGE("This download is not resumed, revoke");
ret = DA_ERR_INVALID_STATE;
goto ERR;
}
- CHANGE_DOWNLOAD_STATE(DOWNLOAD_STATE_NEW_DOWNLOAD,stage);
break;
case 300:
@@ -1249,13 +991,17 @@ da_result_t handle_http_status_code(stage_info *stage,
case 305:
case 306:
case 307:
- DA_LOG(HTTPManager, "HTTP Status is %d - redirection!",http_status);
- ret = exchange_url_from_header_for_redirection(stage, http_msg_response);
- if (ret != DA_RESULT_OK)
- goto ERR;
- CHANGE_HTTP_STATE(HTTP_STATE_REDIRECTED,stage);
+ DA_LOGV("HTTP Status is %d - redirection!",http_status);
+ if (http_msg_response_get_location(http_msg_response, &location)) {
+ DA_SECURE_LOGD("location = %s\n", location);
+ http_info->location_url = location;
+ DA_LOGI("[TEST] location_url[%p]",http_info->location_url);
+ }
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_REDIRECTED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
http_msg_response_destroy(&http_msg_response);
- request_info->http_info.http_msg_response = DA_NULL;
+ http_info->http_msg_response = DA_NULL;
break;
case 100:
@@ -1263,7 +1009,9 @@ da_result_t handle_http_status_code(stage_info *stage,
case 102:
case 204:
case 304:
- DA_LOG(HTTPManager, "HTTP Status is %d - 204 means server got the request, but no content to reply back, 304 means not modified!",http_status);
+ DA_LOGV("HTTP Status is %d - 204 server got the request, \
+ but no content to reply back, \
+ 304 means not modified!", http_status);
ret = DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT;
break;
@@ -1271,9 +1019,9 @@ da_result_t handle_http_status_code(stage_info *stage,
case 503:
case 504:
default:
- GET_REQUEST_HTTP_RESULT(request_info)
- = DA_ERR_UNREACHABLE_SERVER;
- DA_LOG_CRITICAL(HTTPManager, "set internal error code : DA_ERR_UNREACHABLE_SERVER [%d]", DA_ERR_UNREACHABLE_SERVER);
+/// GET_REQUEST_HTTP_RESULT(request_info)
+/// = DA_ERR_UNREACHABLE_SERVER;
+ DA_LOGI("set internal error code : DA_ERR_UNREACHABLE_SERVER");
break;
}
@@ -1281,533 +1029,491 @@ ERR:
return ret;
}
-da_result_t exchange_url_from_header_for_redirection(stage_info *stage,
- http_msg_response_t *http_msg_response)
+da_ret_t __check_before_downloading(da_info_t *da_info, http_state_t state)
{
- da_result_t ret = DA_RESULT_OK;
- char *location = DA_NULL;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- if (http_msg_response_get_location(http_msg_response, &location)) {
- DA_SECURE_LOGD("location = %s\n", location);
- GET_REQUEST_HTTP_REQ_LOCATION(GET_STAGE_TRANSACTION_INFO(stage)) = location;
+ da_ret_t ret = DA_RESULT_OK;
+ http_info_t *http_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ DA_LOGD("state:%s",__get_state_str(state));
+ // resume case
+ if (req_info->temp_file_path && file_info->bytes_written_to_file > 0) {
+ ret = start_file_append(file_info);
+ } else if (state == HTTP_STATE_DOWNLOAD_STARTED) {
+ ret = start_file_writing(da_info);
+ } else {
+ DA_LOGE("Cannot enter here!");
+ ret = DA_ERR_INVALID_ARGUMENT;
+ goto ERR;
}
+ if (DA_RESULT_OK != ret)
+ goto ERR;
+
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOADING;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ ret = send_client_update_dl_info(da_info);
+ERR:
return ret;
}
-da_result_t handle_http_body(stage_info *stage, char *body, int body_len)
+da_ret_t __handle_event_http_header(http_raw_data_t *raw_data, da_info_t *da_info)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
http_state_t http_state = 0;
- int slot_id = DA_INVALID_ID;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- slot_id = GET_STAGE_DL_ID(stage);
-
- if (DA_RESULT_OK
- != GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage))) {
- DA_LOG_CRITICAL(HTTPManager, "ignore because internal error code is set with [%d]",
- GET_REQUEST_HTTP_RESULT(GET_STAGE_TRANSACTION_INFO(stage)));
- return ret;
- }
-
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
-
- if (http_state == HTTP_STATE_DOWNLOAD_STARTED) {
- // resume case
- if (GET_REQUEST_HTTP_USER_REQUEST_ETAG(GET_STAGE_TRANSACTION_INFO(stage)))
- ret = start_file_writing_append_with_new_download(stage);
- else
- ret = start_file_writing(stage);
- if (DA_RESULT_OK != ret)
- goto ERR;
-
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING, stage);
- send_client_update_dl_info(
- slot_id,
- GET_DL_ID(slot_id),
- GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_CONTENT_STORE_PURE_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage)),
- GET_CONTENT_STORE_EXTENSION(GET_STAGE_CONTENT_STORE_INFO(stage))
- );
- } else if (http_state == HTTP_STATE_RESUMED) {
- ret = start_file_writing_append(stage);
- if (DA_RESULT_OK != ret)
+ http_info_t *http_info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ req_info_t *req_info = DA_NULL;
+ http_msg_response_t *http_msg_response = DA_NULL;
+ da_size_t size = 0;
+ char *mime_type = DA_NULL;
+ char *etag = DA_NULL;
+ char *file_name = DA_NULL;
+
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ req_info = da_info->req_info;
+ NULL_CHECK_RET(req_info);
+ NULL_CHECK_RET(raw_data);
+
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGV("http_state[%s]", __get_state_str(http_state));
+ http_msg_response = http_info->http_msg_response;
+ switch (http_state) {
+ case HTTP_STATE_DOWNLOAD_REQUESTED:
+ case HTTP_STATE_REQUEST_PAUSE:
+ case HTTP_STATE_REQUEST_RESUME:
+ case HTTP_STATE_REDIRECTED:
+ http_msg_response_get_content_length(http_msg_response, &size);
+ http_info->content_len_from_header = size;
+ http_msg_response_get_content_type(http_msg_response, &mime_type);
+ http_info->content_type_from_header = mime_type;
+ if (mime_type)
+ file_info->mime_type = strdup(mime_type);
+ http_msg_response_get_ETag(http_msg_response, &etag);
+ http_info->etag_from_header = etag;
+ http_msg_response_get_content_disposition(
+ http_msg_response, DA_NULL, &file_name);
+ http_info->file_name_from_header = file_name;
+ ret = __handle_http_status_code(http_info, file_info, req_info);
+ if (ret != DA_RESULT_OK) {
+ DA_LOGE("Fail to handle http status code");
goto ERR;
+ }
+#ifdef _RAF_SUPPORT
+ char *val = NULL;
+ http_msg_response_get_RAF_mode(http_msg_response, &val);
+ if (!val) {
+ DA_LOGE("Fail to raf mode value from response header");
+ } else {
+ DA_LOGI("[RAF] val[%s:%s]", HTTP_FIELD_RAF_MODE, val);
+ if (strncmp(val, "yes", strlen("yes")) == 0) {
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_STARTED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ ret = __check_before_downloading(da_info, http_info->state);
+ if (ret != DA_RESULT_OK) {
+ free(val);
+ goto ERR;
+ }
+ http_info->is_raf_mode_confirmed = DA_TRUE;
+ ret = PI_http_set_file_name_to_curl(http_info->http_msg, file_info->file_path);
+ if (ret != DA_RESULT_OK) {
+ DA_LOGE("Fail to set file name to curl");
+ free(val);
+ goto ERR;
+ }
+ }
+ free(val);
+ }
+#endif
+ break;
+ case HTTP_STATE_REQUEST_CANCEL:
+ DA_LOGV("Cancel is in progress.. http_state[%s]",
+ __get_state_str(http_state));
+ break;
- CHANGE_HTTP_STATE(HTTP_STATE_DOWNLOADING,stage);
- send_client_update_dl_info(
- slot_id,
- GET_DL_ID(slot_id),
- GET_CONTENT_STORE_CONTENT_TYPE(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_CONTENT_STORE_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_CONTENT_STORE_ACTUAL_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_CONTENT_STORE_PURE_FILE_NAME(GET_STAGE_CONTENT_STORE_INFO(stage)),
- GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage)),
- GET_CONTENT_STORE_EXTENSION(GET_STAGE_CONTENT_STORE_INFO(stage))
- );
+ default:
+ DA_LOGE("http_state[%s]", __get_state_str(http_state));
+ goto ERR;
}
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- http_state = GET_HTTP_STATE_ON_STAGE(stage);
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
+ERR:
+ if (ret != DA_RESULT_OK) {
+ DA_LOGE("Request to cancel due to error[%d]", ret);
+ PI_http_cancel(http_info);
+ http_info->error_code = ret;
+ discard_download(file_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_FAILED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ }
+ free(raw_data);
+ return ret;
+}
+
+da_ret_t __handle_event_http_packet(http_raw_data_t *raw_data, da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_state_t http_state = 0;
+ http_info_t *http_info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
+ time_t t;
+ struct tm *lc_time;
+ DA_LOGV("");
+
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ NULL_CHECK_RET(raw_data);
+
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
switch (http_state) {
+ case HTTP_STATE_DOWNLOAD_STARTED:
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_FALSE) {
+#endif
+ ret = __check_before_downloading(da_info, http_state);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ ret = file_write_ongoing(file_info,
+ raw_data->body, raw_data->body_len);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+#ifdef _RAF_SUPPORT
+ } else {
+ file_info->bytes_written_to_file =
+ raw_data->received_len + file_info->file_size_of_temp_file;
+ file_info->is_updated = DA_TRUE;
+ }
+#endif
+ ret = send_client_update_progress_info(da_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = HTTP_STATE_DOWNLOADING;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ break;
+ case HTTP_STATE_RESUMED:
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_FALSE) {
+#endif
+ __check_before_downloading(da_info, http_state);
+ ret = file_write_ongoing(file_info,
+ raw_data->body, raw_data->body_len);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+#ifdef _RAF_SUPPORT
+ } else {
+ file_info->bytes_written_to_file =
+ raw_data->received_len + file_info->file_size_of_temp_file;
+ file_info->is_updated = DA_TRUE;
+ }
+#endif
+ ret = send_client_update_progress_info(da_info);
+ break;
case HTTP_STATE_REDIRECTED:
- DA_LOG(HTTPManager, "Just ignore http body, because this body is not for redirection one.");
+ DA_LOGV("http_state[%s]", __get_state_str(http_state));
break;
-
case HTTP_STATE_DOWNLOADING:
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_FALSE) {
+#endif
/* Should this function before updating download info
* Because it extract mime type at once only if first download updating at client */
- ret = file_write_ongoing(stage, body, body_len);
+ ret = file_write_ongoing(file_info,
+ raw_data->body, raw_data->body_len);
if (ret != DA_RESULT_OK)
goto ERR;
- if ((DA_TRUE ==
- IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage)))) {
-
- IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(GET_STAGE_CONTENT_STORE_INFO(stage))
- = DA_FALSE;
- send_client_update_progress_info(
- slot_id,
- GET_DL_ID(slot_id),
- GET_CONTENT_STORE_CURRENT_FILE_SIZE(GET_STAGE_CONTENT_STORE_INFO(stage))
- );
-
+#ifdef _RAF_SUPPORT
+ } else {
+ file_info->bytes_written_to_file =
+ raw_data->received_len + file_info->file_size_of_temp_file;
+ file_info->is_updated = DA_TRUE;
+ }
+#endif
+ // send event every 1 second.
+ if ((t = time(DA_NULL)) > 0) {
+ if ((lc_time = localtime(&t)) != DA_NULL) {
+ if (da_info->update_time != lc_time->tm_sec) {
+ da_info->update_time = lc_time->tm_sec;
+ ret = send_client_update_progress_info(da_info);
+ }
+ } else {
+ DA_LOGE("Fail to call localtime[%s]",strerror(errno));
+ ret = send_client_update_progress_info(da_info);
+ }
+ } else {
+ DA_LOGE("Fail to call time[%s]",strerror(errno));
+ ret = send_client_update_progress_info(da_info);
}
break;
-
case HTTP_STATE_REQUEST_PAUSE:
- ret = file_write_ongoing(stage, body, body_len);
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_FALSE) {
+#endif
+ DA_LOGV("http_state[%s]", __get_state_str(http_state));
+ ret = file_write_ongoing(file_info,
+ raw_data->body, raw_data->body_len);
if (ret != DA_RESULT_OK)
goto ERR;
- break;
+#ifdef _RAF_SUPPORT
+ } else {
+ file_info->bytes_written_to_file =
+ raw_data->received_len + file_info->file_size_of_temp_file;
+ file_info->is_updated = DA_TRUE;
+ }
+#endif
+ break;
default:
- DA_LOG(HTTPManager, "Do nothing! http_state is in case %d", http_state);
-
+ DA_LOGE("Do nothing! http_state is in case[%s]",
+ __get_state_str(http_state));
goto ERR;
}
-
-ERR:
- return ret;
-}
-
-/* Function should be renamed , as it is actually not setting the header fields in download info */
-da_result_t set_hdr_fields_on_download_info(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t b_ret = DA_FALSE;
-
- req_dl_info *request_info = DA_NULL;
- http_msg_response_t *http_msg_response = NULL;
-
- char *value = NULL;
- unsigned long long size = 0;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
-
- http_msg_response
- = request_info->http_info.http_msg_response;
- if (!http_msg_response) {
- DA_LOG_ERR(HTTPManager, "There is no header data!!");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- b_ret = http_msg_response_get_content_type(http_msg_response, &value);
- if (b_ret) {
- GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
- value = NULL;
-// DA_SECURE_LOGD("[Content-Type][%s] - stored", GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info));
- }
-
- b_ret = http_msg_response_get_content_length(http_msg_response,
- &size);
- if (b_ret) {
- GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = size;
- size = 0;
- }
-
- b_ret = http_msg_response_get_ETag(http_msg_response, &value);
- if (b_ret) {
- GET_REQUEST_HTTP_HDR_ETAG(request_info) = value;
- value = NULL;
- DA_SECURE_LOGD("[ETag][%s] - stored ", GET_REQUEST_HTTP_HDR_ETAG(request_info));
- }
-
ERR:
+ if (ret != DA_RESULT_OK) {
+ DA_LOGE("Request to cancel due to error[%d]", ret);
+ PI_http_cancel(http_info);
+ http_info->error_code = ret;
+ discard_download(da_info->file_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_FAILED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ }
+ if (raw_data->body)
+ free(raw_data->body);
+ free(raw_data);
return ret;
}
-da_result_t _check_content_type_is_matched(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- req_dl_info *request_info = DA_NULL;
- source_info_t *source_info = DA_NULL;
- char *content_type_from_server = DA_NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
- source_info = GET_STAGE_SOURCE_INFO(stage);
-
- content_type_from_server = GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info);
- if (content_type_from_server == DA_NULL) {
- DA_LOG(HTTPManager, "http header has no Content-Type field, no need to compare");
- return DA_RESULT_OK;
- }
-
- return ret;
-}
-
-da_result_t _check_enough_memory_for_this_download(stage_info *stage)
+da_ret_t __check_file_size_with_header_content_size(file_info_t *file_info)
{
- da_result_t ret = DA_RESULT_OK;
-
- req_dl_info *request_info = DA_NULL;
-
- unsigned long long cont_len = 0;
- da_storage_size_t memory;
+ da_ret_t ret = DA_RESULT_OK;
+ unsigned long long tmp_file_size = 0;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
- memset(&memory, 0x00, sizeof(da_storage_size_t));
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
+ if (file_info->file_size > 0) {
- cont_len = (unsigned long long) GET_REQUEST_HTTP_HDR_CONT_LEN(request_info);
- if (cont_len) {
- ret = get_available_memory(&memory);
- if (DA_RESULT_OK == ret) {
- DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
- memory.b_available,memory.b_size, cont_len);
- if (memory.b_available < ((cont_len
- + (unsigned long long)SAVE_FILE_BUFFERING_SIZE_50KB)
- / (unsigned long long)memory.b_size)) /* 50KB buffering */
- {
- ret = DA_ERR_DISK_FULL;
- goto ERR;
- }
+#ifdef _ENABLE_OMA_DRM
+ if (is_content_drm_dm(file_info->mime_type)) {
+ /* FIXME Later : How can get the file size of DRM file. */
+ return ret;
}
- }
-
-ERR:
- return ret;
-}
-
-da_result_t _check_this_partial_download_is_available(stage_info *stage,
- http_msg_response_t *new_http_msg_response)
-{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t b_ret = DA_FALSE;
- char *origin_ETag = NULL;
- char *new_ETag = NULL;
- unsigned long long remained_content_len = 0;
- da_storage_size_t memory;
- char *value = NULL;
- unsigned long long size = 0;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- origin_ETag
- = GET_REQUEST_HTTP_HDR_ETAG(GET_STAGE_TRANSACTION_INFO(stage));
-
- b_ret = http_msg_response_get_content_length(new_http_msg_response,
- &size);
- if (b_ret) {
- remained_content_len = size;
- size = 0;
- DA_LOG(HTTPManager, "[remained_content_len][%lu]", remained_content_len);
- }
-
- b_ret = http_msg_response_get_ETag(new_http_msg_response, &value);
- if (b_ret) {
- new_ETag = value;
- value = NULL;
- DA_SECURE_LOGD("[new ETag][%s]", new_ETag);
- } else {
- goto ERR;
- }
+#endif
- if (origin_ETag && new_ETag &&
- 0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) {
- DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!");
- /* FIXME Later : Need to detail error exception handling */
- ret = DA_ERR_NETWORK_FAIL;
- /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
- goto ERR;
- }
+ get_file_size(file_info->file_path, &tmp_file_size);
- if (remained_content_len) {
- ret = get_available_memory(&memory);
- if (DA_RESULT_OK == ret) {
- DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
- memory.b_available,memory.b_size, remained_content_len);
- if (memory.b_available < ((remained_content_len
- + SAVE_FILE_BUFFERING_SIZE_50KB)
- / memory.b_size)) /* 50KB buffering */
- {
- ret = DA_ERR_DISK_FULL;
- goto ERR;
- }
+ if (tmp_file_size != file_info->file_size) {
+ DA_SECURE_LOGE("Real file size[%llu], MISMATCH CONTENT SIZE",
+ tmp_file_size);
+ ret = DA_ERR_MISMATCH_CONTENT_SIZE;
}
}
-
-ERR:
- if (new_ETag) {
- free(new_ETag);
- new_ETag = DA_NULL;
- }
-
return ret;
}
-da_result_t _check_resume_download_is_available(stage_info *stage,
- http_msg_response_t *new_http_msg_response)
+da_ret_t __handle_event_http_final(http_raw_data_t *raw_data, da_info_t *da_info)
{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t b_ret = DA_FALSE;
- char *origin_ETag = NULL;
- char *new_ETag = NULL;
- unsigned long long remained_content_len = 0;
- da_storage_size_t memory;
- char *value = NULL;
- unsigned long long size = 0;
- char *temp_file_path = DA_NULL;
- req_dl_info *request_info = DA_NULL;
+ da_ret_t ret = DA_RESULT_OK;
+ http_state_t http_state = 0;
+ http_info_t *http_info = DA_NULL;
+ file_info_t *file_info = DA_NULL;
- DA_LOG_FUNC_LOGD(HTTPManager);
+ DA_LOGV("");
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
- origin_ETag
- = GET_REQUEST_HTTP_USER_REQUEST_ETAG(request_info);
+ NULL_CHECK_RET(da_info);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET(http_info);
+ file_info = da_info->file_info;
+ NULL_CHECK_RET(file_info);
+ NULL_CHECK_RET(raw_data);
- b_ret = http_msg_response_get_content_length(new_http_msg_response,
- &size);
- if (b_ret) {
- remained_content_len = size;
- size = 0;
- DA_LOG(HTTPManager, "[remained_content_len][%lu]", remained_content_len);
- }
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGD("http_state[%s]", __get_state_str(http_state));
- b_ret = http_msg_response_get_ETag(new_http_msg_response, &value);
- if (b_ret) {
- new_ETag = value;
- value = NULL;
- DA_SECURE_LOGD("[new ETag][%s]", new_ETag);
- } else {
- goto ERR;
- }
-
- if (origin_ETag && new_ETag &&
- 0 != strncmp(origin_ETag, new_ETag, strlen(new_ETag))) {
- DA_LOG_ERR(HTTPManager, "ETag is not identical! revoke!");
- /* FIXME Later : Need to detail error exception handling */
- ret = DA_ERR_NETWORK_FAIL;
- /*ret = DA_ERR_MISMATCH_HTTP_HEADER; */
- goto ERR;
- }
-
- if (remained_content_len) {
- ret = get_available_memory(&memory);
- if (DA_RESULT_OK == ret) {
- DA_LOG(HTTPManager, "Memory avail: %lu, Memory block :%lu Content: %llu",
- memory.b_available,memory.b_size, remained_content_len);
- if (memory.b_available < ((remained_content_len
- + SAVE_FILE_BUFFERING_SIZE_50KB)
- / memory.b_size)) /* 50KB buffering */
- {
- ret = DA_ERR_DISK_FULL;
- goto ERR;
- }
+ switch (http_state) {
+ case HTTP_STATE_REDIRECTED:
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_READY_TO_DOWNLOAD;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ break;
+ case HTTP_STATE_DOWNLOAD_REQUESTED:
+ DA_LOGV("case HTTP_STATE_DOWNLOAD_REQUESTED");
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_FINISH;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ break;
+ case HTTP_STATE_DOWNLOADING:
+ DA_LOGD("case HTTP_STATE_DOWNLOADING");
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_TRUE) {
+ ret = file_write_complete_for_raf(file_info);
+ } else {
+ ret = file_write_complete(file_info);
}
- }
- b_ret = http_msg_response_get_content_type(new_http_msg_response, &value);
- if (b_ret) {
- GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info) = value;
- value = NULL;
- DA_SECURE_LOGD("[Content-Type][%s]",
- GET_REQUEST_HTTP_HDR_CONT_TYPE(request_info));
- }
- temp_file_path = GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(request_info);
- get_file_size(temp_file_path, &size);
- GET_REQUEST_HTTP_HDR_CONT_LEN(request_info) = remained_content_len + size;
- DA_SECURE_LOGD("[Content-Length][%llu]",
- GET_REQUEST_HTTP_HDR_CONT_LEN(request_info));
-
-
-ERR:
- if (new_ETag) {
- free(new_ETag);
- new_ETag = DA_NULL;
- }
-
- return ret;
-}
-
-
-da_result_t _check_downloaded_file_size_is_same_with_header_content_size(
- stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
-
- req_dl_info *request_info = DA_NULL;
- file_info *file_info_data = DA_NULL;
-
- char *real_file_path = DA_NULL;
- unsigned long long content_size_from_real_file = 0;
- unsigned long long content_size_from_http_header = 0;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- request_info = GET_STAGE_TRANSACTION_INFO(stage);
- file_info_data = GET_STAGE_CONTENT_STORE_INFO(stage);
-
- content_size_from_http_header
- = GET_CONTENT_STORE_FILE_SIZE(file_info_data);
-
- if (content_size_from_http_header > 0) {
- real_file_path
- = GET_CONTENT_STORE_ACTUAL_FILE_NAME(file_info_data);
-
- get_file_size(real_file_path,
- &content_size_from_real_file);
-
- if (content_size_from_real_file
- != content_size_from_http_header) {
- DA_SECURE_LOGE("size from header = %llu, real size = %llu,\
- DA_ERR_MISMATCH_CONTENT_SIZE",
- content_size_from_http_header, content_size_from_real_file);
- ret = DA_ERR_MISMATCH_CONTENT_SIZE;
+#else
+ ret = file_write_complete(file_info);
+#endif
+ if (ret != DA_RESULT_OK) {
+ discard_download(file_info);
+ goto ERR;
+ }
+ ret = __check_file_size_with_header_content_size(file_info);
+ if(ret != DA_RESULT_OK) {
+ discard_download(file_info) ;
+ goto ERR;
+ }
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_FINISH;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ ret = send_client_update_progress_info(da_info);
+ break;
+ case HTTP_STATE_REQUEST_PAUSE:
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_TRUE) {
+ if (file_info->file_handle)
+ ret = file_write_complete_for_raf(file_info);
+ } else {
+ ret = file_write_complete(file_info);
+ }
+#else
+ if (file_info->file_handle) {
+ ret = file_write_complete(file_info);
+// send_client_update_progress_info(da_info);
+ }
+#endif
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_PAUSED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ DA_LOGV("Server Notification code is set to NULL");
+ break;
+ case HTTP_STATE_ABORTED:
+ case HTTP_STATE_CANCELED:
+ discard_download(file_info);
+ break;
+ case HTTP_STATE_REQUEST_CANCEL:
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_TRUE) {
+ ret = file_write_complete_for_raf(file_info);
+ } else {
+ ret = file_write_complete(file_info);
+ }
+#else
+ ret = file_write_complete(file_info);
+#endif
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ discard_download(file_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_CANCELED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ break;
+ case HTTP_STATE_PAUSED:
+ DA_LOGD("Remain paused stated");
+ break;
+ default:
+#ifdef _RAF_SUPPORT
+ if (http_info->is_raf_mode_confirmed == DA_TRUE) {
+ ret = file_write_complete_for_raf(file_info);
+ } else {
+ ret = file_write_complete(file_info);
}
+#else
+ ret = file_write_complete(file_info);
+#endif
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ discard_download(file_info);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_FAILED;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ break;
}
- return ret;
-}
-
-da_result_t _disconnect_transaction(stage_info *stage)
-{
- da_result_t ret = DA_RESULT_OK;
- int transaction_id = DA_INVALID_ID;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- transaction_id
- = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
-
- DA_LOG(HTTPManager, "transaction_id = %d slot_id = %d", transaction_id, GET_STAGE_DL_ID(stage));
-
- if (transaction_id != DA_INVALID_ID) {
- ret = PI_http_disconnect_transaction(transaction_id);
- GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage))
- = DA_INVALID_ID;
+ERR:
+ /* When file complete is failed */
+ if (DA_RESULT_OK != ret) {
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_info->state = HTTP_STATE_DOWNLOAD_FINISH;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
}
-
+ if (raw_data->body)
+ free(raw_data->body);
+ free(raw_data);
return ret;
}
-da_result_t _cancel_transaction(stage_info *stage)
+void __http_update_cb(http_raw_data_t *data, void *user_param)
{
- da_result_t ret = DA_RESULT_OK;
- int transaction_id = DA_INVALID_ID;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- transaction_id
- = GET_REQUEST_HTTP_TRANS_ID(GET_STAGE_TRANSACTION_INFO(stage));
-
- DA_LOG(HTTPManager, "transaction_id = %d", transaction_id);
-
- if (transaction_id != DA_INVALID_ID) {
- http_state_t state = 0;
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- state = GET_HTTP_STATE_ON_STAGE(stage);
- if (state <= HTTP_STATE_DOWNLOAD_REQUESTED) {
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- ret = PI_http_cancel_transaction(transaction_id, DA_TRUE);
- } else {
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(stage)));
- ret = PI_http_cancel_transaction(transaction_id, DA_FALSE);
- }
-
+ http_raw_data_t *raw_data = DA_NULL;
+ da_info_t *da_info = DA_NULL;
+ if (!data || !user_param) {
+ DA_LOGE("NULL CHECK!: data, user_param");
+ return;
+ }
+ DA_LOGV("");
+ raw_data = data;
+ da_info = (da_info_t *)user_param;
+
+ switch(data->type) {
+ case HTTP_EVENT_GOT_HEADER:
+ __handle_event_http_header(raw_data, da_info);
+ break;
+ case HTTP_EVENT_GOT_PACKET:
+ __handle_event_http_packet(raw_data, da_info);
+ break;
+ case HTTP_EVENT_FINAL:
+ __handle_event_http_final(raw_data, da_info);
+ break;
+/*
+ case HTTP_EVENT_ABORT:
+ ret = __handle_event_http_abort(raw_data, da_info);
+ break;
+*/
}
- return ret;
}
-void __parsing_user_request_header(char *user_request_header,
- char **out_field, char **out_value)
+da_bool_t is_stopped_state(da_info_t *da_info)
{
- int len = 0;
- char *pos = NULL;
- char *temp_pos = NULL;
- char *field = NULL;
- char *value = NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!user_request_header) {
- DA_LOG_ERR(HTTPManager, "user_request_header is NULL");
- goto ERR;
- }
-
- pos = strchr(user_request_header, ':');
- if (!pos) {
- DA_LOG_ERR(HTTPManager, "Fail to parse");
- goto ERR;
- }
- temp_pos = (char *)user_request_header;
- while (*temp_pos)
- {
- if (temp_pos == pos || *temp_pos == ' ') {
- len = temp_pos - user_request_header;
- break;
- }
- temp_pos++;
- }
- if (len < 1) {
- DA_LOG_ERR(HTTPManager, "Wrong field name");
- goto ERR;
- }
- field = (char *)calloc(1, len + 1);
- if (!field) {
- DA_LOG_ERR(HTTPManager, "Fail to calloc");
- goto ERR;
- }
- strncpy(field, user_request_header, len);
- pos++;
- while (*pos)
- {
- if (*pos != ' ')
- break;
- pos++;
- }
- len = strlen(pos) + 1;
- value = (char *)calloc(1, len + 1);
- if (!value) {
- DA_LOG_ERR(HTTPManager, "Fail to calloc");
- goto ERR;
- }
- strncpy(value, pos, len);
- *out_field = field;
- *out_value = value;
- DA_SECURE_LOGD("field[%s], value[%s]", field, value);
-
- return;
-ERR:
- if (field) {
- free(field);
- field = NULL;
+ http_info_t *http_info = DA_NULL;
+ http_state_t http_state;
+ NULL_CHECK_RET_OPT(da_info, DA_FALSE);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET_OPT(http_info, DA_FALSE);
+ DA_MUTEX_LOCK(&(http_info->mutex_state));
+ http_state = http_info->state;
+ DA_MUTEX_UNLOCK(&(http_info->mutex_state));
+ switch (http_state) {
+ case HTTP_STATE_REQUEST_CANCEL:
+ case HTTP_STATE_CANCELED:
+ case HTTP_STATE_FAILED:
+ case HTTP_STATE_ABORTED:
+ //case HTTP_STATE_REQUEST_PAUSE:
+ //case HTTP_STATE_REQUEST_RESUME:
+ //case HTTP_STATE_WAIT_FOR_NET_ERR:
+ return DA_TRUE;
+ default:
+ return DA_FALSE;
}
- return;
+ return DA_FALSE;
}
-
diff --git a/agent/download-agent-http-misc.c b/agent/download-agent-http-misc.c
deleted file mode 100755
index 08cd8ec..0000000
--- a/agent/download-agent-http-misc.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "download-agent-http-misc.h"
-#include "download-agent-debug.h"
-#include "download-agent-dl-mgr.h"
-#include "download-agent-plugin-conf.h"
-#include "download-agent-client-mgr.h"
-
-#define DEFAULT_HTTP_ACCEPT_HEADERS \
- "Accept-Language: en\r\n" \
- "Accept-Charset: utf-8\r\n" \
-
-
-char *get_user_agent()
-{
- char *uagent_str = DA_NULL;
-
- DA_LOG_FUNC_LOGV(Default);
-
- uagent_str = get_client_user_agent_string();
- if (!uagent_str) {
- da_result_t ret = DA_RESULT_OK;
- ret = get_user_agent_string(&uagent_str);
- if (ret != DA_RESULT_OK)
- return NULL;
- }
- return uagent_str;
-}
-
-da_bool_t is_supporting_protocol(const char *protocol)
-{
- if((protocol == NULL) || (1 > strlen(protocol)))
- {
- return DA_FALSE;
- }
-
- if(!strcasecmp(protocol, "http"))
- {
- return DA_TRUE;
- }
- else if(!strcasecmp(protocol, "https"))
- {
- return DA_TRUE;
- }
- else
- {
- return DA_FALSE;
- }
-
-}
diff --git a/agent/download-agent-http-msg-handler.c b/agent/download-agent-http-msg-handler.c
index 6064c37..231a61d 100755
--- a/agent/download-agent-http-msg-handler.c
+++ b/agent/download-agent-http-msg-handler.c
@@ -20,20 +20,19 @@
#include "download-agent-http-msg-handler.h"
#include "download-agent-debug.h"
-#include "download-agent-http-misc.h"
#include "download-agent-encoding.h"
// '.' and ';' are request from Vodafone
-#define IS_TERMINATING_CHAR(c) ( ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
-#define IS_TERMINATING_CHAR_EX(c) ( ((c) == '"') || ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
-#define IS_URI_TERMINATING_CHAR(c) ( ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
+#define IS_TERMINATING_CHAR(c) ( ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
+#define IS_TERMINATING_CHAR_EX(c) ( ((c) == '"') || ((c) == ';') || ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
+#define IS_URI_TERMINATING_CHAR(c) ( ((c) == '\0') || ((c) == 0x0d) || ((c) == 0x0a) || ((c) == 0x20) )
enum parsing_type {
WITH_PARSING_OPTION,
WITHOUT_PARSING_OPTION
};
-static da_result_t __http_header_add_field(http_header_t **head,
+static da_ret_t __http_header_add_field(http_header_t **head,
const char *field, const char *value, enum parsing_type type);
static void __http_header_destroy_all_field(http_header_t **head);
static da_bool_t __get_http_header_for_field(
@@ -41,29 +40,27 @@ static da_bool_t __get_http_header_for_field(
http_header_t **out_header);
static void __exchange_header_value(http_header_t *header,
const char *in_raw_value);
-
static http_header_options_t *__create_http_header_option(const char *field,
const char *value);
static void __http_header_destroy_all_option(http_header_options_t **head);
static da_bool_t __get_http_header_option_for_field(
http_header_options_t *header_option, const char *in_field,
char **out_value);
-
static http_header_options_t *__parsing_N_create_option_str(char *org_str);
static http_header_options_t *__parsing_options(char *org_str);
static void __parsing_raw_value(http_header_t *http_header);
-da_result_t http_msg_request_create(http_msg_request_t **http_msg_request)
+da_ret_t http_msg_request_create(http_msg_request_t **http_msg_request)
{
http_msg_request_t *temp_http_msg_request = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+// DA_LOGV("");
temp_http_msg_request = (http_msg_request_t *)calloc(1,
sizeof(http_msg_request_t));
if (!temp_http_msg_request) {
*http_msg_request = NULL;
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
return DA_ERR_FAIL_TO_MEMALLOC;
}
@@ -73,7 +70,7 @@ da_result_t http_msg_request_create(http_msg_request_t **http_msg_request)
temp_http_msg_request->http_body = NULL;
*http_msg_request = temp_http_msg_request;
- DA_LOG_DEBUG(HTTPManager, "http_msg_request: %x", (unsigned int)(*http_msg_request));
+ DA_LOGV( "http_msg_request: %x", (unsigned int)(*http_msg_request));
return DA_RESULT_OK;
}
@@ -82,99 +79,54 @@ void http_msg_request_destroy(http_msg_request_t **http_msg_request)
{
http_msg_request_t *temp_http_msg_request = *http_msg_request;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (temp_http_msg_request) {
if (temp_http_msg_request->http_method) {
free(temp_http_msg_request->http_method);
temp_http_msg_request->http_method = NULL;
}
-
if (temp_http_msg_request->url) {
free(temp_http_msg_request->url);
temp_http_msg_request->url = NULL;
}
-
if (temp_http_msg_request->http_body) {
free(temp_http_msg_request->http_body);
temp_http_msg_request->http_body = NULL;
}
-
__http_header_destroy_all_field(&(temp_http_msg_request->head));
-
free(temp_http_msg_request);
*http_msg_request = NULL;
}
-
-}
-
-da_result_t http_msg_request_set_method(http_msg_request_t *http_msg_request,
- const char *method)
-{
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- if (!http_msg_request || !method) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- // ToDo: check method is valid
-
- http_msg_request->http_method = strdup(method);
-
- DA_LOG(HTTPManager, "http method : %s", http_msg_request->http_method);
-
- return DA_RESULT_OK;
-}
-
-da_result_t http_msg_request_get_method(http_msg_request_t *http_msg_request,
- const char **method)
-{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!http_msg_request) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- if (http_msg_request->http_method) {
- *method = http_msg_request->http_method;
- return DA_RESULT_OK;
- } else {
- *method = DA_NULL;
- return DA_ERR_INVALID_ARGUMENT;
- }
}
-da_result_t http_msg_request_set_url(http_msg_request_t *http_msg_request,
+da_ret_t http_msg_request_set_url(http_msg_request_t *http_msg_request,
const char *url)
{
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (!http_msg_request) {
- DA_LOG_ERR(HTTPManager, "http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT");
return DA_ERR_INVALID_ARGUMENT;
}
if (!url) {
- DA_LOG_ERR(HTTPManager, "url is NULL; DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("url is NULL; DA_ERR_INVALID_ARGUMENT");
return DA_ERR_INVALID_URL;
}
http_msg_request->url = strdup(url);
-
- //DA_SECURE_LOGD("http url : %s", http_msg_request->url);
-
+ DA_SECURE_LOGI("http url[%s]", http_msg_request->url);
return DA_RESULT_OK;
}
-da_result_t http_msg_request_get_url(http_msg_request_t *http_msg_request,
+da_ret_t http_msg_request_get_url(http_msg_request_t *http_msg_request,
const char **url)
{
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (!http_msg_request) {
- DA_LOG_ERR(HTTPManager, "http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("http_msg_request is NULL; DA_ERR_INVALID_ARGUMENT");
return DA_ERR_INVALID_ARGUMENT;
}
@@ -187,76 +139,34 @@ da_result_t http_msg_request_get_url(http_msg_request_t *http_msg_request,
}
}
-da_result_t http_msg_request_set_body(http_msg_request_t *http_msg_request,
- const char *body)
-{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!http_msg_request) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- if (!body)
- return DA_RESULT_OK;
-
- http_msg_request->http_body = strdup(body);
-
- DA_SECURE_LOGD("http body : %s", http_msg_request->http_body);
-
- return DA_RESULT_OK;
-}
-
-da_result_t http_msg_request_get_body(http_msg_request_t *http_msg_request,
- const char **body)
-{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!http_msg_request) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- if (http_msg_request->http_body) {
- *body = http_msg_request->http_body;
- return DA_RESULT_OK;
- } else {
- *body = DA_NULL;
- return DA_ERR_INVALID_ARGUMENT;
- }
-}
-
-/* FIXME later : check to free filed and value after this API is called */
-da_result_t http_msg_request_add_field(http_msg_request_t *http_msg_request,
+da_ret_t http_msg_request_add_field(http_msg_request_t *http_msg_request,
const char *field, const char *value)
{
- DA_LOG_FUNC_LOGV(HTTPManager);
+ // DA_LOGV("");
if (!http_msg_request) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("Check NULL! : http_msg_request");
return DA_ERR_INVALID_ARGUMENT;
}
return __http_header_add_field(&(http_msg_request->head), field, value, WITHOUT_PARSING_OPTION);
}
-da_result_t http_msg_response_create(http_msg_response_t **http_msg_response)
+da_ret_t http_msg_response_create(http_msg_response_t **http_msg_response)
{
http_msg_response_t *temp_http_msg_response = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
temp_http_msg_response = (http_msg_response_t *)calloc(1,
sizeof(http_msg_response_t));
if (!temp_http_msg_response) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
return DA_ERR_FAIL_TO_MEMALLOC;
} else {
temp_http_msg_response->status_code = 0;
temp_http_msg_response->head = NULL;
-
*http_msg_response = temp_http_msg_response;
-
return DA_RESULT_OK;
}
}
@@ -265,59 +175,27 @@ void http_msg_response_destroy(http_msg_response_t **http_msg_response)
{
http_msg_response_t *temp_http_msg_response = *http_msg_response;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (temp_http_msg_response) {
__http_header_destroy_all_field(&(temp_http_msg_response->head));
-
free(temp_http_msg_response);
*http_msg_response = DA_NULL;
}
}
-da_result_t http_msg_response_set_status_code(
- http_msg_response_t *http_msg_response, int status_code)
-{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!http_msg_response) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- http_msg_response->status_code = status_code;
-
- return DA_RESULT_OK;
-}
-
-da_result_t http_msg_response_get_status_code(
- http_msg_response_t *http_msg_response, int *status_code)
-{
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- if (!http_msg_response) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- *status_code = http_msg_response->status_code;
-
- return DA_RESULT_OK;
-}
-
-da_result_t http_msg_response_add_field(http_msg_response_t *http_msg_response,
+da_ret_t http_msg_response_add_field(http_msg_response_t *http_msg_response,
const char *field, const char *value)
{
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (!http_msg_response) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("DA_ERR_INVALID_ARGUMENT");
return DA_ERR_INVALID_ARGUMENT;
}
-
return __http_header_add_field(&(http_msg_response->head), field, value, WITH_PARSING_OPTION);
}
-da_result_t __http_header_add_field(http_header_t **head,
+da_ret_t __http_header_add_field(http_header_t **head,
const char *field, const char *value, enum parsing_type type)
{
http_header_t *pre = NULL;
@@ -365,7 +243,7 @@ da_result_t __http_header_add_field(http_header_t **head,
else
*head = cur;
} else {
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
return DA_ERR_FAIL_TO_MEMALLOC;
}
@@ -377,8 +255,6 @@ void __http_header_destroy_all_field(http_header_t **head)
http_header_t *pre = NULL;
http_header_t *cur = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
-
cur = *head;
while (cur) {
@@ -386,25 +262,21 @@ void __http_header_destroy_all_field(http_header_t **head)
free(cur->field);
cur->field = DA_NULL;
}
-
if (cur->value) {
free(cur->value);
cur->value = DA_NULL;
}
-
if (cur->raw_value) {
free(cur->raw_value);
cur->raw_value = DA_NULL;
}
-
__http_header_destroy_all_option(&(cur->options));
-
+ free(cur->options);
+ cur->options = DA_NULL;
pre = cur;
cur = cur->next;
-
free(pre);
}
-
*head = DA_NULL;
}
@@ -418,13 +290,10 @@ http_header_options_t *__create_http_header_option(const char *field,
if (option) {
if (field)
option->field = strdup(field);
-
if (value)
option->value = strdup(value);
-
option->next = NULL;
}
-
return option;
}
@@ -433,38 +302,34 @@ void __http_header_destroy_all_option(http_header_options_t **head)
http_header_options_t *pre = NULL;
http_header_options_t *cur = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ // DA_LOGV("");
cur = *head;
while (cur) {
if (cur->field) {
- DA_LOG_VERBOSE("field= %s", cur->field);
+ DA_SECURE_LOGD("field= %s", cur->field);
free(cur->field);
cur->field = DA_NULL;
}
-
if (cur->value) {
free(cur->value);
cur->value = DA_NULL;
}
-
pre = cur;
cur = cur->next;
-
free(pre);
}
-
*head = DA_NULL;
}
-da_result_t http_msg_request_get_iter(http_msg_request_t *http_msg_request,
+da_ret_t http_msg_request_get_iter(http_msg_request_t *http_msg_request,
http_msg_iter_t *http_msg_iter)
{
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (!http_msg_request) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("DA_ERR_INVALID_ARGUMENT");
return DA_ERR_INVALID_ARGUMENT;
}
@@ -473,17 +338,15 @@ da_result_t http_msg_request_get_iter(http_msg_request_t *http_msg_request,
return DA_RESULT_OK;
}
-da_result_t http_msg_response_get_iter(http_msg_response_t *http_msg_response,
+da_ret_t http_msg_response_get_iter(http_msg_response_t *http_msg_response,
http_msg_iter_t *http_msg_iter)
{
if (!http_msg_response) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
+ DA_LOGE("DA_ERR_INVALID_ARGUMENT");
return DA_ERR_INVALID_ARGUMENT;
}
*http_msg_iter = http_msg_response->head;
- // DA_LOG_VERBOSE(HTTPManager, "retrieve iter = 0x%x", (unsigned int)http_msg_iter);
-
return DA_RESULT_OK;
}
@@ -492,16 +355,12 @@ da_bool_t http_msg_get_field_with_iter(http_msg_iter_t *http_msg_iter,
{
http_header_t *cur = *http_msg_iter;
- // DA_LOG_VERBOSE(HTTPManager, "getting iter = 0x%x", (unsigned int)cur);
-
if (cur) {
*out_field = cur->field;
*out_value = cur->value;
*http_msg_iter = cur->next;
-
return DA_TRUE;
} else {
- // DA_LOG_VERBOSE(HTTPManager, "end of iter");
return DA_FALSE;
}
}
@@ -511,16 +370,12 @@ da_bool_t http_msg_get_header_with_iter(http_msg_iter_t *http_msg_iter,
{
http_header_t *cur = *http_msg_iter;
- // DA_LOG_VERBOSE(HTTPManager, "getting iter = 0x%x", (unsigned int)cur);
-
if (cur) {
*out_field = cur->field;
*out_header = cur;
*http_msg_iter = cur->next;
-
return DA_TRUE;
} else {
- // DA_LOG_VERBOSE(HTTPManager, "end of iter");
return DA_FALSE;
}
}
@@ -531,21 +386,18 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str)
char *option_value = NULL;
int option_field_len = 0;
int option_value_len = 0;
-
char *org_pos = NULL;
int org_str_len = 0;
-
char *working_str = NULL;
char *working_pos = NULL;
char *working_pos_field_start = NULL;
char *working_pos_value_start = NULL;
-
da_bool_t is_inside_quotation = DA_FALSE;
da_bool_t is_working_for_field = DA_TRUE;
int i = 0;
http_header_options_t *option = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ // DA_LOGV("");
if (!org_str)
return NULL;
@@ -564,7 +416,6 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str)
for (i = 0; i < org_str_len; i++) {
if (*org_pos == '"')
is_inside_quotation = !is_inside_quotation;
-
if (is_inside_quotation) {
// Leave anything including blank if it is inside of double quotation mark.
*working_pos = *org_pos;
@@ -580,7 +431,6 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str)
is_working_for_field = DA_FALSE;
working_pos_value_start = working_pos;
}
-
org_pos++;
} else {
*working_pos = *org_pos;
@@ -598,21 +448,19 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str)
strncpy(option_field, working_pos_field_start,
option_field_len);
}
-
if (option_value_len > 0 && working_pos_value_start) {
option_value = (char *)calloc(1, option_value_len + 1);
if (option_value)
strncpy(option_value, working_pos_value_start,
option_value_len);
}
-
if (working_str) {
free(working_str);
working_pos = working_str = NULL;
}
-// DA_SECURE_LOGD("option_field = [%s], option_value = [%s]",
-// option_field, option_value);
+ DA_SECURE_LOGD("option_field = [%s], option_value = [%s]",
+ option_field, option_value);
if (option_field || option_value) {
option = __create_http_header_option(
@@ -621,7 +469,6 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str)
free(option_field);
option_field = NULL;
}
-
if (option_value) {
free(option_value);
option_value = NULL;
@@ -632,7 +479,7 @@ http_header_options_t *__parsing_N_create_option_str(char *org_str)
http_header_options_t *__parsing_options(char *org_str)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
http_header_options_t *head = NULL;
http_header_options_t *pre = NULL;
http_header_options_t *cur = NULL;
@@ -643,7 +490,7 @@ http_header_options_t *__parsing_options(char *org_str)
char *wanted_str_end = NULL;
char *cur_pos = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (!org_str)
return NULL;
@@ -662,11 +509,10 @@ http_header_options_t *__parsing_options(char *org_str)
wanted_str_end = org_str + strlen(org_str);
cur_pos = NULL;
}
-
wanted_str_len = wanted_str_end - wanted_str_start;
wanted_str = (char *)calloc(1, wanted_str_len + 1);
if (!wanted_str) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
ret = DA_ERR_FAIL_TO_MEMALLOC;
goto ERR;
}
@@ -688,7 +534,6 @@ http_header_options_t *__parsing_options(char *org_str)
ERR:
if (ret != DA_RESULT_OK)
__http_header_destroy_all_option(&head);
-
return head;
}
@@ -696,10 +541,8 @@ void __parsing_raw_value(http_header_t *http_header_field)
{
char *raw_value = NULL;
char *option_str_start = NULL;
-
char *trimed_value = NULL;
int trimed_value_len = 0;
-
char *trimed_value_start = NULL;
char *trimed_value_end = NULL;
@@ -710,7 +553,6 @@ void __parsing_raw_value(http_header_t *http_header_field)
return;
trimed_value_start = raw_value;
-
trimed_value_end = strchr(raw_value, ';');
if (!trimed_value_end) {
// No options
@@ -722,10 +564,9 @@ void __parsing_raw_value(http_header_t *http_header_field)
// for trimed value
trimed_value_len = trimed_value_end - trimed_value_start;
-
trimed_value = (char *)calloc(1, trimed_value_len + 1);
if (!trimed_value) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
return;
}
strncpy(trimed_value, trimed_value_start, trimed_value_len);
@@ -733,18 +574,15 @@ void __parsing_raw_value(http_header_t *http_header_field)
// for option parsing
option_str_start = trimed_value_end + 1;
-
http_header_field->options = __parsing_options(option_str_start);
/////////////// show
http_header_options_t *cur = NULL;
-
cur = http_header_field->options;
while (cur) {
// DA_SECURE_LOGD("field = [%s], value = [%s]", cur->field, cur->value);
cur = cur->next;
}
-
}
da_bool_t __get_http_header_option_for_field(
@@ -753,10 +591,10 @@ da_bool_t __get_http_header_option_for_field(
{
http_header_options_t *cur = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ // DA_LOGV("");
if (!header_option) {
- DA_LOG_ERR(HTTPManager, "input header_option is NULL.");
+ DA_LOGE("input header_option is NULL.");
return DA_FALSE;
}
@@ -773,7 +611,6 @@ da_bool_t __get_http_header_option_for_field(
}
cur = cur->next;
}
-
return DA_FALSE;
}
@@ -784,12 +621,33 @@ da_bool_t __get_http_header_for_field(http_msg_response_t *http_msg_response,
http_header_t *header = NULL;
char *field = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ //DA_LOGV("");
http_msg_response_get_iter(http_msg_response, &http_msg_iter);
while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) {
if (field && header && !strncasecmp(field, in_field, strlen(field))) {
-// DA_SECURE_LOGD("[%s][%s]", field, header->value);
+ //DA_SECURE_LOGD("[%s][%s]", field, header->value);
+ *out_header = header;
+ return DA_TRUE;
+ }
+ }
+
+ return DA_FALSE;
+}
+
+da_bool_t __get_http_req_header_for_field(http_msg_request_t *http_msg_request,
+ const char *in_field, http_header_t **out_header)
+{
+ http_msg_iter_t http_msg_iter;
+ http_header_t *header = NULL;
+ char *field = NULL;
+
+ //DA_LOGV("");
+
+ http_msg_request_get_iter(http_msg_request, &http_msg_iter);
+ while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) {
+ if (field && header && !strncasecmp(field, in_field, strlen(field))) {
+ //DA_SECURE_LOGD("[%s][%s]", field, header->value);
*out_header = header;
return DA_TRUE;
}
@@ -800,7 +658,7 @@ da_bool_t __get_http_header_for_field(http_msg_response_t *http_msg_response,
void __exchange_header_value(http_header_t *header, const char *in_raw_value)
{
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (!header || !in_raw_value)
return;
@@ -811,7 +669,6 @@ void __exchange_header_value(http_header_t *header, const char *in_raw_value)
free(header->value);
header->value = DA_NULL;
}
-
if (header->raw_value)
free(header->raw_value);
header->raw_value = strdup(in_raw_value);
@@ -825,15 +682,14 @@ da_bool_t http_msg_response_get_content_type(
da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
- b_ret = __get_http_header_for_field(http_msg_response, "Content-Type",
- &header);
+ b_ret = __get_http_header_for_field(http_msg_response,
+ HTTP_FIELD_CONTENT_TYPE, &header);
if (!b_ret) {
- DA_LOG(HTTPManager, "no Content-Type");
+ DA_LOGV("no Content-Type");
return DA_FALSE;
}
-
if (out_type)
*out_type = strdup(header->value);
@@ -846,13 +702,13 @@ void http_msg_response_set_content_type(http_msg_response_t *http_msg_response,
da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
if (!http_msg_response || !in_type)
return;
- b_ret = __get_http_header_for_field(http_msg_response, "Content-Type",
- &header);
+ b_ret = __get_http_header_for_field(http_msg_response,
+ HTTP_FIELD_CONTENT_TYPE, &header);
if (b_ret) {
if (header->raw_value && (!strncmp(header->raw_value, in_type,
strlen(header->raw_value))))
@@ -862,22 +718,22 @@ void http_msg_response_set_content_type(http_msg_response_t *http_msg_response,
__exchange_header_value(header, in_type);
} else {
__http_header_add_field(&(http_msg_response->head),
- "Content-Type", in_type, WITH_PARSING_OPTION);
+ HTTP_FIELD_CONTENT_TYPE, in_type, WITH_PARSING_OPTION);
}
}
da_bool_t http_msg_response_get_content_length(
- http_msg_response_t *http_msg_response, unsigned long long *out_length)
+ http_msg_response_t *http_msg_response, da_size_t *out_length)
{
da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
b_ret = __get_http_header_for_field(http_msg_response,
- "Content-Length", &header);
+ HTTP_FIELD_CONTENT_LENGTH, &header);
if (!b_ret) {
- DA_LOG(HTTPManager, "no Content-Length");
+ DA_LOGV( "no Content-Length");
return DA_FALSE;
}
@@ -894,32 +750,29 @@ da_bool_t http_msg_response_get_content_disposition(
da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
char *file_name = NULL;
-
char *wanted_str = NULL;
char *wanted_str_start = NULL;
char *wanted_str_end = NULL;
char *decoded_str = NULL;
int wanted_str_len = 0;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
b_ret = __get_http_header_for_field(http_msg_response,
- "Content-Disposition", &header);
+ HTTP_FIELD_CONTENT_DISPOSITION, &header);
if (!b_ret) {
- DA_LOG_VERBOSE(HTTPManager, "no Content-Disposition");
+ DA_LOGV( "no Content-Disposition");
return DA_FALSE;
}
-
if (out_disposition)
*out_disposition = strdup(header->value);
-
if (!out_file_name)
return DA_FALSE;
b_ret = __get_http_header_option_for_field(header->options, "filename",
&file_name);
if (!b_ret) {
- DA_LOG(HTTPManager, "no option");
+ DA_LOGV( "no option");
return DA_FALSE;
}
@@ -936,14 +789,14 @@ da_bool_t http_msg_response_get_content_disposition(
wanted_str_len = wanted_str_end - wanted_str_start;
wanted_str = (char*)calloc(1, wanted_str_len + 1);
if (!wanted_str) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
return DA_FALSE;
}
strncpy(wanted_str, wanted_str_start, wanted_str_len);
b_ret = is_base64_encoded_word(wanted_str);
if (b_ret) {
- DA_LOG(HTTPManager, "It's base64 encoded-word string");
+ DA_LOGV("It's base64 encoded-word string");
if (DA_RESULT_OK == decode_base64_encoded_str(
wanted_str, &decoded_str)) {
DA_SECURE_LOGD("base64 decoded str = [%s]", decoded_str);
@@ -951,10 +804,10 @@ da_bool_t http_msg_response_get_content_disposition(
wanted_str = decoded_str;
decoded_str = NULL;
} else {
- DA_LOG(HTTPManager, "Fail to base64 decode. Just use un-decoded string.");
+ DA_LOGV("Fail to base64 decode. Just use un-decoded string.");
}
} else {
- DA_LOG(HTTPManager, "It's NOT base64 encoded-word string");
+ DA_LOGV("It's NOT base64 encoded-word string");
}
decode_url_encoded_str(wanted_str, &decoded_str);
/* If it is url encoded string */
@@ -964,14 +817,11 @@ da_bool_t http_msg_response_get_content_disposition(
wanted_str = decoded_str;
decoded_str = NULL;
}
-
*out_file_name = wanted_str;
-
- DA_SECURE_LOGD("out_file_name = [%s]", *out_file_name);
-
+ DA_SECURE_LOGI("out_file_name = [%s]", *out_file_name);
return DA_TRUE;
} else {
- DA_LOG_ERR(HTTPManager, "Not matched \" !");
+ DA_LOGE("Not matched \" !");
return DA_FALSE;
}
}
@@ -983,51 +833,54 @@ da_bool_t http_msg_response_get_ETag(http_msg_response_t *http_msg_response,
da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
- b_ret = __get_http_header_for_field(http_msg_response, "ETag", &header);
+ b_ret = __get_http_header_for_field(http_msg_response, HTTP_FIELD_ETAG,
+ &header);
if (!b_ret) {
- DA_LOG_VERBOSE(HTTPManager, "no ETag");
+ DA_LOGV( "no ETag");
return DA_FALSE;
}
-
if (out_value)
*out_value = strdup(header->value);
return DA_TRUE;
}
-da_bool_t http_msg_response_get_date(http_msg_response_t *http_msg_response,
+#ifdef _RAF_SUPPORT
+da_bool_t http_msg_response_get_RAF_mode(http_msg_response_t *http_msg_response,
char **out_value)
{
da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
- b_ret = __get_http_header_for_field(http_msg_response, "Date", &header);
+ b_ret = __get_http_header_for_field(http_msg_response, HTTP_FIELD_RAF_MODE,
+ &header);
if (!b_ret) {
- DA_LOG(HTTPManager, "no Date");
+ DA_LOGV( "no RAF mode");
return DA_FALSE;
}
-
if (out_value)
*out_value = strdup(header->value);
return DA_TRUE;
}
+#endif
-da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response,
+da_bool_t http_msg_response_get_date(http_msg_response_t *http_msg_response,
char **out_value)
{
da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
- b_ret = __get_http_header_for_field(http_msg_response, "Location", &header);
+ b_ret = __get_http_header_for_field(http_msg_response,
+ HTTP_FIELD_DATA, &header);
if (!b_ret) {
- DA_LOG(HTTPManager, "no Location");
+ DA_LOGV( "no Date");
return DA_FALSE;
}
if (out_value)
@@ -1036,120 +889,27 @@ da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response,
return DA_TRUE;
}
-da_result_t http_msg_response_get_boundary(
- http_msg_response_t *http_msg_response, char **out_val)
-{
- da_result_t ret = DA_RESULT_OK;
-
- http_msg_iter_t http_msg_iter;
- char *field = NULL;
- char *value = NULL;
- char *boundary = NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!http_msg_response) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_INVALID_ARGUMENT");
- return DA_ERR_INVALID_ARGUMENT;
- }
-
- http_msg_response_get_iter(http_msg_response, &http_msg_iter);
- while (http_msg_get_field_with_iter(&http_msg_iter, &field, &value)) {
- if ((field != DA_NULL) && (value != DA_NULL)) {
- if (!strncasecmp(field, "Content-Type",
- strlen("Content-Type"))) {
- char *org_str = NULL;
- char *boundary_str_start = NULL;
- char *boundary_value_start = NULL;
- char *boundary_value_end = NULL;
- int boundary_value_len = 0;
-
- org_str = value;
-
- boundary_str_start
- = strstr(org_str, "boundary");
- if (boundary_str_start) {
- DA_LOG(HTTPManager, "boundary_str_start = %s", boundary_str_start);
- // this "Content-Type" value has "boundary" in it, so get the value
- boundary_value_start = strchr(
- boundary_str_start, '"');
- boundary_value_start += 1; // start without "
-
- boundary_value_end = strchr(
- boundary_value_start, '"');
- boundary_value_len = boundary_value_end
- - boundary_value_start;
-
- DA_LOG(HTTPManager, "boundary_value_start = %s", boundary_value_start);
- DA_LOG(HTTPManager, "boundary_value_end = %s", boundary_value_end);
- DA_LOG(HTTPManager, "boundary_value_len = %d", boundary_value_len);
-
- } else {
- // no "boundary" field on this "Content-Type" value
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
- // end of clear
-
- boundary = (char *)calloc(1,
- boundary_value_len + 1);
- if (!boundary) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
-
- goto ERR;
- }
- strncpy(boundary, boundary_value_start,
- boundary_value_len);
- DA_SECURE_LOGD("[boundary][%s]", boundary);
- break;
- }
- }
- }
-
- *out_val = boundary;
-
-ERR:
- return ret;
-}
-
-char *get_http_response_header_raw(http_msg_response_t *http_msg_response)
+da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response,
+ char **out_value)
{
- http_msg_iter_t http_msg_iter;
+ da_bool_t b_ret = DA_FALSE;
http_header_t *header = NULL;
- char *field = NULL;
- char tmp_buf[1024*4] = {0,};
- char line_buf[1024] = {0,};
- int len = 0;
- char *buff = NULL;
- DA_LOG_FUNC_LOGV(HTTPManager);
+ DA_LOGV("");
- http_msg_response_get_iter(http_msg_response, &http_msg_iter);
- while (http_msg_get_header_with_iter(&http_msg_iter, &field, &header)) {
- if (field && header) {
- // FIXME later :: buffer length is more than total length. think about getting header's conent length from libsoup
- len = strlen(field) + strlen(header->value) + 2;
- snprintf(line_buf, len,"%s:%s", field, header->value);
- strncat(tmp_buf, line_buf, len);
- strcat(tmp_buf, "\n");
- }
- }
- if (strlen(tmp_buf) > 0) {
- buff = (char *)calloc(1, strlen(tmp_buf) + 1);
- if (buff == DA_NULL) {
- DA_LOG_ERR(HTTPManager, "DA_ERR_FAIL_TO_MEMALLOC");
- return DA_NULL;
- }
- memcpy(buff, tmp_buf, strlen(tmp_buf));
- DA_SECURE_LOGD("\n---raw response header---\n%s\n------\n",buff);
- return buff;
- } else {
- return DA_NULL;
+ b_ret = __get_http_header_for_field(http_msg_response,
+ HTTP_FIELD_LOCATION, &header);
+ if (!b_ret) {
+ DA_LOGV( "no Location");
+ return DA_FALSE;
}
+ if (out_value)
+ *out_value = strdup(header->value);
+
+ return DA_TRUE;
}
-char *_stristr(const char *long_str, const char *find_str)
+char *__stristr(const char *long_str, const char *find_str)
{
int i = 0;
int length_long = 0;
@@ -1159,7 +919,7 @@ char *_stristr(const char *long_str, const char *find_str)
char *look_ptr = NULL;
if (long_str == NULL || find_str == NULL) {
- DA_LOG_ERR(Default,"INVALID ARGUMENT");
+ DA_LOGE("INVALID ARGUMENT");
return NULL;
}
@@ -1169,14 +929,14 @@ char *_stristr(const char *long_str, const char *find_str)
org_ptr = (char*)calloc(1, length_long + 1);
if (org_ptr == NULL) {
- DA_LOG_ERR(Default,"INVALID ARGUMENT");
+ DA_LOGE("INVALID ARGUMENT");
return NULL;
}
look_ptr = (char*)calloc(1, length_find + 1);
if (look_ptr == NULL) {
- DA_LOG_ERR(Default,"INVALID ARGUMENT");
+ DA_LOGE("INVALID ARGUMENT");
free(org_ptr);
return NULL;
}
@@ -1191,7 +951,6 @@ char *_stristr(const char *long_str, const char *find_str)
} else {
org_ptr[i] = long_str[i];
}
-
i++;
}
@@ -1207,7 +966,6 @@ char *_stristr(const char *long_str, const char *find_str)
} else {
look_ptr[i] = find_str[i];
}
-
i++;
}
@@ -1233,7 +991,6 @@ da_bool_t extract_attribute_from_header(
const char *szFindStr,
char **ppRtnValue)
{
-
char *pValuePos = NULL;
int index = 0;
int startPos = 0;
@@ -1241,21 +998,19 @@ da_bool_t extract_attribute_from_header(
int need_to_end_quataion_mark = 0;
if (szHeadStr == DA_NULL || szFindStr == DA_NULL) {
- DA_LOG_ERR(Default,"INVALID ARGUMENT");
+ DA_LOGE("INVALID ARGUMENT");
return DA_FALSE;
}
-
if (strlen(szHeadStr) <= 0 || strlen(szFindStr) <= 0) {
- DA_LOG_ERR(Default,"INVALID ARGUMENT");;
+ DA_LOGE("INVALID ARGUMENT");;
return DA_FALSE;
}
-
if (ppRtnValue == NULL) {
return DA_FALSE;
}
- pValuePos = _stristr(szHeadStr, (char*)szFindStr);
+ pValuePos = __stristr(szHeadStr, (char*)szFindStr);
if (pValuePos == NULL) {
*ppRtnValue = NULL;
goto ERR;
@@ -1287,7 +1042,8 @@ da_bool_t extract_attribute_from_header(
startPos = index;
/* Find the end of data. */
- if (0 == strncasecmp(szFindStr, "Location", strlen("Location")))//terminate character list does not contain ';' in case of URI
+ if (0 == strncasecmp(szFindStr, HTTP_FIELD_LOCATION,
+ strlen(HTTP_FIELD_LOCATION)))//terminate character list does not contain ';' in case of URI
{
while (DA_FALSE == IS_URI_TERMINATING_CHAR(pValuePos[index])) {
index++;
@@ -1305,14 +1061,14 @@ da_bool_t extract_attribute_from_header(
strLen = index - startPos;
if (strLen < 1) {
- DA_LOG_ERR(Default," strLen is < 1");
+ DA_LOGE(" strLen is < 1");
goto ERR;
}
*ppRtnValue = (char*)calloc(1, sizeof(char) * (strLen + 1));
if (*ppRtnValue == NULL) {
- DA_LOG_ERR(Default," *ppRtnValue is NULL");
+ DA_LOGE(" *ppRtnValue is NULL");
goto ERR;
}
@@ -1320,14 +1076,50 @@ da_bool_t extract_attribute_from_header(
*(*ppRtnValue + strLen) = '\0';
return DA_TRUE;
-
ERR:
-
if (*ppRtnValue) {
free(*ppRtnValue);
*ppRtnValue = NULL;
}
-
return DA_FALSE;
}
+da_bool_t http_msg_request_get_if_range(http_msg_request_t *http_msg_request,
+ char **out_value)
+{
+ da_bool_t b_ret = DA_FALSE;
+ http_header_t *header = NULL;
+
+ DA_LOGV("");
+
+ b_ret = __get_http_req_header_for_field(http_msg_request, HTTP_FIELD_IF_RANGE,
+ &header);
+ if (!b_ret) {
+ DA_LOGV( "no If Range");
+ return DA_FALSE;
+ }
+ if (out_value)
+ *out_value = strdup(header->value);
+
+ return DA_TRUE;
+}
+
+da_bool_t http_msg_request_get_range(http_msg_request_t *http_msg_request,
+ char **out_value)
+{
+ da_bool_t b_ret = DA_FALSE;
+ http_header_t *header = NULL;
+
+ DA_LOGV("");
+
+ b_ret = __get_http_req_header_for_field(http_msg_request, HTTP_FIELD_RANGE,
+ &header);
+ if (!b_ret) {
+ DA_LOGV( "no Range");
+ return DA_FALSE;
+ }
+ if (out_value)
+ *out_value = strdup(header->value);
+
+ return DA_TRUE;
+}
diff --git a/agent/download-agent-http-queue.c b/agent/download-agent-http-queue.c
deleted file mode 100755
index 06fe084..0000000
--- a/agent/download-agent-http-queue.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "download-agent-http-queue.h"
-#include "download-agent-http-mgr.h"
-#include "download-agent-debug.h"
-#include "download-agent-pthread.h"
-
-void init_q_event_data_http(q_event_t *q_event);
-void init_q_event_control(q_event_t *q_event);
-
-void Q_init_queue(queue_t *queue)
-{
- queue->having_data = DA_FALSE;
- queue->control_head = DA_NULL;
- queue->data_head = DA_NULL;
- queue->queue_size = 0;
-
- _da_thread_mutex_init(&(queue->mutex_queue), DA_NULL);
- _da_thread_cond_init(&(queue->cond_queue), DA_NULL);
-}
-
-void Q_destroy_queue(queue_t *queue)
-{
- q_event_t *event = DA_NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- do {
- Q_pop_event(queue, &event);
- Q_destroy_q_event(&event);
- } while(event);
-
- queue->having_data = DA_FALSE;
- queue->control_head = DA_NULL;
- queue->data_head = DA_NULL;
- queue->queue_size = 0;
-
- _da_thread_mutex_destroy(&(queue->mutex_queue));
- _da_thread_cond_destroy(&(queue->cond_queue));
-}
-
-void Q_init_q_event(q_event_t *q_event)
-{
- switch(q_event->event_type) {
- case Q_EVENT_TYPE_DATA_HTTP:
- init_q_event_data_http(q_event);
- break;
-
- case Q_EVENT_TYPE_DATA_DRM:
- break;
-
- case Q_EVENT_TYPE_CONTROL:
- init_q_event_control(q_event);
- break;
- }
-
- q_event->size = 0;
- q_event->next = DA_NULL;
-}
-
-void Q_destroy_q_event(q_event_t **in_q_event)
-{
- q_event_t *q_event = DA_NULL;
- q_event = *in_q_event;
-
- if(q_event == DA_NULL)
- return;
-
- switch(q_event->event_type) {
- case Q_EVENT_TYPE_DATA_HTTP:
- init_q_event_data_http(q_event);
- q_event->size = 0;
- q_event->next = DA_NULL;
- free(q_event);
- break;
-
- case Q_EVENT_TYPE_DATA_DRM:
- q_event->size = 0;
- q_event->next = DA_NULL;
- free(q_event);
- break;
-
- case Q_EVENT_TYPE_CONTROL:
- init_q_event_control(q_event);
- q_event->size = 0;
- q_event->next = DA_NULL;
- free(q_event);
- break;
- }
-}
-
-da_result_t Q_make_control_event(q_event_type_control control_type, q_event_t **out_event)
-{
- da_result_t ret = DA_RESULT_OK;
- q_event_t *q_event = DA_NULL;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- q_event = (q_event_t *)calloc(1, sizeof(q_event_t));
- if(q_event == DA_NULL) {
- DA_LOG_ERR(HTTPManager, "calloc fail for q_event");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
-
- *out_event = DA_NULL;
- } else {
- q_event->event_type = Q_EVENT_TYPE_CONTROL;
- q_event->type.q_event_control.control_type = control_type;
- q_event->next = DA_NULL;
-
- *out_event = q_event;
- }
-
- return ret;
-}
-
-da_result_t Q_make_http_data_event(q_event_type_data data_type, q_event_t **out_event)
-{
- da_result_t ret = DA_RESULT_OK;
- q_event_t *q_event = DA_NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- q_event = (q_event_t *)calloc(1, sizeof(q_event_t));
- if(q_event == DA_NULL) {
- DA_LOG_ERR(HTTPManager, "calloc fail for q_event");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- *out_event = DA_NULL;
- } else {
- q_event->event_type = Q_EVENT_TYPE_DATA_HTTP;
- q_event->type.q_event_data_http.data_type = data_type;
- q_event->next = DA_NULL;
-
- *out_event = q_event;
-
-// DA_LOG_VERBOSE(HTTPManager, "made event = %x", *out_event);
- }
-
- return ret;
-
-}
-
-da_result_t Q_set_status_code_on_http_data_event(q_event_t *q_event, int status_code)
-{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
- DA_LOG_ERR(HTTPManager, "status_code can be set only for Q_EVENT_TYPE_DATA_HTTP.");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- q_event->type.q_event_data_http.status_code = status_code;
-
-// DA_LOG_VERBOSE(HTTPManager, "status_code = %d, q_event = %x", q_event->type.q_event_data_http.status_code, q_event);
-
-ERR:
- return ret;
-
-}
-
-da_result_t Q_set_http_body_on_http_data_event(q_event_t *q_event, int body_len, char *body_data)
-{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
- DA_LOG_ERR(HTTPManager, "http body can be set only for Q_EVENT_TYPE_DATA_HTTP.");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- q_event->type.q_event_data_http.body_len = body_len;
- q_event->type.q_event_data_http.body_data = body_data;
- q_event->size = body_len;
-
-// DA_LOG_VERBOSE(HTTPManager, "body_len = %d, body_data = %x, q_event = %x", q_event->type.q_event_data_http.body_len, q_event->type.q_event_data_http.body_data, q_event);
-
-ERR:
- return ret;
-
-}
-
-da_result_t Q_set_error_type_on_http_data_event(q_event_t *q_event, int error_type)
-{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if(q_event->event_type != Q_EVENT_TYPE_DATA_HTTP) {
- DA_LOG_ERR(HTTPManager, "error_type can be set only for Q_EVENT_TYPE_DATA_HTTP.");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- q_event->type.q_event_data_http.error_type = error_type;
-
- DA_LOG_VERBOSE(HTTPManager, "error_type = %d, q_event = %p", q_event->type.q_event_data_http.error_type, q_event);
-
-ERR:
- return ret;
-
-}
-
-da_bool_t Q_push_event(const queue_t *in_queue, const q_event_t *in_event)
-{
- da_bool_t b_ret = DA_FALSE;
- queue_t *queue = (queue_t *)in_queue;
-
- _da_thread_mutex_lock (&(queue->mutex_queue));
- b_ret = Q_push_event_without_lock(in_queue, in_event);
- _da_thread_mutex_unlock (&(queue->mutex_queue));
-
- return b_ret;
-}
-
-da_bool_t Q_push_event_without_lock(const queue_t *in_queue, const q_event_t *in_event)
-{
- da_bool_t b_ret = DA_FALSE;
- queue_t *queue = (queue_t *)in_queue;
- q_event_t *event = (q_event_t *)in_event;
- q_event_type event_type;
- q_event_t *head = DA_NULL;
- q_event_t *cur = DA_NULL;
-
-// DA_LOG_VERBOSE(HTTPManager, "queue = %x", in_queue);
-
- event_type = event->event_type;
-
-// _da_thread_mutex_lock (&(queue->mutex_queue));
-
- if(event_type == Q_EVENT_TYPE_CONTROL) {
- head = queue->control_head;
- if(head == DA_NULL) {
- queue->control_head = event;
- } else {
- cur = head;
-
- while(cur->next != DA_NULL) {
- cur = cur->next;
- }
- cur->next= event;
- }
- b_ret = DA_TRUE;
- } else {
- if((event->size == 0) || (queue->queue_size < MAX_QUEUE_SIZE)) {
- head = queue->data_head;
- if(head == DA_NULL) {
- queue->data_head = event;
- } else {
- cur = head;
- while(cur->next != DA_NULL) {
- cur = cur->next;
- }
- cur->next= event ;
- }
-
- queue->queue_size += event->size;
-// DA_LOG_VERBOSE(HTTPManager, "queue size is %d", queue->queue_size);
-
- b_ret = DA_TRUE;
- } else {
- DA_LOG_CRITICAL(HTTPManager, "rejected event's size is %d queue_size %d", event->size, queue->queue_size);
- b_ret = DA_FALSE;
- }
- }
-
- queue->having_data = DA_TRUE;
- Q_wake_up(queue);
-// _da_thread_mutex_unlock (&(queue->mutex_queue));
- return b_ret;
-}
-
-void Q_pop_event(const queue_t *in_queue, q_event_t **out_event)
-{
- queue_t *queue = (queue_t*)in_queue;
-
-// DA_LOG_VERBOSE(HTTPManager, "queue = %x", in_queue);
-
- /** Pop Priority
- * 1. If there are control event, control event should pop first
- * 2. If there is no control event, data event should pop
- * 3. If there is no control and data event on queue, pop NULL
- */
-
- _da_thread_mutex_lock (&(queue->mutex_queue));
-
- if(queue->control_head != DA_NULL) {/* Priority 1 */
- *out_event = queue->control_head;
- queue->control_head = queue->control_head->next;
- } else {
- if(queue->data_head != DA_NULL) {/* Priority 2 */
- *out_event = queue->data_head;
- queue->data_head = queue->data_head->next;
- queue->queue_size -= (*out_event)->size;
- DA_LOG_VERBOSE(HTTPManager, "queue size is %d", queue->queue_size);
- } else {/* Priority 3 */
- *out_event = DA_NULL;
- }
- }
-
- if((queue->control_head == DA_NULL) && (queue->data_head == DA_NULL)) {
- queue->having_data = DA_FALSE;
- } else {
- queue->having_data = DA_TRUE;
- }
-
- _da_thread_mutex_unlock (&(queue->mutex_queue));
-
-}
-
-void Q_goto_sleep(const queue_t *in_queue)
-{
- DA_LOG_VERBOSE(HTTPManager, "sleep for %p", in_queue);
-
-//** SHOULD NOT use mutex **//
-
-// _da_thread_mutex_lock (&(in_queue->mutex_queue));
- _da_thread_cond_wait((pthread_cond_t*)(&(in_queue->cond_queue)),(pthread_mutex_t*) (&(in_queue->mutex_queue)));
-// _da_thread_mutex_unlock (&(in_queue->mutex_queue));
-}
-
-void Q_wake_up(const queue_t *in_queue)
-{
- DA_LOG_VERBOSE(HTTPManager, "wake up for %p", in_queue);
-
-//** SHOULD NOT use mutex **//
-
-// _da_thread_mutex_lock (&(in_queue->mutex_queue));
- _da_thread_cond_signal((pthread_cond_t*)(&(in_queue->cond_queue)));
-// _da_thread_mutex_unlock (&(in_queue->mutex_queue));
-}
-
-void init_q_event_data_http(q_event_t *q_event)
-{
- q_event_data_http_t *q_event_data_http;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if(q_event->event_type == Q_EVENT_TYPE_DATA_HTTP) {
- q_event_data_http = &(q_event->type.q_event_data_http);
-
- if(q_event_data_http) {
- q_event_data_http->status_code = 0;
- if(q_event_data_http->http_response_msg) {
- http_msg_response_destroy(&(q_event_data_http->http_response_msg));
- q_event_data_http->http_response_msg = DA_NULL;
- }
-
- if(q_event_data_http->body_len > 0 ) {
- if (q_event_data_http->body_data) {
- free(q_event_data_http->body_data);
- q_event_data_http->body_data = DA_NULL;
- }
- }
- q_event_data_http->error_type = 0;
- }
- }
-}
-
-void init_q_event_control(q_event_t *q_event)
-{
- q_event_control_t *q_event_control;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if(q_event->event_type == Q_EVENT_TYPE_CONTROL) {
- q_event_control = &(q_event->type.q_event_control);
- if(q_event_control) {
- q_event_control->control_type = Q_EVENT_TYPE_CONTROL_NONE;
- }
- }
-
-}
diff --git a/agent/download-agent-interface.c b/agent/download-agent-interface.c
index 7d994e6..0b19813 100755
--- a/agent/download-agent-interface.c
+++ b/agent/download-agent-interface.c
@@ -15,214 +15,131 @@
*/
#include "download-agent-interface.h"
-#include "download-agent-debug.h"
-#include "download-agent-utils.h"
-#include "download-agent-http-mgr.h"
-#include "download-agent-http-misc.h"
-#include "download-agent-client-mgr.h"
#include "download-agent-dl-mgr.h"
-#include "download-agent-basic.h"
-#include "download-agent-file.h"
-int da_init(
- da_client_cb_t *da_client_callback)
+int da_init()
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGD(Default);
-
- if (!da_client_callback) {
- ret = DA_ERR_INVALID_ARGUMENT;
- return ret;
- }
-
- ret = init_log_mgr();
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- ret = init_client_app_mgr();
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- ret = reg_client_app(da_client_callback);
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- ret = init_http_mgr();
- if (ret != DA_RESULT_OK)
- goto ERR;
-
- ret = init_download_mgr();
- if (ret != DA_RESULT_OK)
- goto ERR;
-
-ERR:
- if (DA_RESULT_OK != ret)
- da_deinit();
-
- DA_LOG_CRITICAL(Default, "Return ret = %d", ret);
-
+ DA_LOGV("");
+ da_ret_t ret = DA_RESULT_OK;
+ DA_LOGI("Return ret = %d", ret);
return ret;
}
-/* TODO:: deinit should clean up all the clients... */
int da_deinit()
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGV(Default);
-
- deinit_http_mgr();
- deinit_download_mgr();
- /* Do not clean temporary download path
- * The client can resume or restart download with temporary file in case of failed download.
- */
- dereg_client_app();
- DA_LOG(Default, "====== da_deinit EXIT =====");
+ da_ret_t ret = DA_RESULT_OK;
+ DA_LOGV("");
+ destroy_da_info_list();
+ DA_LOGI("====== da_deint EXIT =====");
return ret;
}
-int da_start_download(
- const char *url,
- int *download_id)
+int da_start_download(const char *url, req_data_t *ext_data,
+ da_cb_t *da_cb_data, int *download_id)
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_FUNC_LOGD(Default);
-
- *download_id = DA_INVALID_ID;
-
- if (DA_FALSE == is_valid_url(url, &ret))
- goto ERR;
-
- DA_SECURE_LOGI("url = %s", url);
-
- ret = start_download(url, download_id);
- if (ret != DA_RESULT_OK)
- goto ERR;
-
-ERR:
- DA_LOG_CRITICAL(Default, "Return: Dl req id = %d, ret = %d", *download_id, ret);
- return ret;
-}
-
-int da_start_download_with_extension(
- const char *url,
- extension_data_t *extension_data,
- int *download_id
-)
-{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
int req_header_count = 0;
int i = 0;
-
- DA_LOG_FUNC_LOGV(Default);
+ int da_id = DA_INVALID_ID;
+ da_info_t *da_info = DA_NULL;
*download_id = DA_INVALID_ID;
- if (DA_FALSE == is_valid_url(url, &ret))
- goto ERR;
-
- DA_SECURE_LOGI("url = %s", url);
-
- if (ret != DA_RESULT_OK)
- goto ERR;
- if (!extension_data) {
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- if (extension_data->request_header_count > 0) {
- DA_LOG_VERBOSE(Default, "input request_header_count = [%d]",
- extension_data->request_header_count);
- for (i = 0; i < extension_data->request_header_count; i++) {
- if (extension_data->request_header[i]) {
+ if (ext_data->request_header_count > 0) {
+ DA_LOGI("request_header_count[%d]", ext_data->request_header_count);
+ for (i = 0; i < ext_data->request_header_count; i++) {
+ if (ext_data->request_header[i]) {
req_header_count++;
- DA_SECURE_LOGI("request_header = [%s]",
- extension_data->request_header[i]);
+ DA_SECURE_LOGI("request_header[%s]", ext_data->request_header[i]);
}
}
- DA_LOG_VERBOSE(Default, "actual request_header_count = [%d]", req_header_count);
- if (extension_data->request_header_count != req_header_count) {
- DA_LOG_ERR(Default, "Request header count is not matched with number of request header array");
- extension_data->request_header = NULL;
- extension_data->request_header_count = 0;
+ DA_LOGI("actual request_header_count[%d]", req_header_count);
+ if (ext_data->request_header_count != req_header_count) {
+ DA_LOGE("Request header count is not matched with number of request header array");
ret = DA_ERR_INVALID_ARGUMENT;
goto ERR;
}
}
- if (extension_data->install_path) {
- if (!is_dir_exist(extension_data->install_path))
- return DA_ERR_INVALID_INSTALL_PATH;
- DA_SECURE_LOGI("install_path = [%s]", extension_data->install_path);
- }
-
- if (extension_data->file_name)
- DA_SECURE_LOGI("file_name = [%s]", extension_data->file_name);
- if (extension_data->temp_file_path)
- DA_SECURE_LOGI("temp_file_path = [%s]", extension_data->temp_file_path);
- if (extension_data->etag)
- DA_SECURE_LOGI("etag = [%s]", extension_data->etag);
- if (extension_data->pkg_name)
- DA_SECURE_LOGI("pkg_name = [%s]", extension_data->pkg_name);
- if (extension_data->user_data)
- DA_LOG_VERBOSE(Default, "user_data = [%p]", extension_data->user_data);
+ if (ext_data->install_path)
+ DA_SECURE_LOGI("install path[%s]", ext_data->install_path);
+ if (ext_data->file_name)
+ DA_SECURE_LOGI("file_name[%s]", ext_data->file_name);
+ if (ext_data->temp_file_path)
+ DA_SECURE_LOGI("temp_file_path[%s]", ext_data->temp_file_path);
+ if (ext_data->etag)
+ DA_SECURE_LOGI("etag[%s]", ext_data->etag);
+ if (ext_data->pkg_name)
+ DA_SECURE_LOGI("pkg_name[%s]", ext_data->pkg_name);
+ if (ext_data->network_bonding)
+ DA_LOGD("network bonding option[%d]", ext_data->network_bonding);
+ if (ext_data->user_req_data)
+ DA_LOGI("user_req_data[%p]", ext_data->user_req_data);
+ if (ext_data->user_client_data)
+ DA_LOGI("user_client_data[%p]", ext_data->user_client_data);
+
+ ret = get_available_da_id(&da_id);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
- ret = start_download_with_extension(url, download_id, extension_data);
+ da_info = da_info_list[da_id];
+ da_info->da_id = da_id;
+ ret = copy_user_input_data(da_info, url, ext_data, da_cb_data);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ *download_id = da_id;
+ ret = start_download(da_info);
ERR:
- DA_LOG_CRITICAL(Default, "Return: Dl req id = %d, ret = %d", *download_id, ret);
+ DA_LOGI("Return:id[%d],ret[%d]", *download_id, ret);
return ret;
}
int da_cancel_download(int download_id)
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_VERBOSE(Default, "Cancel for dl_id = %d", download_id);
+ da_ret_t ret = DA_RESULT_OK;
- ret = cancel_download(download_id);
+ DA_LOGV("download_id[%d]", download_id);
+ ret = cancel_download(download_id, DA_TRUE);
+ DA_LOGI("Return:id[%d],ret[%d]", download_id, ret);
+ return ret;
+}
- DA_LOG_CRITICAL(Default, "Return: Cancel id = %d, ret = %d", download_id, ret);
+int da_cancel_download_without_update(int download_id)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ DA_LOGV("download_id[%d]", download_id);
+ ret = cancel_download(download_id, DA_FALSE);
+ DA_LOGI("Return:id[%d],ret[%d]", download_id, ret);
return ret;
}
int da_suspend_download(int download_id)
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_VERBOSE(Default, "Suspend for dl_id = %d", download_id);
-
+ da_ret_t ret = DA_RESULT_OK;
+ DA_LOGV("download_id[%d]", download_id);
ret = suspend_download(download_id, DA_TRUE);
-
- DA_LOG_CRITICAL(Default, "Return: Suspend id = %d, ret = %d", download_id, ret);
+ DA_LOGI("Return:id[%d],ret[%d]", download_id, ret);
return ret;
}
int da_suspend_download_without_update(int download_id)
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_VERBOSE(Default, "Suspend for dl_id = %d", download_id);
-
+ da_ret_t ret = DA_RESULT_OK;
+ DA_LOGV("download_id[%d]", download_id);
ret = suspend_download(download_id, DA_FALSE);
-
- DA_LOG_CRITICAL(Default, "Return: Suspend id = %d, ret = %d", download_id, ret);
+ DA_LOGI("Return:id[%d],ret[%d]", download_id, ret);
return ret;
}
int da_resume_download(int download_id)
{
- da_result_t ret = DA_RESULT_OK;
-
- DA_LOG_VERBOSE(Default, "Resume for dl_id = %d", download_id);
-
+ da_ret_t ret = DA_RESULT_OK;
+ DA_LOGV("download_id[%d]", download_id);
ret = resume_download(download_id);
-
- DA_LOG_CRITICAL(Default, "Return: Resume id = %d, ret = %d", download_id, ret);
+ DA_LOGI("Return:id[%d],ret[%d]", download_id, ret);
return ret;
}
@@ -230,5 +147,6 @@ int da_is_valid_download_id(int download_id)
{
da_bool_t ret = DA_FALSE;
ret = is_valid_download_id(download_id);
+ DA_LOGI("Return:id[%d],ret[%d]", download_id, ret);
return ret;
}
diff --git a/agent/download-agent-mime-util.c b/agent/download-agent-mime-util.c
index 53bab8b..71e08eb 100755
--- a/agent/download-agent-mime-util.c
+++ b/agent/download-agent-mime-util.c
@@ -69,8 +69,6 @@ pthread_mutex_t mutex_for_xdgmime = PTHREAD_MUTEX_INITIALIZER;
da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type)
{
- DA_LOG_FUNC_LOGV(Default);
-
if (!in_mime_type)
return DA_FALSE;
@@ -79,7 +77,7 @@ da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type)
for (index = 0 ; index < list_size ; index++) {
if (0 == strncmp(in_mime_type, ambiguous_MIME_Type_list[index],
strlen(ambiguous_MIME_Type_list[index]))) {
- DA_SECURE_LOGD("It is ambiguous! [%s]", ambiguous_MIME_Type_list[index]);
+ //DA_SECURE_LOGD("It is ambiguous! [%s]", ambiguous_MIME_Type_list[index]);
return DA_TRUE;
}
}
@@ -87,42 +85,41 @@ da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type)
return DA_FALSE;
}
-da_result_t da_mime_get_ext_name(char *mime, char **ext)
+da_ret_t da_mime_get_ext_name(char *mime, char **ext)
{
- da_result_t ret = DA_RESULT_OK;
+ da_ret_t ret = DA_RESULT_OK;
const char **extlist = DA_NULL;
const char *unaliased_mimetype = DA_NULL;
char ext_temp[DA_MAX_STR_LEN] = {0,};
char *temp = NULL;
- DA_LOG_FUNC_LOGV(Default);
+ DA_LOGV("");
if (DA_NULL == mime || DA_NULL == ext) {
ret = DA_ERR_INVALID_ARGUMENT;
- DA_LOG_ERR(Default,"Invalid mime type");
+ DA_LOGE("Invalid mime type");
goto ERR;
}
// DA_SECURE_LOGD("mime str[%s]ptr[%p]len[%d]",mime,mime,strlen(mime));
/* unaliased_mimetype means representative mime among similar types */
- _da_thread_mutex_lock(&mutex_for_xdgmime);
+ DA_MUTEX_LOCK(&mutex_for_xdgmime);
unaliased_mimetype = xdg_mime_unalias_mime_type(mime);
- _da_thread_mutex_unlock(&mutex_for_xdgmime);
if (unaliased_mimetype == DA_NULL) {
ret = DA_ERR_INVALID_MIME_TYPE;
- DA_LOG_ERR(Default,"Invalid mime type : No unsaliased mime type");
+ DA_LOGI("Invalid mime type : No unsaliased mime type");
+ DA_MUTEX_UNLOCK(&mutex_for_xdgmime);
goto ERR;
}
DA_SECURE_LOGD("unaliased_mimetype[%s]\n",unaliased_mimetype);
/* Get extension name from shared-mime-info */
- _da_thread_mutex_lock(&mutex_for_xdgmime);
extlist = xdg_mime_get_file_names_from_mime_type(unaliased_mimetype);
- _da_thread_mutex_unlock(&mutex_for_xdgmime);
+ DA_MUTEX_UNLOCK(&mutex_for_xdgmime);
if (extlist == DA_NULL || *extlist == DA_NULL) {
int i = 0;
ret = DA_ERR_INVALID_MIME_TYPE;
- DA_LOG(Default,"No extension list");
+ DA_LOGV("No extension list");
#ifdef _SAMSUNG_MIME_POLICY
for (i = 0; i < MAX_SEC_MIME_TABLE_INDEX; i++)
{
@@ -134,8 +131,8 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext)
}
#endif
} else { /* For drm case, this else statement is needed */
- DA_SECURE_LOGD("extlist[%s]\n",*extlist);
- strncpy(ext_temp, *extlist, DA_MAX_STR_LEN);
+// DA_LOGD("extlist[%s]\n",*extlist);
+ strncpy(ext_temp, *extlist, DA_MAX_STR_LEN - 1);
/* If only one extension name is existed, don't enter here */
while (*extlist != NULL) {
int i = 0;
@@ -151,12 +148,12 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext)
break;
}
}
- DA_LOG_VERBOSE(Default,"index[%d]\n",i);
+ DA_LOGV("index[%d]\n",i);
/* If there is a mime at extension transform table */
if (i < MAX_EXT_TABLE_INDEX) {
break;
}
- DA_SECURE_LOGD("extlist[%s]\n",*extlist);
+// DA_LOGD("extlist[%s]\n",*extlist);
extlist++;
}
// DA_SECURE_LOGD("extension from shared mime info[%s]",ext_temp);
@@ -165,18 +162,18 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext)
if (strlen(ext_temp) < 1) {
/* If there is no mime string for OMA descriptor mime type */
if (strncmp(DD_MIME_STR, mime, strlen(DD_MIME_STR)) == 0) {
- strncpy(ext_temp, DD_EXT_STR, DA_MAX_STR_LEN-1);
+ strncpy(ext_temp, DD_EXT_STR, DA_MAX_STR_LEN - 1);
ret = DA_RESULT_OK;
/* If there is no extension name for "applicaion/vnd.oma.drm.messeages"
* at shared-mime-info*/
- } else if (strncmp(DRM_MIME_MSG_STR, mime,
- strlen(DRM_MIME_MSG_STR)) == 0) {
- strncpy(ext_temp, DRM_EXT_STR, DA_MAX_STR_LEN-1);
+ } else if (strncmp(DRM_MIME_MSG_STR, mime, strlen(DRM_MIME_MSG_STR)) ==
+ 0) {
+ strncpy(ext_temp, DRM_EXT_STR, DA_MAX_STR_LEN - 1);
/* If there is extension name at extlist, the return value can have an error.*/
ret = DA_RESULT_OK;
} else {
ret = DA_ERR_INVALID_MIME_TYPE;
- DA_LOG_ERR(Default,"Invalid mime type : no extension name at list");
+ DA_LOGI("Invalid mime type : no extension name at list");
}
}
if (ret != DA_RESULT_OK)
@@ -188,6 +185,7 @@ da_result_t da_mime_get_ext_name(char *mime, char **ext)
else
temp++;
+ DA_SECURE_LOGD("final extension name:[%s]",temp);
*ext = (char*)calloc(1, strlen(temp) + 1);
if (*ext != DA_NULL) {
strncpy(*ext, temp,strlen(temp));
@@ -206,11 +204,11 @@ da_bool_t da_get_extension_name_from_url(char *url, char **ext)
char *temp_str = DA_NULL;
int buf_len = 0;
- DA_LOG_FUNC_LOGV(Default);
+ DA_LOGV("");
if (DA_NULL == url || DA_NULL == ext) {
ret = DA_FALSE;
- DA_LOG_ERR(Default,"Invalid Argument");
+ DA_LOGE("Invalid Argument");
return ret;
}
@@ -229,7 +227,7 @@ da_bool_t da_get_extension_name_from_url(char *url, char **ext)
if (DA_NULL == *ext) {
ret = DA_FALSE;
- DA_LOG_ERR(Default,"Memory Fail");
+ DA_LOGE("Memory Fail");
goto ERR;
}
strncpy(*ext,buff,buf_len);
@@ -258,24 +256,24 @@ da_bool_t da_get_file_name_from_url(char *url, char **name)
int len_name = 0;
char name_buff[DA_MAX_FILE_PATH_LEN] = {0,};
- DA_LOG_FUNC_LOGV(Default);
+ DA_LOGV("");
if (DA_NULL == url || DA_NULL == name) {
ret = DA_FALSE;
- DA_LOG_ERR(Default,"Invalid Argument");
+ DA_LOGE("Invalid Argument");
goto ERR;
}
- *name = DA_NULL;
+
if (!strstr(url, "http") && !strstr(url, "https")) {
ret = DA_FALSE;
- DA_LOG_ERR(Default,"Invalid Argument");
+ DA_LOGE("Invalid Argument");
goto ERR;
}
buff = (char*) calloc(1, strlen(url) +1);
if(DA_NULL == buff) {
ret = DA_FALSE;
- DA_LOG_ERR(Default,"Memory Fail");
+ DA_LOGE("Memory Fail");
goto ERR;
}
@@ -339,7 +337,6 @@ da_bool_t da_get_file_name_from_url(char *url, char **name)
}
// DA_SECURE_LOGD("file name BEFORE removing prohibited character = %s", name_buff);
delete_prohibited_char(name_buff, strlen(name_buff));
-// DA_SECURE_LOGD("file name AFTER removing prohibited character = %s", name_buff);
len_name = strlen(name_buff);
*name = (char*) calloc(1, len_name + 1);
if (*name) {
@@ -363,7 +360,7 @@ void delete_prohibited_char(char *szTarget, int str_len)
int tar_len = 0;
if(szTarget == NULL || str_len <= 0 || strlen(szTarget) != str_len) {
- DA_LOG_ERR(Default,"Invaild Parameter\n");
+ DA_LOGE("Invaild Parameter\n");
return;
}
@@ -399,3 +396,54 @@ void delete_prohibited_char(char *szTarget, int str_len)
return;
}
+#ifdef _ENABLE_OMA_DRM
+da_bool_t is_content_drm_dcf(char *content_type)
+{
+ if (content_type == DA_NULL)
+ return DA_FALSE;
+
+ if (0 == strcmp(content_type, DRM_MIME_CONTENT_STR)) {
+ DA_LOGV("DRM_DM content");
+ return DA_TRUE;
+ } else {
+ return DA_FALSE;
+ }
+}
+
+da_bool_t is_content_drm_dm(char *content_type)
+{
+ if (content_type == DA_NULL)
+ return DA_FALSE;
+
+ if (0 == strcmp(content_type, DRM_MIME_MSG_STR)) {
+ DA_LOGV("DRM_DM content");
+ return DA_TRUE;
+ } else {
+ return DA_FALSE;
+ }
+}
+#endif
+
+da_ret_t get_extension_from_mime_type(char *mime_type, char **extension)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ char *ext = DA_NULL;
+
+ DA_LOGV("");
+ if (DA_NULL == mime_type || DA_NULL == extension) {
+ DA_LOGE("received mime_type is null");
+ ret = DA_ERR_INVALID_ARGUMENT;
+ goto ERR;
+ }
+// DA_SECURE_LOGD("input mime type = %s", mime_type);
+ if (DA_RESULT_OK != (ret = da_mime_get_ext_name(mime_type, &ext))) {
+ DA_LOGE("can't find proper extension!");
+ goto ERR;
+ }
+ *extension = ext;
+// DA_SECURE_LOGD("found extension = %s", *extension);
+
+ERR:
+ return ret;
+}
+
diff --git a/agent/download-agent-plugin-conf.c b/agent/download-agent-plugin-conf.c
index 8a547f7..6cb76cb 100755
--- a/agent/download-agent-plugin-conf.c
+++ b/agent/download-agent-plugin-conf.c
@@ -17,12 +17,9 @@
#include <string.h>
#include <stdlib.h>
#include <glib-object.h>
-
-#ifdef _EFL_PLATFORM
-#include <vconf.h>
-#include <vconf-keys.h>
-#include <net_connection.h>
-#endif /* _EFL_PLATFORM */
+#include "vconf.h"
+#include "vconf-keys.h"
+#include "net_connection.h"
#include "download-agent-plugin-conf.h"
#include "download-agent-debug.h"
@@ -30,74 +27,58 @@
#define DEFAULT_UA_STR "Mozilla/5.0 (Linux; U; Tizen 1.0; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Mobile Tizen Browser/1.0"
-da_result_t __get_conf_string(const char *key, char **out_string);
-
-da_result_t __get_conf_string(const char *key, char **out_string)
+da_ret_t __get_conf_string(const char *key, char **out_string)
{
-#ifdef _EFL_PLATFORM
if (!key || !out_string) {
- DA_LOG_ERR(Default,"Invalid Argument");
+ DA_LOGE("Invalid Argument");
return DA_ERR_INVALID_ARGUMENT;
}
*out_string = vconf_get_str(key);
return DA_RESULT_OK;
-#else
- if (out_string)
- *out_string = NULL;
-
- return DA_RESULT_OK;
-#endif
}
-da_result_t get_user_agent_string(char **uagent_str)
+da_ret_t get_user_agent_string(char **uagent_str)
{
- da_result_t ret = DA_RESULT_OK;
-#ifdef _EFL_PLATFORM
+ da_ret_t ret = DA_RESULT_OK;
char *key = DA_NULL;
-#endif
- DA_LOG_FUNC_LOGV(Default);
+ DA_LOGV("");
if (!uagent_str) {
- DA_LOG_ERR(Default,"Invalid Argument");
+ DA_LOGE("Invalid Argument");
return DA_ERR_INVALID_ARGUMENT;
}
-#ifdef _EFL_PLATFORM
key = VCONFKEY_BROWSER_USER_AGENT;
ret = __get_conf_string(key, uagent_str);
if(ret == DA_RESULT_OK) {
if(*uagent_str) {
- DA_SECURE_LOGD("getting uagent_str = \n%s", *uagent_str);
+// DA_SECURE_LOGD("getting uagent_str = \n%s", *uagent_str);
return ret;
}
}
- DA_LOG_ERR(Default,"No UA information from vconf !!");
- *uagent_str = strdup(DEFAULT_UA_STR);
- DA_LOG(Default,"Set default UA");
-#else
+ DA_LOGI("No UA information from vconf !!");
*uagent_str = strdup(DEFAULT_UA_STR);
-#endif
+ DA_LOGV("Set default UA");
return ret;
}
char *get_proxy_address(void)
{
-#ifdef _EFL_PLATFORM
char *proxy = NULL;
char *proxyRet = NULL;
connection_h handle = NULL;
- connection_address_family_e family = CONNECTION_ADDRESS_FAMILY_IPV4;
+ connection_address_family_e family = CONNECTION_ADDRESS_FAMILY_IPV4;
- DA_LOG_FUNC_LOGV(Default);
+ DA_LOGV("");
if (connection_create(&handle) < 0) {
- DA_LOG_ERR(Default,"Fail to create connection handle");
+ DA_LOGE("Fail to create connection handle");
return NULL;
}
if (connection_get_proxy(handle, family, &proxyRet) < 0) {
- DA_LOG_ERR(Default,"Fail to get proxy address");
+ DA_LOGE("Fail to get proxy address");
connection_destroy(handle);
return NULL;
}
@@ -112,11 +93,17 @@ char *get_proxy_address(void)
}
if (connection_destroy(handle) < 0) {
- DA_LOG_ERR(Default,"Fail to desctory connection handle");
+ DA_LOGE("Fail to desctory connection handle");
return NULL;
}
return NULL;
-#else
- return NULL;
-#endif
}
+#ifdef _RAF_SUPPORT
+// test code
+void get_smart_bonding_vconf()
+{
+ int ret = 0;
+ vconf_get_int("file/private/wifi/network_bonding", &ret);
+ DA_LOGI("Smart Bonding Vconf:%d", ret);
+}
+#endif
diff --git a/agent/download-agent-plugin-drm.c b/agent/download-agent-plugin-drm.c
new file mode 100644
index 0000000..22e6f34
--- /dev/null
+++ b/agent/download-agent-plugin-drm.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+
+#include "drm_client.h"
+#include "drm_client_types.h"
+#include "drm_trusted_client.h"
+#include "drm_trusted_client_types.h"
+
+#include "download-agent-debug.h"
+#include "download-agent-plugin-drm.h"
+
+
+void __EDRM_clean_up()
+{
+ int ret = 0;
+ ret = drm_trusted_handle_request(DRM_TRUSTED_REQ_TYPE_CLIENT_CLEAN_UP, NULL, NULL);
+ if (DRM_RETURN_SUCCESS == ret) {
+ DA_LOGD( "Clean up successfull");
+ } else {
+ DA_LOGE("ret[%0x%x]",ret);
+ }
+}
+
+da_bool_t EDRM_convert(const char *in_file_path, char **out_file_path)
+{
+ drm_trusted_conv_info_s input;
+ drm_trusted_conv_resp_info_s output;
+ size_t len = 0;
+ int ret = 0;
+
+ memset(&input, 0x0, sizeof(drm_trusted_conv_info_s));
+ memset(&output, 0x0, sizeof(drm_trusted_conv_resp_info_s));
+
+ len = strlen(in_file_path);
+ if (len >= sizeof(input.filePath))
+ len = sizeof(input.filePath) - 1;
+ memcpy(input.filePath, in_file_path, len);
+
+ ret = drm_trusted_convert_dm(&input, &output);
+
+ if (DRM_TRUSTED_RETURN_SUCCESS != ret) {
+ DA_LOGE("ret[%0x%x]",ret);
+ __EDRM_clean_up();
+ return DA_FALSE;
+ } else {
+ DA_SECURE_LOGD("Returned filePath[%s]", output.filePath);
+ *out_file_path = strdup(output.filePath);
+ }
+ __EDRM_clean_up();
+ return DA_TRUE;
+}
+
+da_ret_t EDRM_wm_get_license(char *rights_url, char **out_content_url)
+{
+ int ret = 0;
+ int len = 0;
+ drm_initiator_info_s init_info;
+ drm_web_server_resp_data_s resp_data;
+
+ if (rights_url == NULL)
+ return DA_ERR_DRM_FAIL;
+
+ memset(&init_info, 0, sizeof(init_info));
+ memset(&resp_data, 0, sizeof(resp_data));
+ strncpy(init_info.initiator_url, rights_url,
+ DRM_MAX_LEN_INITIATOR_URL - 1);
+ len = strlen(rights_url);
+ if (len > DRM_MAX_LEN_INITIATOR_URL - 1)
+ init_info.initiator_url_len = (unsigned int)len;
+ else
+ init_info.initiator_url_len = DRM_MAX_LEN_INITIATOR_URL;
+ ret = drm_process_request(DRM_REQUEST_TYPE_SUBMIT_INITIATOR_URL,
+ &init_info, &resp_data);
+ if (DRM_RETURN_SUCCESS == ret) {
+ DA_SECURE_LOGD("resp_data.content_url = %s", resp_data.content_url);
+ /* Rights or Domain Certificate are installed successfully */
+ /* Check for contentURL */
+ if (strlen(resp_data.content_url) > 0) {
+ char *content_url = NULL;
+ size_t content_url_len = 0;
+ content_url_len = strlen(resp_data.content_url);
+ content_url = (char *)calloc(1, content_url_len + 1);
+ if (content_url) {
+ strncpy(content_url, resp_data.content_url,
+ content_url_len);
+ *out_content_url = content_url;
+ DA_SECURE_LOGD("drm sumitted initiator url "
+ "succeeded with [%s]", *out_content_url);
+ __EDRM_clean_up();
+ return DA_RESULT_OK;
+ } else {
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
+ __EDRM_clean_up();
+ return DA_ERR_FAIL_TO_MEMALLOC;
+ }
+ } else {
+ DA_LOGV("content_url is NULL.\
+ Join/Leave Domain, Metering case.");
+ *out_content_url = DA_NULL;
+ __EDRM_clean_up();
+ return DA_RESULT_OK;
+ }
+ } else {
+ DA_LOGE("drm_process_request() failed");
+ __EDRM_clean_up();
+ return DA_ERR_DRM_FAIL;
+ }
+}
+
diff --git a/agent/download-agent-plugin-libcurl.c b/agent/download-agent-plugin-libcurl.c
new file mode 100644
index 0000000..0c221d2
--- /dev/null
+++ b/agent/download-agent-plugin-libcurl.c
@@ -0,0 +1,702 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "glib.h"
+
+#include "download-agent-dl-info.h"
+#include "download-agent-http-msg-handler.h"
+#include "download-agent-plugin-libcurl.h"
+
+da_bool_t using_content_sniffing = DA_FALSE;
+
+int __translate_error_code(int curl_error)
+{
+ switch (curl_error) {
+ case CURLE_OPERATION_TIMEDOUT:
+ return DA_ERR_HTTP_TIMEOUT;
+ case CURLE_SSL_CONNECT_ERROR:
+ case CURLE_SSL_ENGINE_NOTFOUND:
+ case CURLE_SSL_ENGINE_SETFAILED:
+ case CURLE_SSL_CERTPROBLEM:
+ case CURLE_SSL_CIPHER:
+ case CURLE_SSL_CACERT:
+ case CURLE_SSL_ENGINE_INITFAILED:
+ case CURLE_SSL_CACERT_BADFILE:
+ case CURLE_SSH:
+ case CURLE_SSL_SHUTDOWN_FAILED:
+ case CURLE_SSL_CRL_BADFILE:
+ case CURLE_SSL_ISSUER_ERROR:
+ return DA_ERR_SSL_FAIL;
+ case CURLE_TOO_MANY_REDIRECTS:
+ return DA_ERR_TOO_MANY_REDIRECTS;
+ case CURLE_OUT_OF_MEMORY:
+ return DA_ERR_FAIL_TO_MEMALLOC;
+ case CURLE_UNSUPPORTED_PROTOCOL:
+ case CURLE_URL_MALFORMAT:
+ case CURLE_COULDNT_RESOLVE_PROXY:
+ case CURLE_COULDNT_RESOLVE_HOST:
+ case CURLE_COULDNT_CONNECT:
+ case CURLE_REMOTE_ACCESS_DENIED:
+ case CURLE_HTTP_POST_ERROR:
+ case CURLE_BAD_DOWNLOAD_RESUME:
+ return DA_ERR_CONNECTION_FAIL;
+ case CURLE_ABORTED_BY_CALLBACK:
+ return DA_RESULT_USER_CANCELED;
+ default:
+ return DA_ERR_NETWORK_FAIL;
+ }
+}
+
+int my_trace(CURL *handle, curl_infotype type, char *data, size_t size, void *user)
+{
+ switch(type) {
+ case CURLINFO_TEXT:
+ if (data)
+ DA_SECURE_LOGI("[curl] Info:%s", data);
+ break;
+ case CURLINFO_HEADER_OUT:
+ DA_LOGD("[curl] Send header");
+ if (data)
+ DA_SECURE_LOGI("[curl] %s", data);
+ break;
+ case CURLINFO_DATA_OUT:
+ DA_LOGD("[curl] Send data");
+ if (data)
+ DA_SECURE_LOGI("[curl] %s", data);
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ DA_LOGD("[curl] Send SSL data");
+ break;
+ case CURLINFO_HEADER_IN:
+ DA_LOGD("[curl] Recv header");
+ if (data)
+ DA_SECURE_LOGI("[curl] %s", data);
+ break;
+#if 0
+ case CURLINFO_DATA_IN:
+ DA_LOGD("[curl] Recv data");
+ if (data)
+ DA_SECURE_LOGI("[curl] %d", strlen(data));
+ break;
+#endif
+ case CURLINFO_SSL_DATA_IN:
+ DA_SECURE_LOGI("[curl] Recv SSL data");
+ break;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+void __parse_raw_header(const char *raw_data, http_info_t *http_info)
+{
+ char *ptr = DA_NULL;
+ char *ptr2 = DA_NULL;
+ int len = 0;
+ char *field = DA_NULL;
+ char *value = DA_NULL;
+ http_msg_response_t *http_msg_response = NULL;
+
+ if (!raw_data || !http_info) {
+ DA_LOGE("NULL Check!: raw_data or http_info");
+ return;
+ }
+
+ if (!http_info->http_msg_response) {
+ http_info->http_msg_response = (http_msg_response_t *)calloc(1,
+ sizeof(http_msg_response_t));
+ if (!http_info->http_msg_response) {
+ DA_LOGE("Fail to calloc");
+ return;
+ }
+ http_info->http_msg_response->head = DA_NULL;
+ }
+ http_msg_response = http_info->http_msg_response;
+
+ ptr = strchr(raw_data, ':');
+ if (!ptr)
+ return;
+ len = ptr - (char *)raw_data;
+ field = (char *)calloc(len + 1, sizeof(char));
+ if (!field) {
+ DA_LOGE("Fail to calloc");
+ return;
+ }
+ memcpy(field, raw_data, len);
+ field[len] = '\0';
+ ptr++;
+ while(ptr) {
+ if (*ptr == ' ')
+ ptr++;
+ else
+ break;
+ }
+ ptr2 = strchr(raw_data, '\n');
+ if (ptr2) {
+ len = ptr2 - ptr -1;
+ } else {
+ len = strlen(ptr);
+ }
+ value = (char *)calloc(len + 1, sizeof(char));
+ if (!value) {
+ DA_LOGE("Fail to calloc");
+ free(field);
+ return;
+ }
+ memcpy(value, ptr, len);
+ value[len] = '\0';
+ http_msg_response_add_field(http_msg_response, field, value);
+ free(field);
+ free(value);
+}
+
+void __store_header(void *msg, da_info_t *da_info, size_t header_size,
+ const char *sniffed_type)
+{
+ http_info_t *http_info = DA_NULL;
+
+ if (!da_info || !msg) {
+ DA_LOGE("NULL Check!: da_info or msg");
+ return;
+ }
+ http_info = da_info->http_info;
+ if (!http_info) {
+ DA_LOGE("NULL Check!: http_info");
+ return;
+ }
+
+ // FIXME later : check status code and redirection case check.
+
+ if (strncmp(msg, HTTP_FIELD_END_OF_FIELD,
+ strlen(HTTP_FIELD_END_OF_FIELD)) == 0) {
+ long status = 0;
+ CURLcode res;
+ CURL *curl;
+ http_raw_data_t *raw_data = DA_NULL;
+ curl = http_info->http_msg->curl;
+ res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
+ if (res != CURLE_OK) {
+ DA_LOGE("Fail to get response status code");
+ return;
+ }
+ DA_LOGV("status code[%d]", (int)status);
+ if (http_info->http_msg_response) {
+ http_info->http_msg_response->status_code = (int)status;
+ }
+ raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t));
+ if (!raw_data) {
+ DA_LOGE("Fail to calloc");
+ return;
+ }
+
+ raw_data->status_code = (int)status;
+ raw_data->type = HTTP_EVENT_GOT_HEADER;
+
+ if (http_info->update_cb) {
+ http_info->update_cb(raw_data, da_info);
+ } else {
+ free(raw_data);
+ }
+ return;
+ }
+ DA_LOGI("%s",(char *)msg);
+ __parse_raw_header((const char *)msg, http_info);
+}
+
+size_t __http_gotheaders_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ da_info_t *da_info = DA_NULL;
+ if (!ptr || !userdata) {
+ DA_LOGE("Check NULL!: ptr, userdata");
+ return 0;
+ }
+ da_info = (da_info_t *)userdata;
+ if (da_info->http_info && da_info->http_info->http_msg
+ && da_info->http_info->http_msg->is_cancel_reqeusted) {
+ DA_LOGI("Cancel requested");
+ return -1;
+ }
+ if (!using_content_sniffing)
+ __store_header(ptr, da_info, (size * nmemb), DA_NULL);
+ else
+ DA_LOGV("ignore because content sniffing is turned on");
+/*
+#ifdef _RAF_SUPPORT
+ DA_LOGI("[RAF] __http_gotheaders_cb done");
+#endif
+*/
+ return (size * nmemb);
+}
+
+#ifdef _RAF_SUPPORT
+da_ret_t PI_http_set_file_name_to_curl(http_msg_t *http_msg, char *file_path)
+{
+ NULL_CHECK_RET(http_msg);
+ NULL_CHECK_RET(file_path);
+ DA_LOGI("[RAF]set file_path[%s]", file_path);
+ curl_easy_setopt(http_msg->curl, CURLOPT_BOOSTER_RAF_FILE, file_path);
+ return DA_RESULT_OK;
+}
+#endif
+
+size_t __http_gotchunk_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ http_info_t *http_info = DA_NULL;
+ da_info_t *da_info = DA_NULL;
+ http_raw_data_t *raw_data = DA_NULL;
+ if (!ptr || !userdata) {
+ DA_LOGE("Check NULL!: ptr, stream");
+ return 0;
+ }
+ da_info = (da_info_t *)userdata;
+ NULL_CHECK_RET_OPT(da_info, 0);
+ http_info = da_info->http_info;
+ NULL_CHECK_RET_OPT(http_info, 0);
+ NULL_CHECK_RET_OPT(http_info->http_msg, 0);
+ if (da_info->http_info->http_msg->is_cancel_reqeusted) {
+ DA_LOGI("Cancel requested");
+ return -1;
+ }
+ //DA_LOGV("size=%ld, nmemb=%ld, datalen=%ld", size, nmemb, strlen((const char *)ptr));
+#ifdef _RAF_SUPPORT
+ //DA_LOGI("size=%ld, nmemb=%ld, datalen=%ld", size, nmemb, strlen((const char *)ptr));
+ if (http_info->is_raf_mode_confirmed) {
+ DA_LOGI("[RAF] return chunked callback");
+ return (size * nmemb);
+ }
+#endif
+
+ if (ptr && size * nmemb > 0) {
+ if (http_info->update_cb) {
+ raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t));
+ if (!raw_data) {
+ DA_LOGE("Fail to calloc");
+ return 0;
+ }
+ raw_data->body = (char *)calloc(size, nmemb);
+ if (!(raw_data->body)) {
+ DA_LOGE("Fail to calloc");
+ free(raw_data);
+ return 0;
+ }
+ memcpy(raw_data->body, ptr, size * nmemb);
+ raw_data->body_len = size*nmemb;
+ raw_data->type = HTTP_EVENT_GOT_PACKET;
+ http_info->update_cb(raw_data, da_info);
+ }
+ }
+ return (size * nmemb);
+}
+
+long __http_finished_cb(void *ptr)
+{
+ if (!ptr) {
+ DA_LOGE("Check NULL!: ptr");
+ return CURL_CHUNK_END_FUNC_FAIL;
+ }
+ DA_LOGI("");
+ return CURL_CHUNK_END_FUNC_OK;
+}
+
+
+da_ret_t __set_proxy_on_soup_session(char *proxy_addr, CURL *curl)
+{
+ da_ret_t ret = DA_RESULT_OK;
+
+ if (proxy_addr && strlen(proxy_addr) > 0) {
+ DA_SECURE_LOGI("received proxy[%s]", proxy_addr);
+ if (!strstr(proxy_addr, "0.0.0.0")) {
+ if (strstr((const char *)proxy_addr, "http") == DA_NULL) {
+ char *tmp_str = DA_NULL;
+ int needed_len = 0;
+
+ needed_len = strlen(proxy_addr) + strlen(
+ SCHEME_HTTP) + 1;
+ tmp_str = (char *) calloc(1, needed_len);
+ if (!tmp_str) {
+ DA_LOGE("DA_ERR_FAIL_TO_MEMALLOC");
+ ret = DA_ERR_FAIL_TO_MEMALLOC;
+ goto ERR;
+ }
+ snprintf(tmp_str, needed_len, "%s%s",
+ SCHEME_HTTP, proxy_addr);
+
+ curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr);
+
+ free(tmp_str);
+ } else {
+ DA_LOGV("There is \"http\" on uri, so, push this address to soup directly.");
+ curl_easy_setopt(curl, CURLOPT_PROXY, proxy_addr);
+ }
+ }
+ }
+ERR:
+ return ret;
+}
+
+struct curl_slist *__fill_soup_msg_header(CURL *curl, http_info_t *info)
+{
+ http_msg_request_t *input_http_msg_request;
+ struct curl_slist *headers = DA_NULL;
+
+ if (!curl) {
+ DA_LOGE("NULL Check!: curl");
+ return DA_NULL;
+ }
+ input_http_msg_request = info->http_msg_request;
+
+ if (input_http_msg_request) {
+ char *field = DA_NULL;
+ char *value = DA_NULL;
+ char *buff = DA_NULL;
+ int len = 0;
+ http_header_t *cur = DA_NULL;
+ cur = input_http_msg_request->head;
+ while (cur) {
+ field = cur->field;
+ value = cur->value;
+ if (field && value) {
+ len = strlen(field) + strlen(value) + 1;
+ buff = (char *)calloc(len + 1, sizeof(char));
+ if (!buff) {
+ DA_LOGE("Fail to memalloc");
+ break;
+ }
+// DA_SECURE_LOGI("[%s] %s", field, value);
+ snprintf(buff, len + 1, "%s:%s", field, value);
+ headers = curl_slist_append(headers, (const char *)buff);
+ free(buff);
+ buff = DA_NULL;
+ }
+ cur = cur->next;
+ }
+ } else {
+ DA_LOGE("NULL Check!: input_http_msg_request");
+ return DA_NULL;
+ }
+ if (input_http_msg_request->http_body) {
+ char buff[256] = {0,};
+ int body_len = strlen(input_http_msg_request->http_body);
+ snprintf(buff, sizeof(buff), "%s:%d", HTTP_FIELD_CONTENT_LENGTH,
+ body_len);
+ headers = curl_slist_append(headers, buff);
+ memset(buff, 0x00, 256);
+ snprintf(buff, sizeof(buff), "%s:text/plain", HTTP_FIELD_CONTENT_TYPE);
+ headers = curl_slist_append(headers, buff);
+ headers = curl_slist_append(headers, input_http_msg_request->http_body);
+ }
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+ return headers;
+}
+
+#ifdef _RAF_SUPPORT
+int __http_progress_cb(void *clientp, double dltotal, double dlnow,
+ double ultotal, double ulnow)
+{
+ da_info_t *da_info = DA_NULL;
+ http_info_t *http_info = DA_NULL;
+ http_raw_data_t *raw_data = DA_NULL;
+/*
+ if (dlnow > 0 || ulnow > 0)
+ DA_LOGI("[RAF]dlnow/ulnow[%llu/%llu][%llu,%llu]", (da_size_t)dlnow, (da_size_t)ulnow, (da_size_t)dltotal, (da_size_t)ultotal);
+*/
+
+/*
+ if (dlnow == 0) {
+ DA_LOGI("[RAF]dlnow is zero. Why is this callback called although there is zero size?");
+ }
+*/
+ NULL_CHECK_RET_OPT(clientp, -1);
+ da_info = (da_info_t *)clientp;
+ http_info = da_info->http_info;
+ NULL_CHECK_RET_OPT(http_info, -1);
+ NULL_CHECK_RET_OPT(http_info->http_msg, -1);
+
+ if (http_info->http_msg->is_cancel_reqeusted) {
+ DA_LOGI("Cancel requested");
+ return -1;
+ }
+
+ if (dlnow > 0) {
+ if (http_info->update_cb) {
+ raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t));
+ if (!raw_data) {
+ DA_LOGE("Fail to calloc");
+ return 0;
+ }
+ raw_data->received_len = (da_size_t)dlnow;
+ raw_data->type = HTTP_EVENT_GOT_PACKET;
+ http_info->update_cb(raw_data, da_info);
+ }
+ }
+ return CURLE_OK;
+}
+#endif
+
+da_ret_t PI_http_start(da_info_t *da_info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_method_t http_method;
+ CURL *curl = DA_NULL;
+ CURLcode res;
+ http_msg_t *http_msg = DA_NULL;
+ char *url = DA_NULL;
+ http_info_t *http_info = DA_NULL;
+ long http_status = 0;
+ struct curl_httppost* post = NULL;
+ struct curl_slist *headers = DA_NULL;
+ char err_buffer[CURL_ERROR_SIZE] = {0,};
+
+ DA_LOGV("");
+#ifdef _RAF_SUPPORT
+ // test code
+ get_smart_bonding_vconf();
+#endif
+ NULL_CHECK_GOTO(da_info);
+ NULL_CHECK_GOTO(da_info->req_info);
+ url = da_info->req_info->url;
+ NULL_CHECK_GOTO(url);
+ http_info = da_info->http_info;
+ NULL_CHECK_GOTO(http_info);
+
+ http_method = http_info->http_method;
+ ret = init_http_msg_t(&http_msg);
+ if (ret != DA_RESULT_OK)
+ goto ERR;
+ http_info->http_msg = http_msg;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ curl = curl_easy_init();
+
+ if (!curl) {
+ DA_LOGE("Fail to create curl");
+ return DA_ERR_FAIL_TO_MEMALLOC;
+ }
+ DA_LOGI("curl[%p]", curl);
+
+ curl_easy_setopt(curl, CURLOPT_MAXCONNECTS, MAX_SESSION_COUNT);
+ curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, MAX_TIMEOUT);
+
+ __set_proxy_on_soup_session(http_info->proxy_addr, curl);
+
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ switch (http_method) {
+ case HTTP_METHOD_GET:
+ curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
+ break;
+ case HTTP_METHOD_POST:
+ // FIXME later : If the post method is supprot, the post data should be set with curl_fromadd
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
+ DA_LOGI("Need more information for post filed");
+ break;
+ case HTTP_METHOD_HEAD:
+ DA_LOGI("Donnot implement yet");
+ break;
+ default:
+ DA_LOGE("Cannot enter here");
+ break;
+ }
+
+ if (using_content_sniffing) {
+ /* FIXME later*/
+ } else {
+ /* FIXME later*/
+ }
+ headers = __fill_soup_msg_header(curl, http_info);
+
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, __http_gotheaders_cb); // can replace to started_cb
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, da_info); // param .. same with CURLOPT_WRITEHEADER
+ curl_easy_setopt(curl, CURLOPT_HEADER, 0L); // does not include header to body
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, __http_gotchunk_cb); // can replace to progress_
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, da_info); // param .. same with CURLOPT_WRITEHEADERcb
+ curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, __http_finished_cb);
+ curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, da_info);
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+// curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
+ curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, err_buffer);
+ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+#ifdef _RAF_SUPPORT
+ curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, __http_progress_cb);
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, da_info);
+ curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+#endif
+
+ if (da_info->req_info->network_bonding) {
+#ifdef _DOWNLOAD_BOOSTER_SUPPORT
+ DA_LOGI("network bonding enable");
+ curl_easy_setopt(curl, CURLOPT_MULTIRAT_NEEDED, 1L);
+#endif
+#ifdef _RAF_SUPPORT
+ curl_easy_setopt(curl, CURLOPT_BOOSTER_RAF_MODE, 1L);
+#endif
+ }
+ http_msg->curl = curl;
+ res = curl_easy_perform(curl);
+ DA_LOGD("perform done! res[%d]",res);
+ if (res != CURLE_OK) {
+ //DA_LOGE("Fail to send data :%d[%s]", res, curl_easy_strerror(res));
+ DA_LOGE("Fail to perform :%d[%s]", res, curl_multi_strerror(res));
+ if (strlen(err_buffer) > 1)
+ DA_LOGE("Fail to error buffer[%s]", err_buffer);
+ }
+ if (res != CURLE_OK) {
+ //DA_LOGE("Fail to send data :%d[%s]", res, curl_easy_strerror(res));
+ DA_LOGE("Fail to send data :%d[%s]", res, curl_easy_strerror(res));
+ if (strlen(err_buffer) > 1)
+ DA_LOGE("Fail to error buffer[%s]", err_buffer);
+ } else {
+ res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
+ if (res != CURLE_OK) {
+ //DA_LOGE("Fail to get response code:%d[%s]", res, curl_easy_strerror(res));
+ DA_LOGE("Fail to get response code:%d[%s]", res, curl_easy_strerror(res));
+ ret = DA_ERR_FAIL_TO_MEMALLOC;;
+ goto ERR;
+ } else {
+ DA_LOGD("Response Http Status code[%d]", (int)http_status);
+ }
+ }
+ if (http_info->update_cb) {
+ http_raw_data_t *raw_data = DA_NULL;
+ raw_data = (http_raw_data_t *)calloc(1, sizeof(http_raw_data_t));
+ if (!raw_data) {
+ DA_LOGE("Fail to calloc");
+ ret = DA_ERR_FAIL_TO_MEMALLOC;
+ goto ERR;
+ }
+ if (http_msg->is_cancel_reqeusted ||
+ res == CURLE_ABORTED_BY_CALLBACK) {
+ DA_LOGI("canceled exit. Err[%d]", http_info->error_code);
+ if (http_info->error_code < 0)
+ ret = http_info->error_code;
+ else
+ ret = DA_RESULT_USER_CANCELED;
+ } else if ((http_status > 0 && http_status < 100)) {
+ raw_data->error = __translate_error_code(res);
+ ret = DA_ERR_NETWORK_FAIL;
+ } else if (res != CURLE_OK) {
+ raw_data->error = __translate_error_code(res);
+ ret = DA_ERR_NETWORK_FAIL;
+ } else {
+ raw_data->status_code = (int)http_status;
+ }
+ raw_data->type = HTTP_EVENT_FINAL;
+ http_info->update_cb(raw_data, da_info);
+ }
+ if (DA_NULL != headers)
+ curl_slist_free_all(headers);
+ curl_easy_cleanup(curl);
+ http_msg->curl = DA_NULL;
+ DA_MUTEX_INIT(&(http_msg->mutex), DA_NULL);
+ERR:
+ DA_LOGD("Done");
+ return ret;
+
+}
+
+da_ret_t PI_http_disconnect(http_info_t *info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_msg_t *http_msg = DA_NULL;
+
+ DA_LOGD("");
+ NULL_CHECK_RET(info);
+ http_msg = info->http_msg;
+ NULL_CHECK_RET(http_msg);
+ DA_LOGV("session [%p]", http_msg->curl);
+ DA_MUTEX_LOCK(&(http_msg->mutex));
+ if (http_msg->is_paused)
+ PI_http_unpause(info);
+ if (http_msg->curl)
+ curl_easy_cleanup(http_msg->curl);
+
+ http_msg->curl = DA_NULL;
+ http_msg->is_paused = DA_FALSE;
+ http_msg->is_cancel_reqeusted = DA_FALSE;
+ DA_MUTEX_UNLOCK(&(http_msg->mutex));
+ DA_MUTEX_DESTROY(&(http_msg->mutex));
+ destroy_http_msg_t(http_msg);
+ info->http_msg = DA_NULL;
+ return ret;
+}
+
+da_ret_t PI_http_cancel(http_info_t *info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_msg_t *http_msg = DA_NULL;
+
+ DA_LOGV("");
+
+ NULL_CHECK_RET(info);
+ http_msg = info->http_msg;
+ NULL_CHECK_RET(http_msg);
+ NULL_CHECK_RET(http_msg->curl);
+ DA_MUTEX_LOCK(&(http_msg->mutex));
+ DA_LOGI("curl[%p]", http_msg->curl);
+ http_msg->is_cancel_reqeusted = DA_TRUE;
+ DA_MUTEX_UNLOCK(&(http_msg->mutex));
+ DA_LOGD("Done - soup cancel");
+ return ret;
+}
+
+da_ret_t PI_http_pause(http_info_t *info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_msg_t *http_msg = DA_NULL;
+ CURLcode res = CURLE_OK;
+ DA_LOGV("");
+
+ NULL_CHECK_RET(info);
+ http_msg = info->http_msg;
+ NULL_CHECK_RET(http_msg);
+ DA_LOGD("curl [%p]", http_msg->curl);
+ NULL_CHECK_RET(http_msg->curl);
+ DA_MUTEX_LOCK(&(http_msg->mutex));
+ DA_LOGE("curl_easy_pause call");
+ curl_easy_pause(http_msg->curl, CURLPAUSE_ALL);
+ DA_LOGE("curl_easy_pause:%d", res);
+ if (res == CURLE_OK) {
+ http_msg->is_paused = DA_TRUE;
+ } else {
+ ret = DA_ERR_CANNOT_SUSPEND;
+ }
+ DA_MUTEX_UNLOCK(&(http_msg->mutex));
+ return ret;
+}
+
+da_ret_t PI_http_unpause(http_info_t *info)
+{
+ da_ret_t ret = DA_RESULT_OK;
+ http_msg_t *http_msg = DA_NULL;
+ CURLcode res = CURLE_OK;
+ DA_LOGV("");
+
+ NULL_CHECK_RET(info);
+ http_msg = info->http_msg;
+ DA_LOGV("curl [%p]", http_msg->curl);
+ NULL_CHECK_RET(http_msg->curl);
+ DA_MUTEX_LOCK(&(http_msg->mutex));
+ res = curl_easy_pause(http_msg->curl, CURLPAUSE_CONT);
+ if (res == CURLE_OK)
+ http_msg->is_paused = DA_FALSE;
+ else
+ ret = DA_ERR_CANNOT_RESUME;
+ DA_MUTEX_UNLOCK(&(http_msg->mutex));
+ return ret;
+}
diff --git a/agent/download-agent-plugin-libsoup.c b/agent/download-agent-plugin-libsoup.c
deleted file mode 100755
index 6d54afd..0000000
--- a/agent/download-agent-plugin-libsoup.c
+++ /dev/null
@@ -1,1002 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "download-agent-debug.h"
-#include "download-agent-plugin-libsoup.h"
-#include "download-agent-http-misc.h"
-#include "download-agent-utils.h"
-#include "download-agent-pthread.h"
-
-pthread_mutex_t mutex_for_session_table = PTHREAD_MUTEX_INITIALIZER;
-
-pi_session_table_t pi_session_table[MAX_SESSION_COUNT] = { { 0, }, };
-da_bool_t using_content_sniffing;
-
-da_bool_t _pi_http_is_this_session_table_entry_using(
- const int in_session_table_entry);
-
-da_result_t PI_http_init(void)
-{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- using_content_sniffing = DA_TRUE;
-
- return DA_RESULT_OK;
-}
-
-void PI_http_deinit(void)
-{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- return;
-}
-
-da_result_t _set_proxy_on_soup_session(SoupSession *session, char *proxy_addr)
-{
- da_result_t ret = DA_RESULT_OK;
-
-
- if (proxy_addr && strlen(proxy_addr) > 0) {
- DA_SECURE_LOGD("received proxy = %s \n", proxy_addr);
- if (!strstr(proxy_addr, "0.0.0.0")) {
- if (strstr((const char *)proxy_addr, "http") == DA_NULL) {
- DA_LOG_VERBOSE(Default,"There is no \"http://\" on received uri, so, add it.");
-
- char *tmp_str = DA_NULL;
- int needed_len = 0;
-
- needed_len = strlen(proxy_addr) + strlen(
- SCHEME_HTTP) + 1;
- tmp_str = (char *) calloc(1, needed_len);
- if (!tmp_str) {
- DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
- snprintf(tmp_str, needed_len, "%s%s",
- SCHEME_HTTP, proxy_addr);
-
- g_object_set(session, SOUP_SESSION_PROXY_URI,
- soup_uri_new(tmp_str), NULL);
-
- free(tmp_str);
- } else {
- DA_LOG(HTTPManager,"There is \"http\" on uri, so, push this address to soup directly.");
- g_object_set(session, SOUP_SESSION_PROXY_URI,
- soup_uri_new(proxy_addr), NULL);
- }
- }
- } else {
- DA_LOG_VERBOSE(HTTPManager,"There is no proxy value");
- }
-ERR:
- return ret;
-}
-
-void _fill_soup_msg_header(SoupMessage *msg,
- const input_for_tranx_t *input_for_tranx)
-{
- SoupMessageHeaders *headers = msg->request_headers;
-
- http_msg_request_t *input_http_msg_request;
- http_msg_iter_t http_msg_iter;
- http_msg_iter_t http_msg_iter_pre;
-
- char *field;
- char *value;
-
- input_http_msg_request = input_for_tranx->http_msg_request;
-
- http_msg_request_get_iter(input_http_msg_request, &http_msg_iter);
- http_msg_iter_pre = http_msg_iter;
- while (http_msg_get_field_with_iter(&http_msg_iter, &field, &value)) {
- if ((field != DA_NULL) && (value != DA_NULL)) {
- DA_SECURE_LOGD("[%s] %s", field, value);
- soup_message_headers_append(headers, field, value);
- }
- http_msg_iter_pre = http_msg_iter;
- }
-
- if (input_http_msg_request->http_body) {
- char body_len_str[16] = { 0, };
- int body_len = strlen(input_http_msg_request->http_body);
-
- snprintf(body_len_str, sizeof(body_len_str), "%d", body_len);
-
- soup_message_headers_append(headers, "Content-Length",
- body_len_str);
- soup_message_headers_append(headers, "Content-Type",
- "text/plain");
- soup_message_body_append(msg->request_body, SOUP_MEMORY_COPY,
- input_http_msg_request->http_body, body_len);
- }
-}
-
-da_result_t PI_http_start_transaction(const input_for_tranx_t *input_for_tranx,
- int *out_tranx_id)
-{
- da_result_t ret = DA_RESULT_OK;
- int session_table_entry = -1;
- pi_http_method_t pi_http_method = PI_HTTP_METHOD_GET;
- queue_t *queue = DA_NULL;
- char *url = DA_NULL;
- SoupSession *session = DA_NULL;
- SoupMessage *msg = DA_NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (DA_FALSE == _pi_http_is_valid_input_for_tranx(input_for_tranx)) {
- DA_LOG_ERR(HTTPManager,"input_for_tranx is invalid");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- } else {
- queue = input_for_tranx->queue;
- pi_http_method = input_for_tranx->http_method;
- url = input_for_tranx->http_msg_request->url;
- }
-
- session_table_entry = _pi_http_get_avaiable_session_table_entry();
- if (session_table_entry == -1) {
- ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
- goto ERR;
- }
- DA_LOG_VERBOSE(HTTPManager,"session_table_entry = %d", session_table_entry);
-
- if (DA_FALSE == _pi_http_register_queue_to_session_table(
- session_table_entry, queue)) {
- _pi_http_destroy_session_table_entry(session_table_entry);
- ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
- goto ERR;
- }
-
- /* modified by keunsoon.lee 2010-09-20 use sync_new() instead of async_new() for make different soup thread from UI main thread*/
- session = soup_session_sync_new();
- /* session=soup_session_async_new(); */
- if (!session) {
- DA_LOG_ERR(HTTPManager,"Fail to create session");
- return DA_ERR_INVALID_URL;
- }
- DA_LOG(HTTPManager,"session[%p]", session);
-/*
- SoupLogger* logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1);
- soup_logger_attach(logger, session);
- g_object_unref(logger);
-*/
- if (DA_FALSE == _pi_http_register_session_to_session_table(
- session_table_entry, session)) {
- _pi_http_init_session_table_entry(session_table_entry);
- ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
- goto ERR;
- }
-
- g_object_set(session, SOUP_SESSION_MAX_CONNS, MAX_SESSION_COUNT, NULL);
- /* Set timeout unlimited time to resume a download which has ETag when the network is re-connected
- * => This is changed to 180 seconds due to limitation of max downloading items.
- */
- g_object_set(session, SOUP_SESSION_TIMEOUT, MAX_TIMEOUT, NULL);
-
- _set_proxy_on_soup_session(session, input_for_tranx->proxy_addr);
-
- switch (pi_http_method) {
- case PI_HTTP_METHOD_GET:
- msg = soup_message_new(METHOD_GET, url);
- break;
- case PI_HTTP_METHOD_POST:
- msg = soup_message_new(METHOD_POST, url);
- break;
- case PI_HTTP_METHOD_HEAD:
- msg = soup_message_new(METHOD_HEAD, url);
- break;
- default:
- DA_LOG_ERR(HTTPManager,"Cannot enter here");
- break;
- }
- DA_LOG_VERBOSE(HTTPManager,"msg[%p]", msg);
- /* if it is failed to create a msg, the url can be invalid, becasue of the input argument of soup_message_new API */
- if (msg == NULL) {
- DA_LOG_ERR(HTTPManager,"Fail to create message");
- ret = DA_ERR_INVALID_URL;
- goto ERR;
- }
-
- _fill_soup_msg_header(msg, input_for_tranx);
-
- g_signal_connect(msg, "restarted", G_CALLBACK(_pi_http_restarted_cb),
- NULL); /* for redirection case */
- g_signal_connect(msg, "got-headers",
- G_CALLBACK(_pi_http_gotheaders_cb), NULL);
- g_signal_connect(msg, "got-chunk", G_CALLBACK(_pi_http_gotchunk_cb),
- NULL);
-
- if (using_content_sniffing) {
- soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER);
- g_signal_connect(msg, "content-sniffed",
- G_CALLBACK(_pi_http_contentsniffed_cb), NULL);
- } else {
- soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER);
- }
-
- soup_session_queue_message(session, msg, _pi_http_finished_cb, NULL);
-// g_signal_connect(msg, "finished", G_CALLBACK(_pi_http_finished_cb), NULL);
-
- if (DA_FALSE == _pi_http_register_msg_to_session_table(
- session_table_entry, msg)) {
- _pi_http_destroy_session_table_entry(session_table_entry);
- ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
- goto ERR;
- }
-
- *out_tranx_id = session_table_entry;
- DA_LOG(HTTPManager,"*out_tranx_id = %d", *out_tranx_id);
-
-ERR:
- return ret;
-}
-
-da_result_t PI_http_disconnect_transaction(int in_tranx_id)
-{
- da_result_t ret = DA_RESULT_OK;
- int session_table_entry = -1;
-
- DA_LOG_VERBOSE(HTTPManager,"in_tranx_id = %d", in_tranx_id);
-
- session_table_entry = in_tranx_id;
-
- _pi_http_destroy_session_table_entry(session_table_entry);
-
- return ret;
-}
-
-da_result_t PI_http_cancel_transaction(int in_tranx_id, da_bool_t abort_option)
-{
- da_result_t ret = DA_RESULT_OK;
- SoupSession *session;
- SoupMessage *msg;
- int session_table_entry = -1;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- session_table_entry = in_tranx_id;
- if (!_pi_http_is_this_session_table_entry_using(session_table_entry)) {
- DA_LOG_CRITICAL(HTTPManager,"not using session");
- return ret;
- }
- session = GET_SESSION_FROM_TABLE_ENTRY(session_table_entry);
- msg = GET_MSG_FROM_TABLE_ENTRY(session_table_entry);
-
- if (DA_NULL == session) {
- DA_LOG_ERR(HTTPManager,"invalid session = %p", session);
- goto ERR;
- }
-
- if (DA_NULL == msg) {
- DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
- goto ERR;
- }
- DA_LOG(HTTPManager,"soup cancel API:abort option[%d] tranx_id[%d]",
- abort_option, in_tranx_id);
- if (abort_option)
- soup_session_abort(session);
- else
- soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED);
- DA_LOG(HTTPManager,"soup cancel API-Done");
-ERR:
- return ret;
-}
-
-void PI_http_pause_transaction(int transaction_id)
-{
- int session_table_entry = -1;
- pthread_mutex_t *mutex;
- pthread_cond_t *cond;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- DA_LOG(HTTPManager,"in_tranx_id = %d", transaction_id);
-
- session_table_entry = transaction_id;
-
- if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
- return;
-
- mutex = &(pi_session_table[session_table_entry].mutex);
- cond = &(pi_session_table[session_table_entry].cond);
-
- _da_thread_mutex_lock (mutex);
-
- if (pi_session_table[session_table_entry].is_paused == DA_FALSE) {
- DA_LOG_CRITICAL(HTTPManager,"paused!");
- pi_session_table[session_table_entry].is_paused = DA_TRUE;
- _da_thread_cond_wait(cond, mutex);
- } else {
- DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
- }
-
- _da_thread_mutex_unlock (mutex);
-
-}
-
-void PI_http_unpause_transaction(int transaction_id)
-{
- int session_table_entry = -1;
- pthread_mutex_t *mutex;
- pthread_cond_t *cond;
-
- DA_LOG_FUNC_LOGV(Default);
-
- session_table_entry = transaction_id;
-
- if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
- return;
-
- mutex = &(pi_session_table[session_table_entry].mutex);
- cond = &(pi_session_table[session_table_entry].cond);
-
- _da_thread_mutex_lock (mutex);
-
- if (pi_session_table[session_table_entry].is_paused == DA_TRUE) {
- DA_LOG_CRITICAL(HTTPManager,"wake up!");
- pi_session_table[session_table_entry].is_paused = DA_FALSE;
- _da_thread_cond_signal(cond);
- }
-
- _da_thread_mutex_unlock (mutex);
-
-}
-
-da_bool_t _pi_http_is_valid_input_for_tranx(
- const input_for_tranx_t *input_for_tranx)
-{
- if (!(input_for_tranx->http_msg_request)) {
- DA_LOG_ERR(HTTPManager,"http_msg_request is NULL");
- return DA_FALSE;
- }
-
- if (!((input_for_tranx->http_method == PI_HTTP_METHOD_GET) ||
- (input_for_tranx->http_method == PI_HTTP_METHOD_POST) ||
- (input_for_tranx->http_method == PI_HTTP_METHOD_HEAD))) {
- DA_LOG_ERR(HTTPManager,"http_method is neither GET or POST or HEAD");
- return DA_FALSE;
- }
-
- return DA_TRUE;
-}
-
-da_bool_t _pi_http_is_this_session_table_entry_using(
- const int in_session_table_entry)
-{
- da_bool_t is_using = DA_FALSE;
-
- if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(in_session_table_entry))
- return DA_FALSE;
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- is_using = pi_session_table[in_session_table_entry].is_using;
-
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return is_using;
-}
-
-void _pi_http_init_session_table_entry(const int in_session_table_entry)
-{
- int entry = in_session_table_entry;
-
- if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
- return;
-
-// _da_thread_mutex_lock (&mutex_for_session_table);
-
- pi_session_table[entry].is_using = DA_TRUE;
- pi_session_table[entry].msg = NULL;
- pi_session_table[entry].session = NULL;
- pi_session_table[entry].queue = NULL;
-
- _da_thread_mutex_init(&(pi_session_table[entry].mutex), DA_NULL);
- _da_thread_cond_init(&(pi_session_table[entry].cond), NULL);
- pi_session_table[entry].is_paused = DA_FALSE;
-
-// _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return;
-}
-
-void _pi_http_destroy_session_table_entry(const int in_session_table_entry)
-{
- int entry = in_session_table_entry;
-
- if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
- return;
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- if (pi_session_table[entry].is_paused == DA_TRUE)
- PI_http_unpause_transaction(entry);
-
- /* Warning! Do not g_object_unref(msg) here!
- * soup_session_queue_message() steals msg's reference count,
- * so, we don't need to do anything for memory management.
- *
- * But, if using soup_session_send_message(), MUST call g_object_unref(msg). */
- /* if (pi_session_table[entry].msg)
- g_object_unref(pi_session_table[entry].msg); */
-
- pi_session_table[entry].msg = NULL;
-
- /* FIXME Cannot g_object_unref(session) here,
- * because msg inside this session is not destoryed yet.
- * The msg's reference count is stealed by soup_session_queue_message(),
- * and it will be destroyed when _pi_http_finished_cb() is returned.
- * For now, this _pi_http_destroy_session_table_entry() is called inside
- * _pi_http_finished_cb(), so, g_object_unref(session) is not working.
- * Should find out call this function after _pi_http_finished_cb(). */
- if (pi_session_table[entry].session)
- g_object_unref(pi_session_table[entry].session);
- else
- DA_LOG_ERR(HTTPManager,"session is NULL. Cannot unref this.");
- DA_LOG(HTTPManager,"unref session [%p]",pi_session_table[entry].session);
-
- pi_session_table[entry].session = NULL;
-
- pi_session_table[entry].queue = NULL;
- pi_session_table[entry].is_paused = DA_FALSE;
- pi_session_table[entry].is_using = DA_FALSE;
-
- _da_thread_mutex_destroy(&(pi_session_table[entry].mutex));
- _da_thread_cond_destroy(&(pi_session_table[entry].cond));
-
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return;
-}
-
-int _pi_http_get_avaiable_session_table_entry(void)
-{
- int i;
- int avaiable_entry = -1;
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- for (i = 0; i < MAX_SESSION_COUNT; i++) {
- if (pi_session_table[i].is_using == DA_FALSE) {
- /* pi_session_table[i].is_using = DA_TRUE; */
- DA_LOG_VERBOSE(HTTPManager,"available entry = %d", i);
-
- avaiable_entry = i;
-
- break;
- }
- }
- _pi_http_init_session_table_entry(avaiable_entry);
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return avaiable_entry;
-}
-
-da_bool_t _pi_http_register_queue_to_session_table(
- const int in_session_table_entry, const queue_t *in_queue)
-{
- int entry = in_session_table_entry;
- queue_t *queue = (queue_t *) in_queue;
- da_bool_t ret = DA_FALSE;
-
- if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
- DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
- return DA_FALSE;
- }
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- if (pi_session_table[entry].is_using == DA_FALSE) {
- DA_LOG_ERR(HTTPManager,"this entry [%d] is not using", entry);
- ret = DA_FALSE;
- } else {
- pi_session_table[entry].queue = queue;
- DA_LOG_VERBOSE(HTTPManager,"queue = %p", pi_session_table[entry].queue);
- ret = DA_TRUE;
- }
-
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return ret;
-}
-
-da_bool_t _pi_http_register_session_to_session_table(
- const int in_session_table_entry, SoupSession *session)
-{
- int entry = in_session_table_entry;
- da_bool_t ret = DA_FALSE;
-
- if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
- DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
- return DA_FALSE;
- }
-
- if (DA_NULL == session) {
- DA_LOG_ERR(HTTPManager,"invalid session = %p",session);
- return DA_FALSE;
- }
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- if (pi_session_table[entry].is_using == DA_FALSE) {
- ret = DA_FALSE;
- } else {
- pi_session_table[entry].session = session;
- ret = DA_TRUE;
- }
-
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return ret;
-}
-
-da_bool_t _pi_http_register_msg_to_session_table(
- const int in_session_table_entry, SoupMessage *msg)
-{
- int entry = in_session_table_entry;
- da_bool_t ret = DA_FALSE;
-
- if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
- DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
- return DA_FALSE;
- }
-
- if (DA_NULL == msg) {
- DA_LOG_ERR(HTTPManager,"invalid msg = %p",msg);
- return DA_FALSE;
- }
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- if (pi_session_table[entry].is_using == DA_FALSE) {
- ret = DA_FALSE;
- } else {
- pi_session_table[entry].msg = msg;
- ret = DA_TRUE;
- }
-
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return ret;
-}
-
-queue_t *_pi_http_get_queue_from_session_table_entry(
- const int in_session_table_entry)
-{
- int entry = in_session_table_entry;
- queue_t *out_queue = NULL;
-
- if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
- DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
- return out_queue;
- }
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- out_queue = pi_session_table[entry].queue;
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- return out_queue;
-}
-
-void _pi_http_store_read_header_to_queue(SoupMessage *msg, const char *sniffedType)
-{
- da_result_t ret = DA_RESULT_OK;
-
- queue_t *da_queue = NULL;
- q_event_t *da_event = NULL;
- q_event_type_data da_event_type_data;
-
- int session_table_entry = -1;
- SoupMessageHeadersIter headers_iter;
-
- const char *header_name;
- const char *header_value;
-
- http_msg_response_t *http_msg_response = NULL;
-
- if (msg->response_headers) {
- ret = http_msg_response_create(&http_msg_response);
- if (ret != DA_RESULT_OK)
- return;
-
- http_msg_response_set_status_code(http_msg_response,
- msg->status_code);
-
- DA_LOG_VERBOSE(HTTPManager,"\n----raw header---------------------------------------------");
- DA_LOG(HTTPManager,"status code = %d", msg->status_code);
- soup_message_headers_iter_init(&headers_iter,
- msg->response_headers);
- while (soup_message_headers_iter_next(&headers_iter,
- &header_name, &header_value)) {
- if ((header_name != DA_NULL) && (header_value
- != DA_NULL)) {
- http_msg_response_add_field(http_msg_response,
- header_name, header_value);
- DA_SECURE_LOGI("[%s][%s]", header_name, header_value);
- }
- }
- DA_LOG_VERBOSE(HTTPManager,"\n-------------------------------------------------------------\n");
-
- }
-
- if (using_content_sniffing && sniffedType)
- http_msg_response_set_content_type(http_msg_response, sniffedType);
-
- session_table_entry
- = _pi_http_get_session_table_entry_from_message(msg);
- if (session_table_entry == -1) {
- DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
-
- da_queue = _pi_http_get_queue_from_session_table_entry(
- session_table_entry);
-
- ret = Q_make_http_data_event(da_event_type_data, &da_event);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(HTTPManager,"fail to make da_event");
- goto ERR;
- } else {
- Q_set_status_code_on_http_data_event(da_event, msg->status_code);
- da_event->type.q_event_data_http.http_response_msg
- = http_msg_response;
-
- Q_push_event(da_queue, da_event);
- }
- return;
-
-ERR:
- if (DA_RESULT_OK != ret)
- http_msg_response_destroy(&http_msg_response);
-
- return;
-}
-
-void _pi_http_store_read_data_to_queue(SoupMessage *msg, const char *body_data,
- int received_body_len)
-{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t b_ret = DA_FALSE;
-
- char *body_buffer = NULL;
- queue_t *da_queue = NULL;
- q_event_t *da_event = NULL;
- q_event_type_data da_event_type_data;
- int session_table_entry = -1;
- int http_status = -1;
-
- http_status = msg->status_code;
-
- session_table_entry
- = _pi_http_get_session_table_entry_from_message(msg);
- if (session_table_entry == -1) {
- DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- if (received_body_len == 0) {
- DA_LOG_VERBOSE(HTTPManager,"Q_EVENT_TYPE_DATA_FINAL");
- da_event_type_data = Q_EVENT_TYPE_DATA_FINAL;
- } else {
- da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
- if (received_body_len > 0) {
- body_buffer = (char*) calloc(1, received_body_len);
- DA_LOG_VERBOSE(HTTPManager,"body_buffer[%p]msg[%p]",body_buffer,msg);
- if (body_buffer == DA_NULL) {
- DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC");
- goto ERR;
- }
- memcpy(body_buffer, body_data, received_body_len);
- }
- }
-
- da_queue = _pi_http_get_queue_from_session_table_entry(
- session_table_entry);
-
- ret = Q_make_http_data_event(da_event_type_data, &da_event);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(HTTPManager,"fail to make da_event");
- goto ERR;
- } else {
- Q_set_status_code_on_http_data_event(da_event, http_status);
- Q_set_http_body_on_http_data_event(da_event, received_body_len,
- body_buffer);
-
- _da_thread_mutex_lock (&(da_queue->mutex_queue));
- b_ret = Q_push_event_without_lock(da_queue, da_event);
- if (b_ret == DA_FALSE) {
- DA_LOG_CRITICAL(HTTPManager,"----------------------------------------fail to push!");
-
- pthread_mutex_t *session_mutex = NULL;
- pthread_cond_t *session_cond = NULL;
-
- session_mutex
- = &(pi_session_table[session_table_entry].mutex);
- session_cond
- = &(pi_session_table[session_table_entry].cond);
-
- /* MUST keep this order for these mutexes */
- _da_thread_mutex_lock (session_mutex);
- _da_thread_mutex_unlock (&(da_queue->mutex_queue));
-
- if (pi_session_table[session_table_entry].is_paused
- == DA_FALSE) {
- DA_LOG_CRITICAL(HTTPManager,"paused!");
- pi_session_table[session_table_entry].is_paused
- = DA_TRUE;
- _da_thread_cond_wait(session_cond, session_mutex);
- } else {
- DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
- }
-
- _da_thread_mutex_unlock (session_mutex);
-
- DA_LOG_CRITICAL(HTTPManager,"wake up! push again");
- Q_push_event(da_queue, da_event);
- } else {
- _da_thread_mutex_unlock (&(da_queue->mutex_queue));
- }
-
- }
-
- return;
-
-ERR:
- if (DA_RESULT_OK != ret) {
- if (DA_NULL != body_buffer) {
- free(body_buffer);
- }
- }
-
- return;
-}
-
-int _translate_error_code(int soup_error)
-{
- DA_LOG_CRITICAL(HTTPManager, "soup error code[%d]", soup_error);
- switch (soup_error) {
- case SOUP_STATUS_CANT_RESOLVE:
- case SOUP_STATUS_CANT_RESOLVE_PROXY:
- case SOUP_STATUS_CANT_CONNECT:
- case SOUP_STATUS_CANT_CONNECT_PROXY:
- case SOUP_STATUS_IO_ERROR:
- case SOUP_STATUS_MALFORMED:
- case SOUP_STATUS_TRY_AGAIN:
- return DA_ERR_NETWORK_FAIL;
- case SOUP_STATUS_SSL_FAILED:
- return DA_ERR_SSL_FAIL;
- case SOUP_STATUS_REQUEST_TIMEOUT:
- return DA_ERR_HTTP_TIMEOUT;
- case SOUP_STATUS_TOO_MANY_REDIRECTS:
- return DA_ERR_TOO_MANY_REDIECTS;
- default:
- return DA_ERR_NETWORK_FAIL;
- }
-}
-
-void _pi_http_store_neterr_to_queue(SoupMessage *msg)
-{
- da_result_t ret = DA_RESULT_OK;
- int error_type = -1;
- queue_t *da_queue = NULL;
- q_event_t *da_event = NULL;
- int session_table_entry = -1;
-
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- error_type = _translate_error_code(msg->status_code);
-
- session_table_entry
- = _pi_http_get_session_table_entry_from_message(msg);
- if (session_table_entry == -1) {
- DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-
- da_queue = _pi_http_get_queue_from_session_table_entry(
- session_table_entry);
-
- DA_LOG_CRITICAL(HTTPManager,"Q_EVENT_TYPE_DATA_ABORT");
- ret = Q_make_http_data_event(Q_EVENT_TYPE_DATA_ABORT, &da_event);
- if (ret != DA_RESULT_OK) {
- DA_LOG_ERR(HTTPManager,"fail to make da_event");
- goto ERR;
- } else {
- Q_set_error_type_on_http_data_event(da_event, error_type);
-
- Q_push_event(da_queue, da_event);
- }
-
-ERR:
- return;
-}
-
-int _pi_http_get_session_table_entry_from_message(SoupMessage *msg)
-{
-
- int out_entry = -1;
- int i;
-
- if (DA_NULL == msg) {
- DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
- return out_entry;
- }
-
- _da_thread_mutex_lock (&mutex_for_session_table);
-
- for (i = 0; i < MAX_SESSION_COUNT; i++) {
- if (pi_session_table[i].is_using == DA_TRUE) {
- if (pi_session_table[i].msg == msg) {
- out_entry = i;
- break;
- }
- }
- }
-
- _da_thread_mutex_unlock (&mutex_for_session_table);
-
- if (i == MAX_SESSION_COUNT) {
- DA_LOG_ERR(HTTPManager,"fail to find message = %p", msg);
- }
-
- return out_entry;
-
-}
-
-void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data)
-{
- char *url = NULL;
-
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!msg) {
- DA_LOG_ERR(HTTPManager, "Check NULL:msg");
- return;
- }
-
- url = soup_uri_to_string(soup_message_get_uri(msg), DA_FALSE);
-
- DA_SECURE_LOGI("status_code[%d], reason[%s], url[%s]",msg->status_code,msg->reason_phrase,url);
-
- if (url) {
- free(url);
- url = NULL;
- }
-
- if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
- if (msg->status_code == SOUP_STATUS_CANCELLED) {
- _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
- } else {
- _pi_http_store_neterr_to_queue(msg);
- }
- } else {
- _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
- }
-
-}
-
-/* this callback is called in case of redirection */
-void _pi_http_restarted_cb(SoupMessage *msg, gpointer data)
-{
- DA_LOG_FUNC_LOGD(HTTPManager);
- /* Location URL is needed when extracting the file name from url.
- * So, the response header should be handled by http mgr.*/
-
- if (!msg) {
- DA_LOG_ERR(HTTPManager, "Check NULL:msg");
- return;
- }
- // If there are user id and password at url, libsoup handle it automatically.
- if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
- DA_LOG(HTTPManager,"Ignore:Unauthorized");
- return;
- }
- _pi_http_store_read_header_to_queue(msg, NULL);
-}
-
-void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data)
-{
- DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!msg) {
- DA_LOG_ERR(HTTPManager, "Check NULL:msg");
- return;
- }
-
- if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
- DA_LOG(HTTPManager,"Redirection !!");
- if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
- return;
- }
-
- // If there are user id and password at url, libsoup handle it automatically.
- if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
- DA_LOG(HTTPManager,"Ignore:Unauthorized");
- return;
- }
-
- soup_message_body_set_accumulate(msg->response_body, DA_FALSE);
-
- if (!using_content_sniffing)
- _pi_http_store_read_header_to_queue(msg, NULL);
- else
- DA_LOG_DEBUG(HTTPManager,"ignore because content sniffing is turned on");
-}
-
-void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType,
- GHashTable *params, gpointer data)
-{
- DA_LOG_FUNC_LOGD(HTTPManager);
-
- if (!msg) {
- DA_LOG_ERR(HTTPManager, "Check NULL:msg");
- return;
- }
-
- if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
- DA_LOG(HTTPManager,"Redirection !!");
- if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
- return;
- }
-
- // If there are user id and password at url, libsoup handle it automatically.
- if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
- DA_LOG(HTTPManager,"Ignore:Unauthorized");
- return;
- }
-
- if (using_content_sniffing)
- _pi_http_store_read_header_to_queue(msg, sniffedType);
-}
-
-void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data)
-{
-// DA_LOG_FUNC_LOGV(HTTPManager);
-
- if (!msg) {
- DA_LOG_ERR(HTTPManager, "Check NULL:msg");
- return;
- }
-
- if (!chunk) {
- DA_LOG_ERR(HTTPManager, "Check NULL:chunk");
- return;
- }
-
- if (SOUP_STATUS_IS_REDIRECTION(msg->status_code))
- return;
-
- if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
- DA_LOG(HTTPManager,"Ignore:Unauthorized");
- return;
- }
-
- if (chunk->data && chunk->length > 0) {
- _pi_http_store_read_data_to_queue(msg, chunk->data,
- chunk->length);
- }
-}
diff --git a/agent/download-agent-utils-dl-id-history.c b/agent/download-agent-utils-dl-id-history.c
deleted file mode 100755
index c6e747d..0000000
--- a/agent/download-agent-utils-dl-id-history.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "download-agent-type.h"
-#include "download-agent-utils.h"
-#include "download-agent-utils-dl-id-history.h"
-
-da_result_t init_dl_id_history(dl_id_history_t *dl_id_history)
-{
- da_result_t ret = DA_RESULT_OK;
-
- /* Initial dl_id_history will be starting number for dl_id.
- * dl_id will be sequentially increased from the dl_id_history,
- * then dl_id_history will be updated. */
- _da_thread_mutex_init(&(dl_id_history->mutex), DA_NULL);
- _da_thread_mutex_lock(&(dl_id_history->mutex));
- get_random_number(&(dl_id_history->starting_num));
- dl_id_history->cur_dl_id = DA_INVALID_ID;
- _da_thread_mutex_unlock(&(dl_id_history->mutex));
-
- DA_LOG_VERBOSE(Default,"starting num = %d", dl_id_history->starting_num);
- return ret;
-}
-
-da_result_t deinit_dl_id_history(dl_id_history_t *dl_id_history)
-{
- da_result_t ret = DA_RESULT_OK;
-
- _da_thread_mutex_lock(&(dl_id_history->mutex));
- dl_id_history->starting_num = DA_INVALID_ID;
- dl_id_history->cur_dl_id = DA_INVALID_ID;
- _da_thread_mutex_unlock(&(dl_id_history->mutex));
-
- _da_thread_mutex_destroy(&(dl_id_history->mutex));
-
- return ret;
-}
-
-int get_available_dl_id(dl_id_history_t *dl_id_history)
-{
- int dl_id = 0;
-
- _da_thread_mutex_lock(&(dl_id_history->mutex));
-
- if (dl_id_history->cur_dl_id == DA_INVALID_ID)
- dl_id_history->cur_dl_id = dl_id_history->starting_num;
- else if (dl_id_history->cur_dl_id > 254)
- dl_id_history->cur_dl_id = 1;
- else
- dl_id_history->cur_dl_id++;
-
- dl_id = dl_id_history->cur_dl_id;
-
- _da_thread_mutex_unlock(&(dl_id_history->mutex));
-
- DA_LOG_VERBOSE(Default,"dl_id = %d", dl_id);
- return dl_id;
-}
diff --git a/agent/download-agent-utils.c b/agent/download-agent-utils.c
deleted file mode 100755
index 71aca16..0000000
--- a/agent/download-agent-utils.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/vfs.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <glib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "download-agent-client-mgr.h"
-#include "download-agent-debug.h"
-#include "download-agent-dl-mgr.h"
-#include "download-agent-file.h"
-#include "download-agent-http-misc.h"
-#include "download-agent-mime-util.h"
-#include "download-agent-utils.h"
-#include "download-agent-plugin-conf.h"
-#include "download-agent-dl-info-util.h"
-
-#define DA_HTTP_HEADER_CONTENT_TYPE "Content-Type"
-#define DA_HTTP_HEADER_CONTENT_LENGTH "Content-Length"
-#define DA_FILE_NUMBER_LIMIT (1024*1024)
-
-typedef struct _da_descriptor_mime_table_t {
- char *content_type;
- da_mime_type_id_t mime_type;
-} da_descriptor_mime_table_t;
-
-da_descriptor_mime_table_t
- descriptor_mime_table[] = {
- {"", DA_MIME_TYPE_NONE},
- /* DRM1.0 */
- {"application/vnd.oma.drm.message",
- DA_MIME_TYPE_DRM1_MESSATE}, /* drm1.0 FL.CD*/
- {"", DA_MIME_TYPE_END}};
-
-void get_random_number(int *out_num)
-{
- int temp = DA_INVALID_ID;
- unsigned int seed = (unsigned)time(0);
-
- temp = (int)(rand_r(&seed) % 100 + 1.0);
- *out_num = temp;
-}
-
-da_result_t get_extension_from_mime_type(char *mime_type, char **extension)
-{
- da_result_t ret = DA_RESULT_OK;
- char *ext = DA_NULL;
-
- DA_LOG_FUNC_LOGV(Default);
- if (DA_NULL == mime_type || DA_NULL == extension) {
- DA_LOG_ERR(Default,"received mime_type is null");
- ret = DA_ERR_INVALID_ARGUMENT;
- goto ERR;
- }
-// DA_SECURE_LOGD("input mime type = %s", mime_type);
- if (DA_RESULT_OK != (ret = da_mime_get_ext_name(mime_type, &ext))) {
- DA_LOG_ERR(Default,"can't find proper extension!");
- goto ERR;
- }
- *extension = ext;
-// DA_SECURE_LOGD("found extension = %s", *extension);
-
-ERR:
- return ret;
-}
-
-int read_data_from_file(char *file, char **out_buffer)
-{
- FILE *fd;
- unsigned long long file_size = -1;
- char *buffer = NULL;
- int buffer_len = 0;
- size_t read_len = 0;
-
- *out_buffer = NULL;
-
- if (!file)
- return 0;
-
- /* open file with "rb", because fread() handles the file as binary mode */
- fd = fopen(file, "rb");
- if (!fd) {
- DA_LOG_ERR(FileManager,"File open err! received file path");
- return 0;
- }
-
- get_file_size(file, &file_size);
- if (file_size <= 0) {
- DA_LOG_ERR(FileManager,"file size is [%llu]", file_size);
- fclose(fd);
- return 0;
- }
-
- /* A guide from www.securecoding.cert.org
- * : FIO17-C. Do not rely on an ending null character when using fread()
- *
- * buffer is initialized with null through calloc(), so, it is always null-terminated even if fread() failed.
- * allocate memory one more byte to ensure null-terminated even if the file is not null-terminated.
- */
- buffer_len = sizeof(char) * file_size;
- buffer = (char *)calloc(1, buffer_len + 1);
- if (buffer) {
- read_len = fread(buffer, sizeof(char), file_size, fd);
- if (read_len == file_size) {
- *out_buffer = buffer;
- } else {
- DA_LOG_ERR(FileManager,"File Read Not Complete read length = %d", read_len);
- free(buffer);
- buffer = NULL;
- buffer_len = 0;
- }
- } else {
- buffer_len = 0;
- }
-
- fclose(fd);
-
- return buffer_len;
-}
-
-da_result_t get_available_memory(da_storage_size_t *avail_memory)
-{
- da_result_t ret = DA_RESULT_OK;
- int fs_ret = 0;
- struct statfs filesys_info = {0, };
- char *default_install_dir = NULL;
-
- DA_LOG_FUNC_LOGD(Default);
-
- if (!avail_memory)
- return DA_ERR_INVALID_ARGUMENT;
-
- ret = get_default_install_dir(&default_install_dir);
-
- if (ret == DA_RESULT_OK && default_install_dir) {
- fs_ret = statfs(default_install_dir, &filesys_info);
- } else {
- return DA_ERR_FAIL_TO_ACCESS_STORAGE;
- }
-
- if (fs_ret != 0) {
- DA_LOG_ERR(Default,"Phone file path :statfs error - [%d]", errno);
- free(default_install_dir);
- return DA_ERR_INVALID_INSTALL_PATH;
- }
-
- avail_memory->b_available = filesys_info.f_bavail;
- avail_memory->b_size = filesys_info.f_bsize;
-
- DA_LOG_VERBOSE(Default, "Available Memory(f_bavail) : %llu", filesys_info.f_bavail);
- DA_LOG_VERBOSE(Default, "Available Memory(f_bsize) : %d", filesys_info.f_bsize);
- DA_LOG_VERBOSE(Default, "Available Memory(kbytes) : %lu", (filesys_info.f_bavail/1024)*filesys_info.f_bsize);
-
- free(default_install_dir);
- return DA_RESULT_OK;
-}
-
-da_mime_type_id_t get_mime_type_id(char *content_type)
-{
- int i = 0;
-
- if (content_type == NULL) {
- DA_LOG_CRITICAL(Default, "No Mime Type Id");
- return DA_MIME_TYPE_NONE;
- }
-
- while(descriptor_mime_table[i].mime_type != DA_MIME_TYPE_END)
- {
- if (!strcmp(descriptor_mime_table[i].content_type, content_type)) {
- break;
- }
- i++;
- }
- //DA_LOG_VERBOSE(Default, "dd mime type check: index[%d] type[%d]", i, descriptor_mime_table[i].mime_type);
- return descriptor_mime_table[i].mime_type;
-}
-
-
-
-da_bool_t is_valid_url(const char *url, da_result_t *err_code)
-{
- da_result_t ret = DA_RESULT_OK;
- da_bool_t b_ret = DA_FALSE;
-
- int wanted_str_len = 0;
- char *wanted_str = NULL;
- char *wanted_str_start = NULL;
- char *wanted_str_end = NULL;
-
- if ((DA_NULL == url) || (1 > strlen(url))) {
- ret = DA_ERR_INVALID_URL;
- goto ERR;
- }
-
- wanted_str_start = (char*)url;
- wanted_str_end = strstr(url, "://");
- if (!wanted_str_end) {
- DA_LOG_ERR(Default,"No protocol on this url");
- ret = DA_ERR_INVALID_URL;
- goto ERR;
- }
-
- wanted_str_len = wanted_str_end - wanted_str_start;
- wanted_str = (char*)calloc(1, wanted_str_len + 1);
- if (!wanted_str) {
- DA_LOG_ERR(Default,"DA_ERR_FAIL_TO_MEMALLOC");
- ret = DA_ERR_FAIL_TO_MEMALLOC;
- goto ERR;
- }
- strncpy(wanted_str, wanted_str_start, wanted_str_len);
-
- b_ret = is_supporting_protocol(wanted_str);
- if (!b_ret) {
- ret = DA_ERR_UNSUPPORTED_PROTOCAL;
- goto ERR;
- }
-
-ERR:
- if (wanted_str) {
- free(wanted_str);
- wanted_str = NULL;
- }
-
- if (err_code)
- *err_code = ret;
-
- return b_ret;
-}
-
-da_result_t move_file(const char *from_path, const char *to_path)
-{
- da_result_t ret = DA_RESULT_OK;
-
- if (!from_path || !to_path)
- return DA_ERR_INVALID_ARGUMENT;
-
- if (rename(from_path, to_path) != 0) {
- DA_LOG_CRITICAL(FileManager,"rename failed : syserr[%d]",errno);
- if (errno == EXDEV) {
- DA_LOG_CRITICAL(FileManager,"File system is diffrent. Try to copy a file");
- ret = copy_file(from_path, to_path);
- if (ret == DA_RESULT_OK) {
- remove_file(from_path);
- } else {
- if (is_file_exist(to_path))
- remove_file(to_path);
- ret = DA_ERR_FAIL_TO_INSTALL_FILE;
- }
- } else {
- ret = DA_ERR_FAIL_TO_INSTALL_FILE;
- }
- }
- return ret;
-}
-
-void remove_file(const char *file_path)
-{
- DA_LOG_FUNC_LOGD(FileManager);
-
- if (file_path && is_file_exist(file_path)) {
- DA_SECURE_LOGD("remove file [%s]", file_path);
- if (unlink(file_path) < 0) {
- DA_LOG_ERR(FileManager,"file removing failed.");
- }
- }
-}
diff --git a/agent/include/download-agent-client-mgr.h b/agent/include/download-agent-client-mgr.h
index f4c6234..b2ce1c8 100755
--- a/agent/include/download-agent-client-mgr.h
+++ b/agent/include/download-agent-client-mgr.h
@@ -14,77 +14,14 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Client_Mgr_H
-#define _Download_Agent_Client_Mgr_H
+#ifndef DOWNLOAD_AGENT_CLIENT_MGR_H
+#define DOWNLOAD_AGENT_CLIENT_MGR_H
-#include <string.h>
+#include "download-agent-dl-info.h"
-#include "download-agent-type.h"
-#include "download-agent-interface.h"
-
-#include "download-agent-pthread.h"
-
-typedef enum {
- Q_CLIENT_NOTI_TYPE_STARTED_INFO = 0,
- Q_CLIENT_NOTI_TYPE_PROGRESS_INFO,
- Q_CLIENT_NOTI_TYPE_PAUSED_INFO,
- Q_CLIENT_NOTI_TYPE_FINISHED_INFO,
- Q_CLIENT_NOTI_TYPE_TERMINATE,
-} client_noti_type;
-
-typedef struct _client_noti_t client_noti_t;
-struct _client_noti_t {
- int slot_id;
- void *user_data;
- client_noti_type noti_type;
- union _client_type {
- user_download_info_t update_dl_info;
- user_progress_info_t update_progress_info;
- user_paused_info_t paused_info;
- user_finished_info_t finished_info;
- } type;
-
- client_noti_t *next;
-};
-
-typedef struct _client_queue_t {
- da_bool_t having_data;
- client_noti_t *client_q_head;
- pthread_mutex_t mutex_client_queue;
- pthread_cond_t cond_client_queue;
-} client_queue_t;
-
-typedef struct _client_app_info_t {
- da_client_cb_t client_callback;
- char *client_user_agent;
-} client_app_info_t;
-
-typedef struct _client_app_mgr_t {
- da_bool_t is_init;
- client_queue_t client_queue;
- client_app_info_t client_app_info;
- pthread_t thread_id;
- da_bool_t is_thread_init;
- pthread_mutex_t mutex_client_mgr;
-} client_app_mgr_t;
-
-da_result_t init_client_app_mgr(void);
-da_bool_t is_client_app_mgr_init(void);
-
-da_result_t reg_client_app(da_client_cb_t *da_client_callback);
-da_result_t dereg_client_app(void);
-
-da_result_t send_client_paused_info (int slot_id);
-da_result_t send_client_update_dl_info (int slot_id, int dl_id,
- char *file_type, unsigned long int file_size, char *tmp_saved_path,
- char *pure_file_name, char *etag, char *extension);
-da_result_t send_client_update_progress_info (int slot_id, int dl_id,
- unsigned long int received_size);
-da_result_t send_client_finished_info (int slot_id, int dl_id,
- char *saved_path, char *etag, int error, int http_status);
-
-char *get_client_user_agent_string(void);
-
-void push_client_noti(client_noti_t *client_noti);
+da_ret_t send_client_paused_info(da_info_t *da_info);
+da_ret_t send_client_update_dl_info(da_info_t *da_info);
+da_ret_t send_client_update_progress_info(da_info_t *da_info);
+da_ret_t send_client_finished_info(da_info_t *da_info, int err);
#endif
diff --git a/agent/include/download-agent-debug.h b/agent/include/download-agent-debug.h
index 24ac67e..23c2a66 100755
--- a/agent/include/download-agent-debug.h
+++ b/agent/include/download-agent-debug.h
@@ -14,94 +14,55 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Debug_H
-#define _Download_Agent_Debug_H
+#ifndef _DOWNLOAD_AGENT_DEBUG_H
+#define _DOWNLOAD_AGENT_DEBUG_H
#include "download-agent-type.h"
-#define DA_DEBUG_ENV_KEY "DOWNLOAD_AGENT_DEBUG"
-#define DA_DEBUG_CONFIG_FILE_PATH "/tmp/.download_agent.conf"
-
-#define IS_LOG_ON(channel) (DALogBitMap & (0x1<<(channel)))
-
-typedef enum {
- Soup,
- HTTPManager,
- FileManager,
- DRMManager,
- DownloadManager,
- ClientNoti,
- HTTPMessageHandler,
- Encoding,
- QueueManager,
- Parsing,
- Thread,
- Default,
- DA_LOG_CHANNEL_MAX
-} da_log_channel;
-
-extern int DALogBitMap;
-
-da_result_t init_log_mgr(void);
-
-#ifdef NODEBUG
- #define DA_LOG(channel, format, ...) ((void)0)
- #define DA_LOG_CRITICAL(channel, format, ...) ((void)0)
- #define DA_LOG_VERBOSE(channel, format, ...) ((void)0)
- #define DA_LOG_ERR(channel, format, ...) ((void)0)
- #define DA_LOG_FUNC_LOGD(channel, ...) ((void)0)
- #define DA_LOG_FUNC_LOGV(channel, ...) ((void)0)
- #define DA_SECURE_LOGD(format, ...) ((void)0)
- #define DA_SECURE_LOGI(format, ...) ((void)0)
- #define DA_SECURE_LOGE(format, ...) ((void)0)
-
-#else /* NODEBUG */
#include <stdio.h>
#include <stdarg.h>
#include <pthread.h>
-#ifdef DA_DEBUG_USING_DLOG
- #include <dlog.h>
+// ansi color
+#define COLOR_RED "\033[0;31m"
+#define COLOR_GREEN "\033[0;32m"
+#define COLOR_BROWN "\033[0;33m"
+#define COLOR_LIGHTBLUE "\033[0;37m"
+#define COLOR_END "\033[0;m"
+
+#ifdef _ENABLE_DLOG
+#include <unistd.h>
+#include <syscall.h>
+#include <dlog.h>
+
#ifdef LOG_TAG
#undef LOG_TAG
#endif /* LOG_TAG */
- #define LOG_TAG "DOWNLOAD_AGENT"
- #define DA_LOG(channel, format, ...) LOGI_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__)
- #define DA_LOG_DEBUG(channel, format, ...) LOGD_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__)
- #define DA_LOG_CRITICAL(channel, format, ...) LOGI_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__)
- #define DA_LOG_VERBOSE(channel, format, ...) ((void)0)//LOGD_IF(IS_LOG_ON(channel), format, ##__VA_ARGS__)
- #define DA_LOG_ERR(channel, format, ...) LOGE_IF(IS_LOG_ON(channel), "ERR! "format, ##__VA_ARGS__)
- #define DA_LOG_FUNC_LOGD(channel, ...) LOGD_IF(IS_LOG_ON(channel), "starting...")
- #define DA_LOG_FUNC_LOGV(channel, ...) ((void)0)//LOGD_IF(IS_LOG_ON(channel), "starting...")
- #define DA_SECURE_LOGD(format, ...) SECURE_LOGD(format, ##__VA_ARGS__)
- #define DA_SECURE_LOGI(format, ...) SECURE_LOGI(format, ##__VA_ARGS__)
- #define DA_SECURE_LOGE(format, ...) SECURE_LOGE(format, ##__VA_ARGS__)
-#else /* DA_DEBUG_USING_DLOG */
- #include <unistd.h>
- #include <syscall.h>
+ #define LOG_TAG "DP_DA"
+ #define DA_LOGV(format, ...) ((void)0)//LOGD("[%d]:"format, syscall(__NR_gettid), ##__VA_ARGS__)
+ #define DA_LOGD(format, ...) LOGD(COLOR_LIGHTBLUE "[%d]:"format COLOR_END, syscall(__NR_gettid), ##__VA_ARGS__)
+ #define DA_LOGI(format, ...) LOGI(COLOR_BROWN "[%d]:"format COLOR_END, syscall(__NR_gettid), ##__VA_ARGS__)
+ #define DA_LOGE(format, ...) LOGE(COLOR_RED "[%d]:"format COLOR_END, syscall(__NR_gettid), ##__VA_ARGS__)
+ #define DA_SECURE_LOGD(format, ...) SECURE_LOGD(COLOR_GREEN format COLOR_END, ##__VA_ARGS__)
+ #define DA_SECURE_LOGI(format, ...) SECURE_LOGI(COLOR_GREEN format COLOR_END, ##__VA_ARGS__)
+ #define DA_SECURE_LOGE(format, ...) SECURE_LOGE(COLOR_GREEN format COLOR_END, ##__VA_ARGS__)
+#else
- #define DA_LOG(channel, format, ...) do {\
- IS_LOG_ON(channel) \
- ? fprintf(stderr, "[DA][%u][%s(): %d] "format"\n",(unsigned int)syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__) \
- : ((void)0);\
- }while(0)
- #define DA_LOG_ERR(channel, format, ...) do {\
- IS_LOG_ON(channel) \
- ? fprintf(stderr, "[DA][%u][ERR][%s(): %d]\n",(unsigned int)syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__) \
- : ((void)0); \
+#include <unistd.h>
+#include <syscall.h>
+
+ #define DA_LOGD(format, ...) do {\
+ fprintf(stderr, "[DA][%d][%s():%d] "format"\n",syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__);\
}while(0)
- #define DA_LOG_FUNC_LOGD(channel, ...) do {\
- IS_LOG_ON(channel) \
- ? fprintf(stderr, "[DA][%u][%s(): %d] starting\n",(unsigned int)syscall(__NR_gettid), __FUNCTION__,__LINE__) \
- : ((void)0); \
+ #define DA_LOGE(format, ...) do {\
+ fprintf(stderr, "[DA][%d][ERR][%s():%d]\n",syscall(__NR_gettid), __FUNCTION__,__LINE__, ##__VA_ARGS__);\
}while(0)
- #define DA_LOG_CRITICAL DA_LOG
- #define DA_LOG_VERBOSE DA_LOG
- #define DA_LOG_FUNC_LOGV ((void)0)
+ #define DA_LOGV DA_LOGD
+ #define DA_LOGI DA_LOGD
#define DA_SECURE_LOGD(format, ...) ((void)0)
#define DA_SECURE_LOGI(format, ...) ((void)0)
#define DA_SECURE_LOGE(format, ...) ((void)0)
-#endif /* DA_DEBUG_USING_DLOG */
-#endif /* NDEBUG */
-#endif /* _Download_Agent_Debug_H */
+#endif /* _ENABLE_DLOG */
+
+#endif /* DOWNLOAD_AGENT_DEBUG_H */
diff --git a/agent/include/download-agent-defs.h b/agent/include/download-agent-defs.h
index b69690a..d5b6a5e 100755
--- a/agent/include/download-agent-defs.h
+++ b/agent/include/download-agent-defs.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Defs_H
-#define _Download_Agent_Defs_H
+#ifndef _DOWNLOAD_AGENT_DEFS_H
+#define _DOWNLOAD_AGENT_DEFS_H
#ifndef DEPRECATED
#define DEPRECATED __attribute__((deprecated))
@@ -26,6 +26,7 @@
* Main reason for this restriction is because of Network bandwidth.
*/
#define DA_MAX_DOWNLOAD_REQ_AT_ONCE 50
+#define DA_MAX_TIME_OUT 65
#define DA_RESULT_OK 0
@@ -57,33 +58,28 @@
// System error (-200 ~ -299)
#define DA_ERR_FAIL_TO_MEMALLOC -200
#define DA_ERR_FAIL_TO_CREATE_THREAD -210
-#define DA_ERR_FAIL_TO_OBTAIN_MUTEX -220
#define DA_ERR_FAIL_TO_ACCESS_FILE -230
#define DA_ERR_DISK_FULL -240
-// Platform error (-300 ~ -399)
-#define DA_ERR_FAIL_TO_GET_CONF_VALUE -300
-#define DA_ERR_FAIL_TO_ACCESS_STORAGE -310
-#define DA_ERR_DLOPEN_FAIL -330
-
// Network error (-400 ~ -499)
#define DA_ERR_NETWORK_FAIL -400
#define DA_ERR_UNREACHABLE_SERVER -410
-#define DA_ERR_HTTP_TIMEOUT -420
-#define DA_ERR_SSL_FAIL -430
-#define DA_ERR_TOO_MANY_REDIECTS -440
+#define DA_ERR_CONNECTION_FAIL -420
+#define DA_ERR_HTTP_TIMEOUT -430
+#define DA_ERR_SSL_FAIL -440
+#define DA_ERR_TOO_MANY_REDIRECTS -450
+#define DA_ERR_NETWORK_UNAUTHORIZED -460
// HTTP error - not conforming with HTTP spec (-500 ~ -599)
#define DA_ERR_MISMATCH_CONTENT_TYPE -500
-#define DA_ERR_MISMATCH_CONTENT_SIZE -501
-#define DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT -502
+#define DA_ERR_SERVER_RESPOND_BUT_SEND_NO_CONTENT -501
+#define DA_ERR_MISMATCH_CONTENT_SIZE -502
-// DRM error - not conforming with DRM spec (-700 ~ -799)
-#define DA_ERR_DRM_FAIL -700
-#define DA_ERR_DRM_FILE_FAIL -710
+// DRM error - not conforming with DRM spec (-600 ~ -699)
+#define DA_ERR_DRM_FAIL -600
-// install error (-800 ~ -899)
-#define DA_ERR_FAIL_TO_INSTALL_FILE -800
+// string to check invalid characters in path before using open() and fopen() API's
+#define DA_INVALID_PATH_STRING ";\\\":*?<>|()"
#endif
diff --git a/agent/include/download-agent-dl-info-util.h b/agent/include/download-agent-dl-info-util.h
deleted file mode 100755
index d6e20a8..0000000
--- a/agent/include/download-agent-dl-info-util.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _Download_Agent_Dl_Info_Util_H
-#define _Download_Agent_Dl_Info_Util_H
-
-#include "download-agent-type.h"
-#include "download-agent-http-queue.h"
-#include "download-agent-utils-dl-id-history.h"
-
-#define DA_MAX_DOWNLOAD_ID DA_MAX_DOWNLOAD_REQ_AT_ONCE
-#define DA_MAX_TYPE_COUNT 10
-
-#define DOWNLOAD_NOTIFY_LIMIT (1024*32) //bytes
-extern pthread_mutex_t mutex_download_state[];
-
-typedef enum {
- DOWNLOAD_STATE_IDLE = 0,
- DOWNLOAD_STATE_NEW_DOWNLOAD = 10, /* stage */
- DOWNLOAD_STATE_FINISH = 50, /* stage */
- DOWNLOAD_STATE_PAUSED = 60, /* http */
- DOWNLOAD_STATE_CANCELED = 70, /* http */
- DOWNLOAD_STATE_ABORTED = 80 /* satge */
-} download_state_t;
-
-typedef enum {
- HTTP_STATE_READY_TO_DOWNLOAD = 0,
- HTTP_STATE_REDIRECTED = 1,
- HTTP_STATE_DOWNLOAD_REQUESTED = 2,
- HTTP_STATE_DOWNLOAD_STARTED = 3,
- HTTP_STATE_DOWNLOADING = 4,
- HTTP_STATE_DOWNLOAD_FINISH = 5,
- HTTP_STATE_REQUEST_CANCEL = 6,
- HTTP_STATE_REQUEST_PAUSE = 7,
- HTTP_STATE_REQUEST_RESUME = 8,
- HTTP_STATE_CANCELED = 9,
- HTTP_STATE_PAUSED = 10,
- HTTP_STATE_RESUMED = 11,
- HTTP_STATE_ABORTED = 12,
-} http_state_t;
-
-typedef struct _client_input_basic_t {
- char *req_url;
- char **user_request_header;
- int user_request_header_count;
-} client_input_basic_t;
-
-typedef struct _client_input_t {
- void *user_data;
- char *install_path;
- char *file_name;
- char *etag;
- char *temp_file_path;
- char *pkg_name;
- client_input_basic_t client_input_basic;
-} client_input_t;
-
-typedef struct _download_thread_input {
- int slot_id;
- client_input_t *client_input;
-} download_thread_input;
-
-typedef struct _source_info_basic_t {
- int dl_id;
- char *url;
- char **user_request_header;
- int user_request_header_count;
-} source_info_basic_t;
-
-typedef struct _source_info_t {
- union _source_info_type {
- source_info_basic_t *source_info_basic;
- } source_info_type;
-} source_info_t;
-
-#define GET_SOURCE_TYPE(SOURCE) ((SOURCE)->source_type)
-#define GET_SOURCE_BASIC(SOURCE) ((SOURCE)->source_info_type.source_info_basic)
-#define GET_SOURCE_BASIC_URL(SOURCE) (GET_SOURCE_BASIC(SOURCE)->url)
-
-typedef struct _req_dl_info {
- http_info_t http_info;
-
- /* This is just pointer assignment from stage source info. */
- char *destination_url;
- /* The location url is assigned here in case of redirection.
- * At this time, the pointer should be freed. */
- char *location_url;
- char **user_request_header;
- int user_request_header_count;
- char *user_request_etag;
- char *user_request_temp_file_path;
-
- http_state_t http_state;
- pthread_mutex_t mutex_http_state;
-
- da_result_t result;
- /*************** will be depreciated ***********************/
- /* ToDo : previous http_info should be saved in case of pause */
- char *content_type_from_header; /* calloced in set hdr fiels on download info */
- unsigned long long content_len_from_header;
- char *etag_from_header;
-
- unsigned long int downloaded_data_size;
-
- int invloved_transaction_id;
-} req_dl_info;
-
-#define GET_REQUEST_HTTP_RESULT(REQUEST) (REQUEST->result)
-#define GET_REQUEST_HTTP_TRANS_ID(REQUEST) (REQUEST->invloved_transaction_id)
-#define GET_REQUEST_HTTP_REQ_URL(REQUEST) (REQUEST->destination_url)
-#define GET_REQUEST_HTTP_REQ_LOCATION(REQUEST) (REQUEST->location_url)
-#define GET_REQUEST_HTTP_USER_REQUEST_HEADER(REQUEST) (REQUEST->user_request_header)
-#define GET_REQUEST_HTTP_USER_REQUEST_HEADER_COUNT(REQUEST) (REQUEST->user_request_header_count)
-#define GET_REQUEST_HTTP_USER_REQUEST_ETAG(REQUEST) (REQUEST->user_request_etag)
-#define GET_REQUEST_HTTP_USER_REQUEST_TEMP_FILE_PATH(REQUEST) (REQUEST->user_request_temp_file_path)
-#define GET_REQUEST_HTTP_HDR_ETAG(REQUEST) (REQUEST->etag_from_header)
-#define GET_REQUEST_HTTP_HDR_CONT_TYPE(REQUEST) (REQUEST->content_type_from_header)
-#define GET_REQUEST_HTTP_HDR_CONT_LEN(REQUEST) (REQUEST->content_len_from_header)
-#define GET_REQUEST_HTTP_CONTENT_OFFSET(REQUEST)(REQUEST->downloaded_data_size)
-#define GET_REQUEST_HTTP_MUTEX_HTTP_STATE(STAGE) (GET_STAGE_TRANSACTION_INFO(STAGE)->mutex_http_state)
-#define GET_HTTP_STATE_ON_STAGE(STAGE) (GET_STAGE_TRANSACTION_INFO(STAGE)->http_state)
-#define CHANGE_HTTP_STATE(STATE,STAGE) {\
- _da_thread_mutex_lock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(STAGE)));\
- GET_HTTP_STATE_ON_STAGE(STAGE) = STATE;\
- DA_LOG_DEBUG(Default, "Changed http_state to - [%d] ", GET_HTTP_STATE_ON_STAGE(STAGE));\
- _da_thread_mutex_unlock(&(GET_REQUEST_HTTP_MUTEX_HTTP_STATE(STAGE)));\
-}
-
-typedef struct _file_info {
- void *file_handle;
- char *pure_file_name;
- char *extension;
- char *file_name_final; /* malloced in set_file_path_for_final_saving */
- char *content_type; /* malloced in make file info. */
- char *add_to_buffer;
- unsigned int file_size; /* http header's Content-Length has higher priority than DD's <size> */
- unsigned int total_bytes_written_to_file; /* current written file size */
- unsigned int bytes_written_to_file;
- unsigned int current_buffer_len;
-} file_info;
-
-#define GET_CONTENT_STORE_PURE_FILE_NAME(FILE_CNTXT) (FILE_CNTXT)->pure_file_name
-#define GET_CONTENT_STORE_EXTENSION(FILE_CNTXT) (FILE_CNTXT)->extension
-#define GET_CONTENT_STORE_ACTUAL_FILE_NAME(FILE_CNTXT) (FILE_CNTXT)->file_name_final
-#define GET_CONTENT_STORE_FILE_HANDLE(FILE_CNTXT) (FILE_CNTXT)->file_handle
-#define GET_CONTENT_STORE_FILE_SIZE(FILE_CNTXT) (FILE_CNTXT)->file_size
-#define GET_CONTENT_STORE_CURRENT_FILE_SIZE(FILE_CNTXT) (FILE_CNTXT)->total_bytes_written_to_file
-#define IS_CONTENT_STORE_FILE_BYTES_WRITTEN_TO_FILE(FILE_CNTXT) (FILE_CNTXT)->bytes_written_to_file
-#define GET_CONTENT_STORE_FILE_BUFFER(FILE_CNTXT) (FILE_CNTXT)->add_to_buffer
-#define GET_CONTENT_STORE_FILE_BUFF_LEN(FILE_CNTXT) ((FILE_CNTXT)->current_buffer_len)
-#define GET_CONTENT_STORE_CONTENT_TYPE(FILE_CNTXT) (FILE_CNTXT)->content_type
-
-typedef struct _stage_info {
- int dl_id;
- int thread_id;
- source_info_t dl_request;
- req_dl_info dl_tansaction_context;
- file_info dl_content_storage;
- struct _stage_info *next_stage_info;
-} stage_info;
-
-#define GET_STAGE_DL_ID(STAGE) ((STAGE)->dl_id)
-#define GET_STAGE_THREAD_ID(STAGE) ((STAGE)->thread_id)
-#define GET_STAGE_SOURCE_INFO(STAGE) (&((STAGE)->dl_request))
-#define GET_STAGE_TRANSACTION_INFO(STAGE) (&((STAGE)->dl_tansaction_context))
-#define GET_STAGE_CONTENT_STORE_INFO(STAGE) (&((STAGE)->dl_content_storage))
-#define GET_STAGE_INSTALLATION_INFO(STAGE) (&((STAGE)->post_dl_context))
-
-typedef struct {
- da_bool_t is_using;
- int slot_id;
- int dl_id;
- pthread_t active_dl_thread_id;
- download_state_t state;
- stage_info *download_stage_data;
- queue_t queue;
- int http_status;
- da_bool_t enable_pause_update;
- // FIXME have client_input itself, not to have each of them
- char *user_install_path;
- char *user_file_name;
- char *user_etag;
- char *user_temp_file_path;
- void *user_data;
-} dl_info_t;
-
-#define GET_DL_THREAD_ID(ID) (download_mgr.dl_info[ID].active_dl_thread_id)
-#define GET_DL_STATE_ON_ID(ID) (download_mgr.dl_info[ID].state)
-#define GET_DL_STATE_ON_STAGE(STAGE) (GET_DL_STATE_ON_ID(GET_STAGE_DL_ID(STAGE)))
-#define GET_DL_CURRENT_STAGE(ID) (download_mgr.dl_info[ID].download_stage_data)
-#define GET_DL_ID(ID) (download_mgr.dl_info[ID].dl_id)
-#define GET_DL_QUEUE(ID) &(download_mgr.dl_info[ID].queue)
-#define GET_DL_ENABLE_PAUSE_UPDATE(ID) (download_mgr.dl_info[ID].enable_pause_update)
-#define GET_DL_USER_INSTALL_PATH(ID) (download_mgr.dl_info[ID].user_install_path)
-#define GET_DL_USER_FILE_NAME(ID) (download_mgr.dl_info[ID].user_file_name)
-#define GET_DL_USER_ETAG(ID) (download_mgr.dl_info[ID].user_etag)
-#define GET_DL_USER_TEMP_FILE_PATH(ID) (download_mgr.dl_info[ID].user_temp_file_path)
-#define GET_DL_USER_DATA(ID) (download_mgr.dl_info[ID].user_data)
-#define IS_THIS_DL_ID_USING(ID) (download_mgr.dl_info[ID].is_using)
-
-#define CHANGE_DOWNLOAD_STATE(STATE,STAGE) {\
- _da_thread_mutex_lock (&mutex_download_state[GET_STAGE_DL_ID(STAGE)]);\
- GET_DL_STATE_ON_STAGE(STAGE) = STATE;\
- DA_LOG_DEBUG(Default, "Changed download_state to - [%d] ", GET_DL_STATE_ON_STAGE(STAGE));\
- _da_thread_mutex_unlock (&mutex_download_state[GET_STAGE_DL_ID(STAGE)]);\
- }
-
-typedef struct _download_mgr_t {
- da_bool_t is_init;
- dl_info_t dl_info[DA_MAX_DOWNLOAD_ID];
- dl_id_history_t dl_id_history;
- /* FIXME: This is temporary solution to prevent crash on following case;
- * 1) OMA download(that is, DA's libsoup is using) is on progressing on Browser
- * 2) User push END hard key
- * 3) da_deinit() is called. - on UI thread
- * 4) cancel_download(all) is called.
- * 5) plugin-libsoup.c calls soup_session_cancel_message().
- * 6) da_deinit() is finished and process is over.
- * 7) soup's callback for soup_session_cancel_message() is trying to be called - on UI thread
- * 8) Browser crashed because the callback address is no longer exist.
- *
- * Here is a temporary solution;
- * If cancel is from da_deinit(), plugin-libsoup.c will not call soup_session_cancel_message().
- * So, append following variable to recognize this.
- **/
- //da_bool_t is_progressing_deinit;
-} download_mgr_t;
-
-extern download_mgr_t download_mgr;
-
-da_result_t init_download_mgr();
-da_result_t deinit_download_mgr(void);
-void init_download_info(int slot_id);
-void destroy_download_info(int slot_id);
-void *Add_new_download_stage(int slot_id);
-void remove_download_stage(int slot_id, stage_info *in_stage);
-void empty_stage_info(stage_info *in_stage);
-void clean_up_client_input_info(client_input_t *client_input);
-da_result_t get_available_slot_id(int *available_id);
-da_result_t get_slot_id_for_dl_id(int dl_id , int* slot_id);
-da_bool_t is_valid_slot_id(int slot_id);
-void store_http_status(int dl_id, int status);
-int get_http_status(int dl_id);
-#endif /* _Download_Agent_Dl_Info_Util_H */
diff --git a/agent/include/download-agent-dl-info.h b/agent/include/download-agent-dl-info.h
new file mode 100644
index 0000000..820135e
--- /dev/null
+++ b/agent/include/download-agent-dl-info.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _DOWNLOAD_AGENT_INFO_H
+#define _DOWNLOAD_AGENT_INFO_H
+
+#include "download-agent-type.h"
+#include "download-agent-interface.h"
+#include "download-agent-pthread.h"
+
+#include "curl/curl.h"
+
+typedef struct {
+ CURL *curl;
+ pthread_mutex_t mutex;
+ da_bool_t is_paused;
+ da_bool_t is_cancel_reqeusted;
+} http_msg_t;
+
+typedef enum {
+ HTTP_STATE_READY_TO_DOWNLOAD = 0,
+ HTTP_STATE_REDIRECTED = 1,
+ HTTP_STATE_DOWNLOAD_REQUESTED = 2,
+ HTTP_STATE_DOWNLOAD_STARTED = 3,
+ HTTP_STATE_DOWNLOADING = 4,
+ HTTP_STATE_DOWNLOAD_FINISH = 5,
+ HTTP_STATE_REQUEST_CANCEL = 6,
+ HTTP_STATE_REQUEST_PAUSE = 7,
+ HTTP_STATE_REQUEST_RESUME = 8,
+ HTTP_STATE_CANCELED = 9,
+ HTTP_STATE_FAILED = 10,
+ HTTP_STATE_PAUSED = 11,
+ HTTP_STATE_RESUMED = 12,
+ HTTP_STATE_ABORTED = 13,
+ HTTP_STATE_WAIT_FOR_NET_ERR = 14,
+} http_state_t;
+
+typedef enum {
+ HTTP_METHOD_GET = 1,
+ HTTP_METHOD_HEAD,
+ HTTP_METHOD_POST
+} http_method_t;
+
+typedef struct {
+ char *url;
+ char **req_header;
+ int req_header_count;
+ char *install_path;
+ char *file_name;
+ char *etag;
+ char *temp_file_path;
+ char *pkg_name;
+ int network_bonding;
+ void *user_req_data;
+ void *user_client_data;
+} req_info_t;
+
+typedef enum {
+ HTTP_EVENT_GOT_HEADER = 0,
+ HTTP_EVENT_GOT_PACKET,
+ HTTP_EVENT_FINAL,
+// HTTP_EVENT_ABORT
+} http_event_type_t;
+
+typedef struct _http_header_options_t http_header_options_t;
+struct _http_header_options_t{
+ char *field;
+ char *value;
+ http_header_options_t *next;
+};
+
+typedef struct _http_header_t http_header_t;
+typedef http_header_t *http_msg_iter_t;
+struct _http_header_t{
+ char *field;
+ char *value;
+ http_header_options_t *options;
+ char *raw_value; // raw string including options
+ http_header_t *next;
+};
+
+typedef struct{
+ char *http_method;
+ char *url;
+ http_header_t *head;
+ char *http_body;
+} http_msg_request_t;
+
+
+typedef struct{
+ int status_code;
+ http_header_t *head;
+} http_msg_response_t;
+
+typedef struct {
+ http_event_type_t type;
+ char *body;
+ int body_len;
+#ifdef _RAF_SUPPORT
+ da_size_t received_len;
+#endif
+ int status_code;
+ int error;
+} http_raw_data_t;
+
+typedef void (*http_update_cb) (http_raw_data_t *data, void *user_param);
+
+typedef struct {
+ char *location_url;
+ http_state_t state;
+ pthread_mutex_t mutex_state;
+ pthread_mutex_t mutex_http;
+ pthread_cond_t cond_http;
+ http_msg_request_t *http_msg_request;
+ http_msg_response_t *http_msg_response;
+ http_method_t http_method;
+ http_msg_t *http_msg;
+ char *proxy_addr;
+ char *content_type_from_header;
+ char *file_name_from_header;
+ da_size_t content_len_from_header;
+ char *etag_from_header;
+ int error_code; // for error value for http abort.
+ da_size_t total_size;
+#ifdef _RAF_SUPPORT
+ da_bool_t is_raf_mode_confirmed;
+#endif
+ http_update_cb update_cb;
+} http_info_t;
+
+typedef struct {
+ void *file_handle;
+ char *pure_file_name;
+ char *extension;
+ char *file_path; /* malloced in set_file_path_for_final_saving */
+ char *mime_type;// For drm converting
+ char *buffer;
+ da_size_t buffer_len;
+ da_size_t file_size; /* http header's Content-Length has higher priority than DD's <size> */
+ da_size_t bytes_written_to_file; /* The file size to be written at actual file */
+#ifdef _RAF_SUPPORT
+ da_size_t file_size_of_temp_file; /* If the temporary file is existed, the file size of it */
+#endif
+ da_bool_t is_updated; /* The flag for updating progress event only if the data is wrriten to file not buffer */
+} file_info_t;
+
+typedef struct {
+ int da_id;
+ int tid;
+ pthread_t thread_id;
+ http_info_t *http_info;
+ file_info_t *file_info;
+ req_info_t *req_info;
+ da_cb_t cb_info;
+ da_bool_t is_cb_update;
+ int update_time;
+} da_info_t;
+
+da_info_t *da_info_list[DA_MAX_ID];
+
+#define GET_STATE_MUTEX(INFO) (INFO->mutex_state)
+#define GET_STATE(INFO) (INFO->state)
+#define CHANGE_STATE(STATE,INFO) {\
+ DA_MUTEX_LOCK (&GET_STATE_MUTEX(INFO));\
+ GET_STATE(INFO) = STATE;\
+ DA_LOGV("Changed state[%d]", GET_STATE(INFO));\
+ DA_MUTEX_UNLOCK (&GET_STATE_MUTEX(INFO));\
+ }
+
+da_ret_t get_available_da_id(int *available_id);
+da_ret_t copy_user_input_data(da_info_t *da_info, const char *url,
+ req_data_t *ext_data, da_cb_t *da_cb_data);
+da_bool_t is_valid_download_id(int id);
+void destroy_da_info(int id);
+void destroy_da_info_list(void);
+da_ret_t get_da_info_with_da_id(int id, da_info_t **out_info);
+da_ret_t init_http_msg_t(http_msg_t **http_msg);
+void destroy_http_msg_t(http_msg_t *http_msg);
+void reset_http_info(http_info_t *http_info);
+void reset_http_info_for_resume(http_info_t *http_info);
+void destroy_http_info(http_info_t *http_info);
+void destroy_file_info(file_info_t *file_info);
+
+#endif /* _DOWNLOAD_AGENT_INFO_H */
diff --git a/agent/include/download-agent-dl-mgr.h b/agent/include/download-agent-dl-mgr.h
index b273fd8..c6be7c7 100755
--- a/agent/include/download-agent-dl-mgr.h
+++ b/agent/include/download-agent-dl-mgr.h
@@ -14,20 +14,14 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Dl_Mgr_H
-#define _Download_Agent_Dl_Mgr_H
+#ifndef _Download_Agent_Basic_H
+#define _Download_Agent_Basic_H
-#include "download-agent-type.h"
-#include "download-agent-dl-info-util.h"
+#include "download-agent-dl-info.h"
-da_result_t cancel_download(int dl_id);
-da_result_t suspend_download(int dl_id, da_bool_t is_enable_cb);
-da_result_t resume_download (int dl_id);
+da_ret_t start_download(da_info_t *da_info);
+da_ret_t cancel_download(int dl_id, da_bool_t is_enable_cb);
+da_ret_t suspend_download(int dl_id, da_bool_t is_enable_cb);
+da_ret_t resume_download(int dl_id);
-da_result_t requesting_download(stage_info *stage);
-da_result_t handle_after_download(stage_info *stage);
-da_result_t send_user_noti_and_finish_download_flow(
- int slot_id, char *installed_path, char *etag);
-
-da_bool_t is_valid_download_id(int dl_id);
#endif
diff --git a/agent/include/download-agent-encoding.h b/agent/include/download-agent-encoding.h
index c5c7fe5..49e74e9 100755
--- a/agent/include/download-agent-encoding.h
+++ b/agent/include/download-agent-encoding.h
@@ -20,7 +20,7 @@
#include "download-agent-type.h"
da_bool_t is_base64_encoded_word(const char *in_str);
-da_result_t decode_base64_encoded_str(const char *in_encoded_str,
+da_ret_t decode_base64_encoded_str(const char *in_encoded_str,
char **out_decoded_ascii_str);
void decode_url_encoded_str(const char *in_encoded_str, char **out_str);
diff --git a/agent/include/download-agent-file.h b/agent/include/download-agent-file.h
index b4d3995..2788fdd 100755
--- a/agent/include/download-agent-file.h
+++ b/agent/include/download-agent-file.h
@@ -14,39 +14,32 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_File_H
-#define _Download_Agent_File_H
+#ifndef _DOWNLOAD_AGENT_FILE_H
+#define _DOWNLOAD_AGENT_FILE_H
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "download-agent-type.h"
-#include "download-agent-dl-mgr.h"
+#include "download-agent-dl-info.h"
-#define DA_DEFAULT_INSTALL_PATH_FOR_PHONE "/opt/usr/media/Downloads"
+#define DA_FILE_BUF_SIZE (1024*32) //bytes
+da_ret_t check_drm_convert(file_info_t *file_info);
da_bool_t is_file_exist(const char *file_path);
-da_bool_t is_dir_exist(const char *dir_path);
-
-void get_file_size(char *file_path, unsigned long long *out_file_size);
-
-da_result_t clean_files_from_dir(char *dir_path);
-da_result_t file_write_ongoing(stage_info *stage, char *body, int body_len);
-da_result_t file_write_complete(stage_info *stage);
-da_result_t start_file_writing(stage_info *stage);
-da_result_t start_file_writing_append(stage_info *stage);
-da_result_t start_file_writing_append_with_new_download(stage_info *stage);
-
-da_result_t get_mime_type(stage_info *stage, char **out_mime_type);
-da_result_t discard_download(stage_info *stage) ;
-void clean_paused_file(stage_info *stage);
-da_result_t replace_content_file_in_stage(stage_info *stage, const char *dest_dd_file_path);
-da_result_t decide_tmp_file_path(stage_info *stage);
-char *get_full_path_avoided_duplication(char *in_dir, char *in_candidate_file_name, char *in_extension);
-
-da_result_t copy_file(const char *src, const char *dest);
-da_result_t create_dir(const char *install_dir);
-da_result_t get_default_install_dir(char **out_path);
-
+void get_file_size(char *file_path, da_size_t *out_file_size);
+da_ret_t file_write_ongoing(file_info_t *file_info, char *body, int body_len);
+da_ret_t file_write_complete(file_info_t *file_info);
+#ifdef _RAF_SUPPORT
+da_ret_t file_write_complete_for_raf(file_info_t *file_info);
+#endif
+da_ret_t start_file_writing(da_info_t *da_info);
+da_ret_t start_file_append(file_info_t *file_info);
+da_ret_t discard_download(file_info_t *file_info) ;
+void clean_paused_file(file_info_t *file_info);
+char *get_full_path_avoided_duplication(char *in_dir,
+ char *in_candidate_file_name, char *in_extension);
+void remove_file(const char *file_path);
+da_ret_t get_available_memory(char *dir_path, da_size_t len);
#endif
diff --git a/agent/include/download-agent-http-mgr.h b/agent/include/download-agent-http-mgr.h
index 6653af0..95a0b3a 100755
--- a/agent/include/download-agent-http-mgr.h
+++ b/agent/include/download-agent-http-mgr.h
@@ -21,27 +21,14 @@
#include "download-agent-type.h"
#include "download-agent-dl-mgr.h"
-#include "download-agent-http-queue.h"
#define DA_MAX_SESSION_INFO DA_MAX_DOWNLOAD_ID
-#define DA_MAX_TRANSACTION_INFO 10
-#define DA_MAX_TRANSACTION_MUTEX DA_MAX_SESSION_INFO*DA_MAX_TRANSACTION_INFO
-typedef struct _http_mgr_t
-{
- da_bool_t is_init;
- da_bool_t is_http_init;
-}http_mgr_t;
-
-extern http_mgr_t http_mgr;
-
-da_result_t init_http_mgr(void);
-void deinit_http_mgr(void);
-da_result_t make_req_dl_info_http(stage_info *stage, req_dl_info *out_info);
-da_result_t request_http_download(stage_info *stage);
-da_result_t request_to_cancel_http_download(stage_info *stage);
-da_result_t request_to_abort_http_download(stage_info *stage);
-da_result_t request_to_suspend_http_download(stage_info *stage);
-da_result_t request_to_resume_http_download(stage_info *stage);
+da_ret_t request_http_download(da_info_t *da_info);
+da_ret_t request_to_cancel_http_download(da_info_t *da_info);
+da_ret_t request_to_abort_http_download(da_info_t *da_info);
+da_ret_t request_to_suspend_http_download(da_info_t *da_info);
+da_ret_t request_to_resume_http_download(da_info_t *da_info);
+da_bool_t is_stopped_state(da_info_t *da_info);
#endif
diff --git a/agent/include/download-agent-http-misc.h b/agent/include/download-agent-http-misc.h
deleted file mode 100755
index 3bf137b..0000000
--- a/agent/include/download-agent-http-misc.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _Download_Agent_Http_Misc_H
-#define _Download_Agent_Http_Misc_H
-
-#include <string.h>
-
-#include "download-agent-type.h"
-
-#define SCHEME_HTTP "http://"
-#define SCHEME_HTTPS "https://"
-#define SCHEME_CID "cid:"
-
-#define METHOD_GET "GET"
-#define METHOD_POST "POST"
-#define METHOD_HEAD "HEAD"
-
-#define HTTP_TAG_UAGENT "User-Agent: "
-#define HTTP_TAG_HOST "Host: "
-#define HTTP_TAG_UAPROF "X-Wap-Profile: "
-#define HTTP_TAG_CONTENT_LENGTH "Content-Length: "
-#define HTTP_TAG_CONTENT_TYPE "Content-Type: "
-#define HTTP_TAG_IF_MATCH "If-Match: "
-#define HTTP_TAG_RANGE "Range: "
-#define HTTP_TAG_IF_RANGE "If-Range: "
-
-#define END_OF_FIELD "\r\n"
-
-char *get_user_agent();
-
-da_bool_t is_supporting_protocol(const char *protocol);
-
-#endif
diff --git a/agent/include/download-agent-http-msg-handler.h b/agent/include/download-agent-http-msg-handler.h
index 29d0ae4..70abbda 100755
--- a/agent/include/download-agent-http-msg-handler.h
+++ b/agent/include/download-agent-http-msg-handler.h
@@ -18,103 +18,60 @@
#define _Download_Agent_Http_Msg_Handler_H
#include "download-agent-type.h"
+#include "download-agent-dl-info.h"
+// Reqeust Header
#define HTTP_FIELD_UAGENT "User-Agent"
#define HTTP_FIELD_HOST "Host"
#define HTTP_FIELD_UAPROF "X-Wap-Profile"
-#define HTTP_FIELD_CONTENT_LENGTH "Content-Length"
-#define HTTP_FIELD_CONTENT_TYPE "Content-Type"
#define HTTP_FIELD_IF_MATCH "If-Match"
#define HTTP_FIELD_RANGE "Range"
#define HTTP_FIELD_IF_RANGE "If-Range"
#define HTTP_FIELD_ACCEPT_LANGUAGE "Accept-Language"
#define HTTP_FIELD_ACCEPT_CHARSET "Accept-Charset"
-typedef struct _http_header_options_t http_header_options_t;
-struct _http_header_options_t{
- char *field;
- char *value;
-
- http_header_options_t *next;
-};
-
-typedef struct _http_header_t http_header_t;
-struct _http_header_t{
- char *field;
- char *value;
- http_header_options_t *options;
-
- char *raw_value; // raw string including options
-
- http_header_t *next;
-};
-
-typedef struct{
- char *http_method;
- char *url;
- http_header_t *head;
- char *http_body;
-}http_msg_request_t;
-
-
-typedef struct{
- int status_code;
- http_header_t *head;
-}http_msg_response_t;
-
-typedef http_header_t *http_msg_iter_t;
-
-
-typedef struct{
- http_msg_request_t *http_msg_request;
- http_msg_response_t *http_msg_response;
-}http_info_t;
+// Response Header
+#define HTTP_FIELD_CONTENT_LENGTH "Content-Length"
+#define HTTP_FIELD_CONTENT_TYPE "Content-Type"
+#define HTTP_FIELD_CONTENT_DISPOSITION "Content-Disposition"
+#define HTTP_FIELD_LOCATION "Location"
+#define HTTP_FIELD_DATA "Date"
+#define HTTP_FIELD_ETAG "ETag"
+#ifdef _RAF_SUPPORT
+#define HTTP_FIELD_RAF_MODE "x-direct-write"
+#endif
+#define HTTP_FIELD_END_OF_FIELD "\r\n"
-da_result_t http_msg_request_create(http_msg_request_t **http_msg_request);
+da_ret_t http_msg_request_create(http_msg_request_t **http_msg_request);
void http_msg_request_destroy(http_msg_request_t **http_msg_request);
+da_ret_t http_msg_request_set_url(http_msg_request_t *http_msg_request, const char *url);
+da_ret_t http_msg_request_get_url(http_msg_request_t *http_msg_request, const char **url);
+da_ret_t http_msg_request_add_field(http_msg_request_t *http_msg_request, const char *field, const char *value);
-da_result_t http_msg_request_set_method(http_msg_request_t *http_msg_request, const char *method);
-da_result_t http_msg_request_get_method(http_msg_request_t *http_msg_request, const char **method);
-
-da_result_t http_msg_request_set_url(http_msg_request_t *http_msg_request, const char *url);
-da_result_t http_msg_request_get_url(http_msg_request_t *http_msg_request, const char **url);
-
-da_result_t http_msg_request_set_body(http_msg_request_t *http_msg_request, const char *body);
-da_result_t http_msg_request_get_body(http_msg_request_t *http_msg_request, const char **body);
-
-da_result_t http_msg_request_add_field(http_msg_request_t *http_msg_request, const char *field, const char *value);
-
-
-da_result_t http_msg_response_create(http_msg_response_t **http_msg_response);
+da_ret_t http_msg_response_create(http_msg_response_t **http_msg_response);
void http_msg_response_destroy(http_msg_response_t **http_msg_response);
-
-da_result_t http_msg_response_set_status_code(http_msg_response_t *http_msg_response, int status_code);
-da_result_t http_msg_response_get_status_code(http_msg_response_t *http_msg_response, int *status_code);
-
-da_result_t http_msg_response_add_field(http_msg_response_t *http_msg_response, const char *field, const char *value);
-
+da_ret_t http_msg_response_add_field(http_msg_response_t *http_msg_response, const char *field, const char *value);
/* Caution! Caller must free memory for every "char** out_xxx" for followings */
da_bool_t http_msg_response_get_content_type(http_msg_response_t *http_msg_response, char **out_type);
void http_msg_response_set_content_type(http_msg_response_t *http_msg_response, const char *in_type);
-da_bool_t http_msg_response_get_content_length(http_msg_response_t *http_msg_response, unsigned long long *out_length);
+da_bool_t http_msg_response_get_content_length(http_msg_response_t *http_msg_response, da_size_t *out_length);
da_bool_t http_msg_response_get_content_disposition(http_msg_response_t *http_msg_response, char **out_disposition, char **out_file_name);
da_bool_t http_msg_response_get_ETag(http_msg_response_t *http_msg_response, char **out_value);
da_bool_t http_msg_response_get_date(http_msg_response_t *http_msg_response, char **out_value);
da_bool_t http_msg_response_get_location(http_msg_response_t *http_msg_response, char **out_value);
-// should be refactored later
-da_result_t http_msg_response_get_boundary(http_msg_response_t *http_msg_response, char **out_val);
-
-
-da_result_t http_msg_request_get_iter(http_msg_request_t *http_msg_request, http_msg_iter_t *http_msg_iter);
-da_result_t http_msg_response_get_iter(http_msg_response_t *http_msg_response, http_msg_iter_t *http_msg_iter);
-
+#ifdef _RAF_SUPPORT
+da_bool_t http_msg_response_get_RAF_mode(http_msg_response_t *http_msg_response,
+ char **out_value);
+#endif
+da_ret_t http_msg_request_get_iter(http_msg_request_t *http_msg_request, http_msg_iter_t *http_msg_iter);
+da_ret_t http_msg_response_get_iter(http_msg_response_t *http_msg_response, http_msg_iter_t *http_msg_iter);
// should remove later
da_bool_t http_msg_get_field_with_iter(http_msg_iter_t *http_msg_iter, char **field, char **value);
da_bool_t http_msg_get_header_with_iter(http_msg_iter_t *http_msg_iter, char **out_field, http_header_t **out_header);
-
-char *get_http_response_header_raw(http_msg_response_t *http_msg_response);
-
da_bool_t extract_attribute_from_header(char *szHeadStr, const char *szFindStr, char **ppRtnValue);
+da_bool_t http_msg_request_get_if_range(http_msg_request_t *http_msg_request, char **out_value);
+da_bool_t http_msg_request_get_range(http_msg_request_t *http_msg_request, char **out_value);
+
#endif // _Download_Agent_Http_Msg_Handler_H
diff --git a/agent/include/download-agent-http-queue.h b/agent/include/download-agent-http-queue.h
deleted file mode 100755
index 9973698..0000000
--- a/agent/include/download-agent-http-queue.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _Download_Agent_Http_Queue_H
-#define _Download_Agent_Http_Queue_H
-
-
-#include "download-agent-type.h"
-#include "download-agent-http-msg-handler.h"
-
-#include <pthread.h>
-#include <stdlib.h>
-
-#define MAX_QUEUE_SIZE 1024*64
-
-typedef enum
-{
- Q_EVENT_TYPE_DATA_HTTP,
- Q_EVENT_TYPE_DATA_DRM,
- Q_EVENT_TYPE_CONTROL,
-}q_event_type;
-
-typedef enum
-{
- Q_EVENT_TYPE_CONTROL_NONE = 0,
- Q_EVENT_TYPE_CONTROL_CANCEL,
- Q_EVENT_TYPE_CONTROL_SUSPEND,
- Q_EVENT_TYPE_CONTROL_RESUME,
- Q_EVENT_TYPE_CONTROL_NET_DISCONNECTED,
- Q_EVENT_TYPE_CONTROL_ABORT,
-// [090205][jungki]not used yet.
-// Q_EVENT_TYPE_CONTROL_USER_CONFIRM_RESULT,
-// Q_EVENT_TYPE_CONTROL_INSTALL_RESULT,
-}q_event_type_control;
-
-typedef enum
-{
- Q_EVENT_TYPE_DATA_PACKET,
- Q_EVENT_TYPE_DATA_FINAL,
- Q_EVENT_TYPE_DATA_ABORT,
-}q_event_type_data;
-
-typedef struct _q_event_data_http_t
-{
- q_event_type_data data_type;
-
- int status_code;
-
- http_msg_response_t* http_response_msg;
-
- int body_len;
- char *body_data;
-
- da_result_t error_type;
-}q_event_data_http_t;
-
-typedef struct _q_event_control_t
-{
- q_event_type_control control_type;
-}q_event_control_t;
-
-typedef struct _q_event_t q_event_t;
-struct _q_event_t
-{
- int size;
- q_event_type event_type;
- union _type
- {
- q_event_data_http_t q_event_data_http;
- q_event_control_t q_event_control;
- } type;
-
- q_event_t *next;
-};
-
-typedef struct _queue_t
-{
- da_bool_t having_data;
-
- q_event_t *control_head;
- q_event_t *data_head;
-
- pthread_mutex_t mutex_queue;
- pthread_cond_t cond_queue;
-
- int queue_size;
-}queue_t;
-
-void Q_init_queue(queue_t *queue);
-void Q_destroy_queue(queue_t *queue);
-
-void Q_init_q_event(q_event_t *q_event);
-void Q_destroy_q_event(q_event_t **q_event);
-
-da_result_t Q_make_control_event(q_event_type_control control_type, q_event_t **out_event);
-
-da_result_t Q_make_http_data_event(q_event_type_data data_type, q_event_t **out_event);
-da_result_t Q_set_status_code_on_http_data_event(q_event_t *q_event, int status_code);
-da_result_t Q_set_http_body_on_http_data_event(q_event_t *q_event, int body_len, char *body_data);
-da_result_t Q_set_error_type_on_http_data_event(q_event_t *q_event, int error_type);
-
-
-da_bool_t Q_push_event(const queue_t *in_queue, const q_event_t *in_event);
-da_bool_t Q_push_event_without_lock(const queue_t *in_queue, const q_event_t *in_event);
-void Q_pop_event(const queue_t *in_queue, q_event_t **out_event);
-
-#define GET_IS_Q_HAVING_DATA(QUEUE) (QUEUE->having_data)
-
-void Q_goto_sleep(const queue_t *in_queue);
-void Q_wake_up(const queue_t *in_queue);
-
-
-#endif
diff --git a/agent/include/download-agent-interface.h b/agent/include/download-agent-interface.h
index 44081bd..f5ce653 100755
--- a/agent/include/download-agent-interface.h
+++ b/agent/include/download-agent-interface.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Interface_H
-#define _Download_Agent_Interface_H
+#ifndef _DOWNLOAD_AGENT_INTERFACE_H
+#define _DOWNLOAD_AGENT_INTERFACE_H
#ifndef EXPORT_API
#define EXPORT_API __attribute__((visibility("default")))
@@ -29,450 +29,69 @@ extern "C"
#include "download-agent-defs.h"
#include <stdarg.h>
-/**
- * @struct user_paused_info_t
- * @brief Download Agent will send its state through this structure.
- * @see da_paused_info_cb
- * @par
- * This is used only by callback /a user_paused_info_t. \n
- */
-typedef struct {
- /// download request id for this notification
- int download_id;
-} user_paused_info_t;
-
-/**
- * @struct user_progress_info_t
- * @brief Download Agent will send current downloading file's information through this structure.
- * @see da_progress_info_cb
- * @par
- * This is used only by callback /a da_progress_info_cb. \n
- */
-typedef struct {
- /// download request id for this updated download information
- int download_id;
- /// received size of chunked data.
- unsigned long int received_size;
-} user_progress_info_t;
-
-/**
- * @struct user_download_info_t
- * @brief Download Agent will send current download's information through this structure.
- * @see da_started_info_cb
- * @par
- * This is used only by callback /a da_started_info_cb. \n
- */
typedef struct {
- /// download request id for this updated download information
int download_id;
- /// file's mime type from http header.
char *file_type;
- /// file size from http header.
- unsigned long int file_size;
- /// This is temporary file path.
+ unsigned long long file_size;
char *tmp_saved_path;
- /// This is the file name for showing to user.
char *content_name;
- /// etag string value for resume download,
char *etag;
-} user_download_info_t;
+} download_info_t;
typedef struct {
- /// download request id for this updated download information
int download_id;
- /// This has only file name for now.
char *saved_path;
- /// etag string value for resume download,
- /// This is returned when the download is failed and the etag is received from content server
char *etag;
- /// convey error code if necessary, or it is zero.
int err;
- /// http status code if necessary, or it is zero.
int http_status;
-} user_finished_info_t;
+} finished_info_t;
typedef struct {
const char **request_header;
int request_header_count;
const char *install_path;
const char *file_name;
- const char *temp_file_path; /* For resume download, the "etag" value should be existed together */
- const char *etag; /* For resume download */
- const char *pkg_name; /* For system resource */
- void *user_data;
-} extension_data_t;
-
-/**
- * @typedef da_paused_cb
- * @brief Download Agent will call this function to paused its state.
- *
- * This is user callback function registered on \a da_init. \n
- *
- * @remarks For the most of time, this state is just informative, so, user doesn't need to do any action back to Download Agent.
- *
- * @warning Download will be holding until getting user confirmation result through the function.
- *
- * @param[in] state state from Download Agent
- * @param[in] user_param user parameter which is set with \a DA_FEATURE_USER_DATA
- *
- * @see da_init
- * @see da_client_cb_t
- */
-typedef void (*da_paused_info_cb) (user_paused_info_t *paused_info, void *user_param);
-
-/**
- * @brief Download Agent will call this function to update received size of download-requested file.
- *
- * This is user callback function registered on \a da_init. \n
- * This is informative, so, user doesn't need to do any action back to Download Agent.\n
- *
- * @param[in] progress_info updated downloading information
- * @param[in] user_param user parameter which is set with \a DA_FEATURE_USER_DATA
- *
- * @see da_init
- * @see da_client_cb_t
- */
-typedef void (*da_progress_info_cb) (user_progress_info_t *progress_info, void *user_param);
-
-/**
- * @brief Download Agent will call this function to update mime type, temp file name, total file sizeand installed path.
- *
- * This is user callback function registered on \a da_init. \n
- * This is informative, so, user doesn't need to do any action back to Download Agent.\n
- *
- * @param[in] download_info updated download information
- * @param[in] user_param user parameter which is set with \a DA_FEATURE_USER_DATA
- *
- * @see da_init
- * @see da_client_cb_t
- */
-typedef void (*da_started_info_cb) (user_download_info_t *download_info, void *user_param);
+ const char *temp_file_path;
+ const char *etag;
+ const char *pkg_name;
+ int network_bonding;
+ void *user_req_data;
+ void *user_client_data;
+} req_data_t;
+
+typedef void (*da_paused_cb) (int download_id,
+ void *user_param1, void *user_param2);
+typedef void (*da_progress_cb) (int download_id,
+ unsigned long long received_size,
+ void *user_param1, void *user_param2);
+typedef void (*da_started_cb) (download_info_t *download_info,
+ void *user_param1, void *user_param2);
+typedef void (*da_finished_cb) (finished_info_t *finished_info,
+ void *user_param1, void *user_param2);
-typedef void (*da_finished_info_cb) (user_finished_info_t *finished_info, void *user_param);
- /**
- * @struct da_client_cb_t
- * @brief This structure convey User's callback functions for \a da_init
- * @see da_init
- */
typedef struct {
- /// callback to convey download information
- da_started_info_cb update_dl_info_cb;
- /// callback to convey downloading information while downloading including received file size
- da_progress_info_cb update_progress_info_cb;
- /// callback to convey saved path
- da_finished_info_cb finished_info_cb;
- /// callback to convey etag value
- da_paused_info_cb paused_info_cb;
-} da_client_cb_t;
-
-/**
- * @fn int da_init (da_client_cb_t *da_client_callback)
- * @brief This function initiates Download Agent and registers user callback functions.
- * @warning This should be called at once when client application is initialized before using other Download Agent APIs
- * @warning This function is paired with da_deinit function.
- *
- * @pre None.
- * @post None.
- *
- * @param[in] da_client_callback User callback function structure. The type is struct data pointer.
- * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h.
- * @remarks User MUST call this function first rather than any other DA APIs. \n
- * Please do not call UI code at callback function in direct. \n
- * It is better that it returns as soon as copying the data of callback functon. \n
- * @see da_deinit
- * @par Example
- * @code
- * #include <download-agent-interface.h>
- *
- * void da_started_info_cb(user_download_info_t *download_info,void *user_param);
- * void da_progress_info_cb(user_downloading_info_t *downloading_info,void *user_param);
- * void da_finished_cb(user_finished_info_t *complted_info, void *user_param);
- * void da_paused_info_cb(user_paused_info_t *paused_info, void *user_param);
- *
- * int download_initialize()
- * {
- * int da_ret;
- * da_client_cb_t da_cb = {0};
- *
- * da_cb.update_dl_info_cb = &update_download_info_cb;
- * da_cb.update_progress_info_cb = &progress_info_cb;
- * da_cb.finished_info_cb = &finished_info_cb;
- * da_cb.paused_info_cb = &paused_cb;
- *
- * da_ret = da_init (&da_cb, 0);
- * if (da_ret == DA_RESULT_OK) {
- * // printf("successed\n");
- * return true;
- * } else {
- * // printf("failed with error code %d\n", da_ret);
- * return fail;
- * }
- * }
- * @endcode
- */
-EXPORT_API int da_init(da_client_cb_t *da_client_callback);
+ da_started_cb download_info_cb;
+ da_progress_cb progress_cb;
+ da_finished_cb finished_cb;
+ da_paused_cb paused_cb;
+} da_cb_t;
- /**
- * @fn int da_deinit ()
- * @brief This function deinitiates Download Agent.
- *
- * This function destroys all infomation for client manager.
- * When Download Agent is not used any more, please call this function.
- * Usually when client application is destructed, this is needed.
- *
- * @remarks This is paired with da_init. \n
- * The client Id should be the one from /a da_init(). \n
- * Otherwise, it cannot excute to deinitialize. \n
- *
- * @pre da_init() must be called in advance.
- * @post None.
- *
- * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h.
- * @see da_init
- * @par Example
- * @code
- * #include <download-agent-interface.h>
- *
- *
- * int download_deinitialize()
- * {
- * int da_ret;
- * da_ret = da_deinit();
- * if(da_ret == DA_RESULT_OK) {
- * // printf("successed\n");
- * return true;
- * } else {
- * // printf("failed with error code %d\n", da_ret);
- * return fail;
- * }
- * }
- @endcode
- */
+EXPORT_API int da_init();
EXPORT_API int da_deinit();
- /**
- * @fn int da_start_download(const char *url, int *download_id)
- * @brief This function starts to download a content on passed URL.
- *
- * Useful information and result are conveyed through following callbacks.
- * @li da_started_info_cb
- * @li da_progress_cb
- *
- * @pre da_init() must be called in advance.
- * @post None.
- * @remarks
- * Downloaded file is automatically registered to system. (e.g. File DB) \n
- * If there is another file has same name on registering directory, new one's name would have numbering postfix. \n
- * (e.g. abc.mp3 to abc_1.mp3)
- *
- * @param[in] url url to start download
- * @param[out] download_id assigned download request id for this URL
- * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h.
- *
- * @see None.
- *
- * @par Example
- * @code
- * #include <download-agent-interface.h>
- *
- * int da_ret;
- * int download_id;
- * char *url = "http://www.test.com/sample.mp3";
- *
- * da_ret = da_start_download(url,&download_id);
- * if (da_ret == DA_RESULT_OK)
- * printf("download requesting is successed\n");
- * else
- * printf("download requesting is failed with error code %d\n", da_ret);
- * @endcode
- */
-EXPORT_API int da_start_download(const char *url, int *download_id);
-
-/**
-* @fn int da_start_download_with_extension(const char *url, extension_data_t ext_data, int *download_id)
-* @brief This function starts to download a content on passed URL with passed extension.
-*
-* Useful information and result are conveyed through following callbacks.
-* @li da_started_info_cb
-* @li da_progress_cb
-*
-* @pre da_init() must be called in advance.
-* @post None.
-* @remarks This API operation is exactly same with da_start_download(), except for input properties. \n
-*
-* @param[in] url url to start download
-* @param[in] ext_data extension data
-* @param[out] download_id assigned download request id for this URL
-* @return DA_RESULT_OK for success, or DA_ERR_XXX for fail. DA_ERR_XXX is defined at download-agent-def.h.
-*
-*
-* @par Example
-* @code
- #include <download-agent-interface.h>
-
- int da_ret;
- int download_id;
- extension_data_t ext_data = {0,};
- const char *url = "https://www.test.com/sample.mp3";
- const char *install_path = "/myFiles/music";
- const char *my_data = strdup("data");
- ext_data.install_path = install_path;
- ext_data.user_data = (void *)my_data;
-
- da_ret = da_start_download_with_extension(url, &download_id, &ext_data);
- if (da_ret == DA_RESULT_OK)
- printf("download requesting is successed\n");
- else
- printf("download requesting is failed with error code %d\n", da_ret);
- @endcode
-*/
-EXPORT_API int da_start_download_with_extension(const char *url,
- extension_data_t *ext_data,
- int *download_id
-);
-
-
-/**
- * @fn int da_cancel_download(int download_id)
- * @brief This function cancels a download for passed download_id.
- *
- * Client can use this function if user wants to cancel already requested download.
- *
- * @remarks Should check return value. \n
- * If return value is not DA_RESULT_OK, then previous requested download can be keep downloading.
- * @remarks After calling this function, all information for the download_id will be deleted. So, client cannot request anything for the download_id.
- *
- * @pre There should be exist ongoing or suspended download for download_id.
- * @post None.
- *
- * @param[in] download_id download request id
- * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail
- *
- * @see None.
- *
- * @par Example
- * @code
- #include <download-agent-interface.h>
-
- int da_ret;
- int download_id;
-
- da_ret = da_cancel_download(download_id);
- if(da_ret == DA_RESULT_OK) {
- // printf("download with [%d] is successfully canceled.\n", download_id);
- }
- else {
- // in this case, downloading with download_id is keep ongoing.
- printf("failed to cancel with error code %d\n", da_ret);
- }
- @endcode
- */
+EXPORT_API int da_start_download(const char *url, req_data_t *ext_data,
+ da_cb_t *da_cb_data, int *download_id);
EXPORT_API int da_cancel_download(int download_id);
-
-
-/**
- * @fn int da_suspend_download(int download_id)
- * @brief This function suspends downloading for passed download_id.
- *
- * Client can use this function if user wants to suspend already requested download.
- *
- * @remarks Should check return value. \n
- * If return value is not DA_RESULT_OK, then previous requested download can be keep downloading.
- * @remarks After calling this function, all information for the download_id will be remained. So, client can request resume for the download_id.
- * @remarks Client should cancel or resume for this download_id, or all information for the download_id will be leaved forever.
- *
- * @pre There should be exist ongoing download for download_id.
- * @post None.
- *
- * @param[in] download_id download request id
- * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail
- *
- * @see da_resume_download()
- * @see da_cancel_download()
- *
- * @par Example
- * @code
- #include <download-agent-interface.h>
-
- int da_ret;
- int download_id;
-
- da_ret = da_suspend_download(download_id);
- if(da_ret == DA_RESULT_OK) {
- // printf("download with [%d] is successfully suspended.\n", download_id);
- }
- else {
- // in this case, downloading with download_id is keep ongoing.
- printf("failed to suspend with error code %d\n", da_ret);
- }
- @endcode
- */
+EXPORT_API int da_cancel_download_without_update(int download_id);
EXPORT_API int da_suspend_download(int download_id);
-
EXPORT_API int da_suspend_download_without_update(int download_id);
-/**
- * @fn int da_resume_download(int download_id)
- * @brief This function resumes downloading for passed download_id.
- *
- * Client can use this function if user wants to resume suspended download.
- *
- * @remarks Should check return value. \n
- * If return value is not DA_RESULT_OK, then requested download can be not to resume.
- *
- * @pre There should be exist suspended download for download_id.
- * @post None.
- *
- * @param[in] download_id download request id
- * @return DA_RESULT_OK for success, or DA_ERR_XXX for fail
- *
- * @see da_suspend_download()
- *
- * @par Example
- * @code
- #include <download-agent-interface.h>
-
- int da_ret;
- int download_id;
-
- da_ret = da_resume_download(download_id);
- if(da_ret == DA_RESULT_OK) {
- // printf("download with [%d] is successfully resumed.\n", download_id);
- }
- else {
- // in this case, downloading with download_id is keep suspended.
- printf("failed to resume with error code %d\n", da_ret);
- }
- @endcode
- */
EXPORT_API int da_resume_download(int download_id);
-
-/**
- * @fn int da_is_valid_download_id(int download_id)
- * @brief This function return the download id is valid and the download thread is still alive.
- *
- * Client can use this function if user wants to resume download.
- * If the download id is vaild and the download thread is alive, it can resume download with using da_resume_download()
- * If the the download thread was already terminated due to restarting the process,
- * it can resume download with using da_start_download_with_extension()
- *
- *
- *
- * @remarks Should check return value. \n
- * If return value is not DA_RESULT_OK, then requested download can be not to resume.
- *
- * @pre There should be exist suspended download for download_id.
- * @post None.
- *
- * @param[in] download_id download request id
- * @return 1 for success, or 0 for fail
- *
- */
EXPORT_API int da_is_valid_download_id(int download_id);
#ifdef __cplusplus
}
#endif
-#endif //_Download_Agent_Interface_H
+#endif //_DOWNLOAD_AGENT_INTERFACE_H
diff --git a/agent/include/download-agent-mime-util.h b/agent/include/download-agent-mime-util.h
index 5f143e9..7f57899 100755
--- a/agent/include/download-agent-mime-util.h
+++ b/agent/include/download-agent-mime-util.h
@@ -34,7 +34,15 @@ typedef struct {
da_bool_t is_ambiguous_MIME_Type(const char *in_mime_type);
da_bool_t da_get_extension_name_from_url(char *url, char **ext);
-da_result_t da_mime_get_ext_name(char *mime, char **ext);
+da_ret_t da_mime_get_ext_name(char *mime, char **ext);
da_bool_t da_get_file_name_from_url(char *url, char **name) ;
void delete_prohibited_char(char *szTarget, int str_len);
+da_ret_t get_extension_from_mime_type(char *mime_type, char **extension);
+#ifdef _ENABLE_OMA_DRM
+da_bool_t is_content_drm_dcf(char *content_type);
+da_bool_t is_content_drm_dm(char *content_type);
+#endif
+
+
+
#endif
diff --git a/agent/include/download-agent-plugin-conf.h b/agent/include/download-agent-plugin-conf.h
index 2c4f55f..11e8095 100755
--- a/agent/include/download-agent-plugin-conf.h
+++ b/agent/include/download-agent-plugin-conf.h
@@ -19,9 +19,12 @@
#include "download-agent-type.h"
#include "download-agent-interface.h"
-#include "download-agent-utils.h"
-da_result_t get_user_agent_string(char **uagent_str);
+da_ret_t get_user_agent_string(char **uagent_str);
char *get_proxy_address(void);
+#ifdef _RAF_SUPPORT
+//test code
+void get_smart_bonding_vconf();
+#endif
#endif
diff --git a/agent/include/download-agent-basic.h b/agent/include/download-agent-plugin-drm.h
index 340a34a..361f387 100755..100644
--- a/agent/include/download-agent-basic.h
+++ b/agent/include/download-agent-plugin-drm.h
@@ -14,16 +14,12 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Basic_H
-#define _Download_Agent_Basic_H
-
-#include <string.h>
+#ifndef _Download_Agent_Plugin_Drm_H
+#define _Download_Agent_Plugin_Drm_H
#include "download-agent-type.h"
-#include "download-agent-interface.h"
-#include "download-agent-dl-mgr.h"
-da_result_t start_download(const char *url, int *dl_id);
-da_result_t start_download_with_extension(const char *url , int *dl_id, extension_data_t *extension_data);
+da_bool_t EDRM_convert(const char *in_file_path, char **out_file_path);
+da_ret_t EDRM_wm_get_license(char *rights_url, char **out_content_url);
#endif
diff --git a/agent/include/download-agent-plugin-http-interface.h b/agent/include/download-agent-plugin-http-interface.h
deleted file mode 100755
index b9698bb..0000000
--- a/agent/include/download-agent-plugin-http-interface.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _Download_Agent_Plugin_Http_Interface_H
-#define _Download_Agent_Plugin_Http_Interface_H
-
-#include "download-agent-type.h"
-#include "download-agent-http-msg-handler.h"
-
-typedef enum {
- PI_HTTP_METHOD_GET = 1,
- PI_HTTP_METHOD_POST = 2,
- PI_HTTP_METHOD_HEAD = 3
-} pi_http_method_t;
-
-
-typedef struct _input_for_tranx_t {
- pi_http_method_t http_method;
-
- char *proxy_addr;
- queue_t *queue;
-
- http_msg_request_t* http_msg_request;
-} input_for_tranx_t;
-
-
-
-da_result_t PI_http_init(void);
-void PI_http_deinit(void);
-
-da_result_t PI_http_start_transaction(const input_for_tranx_t *input_for_tranx, int *out_tranx_id);
-da_result_t PI_http_cancel_transaction(int in_tranx_id, da_bool_t abort_option);
-da_result_t PI_http_disconnect_transaction(int in_tranx_id);
-void PI_http_pause_transaction(int transaction_id);
-void PI_http_unpause_transaction(int transaction_id);
-
-#endif
-
diff --git a/agent/include/download-agent-plugin-libcurl.h b/agent/include/download-agent-plugin-libcurl.h
new file mode 100644
index 0000000..67a4c53
--- /dev/null
+++ b/agent/include/download-agent-plugin-libcurl.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _Download_Agent_Plugin_Libcurl_H
+#define _Download_Agent_Plugin_Libcrul_H
+
+#include "download-agent-type.h"
+#include "download-agent-dl-info.h"
+
+#define MAX_SESSION_COUNT DA_MAX_DOWNLOAD_REQ_AT_ONCE
+#define MAX_TIMEOUT DA_MAX_TIME_OUT
+
+da_ret_t PI_http_start(da_info_t *da_info);
+da_ret_t PI_http_disconnect(http_info_t *info);
+da_ret_t PI_http_cancel(http_info_t *info);
+da_ret_t PI_http_pause(http_info_t *info);
+da_ret_t PI_http_unpause(http_info_t *info);
+#ifdef _RAF_SUPPORT
+da_ret_t PI_http_set_file_name_to_curl(http_msg_t *http_msg, char *file_path);
+#endif
+
+#endif
diff --git a/agent/include/download-agent-plugin-libsoup.h b/agent/include/download-agent-plugin-libsoup.h
deleted file mode 100755
index 8160042..0000000
--- a/agent/include/download-agent-plugin-libsoup.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _Download_Agent_Plugin_Libsoup_H
-#define _Download_Agent_Plugin_Libsoup_H
-
-#include <string.h>
-#include <libsoup/soup.h>
-
-#include "download-agent-http-queue.h"
-#include "download-agent-pthread.h"
-#include "download-agent-plugin-http-interface.h"
-
-typedef struct _pi_session_table_t {
- da_bool_t is_using;
- SoupSession *session;
- SoupMessage *msg;
- queue_t *queue;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- da_bool_t is_paused;
-} pi_session_table_t;
-
-extern pi_session_table_t pi_session_table[];
-
-#define MAX_SESSION_COUNT DA_MAX_DOWNLOAD_REQ_AT_ONCE
-#define MAX_TIMEOUT 60 // second
-
-#define IS_VALID_SESSION_TABLE_ENTRY(ENTRY) ((((ENTRY) < 0) || ((ENTRY) > MAX_SESSION_COUNT-1)) ? 0 : 1)
-
-
-#define GET_SESSION_FROM_TABLE_ENTRY(ENTRY) (pi_session_table[ENTRY].session)
-#define GET_MSG_FROM_TABLE_ENTRY(ENTRY) (pi_session_table[ENTRY].msg)
-#define GET_QUEUE_FROM_TABLE_ENTRY(ENTRY) (pi_session_table[ENTRY].queue)
-
-
-da_bool_t _pi_http_is_valid_input_for_tranx(const input_for_tranx_t *input_for_tranx);
-
-void _pi_http_init_session_table_entry(const int in_session_table_entry);
-void _pi_http_destroy_session_table_entry(const int in_session_table_entry);
-int _pi_http_get_avaiable_session_table_entry(void);
-
-da_bool_t _pi_http_register_queue_to_session_table(const int session_table_entry, const queue_t *in_queue);
-da_bool_t _pi_http_register_session_to_session_table(const int in_session_table_entry, SoupSession *session);
-da_bool_t _pi_http_register_msg_to_session_table(const int in_session_table_entry, SoupMessage *msg);
-
-queue_t *_pi_http_get_queue_from_session_table_entry(const int in_session_table_entry);
-int _pi_http_get_session_table_entry_from_message(SoupMessage *msg);
-
-void _pi_http_store_read_data_to_queue(SoupMessage *msg, const char *body_data, int received_body_len);
-void _pi_http_store_read_header_to_queue(SoupMessage *msg, const char *sniffedType);
-void _pi_http_store_neterr_to_queue(SoupMessage *msg);
-
-
-void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data);
-void _pi_http_restarted_cb(SoupMessage *msg, gpointer data);
-void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data);
-void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType, GHashTable *params, gpointer data);
-void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data);
-
-
-#endif
diff --git a/agent/include/download-agent-pthread.h b/agent/include/download-agent-pthread.h
index 8523567..2748581 100755
--- a/agent/include/download-agent-pthread.h
+++ b/agent/include/download-agent-pthread.h
@@ -14,134 +14,131 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Pthread_H
-#define _Download_Agent_Pthread_H
+#ifndef _DOWNLOAD_AGENT_PTHREAD_H
+#define _DOWNLOAD_AGENT_PTHREAD_H
#include <pthread.h>
#include <errno.h>
#include <time.h>
-#include "download-agent-type.h"
#include "download-agent-debug.h"
-#define _da_thread_mutex_init(mutex_add, attr) { \
- int ret = 0; \
- do{ \
- ret = pthread_mutex_init(mutex_add, attr); \
- if (0 == ret){ \
- break; \
- } \
- else if(EINVAL == ret){ \
- DA_LOG_ERR(Default, "pthread_mutex_init FAIL with EINVAL."); \
- break; \
- } \
- else if(ENOMEM == ret){ \
- DA_LOG_ERR(Default, "pthread_mutex_init FAIL with ENOMEM."); \
- break; \
- } \
- else{ \
- DA_LOG_ERR(Default, "pthread_mutex_init FAIL with %d.", ret); \
- break; \
- } \
- }while(1); \
- }
-
-#define _da_thread_cond_init(cond_add, attr) do{ \
- if (0 != pthread_cond_init(cond_add, attr)){\
- DA_LOG_ERR(Default, "pthread_cond_init FAIL");} \
- }while(0)
-
-
-
-#define _da_thread_mutex_lock(mutex_add) {\
- int ret = 0;\
- do{\
- ret = pthread_mutex_lock(mutex_add);\
- if (0 == ret){\
- break;\
- }\
- else if(EINVAL == ret){\
- DA_LOG_ERR(Default, "pthread_mutex_lock FAIL with EINVAL.");\
- break;\
- }\
- else if(EDEADLK == ret){\
- DA_LOG_ERR(Default, "pthread_mutex_lock FAIL with EDEADLK.");\
- break;\
- }\
- else{\
- DA_LOG_ERR(Default, "pthread_mutex_lock FAIL with %d.", ret);\
- break;\
- }\
- }while(1);\
- }
-
-
-#define _da_thread_mutex_unlock(mutex_add) {\
- int ret = 0;\
- do{\
- ret = pthread_mutex_unlock(mutex_add);\
- if (0 == ret){\
- break;\
- }\
- else if(EINVAL == ret){\
- DA_LOG_ERR(Default, "pthread_mutex_unlock FAIL with EINVAL.");\
- break;\
- }\
- else if(EPERM == ret){\
- DA_LOG_ERR(Default, "pthread_mutex_unlock FAIL with EPERM.");\
- break;\
- }\
- else{\
- DA_LOG_ERR(Default, "pthread_mutex_unlock FAIL with %d.", ret);\
- break;\
- }\
- }while(1);\
- }
-
-
-#define _da_thread_cond_signal(cond_add) do{ \
- if (0 != pthread_cond_signal(cond_add)){\
- DA_LOG_ERR(Default, "pthread_cond_signal FAIL");} \
- }while(0)
-
-
-
-#define _da_thread_cond_wait(cond_add, mutex_add) do{ \
- if (0 != pthread_cond_wait(cond_add, mutex_add)){\
- DA_LOG_ERR(Default, "pthread_cond_wait FAIL");} \
- }while(0)
-
-#define _da_thread_cond_timed_wait(cond_add, mutex_add, time) do{ \
- if (0 != pthread_cond_timedwait(cond_add, mutex_add, time)){\
- DA_LOG_ERR(Default, "pthread_cond_wait FAIL");} \
- }while(0)
-
-
-#define _da_thread_cond_destroy(cond_add) do{ \
- if (0 != pthread_cond_destroy(cond_add)){\
- DA_LOG_ERR(Default, "pthread_cond_destroy FAIL");} \
- }while(0)
-
-#define _da_thread_mutex_destroy(mutex_add) {\
- int ret = 0;\
- do{\
- ret = pthread_mutex_destroy(mutex_add);\
- if (0 == ret){\
- break;\
- }\
- else if(EINVAL == ret){\
- DA_LOG_ERR(Default, "pthread_mutex_destroy FAIL with EINVAL.");\
- break;\
- }\
- else if(EBUSY == ret){\
- DA_LOG_ERR(Default, "pthread_mutex_destroy FAIL with EBUSY.");\
- break;\
- }\
- else{\
- DA_LOG_ERR(Default, "pthread_mutex_destroy FAIL with %d.", ret);\
- break;\
- }\
- }while(1);\
- }
-
+#define DA_MUTEX_INIT(mutex_add, attr) {\
+ int ret = 0;\
+ do {\
+ ret = pthread_mutex_init(mutex_add, attr);\
+ if (0 == ret){\
+ break;\
+ }\
+ else if (EINVAL == ret){\
+ DA_LOGE("pthread_mutex_init FAIL with EINVAL.");\
+ break;\
+ }\
+ else if (ENOMEM == ret){\
+ DA_LOGE("pthread_mutex_init FAIL with ENOMEM.");\
+ break;\
+ }\
+ else{\
+ DA_LOGE("pthread_mutex_init FAIL with %d.", ret);\
+ break;\
+ }\
+ } while(1);\
+}
+
+#define DA_COND_INIT(cond_add, attr) do {\
+ if (0 != pthread_cond_init(cond_add, attr)){\
+ DA_LOGE("pthread_cond_init FAIL");\
+ }\
+} while(0)
+
+#define DA_MUTEX_LOCK(mutex_add) {\
+ int ret = 0;\
+ do {\
+ ret = pthread_mutex_lock(mutex_add);\
+ if (0 == ret){\
+ break;\
+ }\
+ else if (EINVAL == ret){\
+ DA_LOGE("pthread_mutex_lock FAIL with EINVAL.");\
+ break;\
+ }\
+ else if (EDEADLK == ret){\
+ DA_LOGE("pthread_mutex_lock FAIL with EDEADLK.");\
+ break;\
+ }\
+ else{\
+ DA_LOGE("pthread_mutex_lock FAIL with %d.", ret);\
+ break;\
+ }\
+ } while(1);\
+}
+
+#define DA_MUTEX_UNLOCK(mutex_add) {\
+ int ret = 0;\
+ do {\
+ ret = pthread_mutex_unlock(mutex_add);\
+ if (0 == ret){\
+ break;\
+ }\
+ else if (EINVAL == ret) {\
+ DA_LOGE("pthread_mutex_unlock FAIL with EINVAL.");\
+ break;\
+ }\
+ else if (EPERM == ret) {\
+ DA_LOGE("pthread_mutex_unlock FAIL with EPERM.");\
+ break;\
+ }\
+ else {\
+ DA_LOGE("pthread_mutex_unlock FAIL with %d.", ret);\
+ break;\
+ }\
+ } while(1);\
+}
+
+#define DA_COND_SIGNAL(cond_add) do {\
+ if (0 != pthread_cond_signal(cond_add)) {\
+ DA_LOGE("pthread_cond_signal FAIL");\
+ }\
+ } while(0)
+
+#define DA_COND_WAIT(cond_add, mutex_add) do {\
+ if (0 != pthread_cond_wait(cond_add, mutex_add)){\
+ DA_LOGE("pthread_cond_wait FAIL");\
+ }\
+ } while(0)
+
+#define DA_COND_TIMED_WAIT(cond_add, mutex_add, time) do {\
+ if (0 != pthread_cond_timedwait(cond_add, mutex_add, time)){\
+ DA_LOGE("pthread_cond_wait FAIL");\
+ }\
+ } while(0)
+
+
+#define DA_COND_DESTROY(cond_add) do {\
+ if (0 != pthread_cond_destroy(cond_add)){\
+ DA_LOGE("pthread_cond_destroy FAIL");\
+ }\
+ } while(0)
+
+#define DA_MUTEX_DESTROY(mutex_add) {\
+ int ret = 0;\
+ do {\
+ ret = pthread_mutex_destroy(mutex_add);\
+ if (0 == ret){\
+ break;\
+ }\
+ else if (EINVAL == ret){\
+ DA_LOGE("pthread_mutex_destroy FAIL with EINVAL.");\
+ break;\
+ }\
+ else if (EBUSY == ret){\
+ DA_LOGE("pthread_mutex_destroy FAIL with EBUSY.");\
+ break;\
+ }\
+ else {\
+ DA_LOGE("pthread_mutex_destroy FAIL with %d.", ret);\
+ break;\
+ }\
+ } while(1);\
+}
#endif
diff --git a/agent/include/download-agent-type.h b/agent/include/download-agent-type.h
index 86fa5ca..e77c121 100755
--- a/agent/include/download-agent-type.h
+++ b/agent/include/download-agent-type.h
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Types_H
-#define _Download_Agent_Types_H
+#ifndef _DOWNLOAD_AGENT_TYPE_H
+#define _DOWNLOAD_AGENT_TYPE_H
#include "download-agent-defs.h"
-typedef int da_result_t;
+typedef int da_ret_t;
typedef int da_bool_t;
+typedef unsigned long long da_size_t;
#define IS_NOT_VALID_ID(x) (x <= DA_INVALID_ID)
@@ -31,5 +32,42 @@ typedef int da_bool_t;
#define DA_MAX_MIME_STR_LEN 256
#define DA_MAX_PROXY_ADDR_LEN 64 // e.g. 100.200.300.400:10000
+#define SCHEME_HTTP "http://"
+
+#define DA_DEFAULT_INSTALL_PATH_FOR_PHONE "/opt/usr/media/Downloads"
+
+#define DA_MAX_ID DA_MAX_DOWNLOAD_REQ_AT_ONCE
+
+#define SAVE_FILE_BUFFERING_SIZE_50KB (50*1024)
+
+#define NULL_CHECK(DATA) {\
+ if (!DATA) {\
+ DA_LOGE("NULL CHECK!:%s",(#DATA));\
+ return;\
+ }\
+}
+
+#define NULL_CHECK_RET(DATA) {\
+ if (!DATA) {\
+ DA_LOGE("NULL CHECK!:%s",(#DATA));\
+ return DA_ERR_INVALID_ARGUMENT;\
+ }\
+}
+
+#define NULL_CHECK_GOTO(DATA) {\
+ if (!DATA) {\
+ DA_LOGE("NULL CHECK!:%s",(#DATA));\
+ ret = DA_ERR_INVALID_ARGUMENT;\
+ goto ERR;\
+ }\
+}
+
+#define NULL_CHECK_RET_OPT(DATA, RET_DATA) {\
+ if (!DATA) {\
+ DA_LOGE("NULL CHECK!:%s",(#DATA));\
+ return RET_DATA;\
+ }\
+}
+
#endif
diff --git a/agent/include/download-agent-utils.h b/agent/include/download-agent-utils.h
deleted file mode 100755
index ee73307..0000000
--- a/agent/include/download-agent-utils.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _Download_Agent_Utils_H
-#define _Download_Agent_Utils_H
-
-#include <time.h>
-#include "download-agent-defs.h"
-#include "download-agent-interface.h"
-#include "download-agent-dl-mgr.h"
-
-#define SAVE_FILE_BUFFERING_SIZE_50KB (50*1024)
-#define SAVE_FILE_BUFFERING_SIZE_5MB (5*1024*1024)
-
-#define DA_SLEEP(x) \
- do \
- { \
- struct timespec interval,remainder; \
- interval.tv_sec = (unsigned int)((x)/1000); \
- interval.tv_nsec = (((x)-(interval.tv_sec*1000))*1000000); \
- nanosleep(&interval,&remainder); \
- } while(0)
-
-typedef struct _da_storage_size_t {
- unsigned long b_available;
- unsigned long b_size;
-} da_storage_size_t;
-
-typedef enum {
- DA_MIME_TYPE_NONE,
- DA_MIME_TYPE_DRM1_MESSATE,
- DA_MIME_TYPE_END
-} da_mime_type_id_t;
-
-void get_random_number(int *out_num);
-da_result_t get_available_dd_id(int *available_id);
-da_result_t get_extension_from_mime_type(char *mime_type, char **extension);
-da_mime_type_id_t get_mime_type_id(char *content_type);
-da_result_t get_available_memory(da_storage_size_t *avail_memory);
-da_bool_t is_valid_url(const char *url, da_result_t *err_code);
-
-int read_data_from_file(char *file, char**out_buffer);
-da_result_t move_file(const char *from_path, const char *to_path);
-void remove_file(const char *file_path);
-char *_stristr(const char *long_str, const char *find_str);
-
-#endif
diff --git a/download-provider-schema.sql b/download-provider-schema.sql
deleted file mode 100644
index 44beda2..0000000
--- a/download-provider-schema.sql
+++ /dev/null
@@ -1,74 +0,0 @@
-CREATE TABLE IF NOT EXISTS groups
-(
-id INTEGER UNIQUE PRIMARY KEY,
-uid INTEGER DEFAULT 0,
-gid INTEGER DEFAULT 0,
-extra_int INTEGER DEFAULT 0,
-packagename TEXT DEFAULT NULL,
-smack_label TEXT DEFAULT NULL,
-extra TEXT DEFAULT NULL,
-date_first_connected DATE,
-date_last_connected DATE
-);
-
-CREATE TABLE IF NOT EXISTS logging
-(
-id INTEGER UNIQUE PRIMARY KEY,
-state INTEGER DEFAULT 0,
-errorcode INTEGER DEFAULT 0,
-startcount INTEGER DEFAULT 0,
-packagename TEXT DEFAULT NULL,
-createtime DATE,
-accesstime DATE
-);
-
-CREATE TABLE IF NOT EXISTS requestinfo
-(
-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,
-url TEXT DEFAULT NULL,
-FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE TABLE IF NOT EXISTS downloadinfo
-(
-id INTEGER UNIQUE PRIMARY KEY,
-http_status INTEGER DEFAULT 0,
-content_size UNSIGNED BIG INT DEFAULT 0,
-mimetype VARCHAR(64) DEFAULT NULL,
-content_name TEXT DEFAULT NULL,
-saved_path TEXT DEFAULT NULL,
-tmp_saved_path TEXT DEFAULT NULL,
-etag TEXT DEFAULT NULL,
-FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE TABLE IF NOT EXISTS httpheaders
-(
-id INTEGER NOT NULL,
-header_field TEXT DEFAULT NULL,
-header_data TEXT DEFAULT NULL,
-FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE TABLE IF NOT EXISTS notification
-(
-id INTEGER NOT NULL,
-extra_key TEXT DEFAULT NULL,
-extra_data TEXT DEFAULT NULL,
-raw_bundle_data_complete_state BLOB DEFAULT NULL,
-raw_bundle_data_fail_state BLOB DEFAULT NULL,
-raw_bundle_data_ongoing_state BLOB DEFAULT NULL,
-title TEXT DEFAULT NULL,
-description TEXT DEFAULT NULL,
-noti_type INTEGER DEFAULT 0,
-FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE UNIQUE INDEX IF NOT EXISTS requests_index ON logging (id, state, errorcode, packagename, createtime, accesstime);
diff --git a/download-provider-w.manifest b/download-provider-w.manifest
new file mode 100644
index 0000000..e72ee5e
--- /dev/null
+++ b/download-provider-w.manifest
@@ -0,0 +1,36 @@
+<manifest>
+ <define>
+ <domain name="download-provider" />
+ <provide>
+ <label name="download-provider::db" />
+ </provide>
+ <request>
+ <smack request="download-provider::db" type="rw" />
+ <smack request="system::use_internet" type="w" />
+ <smack request="sys-assert::core" type="rwxat" />
+ <smack request="device::sys_logging" type="w" />
+ <smack request="system::media" type="arwxt" />
+ <smack request="system::ext_media" type="arwxt" />
+ <smack request="connman" type="rw" />
+ <smack request="net-config" type="rw" />
+ <smack request="wifi-direct::info" type="r" />
+ <smack request="connman::get" type="rw" />
+ <smack request="telephony_framework::api_ps_public" type="rw" />
+ </request>
+ <permit>
+ <smack permit="system::use_internet" type="w" />
+ </permit>
+ </define>
+ <request>
+ <domain name="download-provider" />
+ </request>
+ <assign>
+ <filesystem path="/usr/lib/libdownload-provider-interface.so*" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/libdownloadagent2.so*" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/download-provider.service" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/graphical.target.wants/download-provider.service" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/download-provider.socket" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/sockets.target.wants/download-provider.socket" label="_" exec_label="none" />
+ <filesystem path="/opt/etc/dump.d/module.d/dump-download-provider.sh" label="_" exec_label="none" />
+ </assign>
+</manifest>
diff --git a/download-provider.manifest b/download-provider.manifest
index ffeb523..ae67354 100755..100644
--- a/download-provider.manifest
+++ b/download-provider.manifest
@@ -9,14 +9,17 @@
<smack request="system::use_internet" type="w" />
<smack request="sys-assert::core" type="rwxat" />
<smack request="device::sys_logging" type="w" />
- <smack request="system::media" type="arwxt" />
+ <smack request="system::ext_storage" type="arwxt" />
<smack request="system::ext_media" type="arwxt" />
+ <smack request="system::media" type="rwxat" />
+ <smack request="system::media::root" type="rwxat" />
<smack request="connman" type="rw" />
<smack request="net-config" type="rw" />
+ <smack request="wifi-direct::info" type="r" />
+ <smack request="connman::get" type="rw" />
+ <smack request="telephony_framework::api_ps_public" type="rw" />
</request>
<permit>
- <smack permit="org.tizen.indicator" type="rx" />
- <smack permit="org.tizen.quickpanel" type="rx" />
<smack permit="system::use_internet" type="w" />
</permit>
</define>
@@ -24,11 +27,13 @@
<domain name="download-provider" />
</request>
<assign>
+ <filesystem path="/usr/share/download-provider*" 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="/usr/lib/systemd/user/download-provider.service" label="_" exec_label="none" />
- <filesystem path="/usr/lib/systemd/user/tizen-middleware.target.wants/download-provider.service" label="_" exec_label="none" />
- <filesystem path="/usr/lib/systemd/user/download-provider.socket" label="_" exec_label="none" />
- <filesystem path="/usr/lib/systemd/user/sockets.target.wants/download-provider.socket" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/download-provider.service" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/graphical.target.wants/download-provider.service" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/download-provider.socket" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/sockets.target.wants/download-provider.socket" label="_" exec_label="none" />
+ <filesystem path="/opt/etc/dump.d/module.d/dump-download-provider.sh" label="_" exec_label="none" />
</assign>
</manifest>
diff --git a/download-provider.rule b/download-provider.rule
deleted file mode 100644
index 9739e6d..0000000
--- a/download-provider.rule
+++ /dev/null
@@ -1,17 +0,0 @@
-root download-provider rw---
-_default_ download-provider rw---
-download-provider _ -w---
-download-provider data-provider-master::notification.client -w---
-download-provider data-provider-master::notification rw---
-download-provider ail::db rw---
-download-provider device::app_logging -w---
-download-provider system::vconf rwx--
-download-provider system::ext_media rwxat
-download-provider system::media rwxat
-download-provider device::sys_logging -w---
-download-provider sys-assert::core rwxat
-download-provider system::use_internet -w---
-download-provider download-provider::db rw---
-system::use_internet download-provider -w---
-org.tizen.quickpanel download-provider r-x--
-org.tizen.indicator download-provider rwx--
diff --git a/dump-download-provider.sh b/dump-download-provider.sh
new file mode 100644
index 0000000..e639496
--- /dev/null
+++ b/dump-download-provider.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+PKG_NAME=download-provider
+
+DUMP_DIR=$1/$PKG_NAME
+/bin/mkdir -p $DUMP_DIR
+
+# Download DB
+DB_DIR=/opt/usr/data/download-provider/database
+if [ "$DB_DIR" ]
+then
+ /bin/echo "copy download DB ..."
+ /bin/cp -rf ${DB_DIR}* $DUMP_DIR
+fi
diff --git a/packaging/download-provider.spec b/packaging/download-provider.spec
index d2db7e5..0c271de 100755..100644
--- a/packaging/download-provider.spec
+++ b/packaging/download-provider.spec
@@ -1,38 +1,44 @@
+%define _ux_define tizen2.3
Name: download-provider
-Summary: download the contents in background.
-Version: 1.1.6
+Summary: Download the contents in background
+Version: 2.1.23
Release: 0
Group: Development/Libraries
License: Apache License, Version 2.0
Source0: %{name}-%{version}.tar.gz
Requires(post): sys-assert
Requires(post): libdevice-node
-Requires(post): org.tizen.indicator
-Requires(post): org.tizen.quickpanel
Requires(post): sqlite
Requires(post): connman
BuildRequires: cmake
-BuildRequires: libprivilege-control-conf
-BuildRequires: pkgconfig(glib-2.0)
-BuildRequires: pkgconfig(gobject-2.0)
BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(libsoup-2.4)
+BuildRequires: pkgconfig(gobject-2.0)
BuildRequires: pkgconfig(xdgmime)
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(sqlite3)
BuildRequires: pkgconfig(bundle)
BuildRequires: pkgconfig(capi-base-common)
BuildRequires: pkgconfig(capi-appfw-app-manager)
+BuildRequires: pkgconfig(capi-appfw-application)
BuildRequires: pkgconfig(capi-network-connection)
-BuildRequires: pkgconfig(notification)
BuildRequires: pkgconfig(appsvc)
-BuildRequires: pkgconfig(wifi-direct)
+BuildRequires: pkgconfig(libcurl)
+BuildRequires: pkgconfig(capi-content-mime-type)
BuildRequires: pkgconfig(libsmack)
BuildRequires: gettext-devel
BuildRequires: pkgconfig(libsystemd-daemon)
+BuildRequires: pkgconfig(capi-network-wifi-direct)
+BuildRequires: pkgconfig(system-resource)
+BuildRequires: model-build-features
+BuildRequires: pkgconfig(storage)
+%if "%{?tizen_profile_name}" == "wearable"
+BuildRequires: pkgconfig(security-server)
+%else if "%{?tizen_profile_name}" == "mobile"
+BuildRequires: pkgconfig(notification)
+%endif
%description
-Description: download the contents in background
+Description: Download the contents in background
%package devel
Summary: download-provider
@@ -40,20 +46,40 @@ Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
-Description: download the contents in background (developement files)
+Description: Download the contents in background (development files)
%prep
%setup -q
-%define _data_install_path /usr/share/%{name}
-%define _imagedir %{_data_install_path}/images
-%define _localedir %{_data_install_path}/locales
-%define _sqlschemadir %{_data_install_path}/sql
-%define _databasedir /opt/usr/dbspace
-%define _databasefile %{_databasedir}/.download-provider.db
-%define _sqlschemafile %{_sqlschemadir}/download-provider-schema.sql
+%define _data_install_path /opt/usr/data/%{name}
+%define _resource_install_path /usr/share/%{name}
+%define _imagedir %{_resource_install_path}/images
+%define _localedir %{_resource_install_path}/locales
+%define _databasedir %{_data_install_path}/database
+%define _database_client_dir %{_databasedir}/clients
+%define _notifydir %{_data_install_path}/notify
+%define _ipc_socket /opt/data/%{name}/%{name}.sock
%define _licensedir /usr/share/license
-%define _smackruledir /opt/etc/smack/accesses.d
+%define _logdump_script_dir /opt/etc/dump.d/module.d
+%define _http_lib libcurl
+
+%define download_booster OFF
+%define sys_resource OFF
+%define support_oma_drm OFF
+%define wifi_direct ON
+%define support_security_privilege OFF
+%define support_companion_mode OFF
+%define support_notification ON
+%define _manifest_name %{name}.manifest
+
+%if 0%{?model_build_feature_wlan_p2p_disable }
+%define wifi_direct OFF
+%endif
+%if "%{?tizen_profile_name}" == "wearable"
+%define download_booster OFF
+%define support_notification OFF
+%define _manifest_name %{name}-w.manifest
+%endif
%define cmake \
CFLAGS="${CFLAGS:-%optflags} -fPIC -D_REENTRANT -fvisibility=hidden"; export CFLAGS \
@@ -67,16 +93,55 @@ Description: download the contents in background (developement files)
-DPKG_NAME=%{name} \\\
-DPKG_VERSION=%{version} \\\
-DPKG_RELEASE=%{release} \\\
+ -DIPC_SOCKET:PATH=%{_ipc_socket} \\\
+ -DPROVIDER_DIR:PATH=%{_data_install_path} \\\
+ -DNOTIFY_DIR:PATH=%{_notifydir} \\\
+ -DDATABASE_DIR:PATH=%{_databasedir} \\\
+ -DDATABASE_CLIENT_DIR:PATH=%{_database_client_dir} \\\
-DIMAGE_DIR:PATH=%{_imagedir} \\\
-DLOCALE_DIR:PATH=%{_localedir} \\\
- -DDATABASE_SCHEMA_DIR=%{_sqlschemadir} \\\
- -DDATABASE_FILE:PATH=%{_databasefile} \\\
- -DDATABASE_SCHEMA_FILE=%{_sqlschemafile} \\\
-DLICENSE_DIR:PATH=%{_licensedir} \\\
- -DSMACK_RULE_DIR:PATH=%{_smackruledir} \\\
+ %if "%{?wifi_direct}" == "ON" \
+ -DSUPPORT_WIFI_DIRECT:BOOL=ON \\\
+ %else \
-DSUPPORT_WIFI_DIRECT:BOOL=OFF \\\
+ %endif \
+ %if "%{?sys_resource}" == "ON" \
+ -DSUPPORT_SYS_RESOURCE:BOOL=ON \\\
+ %else \
+ -DSUPPORT_SYS_RESOURCE:BOOL=OFF \\\
+ %endif \
+ %if "%{?download_booster}" == "ON" \
+ -DSUPPORT_DOWNLOAD_BOOSTER:BOOL=ON \\\
+ %else \
+ -DSUPPORT_DOWNLOAD_BOOSTER:BOOL=OFF \\\
+ %endif \
+ %if "%{?support_notification}" == "ON" \
+ -DSUPPORT_NOTIFICATION:BOOL=ON \\\
+ %else \
+ -DSUPPORT_NOTIFICATION:BOOL=OFF \\\
+ %endif \
-DSUPPORT_LOG_MESSAGE:BOOL=ON \\\
- -DSUPPORT_CHECK_IPC:BOOL=ON \\\
+ %if "%{?support_oma_drm}" == "ON" \
+ -DSUPPORT_OMA_DRM:BOOL=ON \\\
+ %else \
+ -DSUPPORT_OMA_DRM:BOOL=OFF \\\
+ %endif \
+ %if "%{?support_security_privilege}" == "ON" \
+ -DSUPPORT_SECURITY_PRIVILEGE:BOOL=ON \\\
+ %else \
+ -DSUPPORT_SECURITY_PRIVILEGE:BOOL=OFF \\\
+ %endif \
+ %if "%{?support_companion_mode}" == "ON" \
+ -DSUPPORT_COMPANION_MODE:BOOL=ON \\\
+ %else \
+ -DSUPPORT_COMPANION_MODE:BOOL=OFF \\\
+ %endif \
+ %if "%{?_ux_define}" == "tizen2.3" \
+ -DTIZEN_2_3_UX:BOOL=ON \\\
+ %endif \
+ -DCMAKE_LOG_DUMP_SCRIPT_DIR=%{_logdump_script_dir} \\\
+ -DHTTP_LIB=%{_http_lib} \\\
%if "%{?_lib}" == "lib64" \
%{?_cmake_lib_suffix64} \\\
%endif \
@@ -84,11 +149,9 @@ Description: download the contents in background (developement files)
-DBUILD_SHARED_LIBS:BOOL=ON
%build
-%if 0%{?tizen_build_binary_release_type_eng}
-export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE"
-export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE"
-export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE"
-%endif
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
%cmake .
make %{?jobs:-j%jobs}
@@ -96,29 +159,25 @@ make %{?jobs:-j%jobs}
rm -rf %{buildroot}
%make_install
mkdir -p %{buildroot}%{_licensedir}
-mkdir -p %{buildroot}/%{_data_install_path}
mkdir -p %{buildroot}%{_libdir}/systemd/system/graphical.target.wants
mkdir -p %{buildroot}%{_libdir}/systemd/system/sockets.target.wants
ln -s ../download-provider.service %{buildroot}%{_libdir}/systemd/system/graphical.target.wants/
ln -s ../download-provider.socket %{buildroot}%{_libdir}/systemd/system/sockets.target.wants/
%post
-mkdir -p %{_databasedir}
-
-if [ ! -f %{_databasefile} ];
-then
-sqlite3 %{_databasefile} '.read %{_sqlschemafile}'
-chmod 660 %{_databasefile}
-chmod 660 %{_databasefile}-journal
-fi
+#make notify dir in post section for smack
+mkdir -p %{_notifydir}
+mkdir -p --mode=0700 %{_databasedir}
+chsmack -a 'download-provider' %{_databasedir}
+mkdir -p --mode=0700 %{_database_client_dir}
+chsmack -a 'download-provider' %{_database_client_dir}
%files
%defattr(-,root,root,-)
-%manifest download-provider.manifest
+%manifest %{_manifest_name}
%{_imagedir}/*.png
-%{_imagedir}/*.gif
-%{_localedir}/*
-%{_libdir}/libdownloadagent2.so.0.0.1
+%{_localedir}/*/*/download-provider.mo
+%{_libdir}/libdownloadagent2.so.0.1.0
%{_libdir}/libdownloadagent2.so
%{_libdir}/systemd/system/download-provider.service
%{_libdir}/systemd/system/graphical.target.wants/download-provider.service
@@ -128,47 +187,15 @@ fi
%{_libdir}/libdownload-provider-interface.so.0
%{_bindir}/%{name}
%{_licensedir}/%{name}
-%{_smackruledir}/%{name}.rule
-%{_sqlschemafile}
+%attr(0544,root,root) %{_logdump_script_dir}/dump-%{name}.sh
%files devel
%defattr(-,root,root,-)
-%{_libdir}/libdownloadagent2.so.0.0.1
+%{_libdir}/libdownloadagent2.so.0.1.0
%{_libdir}/libdownloadagent2.so
%{_libdir}/libdownload-provider-interface.so
-%{_includedir}/download-provider/download-provider-defs.h
+%{_includedir}/download-provider/download-provider.h
%{_includedir}/download-provider/download-provider-interface.h
%{_bindir}/%{name}
%{_libdir}/pkgconfig/download-provider.pc
%{_libdir}/pkgconfig/download-provider-interface.pc
-
-%changelog
-* Tue Oct 29 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Resolve a bug about invalid url
-
-* Tue Sep 17 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Add depenency of connman for smack label
-
-* Thu Sep 12 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Resolve a bug to check return value
-- Resolve build warnnings and add error exception
-- Register download notification when client process is exited
-
-* Wed Sep 11 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Implement auto-resume in ip-changed case
-- Remove dbus-activation feature
-- Implementation of new APIs for notification
-
-* Tue Sep 05 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Update downloading icon for ongoing notification
-- Return disk full error when file system call return in case of ENOSPC
-
-* Tue Jul 09 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Change to use vconf for downloading icon of indicator
-
-* Mon Jul 08 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Add to check smack enable state
-
-* Thu Jul 04 2013 Jungki Kwak <jungki.kwak@samsung.com>
-- Check smack integrity about install directory and downloaded file
-
diff --git a/po/POTFILES.in.in b/po/POTFILES.in.in
deleted file mode 100755
index bcb7f1f..0000000
--- a/po/POTFILES.in.in
+++ /dev/null
@@ -1,2 +0,0 @@
-# List of source files containing translatable strings.
-@@APPNAME@@.c
diff --git a/po/ar.po b/po/ar.po
deleted file mode 100755
index db4e25e..0000000
--- a/po/ar.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "تم التنزيل"
-
diff --git a/po/az.po b/po/az.po
deleted file mode 100755
index 8120d37..0000000
--- a/po/az.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Yükləmə tamamlandı"
-
diff --git a/po/bg.po b/po/bg.po
deleted file mode 100755
index b8b9584..0000000
--- a/po/bg.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Изтеглянето завършено"
-
diff --git a/po/ca.po b/po/ca.po
deleted file mode 100755
index 291f7a7..0000000
--- a/po/ca.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Descàrrega completa"
-
diff --git a/po/cs.po b/po/cs.po
deleted file mode 100755
index cf228be..0000000
--- a/po/cs.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Stahování dokončeno"
-
diff --git a/po/da.po b/po/da.po
deleted file mode 100755
index ffba089..0000000
--- a/po/da.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Overførsel fuldført"
-
diff --git a/po/de_DE.po b/po/de_DE.po
deleted file mode 100755
index 1c9c61a..0000000
--- a/po/de_DE.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Download beendet"
-
diff --git a/po/en.po b/po/en.po
deleted file mode 100755
index 03ffa61..0000000
--- a/po/en.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Download complete"
-
diff --git a/po/en_PH.po b/po/en_PH.po
deleted file mode 100755
index 03ffa61..0000000
--- a/po/en_PH.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Download complete"
-
diff --git a/po/en_US.po b/po/en_US.po
deleted file mode 100755
index 03ffa61..0000000
--- a/po/en_US.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Download complete"
-
diff --git a/po/es_ES.po b/po/es_ES.po
deleted file mode 100755
index 3cd494a..0000000
--- a/po/es_ES.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Descarga completa"
-
diff --git a/po/es_MX.po b/po/es_MX.po
deleted file mode 100755
index 3cd494a..0000000
--- a/po/es_MX.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Descarga completa"
-
diff --git a/po/eu.po b/po/eu.po
deleted file mode 100755
index b1e418a..0000000
--- a/po/eu.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Deskarga osatuta"
-
diff --git a/po/fi.po b/po/fi.po
deleted file mode 100755
index 058a8d6..0000000
--- a/po/fi.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Lataus valmis"
-
diff --git a/po/fr_CA.po b/po/fr_CA.po
deleted file mode 100755
index 64e4156..0000000
--- a/po/fr_CA.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Téléchargement terminé"
-
diff --git a/po/fr_FR.po b/po/fr_FR.po
deleted file mode 100755
index 64e4156..0000000
--- a/po/fr_FR.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Téléchargement terminé"
-
diff --git a/po/ga.po b/po/ga.po
deleted file mode 100755
index 5e9474a..0000000
--- a/po/ga.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Íoslódáilte"
-
diff --git a/po/gl.po b/po/gl.po
deleted file mode 100755
index 3cd494a..0000000
--- a/po/gl.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Descarga completa"
-
diff --git a/po/hi.po b/po/hi.po
deleted file mode 100755
index 5ece567..0000000
--- a/po/hi.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "डाउनलोड पूर्ण"
-
diff --git a/po/hr.po b/po/hr.po
deleted file mode 100755
index b4ae9f2..0000000
--- a/po/hr.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Skidanje dovršeno"
-
diff --git a/po/hu.po b/po/hu.po
deleted file mode 100755
index 239c6b9..0000000
--- a/po/hu.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "A letöltés befejeződött"
-
diff --git a/po/hy.po b/po/hy.po
deleted file mode 100755
index 12ea497..0000000
--- a/po/hy.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Ներբեռնումն ավարտվեց"
-
diff --git a/po/is.po b/po/is.po
deleted file mode 100755
index 470a453..0000000
--- a/po/is.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Niðurhali lokið"
-
diff --git a/po/it_IT.po b/po/it_IT.po
deleted file mode 100755
index e96495c..0000000
--- a/po/it_IT.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Download completato"
-
diff --git a/po/ja_JP.po b/po/ja_JP.po
deleted file mode 100755
index 41ea60e..0000000
--- a/po/ja_JP.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "ダウンロード完了"
-
diff --git a/po/kk.po b/po/kk.po
deleted file mode 100755
index 40ff8b2..0000000
--- a/po/kk.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Жүктеу аяқталды"
-
diff --git a/po/ko_KR.po b/po/ko_KR.po
deleted file mode 100755
index 1f47a18..0000000
--- a/po/ko_KR.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "다운로드 완료"
-
diff --git a/po/lt.po b/po/lt.po
deleted file mode 100755
index ea1075f..0000000
--- a/po/lt.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Atsisiuntimas baigtas"
-
diff --git a/po/lv.po b/po/lv.po
deleted file mode 100755
index d3bf10c..0000000
--- a/po/lv.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Lejupielāde pabeigta"
-
diff --git a/po/mk.po b/po/mk.po
deleted file mode 100755
index 8ae0de2..0000000
--- a/po/mk.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Преземањето заврши"
-
diff --git a/po/nb.po b/po/nb.po
deleted file mode 100755
index 33af7b7..0000000
--- a/po/nb.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Nedlasting fullført"
-
diff --git a/po/nl_NL.po b/po/nl_NL.po
deleted file mode 100755
index 2273390..0000000
--- a/po/nl_NL.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Downloaden voltooid"
-
diff --git a/po/pl.po b/po/pl.po
deleted file mode 100755
index 8a48b82..0000000
--- a/po/pl.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Pobieranie zakończone"
-
diff --git a/po/pt_BR.po b/po/pt_BR.po
deleted file mode 100755
index f97065e..0000000
--- a/po/pt_BR.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Download concluído"
-
diff --git a/po/pt_PT.po b/po/pt_PT.po
deleted file mode 100755
index cbe7377..0000000
--- a/po/pt_PT.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Transferência concluída"
-
diff --git a/po/CMakeLists.txt b/po/redwood/CMakeLists.txt
index 9e2d8c6..706d725 100755..100644
--- a/po/CMakeLists.txt
+++ b/po/redwood/CMakeLists.txt
@@ -1,10 +1,9 @@
# for i18n
-SET(POFILES ar.po az.po bg.po ca.po cs.po da.po de_DE.po el_GR.po en.po en_PH.po
- en_US.po es_ES.po es_MX.po et.po eu.po fi.po fr_CA.po fr_FR.po ga.po gl.po hi.po
- hr.po hu.po hy.po is.po it_IT.po ja_JP.po ka.po kk.po ko_KR.po lt.po lv.po mk.po
- nb.po nl_NL.po pl.po pt_BR.po pt_PT.po ro.po ru_RU.po sk.po sl.po sr.po sv.po
- tr_TR.po uk.po uz.po zh_CN.po zh_HK.po zh_SG.po zh_TW.po)
+SET(POFILES az.po bg.po ca.po cs.po da.po de.po el_GR.po en.po en_US.po es_ES.po
+ es_US.po et.po eu.po fi.po fr_CA.po fr.po gl.po hr.po hu.po hy.po is.po
+ it_IT.po ka.po kk.po ko_KR.po lt.po lv.po mn_MN.po nb.po nl.po pl.po
+ pt_BR.po pt_PT.po ro.po ru_RU.po sk.po sl.po sr.po sv.po tr_TR.po uk.po uz.po)
SET(MSGFMT "/usr/bin/msgfmt")
diff --git a/po/redwood/az.po b/po/redwood/az.po
new file mode 100644
index 0000000..f8d4868
--- /dev/null
+++ b/po/redwood/az.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Yükləmə tamamlandı"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Yükləmə alınmadı"
+
diff --git a/po/redwood/bg.po b/po/redwood/bg.po
new file mode 100644
index 0000000..4b2b9cb
--- /dev/null
+++ b/po/redwood/bg.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Изтеглянето завършено"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Изтеглянето неуспешно"
+
diff --git a/po/redwood/ca.po b/po/redwood/ca.po
new file mode 100644
index 0000000..e4cb32e
--- /dev/null
+++ b/po/redwood/ca.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descàrrega completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Descàrrega fallida"
+
diff --git a/po/redwood/cs.po b/po/redwood/cs.po
new file mode 100644
index 0000000..7c33b8b
--- /dev/null
+++ b/po/redwood/cs.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Stahování dokončeno"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Stažení se nezdařilo"
+
diff --git a/po/redwood/da.po b/po/redwood/da.po
new file mode 100644
index 0000000..1cbbbec
--- /dev/null
+++ b/po/redwood/da.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Overførsel fuldført"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Overførsel mislykkedes"
+
diff --git a/po/redwood/de.po b/po/redwood/de.po
new file mode 100644
index 0000000..8301d76
--- /dev/null
+++ b/po/redwood/de.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download beendet"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download fehlgeschlagen"
+
diff --git a/po/el_GR.po b/po/redwood/el_GR.po
index 29efbc7..f96c0a1 100755..100644
--- a/po/el_GR.po
+++ b/po/redwood/el_GR.po
@@ -1,3 +1,6 @@
msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
msgstr "Η λήψη ολοκληρώθηκε"
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Αποτυχία λήψης"
+
diff --git a/po/redwood/en.po b/po/redwood/en.po
new file mode 100644
index 0000000..0bcc00f
--- /dev/null
+++ b/po/redwood/en.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download complete"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download failed"
+
diff --git a/po/redwood/en_US.po b/po/redwood/en_US.po
new file mode 100644
index 0000000..0bcc00f
--- /dev/null
+++ b/po/redwood/en_US.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download complete"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download failed"
+
diff --git a/po/redwood/es_ES.po b/po/redwood/es_ES.po
new file mode 100644
index 0000000..300e275
--- /dev/null
+++ b/po/redwood/es_ES.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descarga completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Error de descarga"
+
diff --git a/po/redwood/es_US.po b/po/redwood/es_US.po
new file mode 100644
index 0000000..6be685a
--- /dev/null
+++ b/po/redwood/es_US.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descarga completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Error al descargar"
+
diff --git a/po/et.po b/po/redwood/et.po
index 4ad6fad..6ffe386 100755..100644
--- a/po/et.po
+++ b/po/redwood/et.po
@@ -1,3 +1,6 @@
msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
msgstr "Allalaadimine on lõpule viidud"
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Allalaadimine nurjus"
+
diff --git a/po/redwood/eu.po b/po/redwood/eu.po
new file mode 100644
index 0000000..b9db71f
--- /dev/null
+++ b/po/redwood/eu.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Deskarga osatuta"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Deskargak huts egin du"
+
diff --git a/po/redwood/fi.po b/po/redwood/fi.po
new file mode 100644
index 0000000..7929571
--- /dev/null
+++ b/po/redwood/fi.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Lataus valmis"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Lataus epäonnistui"
+
diff --git a/po/redwood/fr.po b/po/redwood/fr.po
new file mode 100644
index 0000000..f1e8884
--- /dev/null
+++ b/po/redwood/fr.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Téléchargement terminé"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Echec du téléchargement"
+
diff --git a/po/redwood/fr_CA.po b/po/redwood/fr_CA.po
new file mode 100644
index 0000000..608ae3d
--- /dev/null
+++ b/po/redwood/fr_CA.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Téléchargement terminé"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Échec du téléchargement"
+
diff --git a/po/redwood/gl.po b/po/redwood/gl.po
new file mode 100644
index 0000000..8527d75
--- /dev/null
+++ b/po/redwood/gl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descarga completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Erro na descarga"
+
diff --git a/po/redwood/hr.po b/po/redwood/hr.po
new file mode 100644
index 0000000..0f225a4
--- /dev/null
+++ b/po/redwood/hr.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Skidanje dovršeno"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Skidanje neuspješno"
+
diff --git a/po/redwood/hu.po b/po/redwood/hu.po
new file mode 100644
index 0000000..847e5af
--- /dev/null
+++ b/po/redwood/hu.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "A letöltés befejeződött"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Sikertelen letöltés"
+
diff --git a/po/redwood/hy.po b/po/redwood/hy.po
new file mode 100644
index 0000000..8636b2b
--- /dev/null
+++ b/po/redwood/hy.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Ներբեռնումն ավարտվեց"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Ներբեռնումը ձախողվեց"
+
diff --git a/po/redwood/is.po b/po/redwood/is.po
new file mode 100644
index 0000000..3bb7f29
--- /dev/null
+++ b/po/redwood/is.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Niðurhali lokið"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Niðurhal mistókst"
+
diff --git a/po/redwood/it_IT.po b/po/redwood/it_IT.po
new file mode 100644
index 0000000..51a407e
--- /dev/null
+++ b/po/redwood/it_IT.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download completato"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download non riuscito"
+
diff --git a/po/ka.po b/po/redwood/ka.po
index 10a084d..83aea79 100755..100644
--- a/po/ka.po
+++ b/po/redwood/ka.po
@@ -1,3 +1,6 @@
msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
msgstr "ჩამოტვირთვა დასრულდა"
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "ვერ ჩამოიტვირთა"
+
diff --git a/po/redwood/kk.po b/po/redwood/kk.po
new file mode 100644
index 0000000..bd25ab4
--- /dev/null
+++ b/po/redwood/kk.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Жүктеу аяқталды"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Жүктеу орындалмады"
+
diff --git a/po/redwood/ko_KR.po b/po/redwood/ko_KR.po
new file mode 100644
index 0000000..80d1e37
--- /dev/null
+++ b/po/redwood/ko_KR.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "다운로드 완료"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "다운로드 안 됨"
+
diff --git a/po/redwood/lt.po b/po/redwood/lt.po
new file mode 100644
index 0000000..d08e1d5
--- /dev/null
+++ b/po/redwood/lt.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Atsisiuntimas baigtas"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Atsisiųsti nepavyko"
+
diff --git a/po/redwood/lv.po b/po/redwood/lv.po
new file mode 100644
index 0000000..323c609
--- /dev/null
+++ b/po/redwood/lv.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Lejupielāde pabeigta"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Lejupielāde neizdevās"
+
diff --git a/po/redwood/mn_MN.po b/po/redwood/mn_MN.po
new file mode 100644
index 0000000..7060f68
--- /dev/null
+++ b/po/redwood/mn_MN.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Татан авалт дууссан"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Татаж авч чадсангүй"
+
diff --git a/po/redwood/nb.po b/po/redwood/nb.po
new file mode 100644
index 0000000..49448f5
--- /dev/null
+++ b/po/redwood/nb.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Nedlasting fullført"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Nedlastingen mislyktes"
+
diff --git a/po/redwood/nl.po b/po/redwood/nl.po
new file mode 100644
index 0000000..1195f04
--- /dev/null
+++ b/po/redwood/nl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Downloaden voltooid"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Downloaden mislukt"
+
diff --git a/po/redwood/pl.po b/po/redwood/pl.po
new file mode 100644
index 0000000..9e52a17
--- /dev/null
+++ b/po/redwood/pl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Pobieranie zakończone"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Pobieranie nie powiodło się"
+
diff --git a/po/redwood/pt_BR.po b/po/redwood/pt_BR.po
new file mode 100644
index 0000000..0fdce74
--- /dev/null
+++ b/po/redwood/pt_BR.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download concluído"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Falha no download"
+
diff --git a/po/redwood/pt_PT.po b/po/redwood/pt_PT.po
new file mode 100644
index 0000000..c934937
--- /dev/null
+++ b/po/redwood/pt_PT.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Transferência concluída"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "A transferência falhou"
+
diff --git a/po/redwood/ro.po b/po/redwood/ro.po
new file mode 100644
index 0000000..820ab33
--- /dev/null
+++ b/po/redwood/ro.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descărcare finalizată"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Descărcarea nu a reuşit"
+
diff --git a/po/ru_RU.po b/po/redwood/ru_RU.po
index 27aa56c..e3cb63a 100755..100644
--- a/po/ru_RU.po
+++ b/po/redwood/ru_RU.po
@@ -1,3 +1,6 @@
msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
msgstr "Загрузка завершена"
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Сбой загрузки"
+
diff --git a/po/redwood/sk.po b/po/redwood/sk.po
new file mode 100644
index 0000000..6d92c75
--- /dev/null
+++ b/po/redwood/sk.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Sťahovanie je dokončené"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Sťahovanie zlyhalo"
+
diff --git a/po/redwood/sl.po b/po/redwood/sl.po
new file mode 100644
index 0000000..1c256ab
--- /dev/null
+++ b/po/redwood/sl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Prenos je končan"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Prenos ni uspel"
+
diff --git a/po/redwood/sr.po b/po/redwood/sr.po
new file mode 100644
index 0000000..2e6331a
--- /dev/null
+++ b/po/redwood/sr.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Preuzimanje završeno"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Neuspešno preuzimanje"
+
diff --git a/po/redwood/sv.po b/po/redwood/sv.po
new file mode 100644
index 0000000..e792e63
--- /dev/null
+++ b/po/redwood/sv.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Hämtningen är klar"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Hämtningen misslyckades"
+
diff --git a/po/redwood/tr_TR.po b/po/redwood/tr_TR.po
new file mode 100644
index 0000000..73277df
--- /dev/null
+++ b/po/redwood/tr_TR.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "İndirme tamamlandı"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "İndirme başarısız"
+
diff --git a/po/uk.po b/po/redwood/uk.po
index 504e5f1..ad32cd3 100755..100644
--- a/po/uk.po
+++ b/po/redwood/uk.po
@@ -1,3 +1,6 @@
msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
msgstr "Завантаження завершено"
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Збій завантаження"
+
diff --git a/po/redwood/uz.po b/po/redwood/uz.po
new file mode 100644
index 0000000..ff9b724
--- /dev/null
+++ b/po/redwood/uz.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Yuklab olish yakunlandi"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Yuklab olib bo‘lmadi"
+
diff --git a/po/ro.po b/po/ro.po
deleted file mode 100755
index d82366c..0000000
--- a/po/ro.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Descărcare finalizată"
-
diff --git a/po/sk.po b/po/sk.po
deleted file mode 100755
index 178001d..0000000
--- a/po/sk.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Sťahovanie je dokončené"
-
diff --git a/po/sl.po b/po/sl.po
deleted file mode 100755
index d031ce5..0000000
--- a/po/sl.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Prenos je končan"
-
diff --git a/po/sr.po b/po/sr.po
deleted file mode 100755
index e21e6d3..0000000
--- a/po/sr.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Preuzimanje završeno"
-
diff --git a/po/sv.po b/po/sv.po
deleted file mode 100755
index 8f0dce9..0000000
--- a/po/sv.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Hämtningen är klar"
-
diff --git a/po/tizen2.3/CMakeLists.txt b/po/tizen2.3/CMakeLists.txt
new file mode 100644
index 0000000..1ff1ce8
--- /dev/null
+++ b/po/tizen2.3/CMakeLists.txt
@@ -0,0 +1,30 @@
+# for i18n
+
+SET(POFILES
+ ar.po az.po bg.po ca.po cs.po da.po de.po el_GR.po en.po
+ en_PH.po en_US.po es_ES.po es_US.po et.po eu.po fi.po fr.po
+ fr_CA.po ga.po gl.po hi.po hr.po hu.po hy.po is.po it_IT.po
+ ja_JP.po ka.po kk.po ko_KR.po lt.po lv.po mk.po nb.po nl.po
+ pl.po pt_BR.po pt_PT.po ro.po ru_RU.po sk.po sl.po sr.po sv.po
+ tr_TR.po uk.po uz.po zh_CN.po zh_HK.po zh_TW.po)
+
+SET(MSGFMT "/usr/bin/msgfmt")
+
+FOREACH(pofile ${POFILES})
+ SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile})
+ MESSAGE("PO: ${pofile}")
+ GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE)
+ GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE)
+ SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${moFile}
+ COMMAND ${MSGFMT} -o ${moFile} ${absPofile}
+ DEPENDS ${absPofile}
+ )
+ INSTALL(FILES ${moFile}
+ DESTINATION ${LOCALE_DIR}/${lang}/LC_MESSAGES RENAME ${PKG_NAME}.mo)
+ SET(moFiles ${moFiles} ${moFile})
+ENDFOREACH(pofile)
+
+MESSAGE(".mo files: ${moFiles}")
+ADD_CUSTOM_TARGET(po ALL DEPENDS ${moFiles})
diff --git a/po/tizen2.3/ar.po b/po/tizen2.3/ar.po
new file mode 100644
index 0000000..1bf0a3c
--- /dev/null
+++ b/po/tizen2.3/ar.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "تم التنزيل"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "فشل التنزيل"
+
diff --git a/po/tizen2.3/az.po b/po/tizen2.3/az.po
new file mode 100644
index 0000000..f8d4868
--- /dev/null
+++ b/po/tizen2.3/az.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Yükləmə tamamlandı"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Yükləmə alınmadı"
+
diff --git a/po/tizen2.3/bg.po b/po/tizen2.3/bg.po
new file mode 100644
index 0000000..4b2b9cb
--- /dev/null
+++ b/po/tizen2.3/bg.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Изтеглянето завършено"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Изтеглянето неуспешно"
+
diff --git a/po/tizen2.3/ca.po b/po/tizen2.3/ca.po
new file mode 100644
index 0000000..e4cb32e
--- /dev/null
+++ b/po/tizen2.3/ca.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descàrrega completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Descàrrega fallida"
+
diff --git a/po/tizen2.3/cs.po b/po/tizen2.3/cs.po
new file mode 100644
index 0000000..7c33b8b
--- /dev/null
+++ b/po/tizen2.3/cs.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Stahování dokončeno"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Stažení se nezdařilo"
+
diff --git a/po/tizen2.3/da.po b/po/tizen2.3/da.po
new file mode 100644
index 0000000..1cbbbec
--- /dev/null
+++ b/po/tizen2.3/da.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Overførsel fuldført"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Overførsel mislykkedes"
+
diff --git a/po/tizen2.3/de.po b/po/tizen2.3/de.po
new file mode 100644
index 0000000..8301d76
--- /dev/null
+++ b/po/tizen2.3/de.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download beendet"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download fehlgeschlagen"
+
diff --git a/po/tizen2.3/el_GR.po b/po/tizen2.3/el_GR.po
new file mode 100644
index 0000000..f96c0a1
--- /dev/null
+++ b/po/tizen2.3/el_GR.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Η λήψη ολοκληρώθηκε"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Αποτυχία λήψης"
+
diff --git a/po/tizen2.3/en.po b/po/tizen2.3/en.po
new file mode 100644
index 0000000..0bcc00f
--- /dev/null
+++ b/po/tizen2.3/en.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download complete"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download failed"
+
diff --git a/po/tizen2.3/en_PH.po b/po/tizen2.3/en_PH.po
new file mode 100644
index 0000000..0bcc00f
--- /dev/null
+++ b/po/tizen2.3/en_PH.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download complete"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download failed"
+
diff --git a/po/tizen2.3/en_US.po b/po/tizen2.3/en_US.po
new file mode 100644
index 0000000..0bcc00f
--- /dev/null
+++ b/po/tizen2.3/en_US.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download complete"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download failed"
+
diff --git a/po/tizen2.3/es_ES.po b/po/tizen2.3/es_ES.po
new file mode 100644
index 0000000..300e275
--- /dev/null
+++ b/po/tizen2.3/es_ES.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descarga completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Error de descarga"
+
diff --git a/po/tizen2.3/es_US.po b/po/tizen2.3/es_US.po
new file mode 100644
index 0000000..6be685a
--- /dev/null
+++ b/po/tizen2.3/es_US.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descarga completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Error al descargar"
+
diff --git a/po/tizen2.3/et.po b/po/tizen2.3/et.po
new file mode 100644
index 0000000..6ffe386
--- /dev/null
+++ b/po/tizen2.3/et.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Allalaadimine on lõpule viidud"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Allalaadimine nurjus"
+
diff --git a/po/tizen2.3/eu.po b/po/tizen2.3/eu.po
new file mode 100644
index 0000000..b9db71f
--- /dev/null
+++ b/po/tizen2.3/eu.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Deskarga osatuta"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Deskargak huts egin du"
+
diff --git a/po/tizen2.3/fi.po b/po/tizen2.3/fi.po
new file mode 100644
index 0000000..7929571
--- /dev/null
+++ b/po/tizen2.3/fi.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Lataus valmis"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Lataus epäonnistui"
+
diff --git a/po/tizen2.3/fr.po b/po/tizen2.3/fr.po
new file mode 100644
index 0000000..f1e8884
--- /dev/null
+++ b/po/tizen2.3/fr.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Téléchargement terminé"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Echec du téléchargement"
+
diff --git a/po/tizen2.3/fr_CA.po b/po/tizen2.3/fr_CA.po
new file mode 100644
index 0000000..608ae3d
--- /dev/null
+++ b/po/tizen2.3/fr_CA.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Téléchargement terminé"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Échec du téléchargement"
+
diff --git a/po/tizen2.3/ga.po b/po/tizen2.3/ga.po
new file mode 100644
index 0000000..f8651ef
--- /dev/null
+++ b/po/tizen2.3/ga.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Íoslódáilte"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Theip ar íoslódáil"
+
diff --git a/po/tizen2.3/gl.po b/po/tizen2.3/gl.po
new file mode 100644
index 0000000..8527d75
--- /dev/null
+++ b/po/tizen2.3/gl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descarga completa"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Erro na descarga"
+
diff --git a/po/tizen2.3/hi.po b/po/tizen2.3/hi.po
new file mode 100644
index 0000000..36382aa
--- /dev/null
+++ b/po/tizen2.3/hi.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "डाउनलोड पूर्ण"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "डाउनलोड विफल"
+
diff --git a/po/tizen2.3/hr.po b/po/tizen2.3/hr.po
new file mode 100644
index 0000000..0f225a4
--- /dev/null
+++ b/po/tizen2.3/hr.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Skidanje dovršeno"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Skidanje neuspješno"
+
diff --git a/po/tizen2.3/hu.po b/po/tizen2.3/hu.po
new file mode 100644
index 0000000..847e5af
--- /dev/null
+++ b/po/tizen2.3/hu.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "A letöltés befejeződött"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Sikertelen letöltés"
+
diff --git a/po/tizen2.3/hy.po b/po/tizen2.3/hy.po
new file mode 100644
index 0000000..8636b2b
--- /dev/null
+++ b/po/tizen2.3/hy.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Ներբեռնումն ավարտվեց"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Ներբեռնումը ձախողվեց"
+
diff --git a/po/tizen2.3/is.po b/po/tizen2.3/is.po
new file mode 100644
index 0000000..3bb7f29
--- /dev/null
+++ b/po/tizen2.3/is.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Niðurhali lokið"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Niðurhal mistókst"
+
diff --git a/po/tizen2.3/it_IT.po b/po/tizen2.3/it_IT.po
new file mode 100644
index 0000000..51a407e
--- /dev/null
+++ b/po/tizen2.3/it_IT.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download completato"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Download non riuscito"
+
diff --git a/po/tizen2.3/ja_JP.po b/po/tizen2.3/ja_JP.po
new file mode 100644
index 0000000..b466c9b
--- /dev/null
+++ b/po/tizen2.3/ja_JP.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "ダウンロード完了"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "ダウンロード失敗"
+
diff --git a/po/tizen2.3/ka.po b/po/tizen2.3/ka.po
new file mode 100644
index 0000000..83aea79
--- /dev/null
+++ b/po/tizen2.3/ka.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "ჩამოტვირთვა დასრულდა"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "ვერ ჩამოიტვირთა"
+
diff --git a/po/tizen2.3/kk.po b/po/tizen2.3/kk.po
new file mode 100644
index 0000000..bd25ab4
--- /dev/null
+++ b/po/tizen2.3/kk.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Жүктеу аяқталды"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Жүктеу орындалмады"
+
diff --git a/po/tizen2.3/ko_KR.po b/po/tizen2.3/ko_KR.po
new file mode 100644
index 0000000..80d1e37
--- /dev/null
+++ b/po/tizen2.3/ko_KR.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "다운로드 완료"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "다운로드 안 됨"
+
diff --git a/po/tizen2.3/lt.po b/po/tizen2.3/lt.po
new file mode 100644
index 0000000..d08e1d5
--- /dev/null
+++ b/po/tizen2.3/lt.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Atsisiuntimas baigtas"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Atsisiųsti nepavyko"
+
diff --git a/po/tizen2.3/lv.po b/po/tizen2.3/lv.po
new file mode 100644
index 0000000..323c609
--- /dev/null
+++ b/po/tizen2.3/lv.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Lejupielāde pabeigta"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Lejupielāde neizdevās"
+
diff --git a/po/tizen2.3/mk.po b/po/tizen2.3/mk.po
new file mode 100644
index 0000000..0ef6f04
--- /dev/null
+++ b/po/tizen2.3/mk.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Преземањето заврши"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Преземањето не успеа"
+
diff --git a/po/tizen2.3/nb.po b/po/tizen2.3/nb.po
new file mode 100644
index 0000000..49448f5
--- /dev/null
+++ b/po/tizen2.3/nb.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Nedlasting fullført"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Nedlastingen mislyktes"
+
diff --git a/po/tizen2.3/nl.po b/po/tizen2.3/nl.po
new file mode 100644
index 0000000..1195f04
--- /dev/null
+++ b/po/tizen2.3/nl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Downloaden voltooid"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Downloaden mislukt"
+
diff --git a/po/tizen2.3/pl.po b/po/tizen2.3/pl.po
new file mode 100644
index 0000000..9e52a17
--- /dev/null
+++ b/po/tizen2.3/pl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Pobieranie zakończone"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Pobieranie nie powiodło się"
+
diff --git a/po/tizen2.3/pt_BR.po b/po/tizen2.3/pt_BR.po
new file mode 100644
index 0000000..0fdce74
--- /dev/null
+++ b/po/tizen2.3/pt_BR.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Download concluído"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Falha no download"
+
diff --git a/po/tizen2.3/pt_PT.po b/po/tizen2.3/pt_PT.po
new file mode 100644
index 0000000..c934937
--- /dev/null
+++ b/po/tizen2.3/pt_PT.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Transferência concluída"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "A transferência falhou"
+
diff --git a/po/tizen2.3/ro.po b/po/tizen2.3/ro.po
new file mode 100644
index 0000000..820ab33
--- /dev/null
+++ b/po/tizen2.3/ro.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Descărcare finalizată"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Descărcarea nu a reuşit"
+
diff --git a/po/tizen2.3/ru_RU.po b/po/tizen2.3/ru_RU.po
new file mode 100644
index 0000000..e3cb63a
--- /dev/null
+++ b/po/tizen2.3/ru_RU.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Загрузка завершена"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Сбой загрузки"
+
diff --git a/po/tizen2.3/sk.po b/po/tizen2.3/sk.po
new file mode 100644
index 0000000..6d92c75
--- /dev/null
+++ b/po/tizen2.3/sk.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Sťahovanie je dokončené"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Sťahovanie zlyhalo"
+
diff --git a/po/tizen2.3/sl.po b/po/tizen2.3/sl.po
new file mode 100644
index 0000000..1c256ab
--- /dev/null
+++ b/po/tizen2.3/sl.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Prenos je končan"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Prenos ni uspel"
+
diff --git a/po/tizen2.3/sr.po b/po/tizen2.3/sr.po
new file mode 100644
index 0000000..2e6331a
--- /dev/null
+++ b/po/tizen2.3/sr.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Preuzimanje završeno"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Neuspešno preuzimanje"
+
diff --git a/po/tizen2.3/sv.po b/po/tizen2.3/sv.po
new file mode 100644
index 0000000..e792e63
--- /dev/null
+++ b/po/tizen2.3/sv.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Hämtningen är klar"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Hämtningen misslyckades"
+
diff --git a/po/tizen2.3/tr_TR.po b/po/tizen2.3/tr_TR.po
new file mode 100644
index 0000000..73277df
--- /dev/null
+++ b/po/tizen2.3/tr_TR.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "İndirme tamamlandı"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "İndirme başarısız"
+
diff --git a/po/tizen2.3/uk.po b/po/tizen2.3/uk.po
new file mode 100644
index 0000000..ad32cd3
--- /dev/null
+++ b/po/tizen2.3/uk.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Завантаження завершено"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Збій завантаження"
+
diff --git a/po/tizen2.3/uz.po b/po/tizen2.3/uz.po
new file mode 100644
index 0000000..ff9b724
--- /dev/null
+++ b/po/tizen2.3/uz.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "Yuklab olish yakunlandi"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "Yuklab olib bo‘lmadi"
+
diff --git a/po/tizen2.3/zh_CN.po b/po/tizen2.3/zh_CN.po
new file mode 100644
index 0000000..f5e03c8
--- /dev/null
+++ b/po/tizen2.3/zh_CN.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "下载完成"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "下载失败"
+
diff --git a/po/tizen2.3/zh_HK.po b/po/tizen2.3/zh_HK.po
new file mode 100644
index 0000000..ef7afd3
--- /dev/null
+++ b/po/tizen2.3/zh_HK.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "下載完成"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "下載失敗"
+
diff --git a/po/tizen2.3/zh_TW.po b/po/tizen2.3/zh_TW.po
new file mode 100644
index 0000000..ef7afd3
--- /dev/null
+++ b/po/tizen2.3/zh_TW.po
@@ -0,0 +1,6 @@
+msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
+msgstr "下載完成"
+
+msgid "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB"
+msgstr "下載失敗"
+
diff --git a/po/tr_TR.po b/po/tr_TR.po
deleted file mode 100755
index ec760e5..0000000
--- a/po/tr_TR.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "İndirme tamamlandı"
-
diff --git a/po/uz.po b/po/uz.po
deleted file mode 100755
index c97fec7..0000000
--- a/po/uz.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "Yuklab olish yakunlandi"
-
diff --git a/po/zh_CN.po b/po/zh_CN.po
deleted file mode 100755
index 3238acd..0000000
--- a/po/zh_CN.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "下载完成"
-
diff --git a/po/zh_HK.po b/po/zh_HK.po
deleted file mode 100755
index 51101ba..0000000
--- a/po/zh_HK.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "下載完成"
-
diff --git a/po/zh_SG.po b/po/zh_SG.po
deleted file mode 100755
index 3238acd..0000000
--- a/po/zh_SG.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "下载完成"
-
diff --git a/po/zh_TW.po b/po/zh_TW.po
deleted file mode 100755
index 51101ba..0000000
--- a/po/zh_TW.po
+++ /dev/null
@@ -1,3 +0,0 @@
-msgid "IDS_DM_HEADER_DOWNLOAD_COMPLETE"
-msgstr "下載完成"
-
diff --git a/provider-interface/CMakeLists.txt b/provider-interface/CMakeLists.txt
index eb523c4..70792e7 100755
--- a/provider-interface/CMakeLists.txt
+++ b/provider-interface/CMakeLists.txt
@@ -8,7 +8,7 @@ IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
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 bundle")
+SET(PC_REQUIRED "glib-2.0 gobject-2.0 dlog capi-base-common capi-appfw-app-manager capi-appfw-application bundle")
INCLUDE(FindPkgConfig)
@@ -32,7 +32,12 @@ SET(PROVIDER_INTERFACE_LINK_LIBRARIES
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -Wall")
+ADD_DEFINITIONS(-DDOWNLOAD_PROVIDER_LOG_TAG=\"DOWNLOAD_PROVIDER_INTERFACE\")
+
ADD_LIBRARY(${PROJECT_NAME} SHARED
+ ${CMAKE_SOURCE_DIR}/provider/download-provider-utils.c
+ ${CMAKE_SOURCE_DIR}/provider/download-provider-ipc.c
+ ${CMAKE_SOURCE_DIR}/provider/download-provider-pthread.c
${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})
diff --git a/provider-interface/download-provider-interface.c b/provider-interface/download-provider-interface.c
index ac93263..8b0790e 100755
--- a/provider-interface/download-provider-interface.c
+++ b/provider-interface/download-provider-interface.c
@@ -30,27 +30,24 @@
#include <dlog.h>
#include <download-provider-interface.h>
#include <download-provider.h>
+#include <download-provider-log.h>
+#include <download-provider-pthread.h>
+#include <download-provider-ipc.h>
+#include <download-provider-utils.h>
+
+#include <bundle.h> // for notification bundle
+#include <app_control.h>
+#include <app_control_internal.h>
#ifdef SUPPORT_CHECK_IPC
#include <sys/ioctl.h>
#endif
#define DP_CHECK_CONNECTION do {\
- 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);\
- if (errorcode == DP_ERROR_IO_ERROR)\
- __disconnect_from_provider();\
- pthread_mutex_unlock(&g_function_mutex);\
- return DOWNLOAD_ADAPTOR_ERROR_IO_ERROR;\
+ int dp_errorcode = __check_connections();\
+ if (dp_errorcode != DP_ERROR_NONE) {\
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);\
+ return __dp_interface_convert_errorcode(dp_errorcode);\
}\
} while(0)
@@ -61,111 +58,30 @@
}\
} while(0)
-#define MAX_DOWNLOAD_HANDLE 32
-
-#ifdef SUPPORT_LOG_MESSAGE
-#include <dlog.h>
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "DOWNLOAD_PROVIDER_INTERFACE"
-#define TRACE_DEBUG(format, ARG...) LOGD(format, ##ARG)
-#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)
-
-#ifdef SECURE_LOGD
-#define TRACE_SECURE_DEBUG(format, ARG...) SECURE_LOGD(format, ##ARG)
-#else
-#define TRACE_SECURE_DEBUG(...) do { } while(0)
-#endif
-#ifdef SECURE_LOGI
-#define TRACE_SECURE_INFO(format, ARG...) SECURE_LOGI(format, ##ARG)
-#else
-#define TRACE_SECURE_INFO(...) do { } while(0)
-#endif
-#ifdef SECURE_LOGE
-#define TRACE_SECURE_ERROR(format, ARG...) SECURE_LOGE(format, ##ARG)
-#else
-#define TRACE_SECURE_ERROR(...) do { } while(0)
-#endif
-
-#else
-#define TRACE_DEBUG(...) do { } while(0)
-#define TRACE_ERROR(...) do { } while(0)
-#define TRACE_STRERROR(...) do { } while(0)
-#define TRACE_INFO(...) do { } while(0)
-#define TRACE_SECURE_DEBUG(...) do { } while(0)
-#define TRACE_SECURE_INFO(...) do { } while(0)
-#define TRACE_SECURE_ERROR(...) do { } while(0)
-#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;
+ int channel; // query & response
+ int notify; // event from provider
+} dp_interface_ipc;
typedef struct {
+ int id;
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_ipc *g_dp_client = NULL;
dp_interface_slot g_interface_slots[MAX_DOWNLOAD_HANDLE];
static pthread_mutex_t g_function_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_clear_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_t g_interface_event_thread_id = 0;
+static pthread_t g_dp_event_thread_id = 0;
//////////// 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;
- case DOWNLOAD_ADAPTOR_NETWORK_ALL:
- return DP_NETWORK_TYPE_ALL;
- default:
- break;
- }
- return type;
-}
-
-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;
- case DOWNLOAD_ADAPTOR_NETWORK_ALL:
- return DP_NETWORK_TYPE_ALL;
- default:
- break;
- }
- return type;
-}
-
static int __dp_interface_convert_state(int state)
{
switch (state) {
@@ -181,9 +97,6 @@ static int __dp_interface_convert_state(int state)
case DP_STATE_DOWNLOADING:
TRACE_DEBUG("DOWNLOADING");
return DOWNLOAD_ADPATOR_STATE_DOWNLOADING;
- case DP_STATE_PAUSE_REQUESTED:
- TRACE_DEBUG("PAUSE_REQUESTED/DOWNLOADING");
- return DOWNLOAD_ADPATOR_STATE_DOWNLOADING;
case DP_STATE_PAUSED:
TRACE_DEBUG("PAUSED");
return DOWNLOAD_ADPATOR_STATE_PAUSED;
@@ -235,6 +148,7 @@ static int __dp_interface_convert_errorcode(int errorcode)
TRACE_DEBUG("ERROR_INVALID_STATE");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_STATE;
case DP_ERROR_CONNECTION_FAILED:
+ case DP_ERROR_NETWORK_ERROR:
TRACE_DEBUG("ERROR_CONNECTION_TIMED_OUT/CONNECTION_FAILED");
return DOWNLOAD_ADAPTOR_ERROR_CONNECTION_TIMED_OUT;
case DP_ERROR_INVALID_URL:
@@ -273,6 +187,9 @@ static int __dp_interface_convert_errorcode(int errorcode)
case DP_ERROR_UNKNOWN:
TRACE_DEBUG("ERROR_INVALID_STATE/UNKNOWN");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_STATE;
+ case DP_ERROR_INVALID_NETWORK_TYPE:
+ TRACE_DEBUG("ERROR_INVALID_NETWORK_TYPE");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_NETWORK_TYPE;
default:
break;
}
@@ -298,335 +215,9 @@ static int __get_empty_slot_index()
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_ERROR;
- }
- 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 (value == NULL) {
- TRACE_ERROR("[CHECK value]");
- return -1;
- }
- if (type_size <= 0) {
- TRACE_ERROR("[CHECK size]");
- return -1;
- }
-
- ssize_t recv_bytes = read(fd, value, type_size);
- if (recv_bytes < 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;
- }
- ssize_t recv_bytes = read(fd, &value, sizeof(int));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[CRITICAL] read");
- return -1;
- }
- return value;
-}
-
-static int __ipc_read_download_id(int fd)
-{
- int value = -1;
- int read_len = 0;
- int try_count = 5;
-
- if (fd < 0) {
- TRACE_ERROR("[CHECK SOCKET]");
- return -1;
- }
- do {
- read_len = read(fd, &value, sizeof(int));
- if (read_len < 0) {
- TRACE_STRERROR("[CRITICAL] read");
- return -1;
- }
- try_count--;
- } while (read_len == 0 && value == 0 && try_count > 0);
- return value;
-}
-
-// keep the order/ unsigned , str
-static char *__ipc_read_string(int fd)
-{
- unsigned length = 0;
- size_t recv_size = 0;
- unsigned remain_size = 0;
- size_t buffer_size = 0;
- char *str = NULL;
-
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return NULL;
- }
-
- // read flexible URL from client.
- ssize_t recv_bytes = read(fd, &length, sizeof(unsigned));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
- return NULL;
- }
- if (length < 1 || length > DP_MAX_URL_LEN) {
- TRACE_ERROR("[STRING LEGNTH] [%d]", length);
- return NULL;
- }
- str = (char *)calloc((length + 1), sizeof(char));
- if (str == NULL) {
- TRACE_STRERROR("[ERROR] calloc length:%d FD[%d]", length, fd);
- return NULL;
- }
- remain_size = length;
- do {
- buffer_size = 0;
- if (remain_size > DP_DEFAULT_BUFFER_SIZE)
- buffer_size = DP_DEFAULT_BUFFER_SIZE;
- else
- buffer_size = remain_size;
- recv_size = (size_t)read(fd, str + (int)(length - remain_size),
- buffer_size * sizeof(char));
- if (recv_size > DP_DEFAULT_BUFFER_SIZE) {
- recv_size = -1;
- break;
- }
- if (recv_size > 0)
- remain_size = remain_size - (unsigned)recv_size;
- } while (recv_size > 0 && remain_size > 0);
-
- if (recv_size == 0) {
- TRACE_STRERROR("[ERROR] closed peer:%d", fd);
- free(str);
- return NULL;
- }
- str[length] = '\0';
- return str;
-}
-
-int __ipc_read_bundle(int fd, bundle_raw **b)
-{
- unsigned length = 0;
- size_t recv_size = 0;
- unsigned remain_size = 0;
- size_t buffer_size = 0;
- bundle_raw *b_raw = NULL;
-
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return 0;
- }
-
- // read bundle data from client.
- ssize_t recv_bytes = read(fd, &length, sizeof(unsigned));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
- return 0;
- }
- if (length < 1 || length > DP_MAX_URL_LEN) {
- TRACE_ERROR("[STRING LEGNTH] [%d]", length);
- return 0;
- }
- b_raw = (bundle_raw *)calloc(length, 1);
- if (b_raw == NULL) {
- TRACE_STRERROR("[ERROR] calloc length:%d FD[%d]", length, fd);
- return 0;
- }
- remain_size = length;
- do {
- buffer_size = 0;
- if (remain_size > DP_DEFAULT_BUFFER_SIZE)
- buffer_size = DP_DEFAULT_BUFFER_SIZE;
- else
- buffer_size = remain_size;
- recv_size = (size_t)read(fd, b_raw + (int)(length - remain_size),
- buffer_size);
- if (recv_size > DP_DEFAULT_BUFFER_SIZE) {
- recv_size = -1;
- break;
- }
- if (recv_size > 0)
- remain_size = remain_size - (unsigned)recv_size;
- } while (recv_size > 0 && remain_size > 0);
-
- if (recv_size == 0) {
- TRACE_STRERROR("[ERROR] closed peer:%d", fd);
- bundle_free_encoded_rawdata(&b_raw);
- return 0;
- }
- *b = b_raw;
- return (int)length;
-}
-
-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;
- }
- ssize_t recv_bytes = read(fd, &errorcode, sizeof(dp_error_type));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[CRITICAL] read");
- return __get_standard_errorcode(DP_ERROR_IO_ERROR);
- }
- if (errorcode != DP_ERROR_NONE)
- TRACE_ERROR("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;
- }
- ssize_t recv_bytes = read(fd, event, sizeof(dp_event_info));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[CRITICAL] read");
- free(event);
- return NULL;
- }
- 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_raw_bundle(int fd, int type, const bundle_raw *b, int len)
-{
- if (fd < 0) {
- TRACE_ERROR("[CHECK FD]");
- return DP_ERROR_IO_ERROR;
- }
- if (b == NULL || len <= 0) {
- TRACE_ERROR("[CHECK STRING]");
- return DP_ERROR_INVALID_PARAMETER;
- }
- if (fd >= 0 && write(fd, &type, sizeof(unsigned)) < 0) {
- TRACE_STRERROR("[CRITICAL] send");
- return DP_ERROR_IO_ERROR;
- }
- if (fd >= 0 && write(fd, &len, sizeof(unsigned)) < 0) {
- TRACE_STRERROR("[CRITICAL] send");
- return DP_ERROR_IO_ERROR;
- }
- if (fd >= 0 && write(fd, b, len) < 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)
-{
- 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;
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
@@ -634,21 +225,18 @@ static int __create_socket()
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';
+ strncpy(clientaddr.sun_path, IPC_SOCKET, strlen(IPC_SOCKET));
+ clientaddr.sun_path[strlen(IPC_SOCKET)] = '\0';
if (connect(sockfd,
(struct sockaddr*)&clientaddr, sizeof(clientaddr)) < 0) {
close(sockfd);
+ if (errno == EACCES || errno == EPERM) {
+ TRACE_STRERROR("check permission");
+ return -DP_ERROR_PERMISSION_DENIED;
+ }
return -1;
}
TRACE_DEBUG("sockfd [%d]", sockfd);
@@ -658,88 +246,53 @@ static int __create_socket()
static void __clear_interface()
{
TRACE_DEBUG("");
- pthread_mutex_lock(&g_clear_mutex);
- 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;
- }
- pthread_mutex_unlock(&g_clear_mutex);
-}
-
-static int __disconnect_from_provider()
-{
- TRACE_DEBUG("");
- if (g_interface_event_thread_id > 0 &&
- pthread_kill(g_interface_event_thread_id, 0) != ESRCH) {
- if (pthread_cancel(g_interface_event_thread_id) != 0) {
- TRACE_STRERROR("pthread:%d", (int)g_interface_event_thread_id);
+ CLIENT_MUTEX_LOCK(&g_clear_mutex);
+ if (g_dp_client != NULL) {
+ if (g_dp_client->channel >= 0)
+ close(g_dp_client->channel);
+ g_dp_client->channel= -1;
+ if (g_dp_client->notify >= 0)
+ close(g_dp_client->notify);
+ g_dp_client->notify = -1;
+ free(g_dp_client);
+ g_dp_client = NULL;
+ }
+ CLIENT_MUTEX_UNLOCK(&g_clear_mutex);
+}
+
+static int __bp_disconnect(const char *funcname)
+{
+ TRACE_DEBUG("%s", funcname);
+ if (g_dp_event_thread_id > 0 &&
+ pthread_kill(g_dp_event_thread_id, 0) != ESRCH) {
+ if (pthread_cancel(g_dp_event_thread_id) != 0) {
+ TRACE_STRERROR("pthread:%d", (int)g_dp_event_thread_id);
}
- g_interface_event_thread_id = 0;
+ g_dp_event_thread_id = 0;
}
__clear_interface();
return DP_ERROR_NONE;
}
-#ifdef SUPPORT_CHECK_IPC
-// 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_DEBUG("[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 SUPPORT_CHECK_IPC
- // 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)
+static void *__dp_event_manager(void *arg)
{
- int maxfd, index;
- fd_set rset, read_fdset;
- dp_event_info *eventinfo = NULL;
-
- if (g_interface_info == NULL) {
+ if (g_dp_client == NULL) {
TRACE_STRERROR("[CRITICAL] INTERFACE null");
return 0;
}
- if (g_interface_info->event_socket < 0) {
- TRACE_STRERROR("[CRITICAL] IPC NOT ESTABILISH");
+
+ size_t path_size = sizeof(NOTIFY_DIR) + 11;
+ char notify_fifo[path_size];
+ snprintf((char *)&notify_fifo, path_size,"%s/%d", NOTIFY_DIR, getpid());
+ TRACE_DEBUG("IPC ESTABILISH %s", notify_fifo);
+ g_dp_client->notify = open(notify_fifo, O_RDONLY, 0600);
+ if (g_dp_client->notify < 0) {
+ TRACE_STRERROR("[CRITICAL] failed to ESTABILISH IPC %s", notify_fifo);
+ g_dp_event_thread_id = 0;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ __clear_interface();
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
return 0;
}
@@ -747,603 +300,421 @@ static void *__dp_interface_event_manager(void *arg)
// ex) function : select, read in this thread
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
- maxfd = g_interface_info->event_socket;
- FD_ZERO(&read_fdset);
- FD_SET(g_interface_info->event_socket, &read_fdset);
-
- int sock = g_interface_info->event_socket;
+ while(g_dp_client != NULL && g_dp_client->notify >= 0) {
- 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");
+ if (g_dp_event_thread_id <= 0 ||
+ pthread_self() != g_dp_event_thread_id) {
+ TRACE_ERROR("competitive threads self:%0x global:%0x",
+ pthread_self(), g_dp_event_thread_id);
+ // another thread may work. just terminate
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
- break;
+ // blocking fifo.
+ dp_ipc_event_fmt eventinfo;
+ memset(&eventinfo, 0x00, sizeof(dp_ipc_event_fmt));
+ if (dp_ipc_read(g_dp_client->notify, &eventinfo,
+ sizeof(dp_ipc_event_fmt), __FUNCTION__) <= 0 ||
+ (eventinfo.id <= 0 &&
+ eventinfo.errorcode == DP_ERROR_CLIENT_DOWN)) {
+ TRACE_INFO("expelled by provider");
+ g_dp_event_thread_id = 0;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ __clear_interface();
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ return 0;
}
- if (FD_ISSET(sock, &rset) > 0) {
- // read state info from socket
- eventinfo = __ipc_event(sock);
- if (eventinfo == NULL || eventinfo->id <= 0) {
- // failed to read from socket // ignore this status
- free(eventinfo);
- TRACE_STRERROR("[CRITICAL] Can not read Event packet");
- g_interface_event_thread_id = 0;
- __clear_interface();
- return 0;
- }
+ int index = -1;
+ if ((index = __get_my_slot_index(eventinfo.id)) < 0) {
+ TRACE_ERROR("[CRITICAL] not found slot id:%d", eventinfo.id);
+ continue;
+ }
- if ((index = __get_my_slot_index(eventinfo->id)) < 0) {
- TRACE_ERROR("[CRITICAL] not found slot for [%d]",
- eventinfo->id);
- free(eventinfo);
- continue;
+ // begin protect callback sections & thread safe
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ if (eventinfo.state == DP_STATE_DOWNLOADING &&
+ eventinfo.received_size > 0) {
+ if (eventinfo.id == g_interface_slots[index].id &&
+ g_interface_slots[index].progress != NULL) {
+ // progress event
+ g_interface_slots[index].progress(eventinfo.id,
+ eventinfo.received_size,
+ g_interface_slots[index].progress_data);
}
-
- // begin protect callback sections & thread safe
- 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 (eventinfo->id == g_interface_slots[index].id &&
- callback->progress != NULL) {
- // progress event
- callback->progress(eventinfo->id,
- eventinfo->received_size,
- callback->progress_data);
- }
- } else {
- if (eventinfo->id == g_interface_slots[index].id &&
- callback->state != NULL) {
- // state event
- callback->state(eventinfo->id,
- __dp_interface_convert_state(eventinfo->state),
- callback->state_data);
- }
+ } else {
+ if (eventinfo.id == g_interface_slots[index].id &&
+ g_interface_slots[index].state != NULL) {
+ // state event
+ g_interface_slots[index].state(eventinfo.id,
+ __dp_interface_convert_state(eventinfo.state),
+ g_interface_slots[index].state_data);
}
- free(eventinfo);
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
}
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
} // while
- FD_CLR(sock, &read_fdset);
- g_interface_event_thread_id = 0; // set 0 to not call pthread_cancel
+ g_dp_event_thread_id = 0; // set 0 to not call pthread_cancel
TRACE_DEBUG("thread end by itself");
return 0;
}
+
+
+
+
+
+////////////////// new download-provider ///////////////////////////////
+////////////////// created on 7 November, 2013 /////////////////////////
+
+#define DP_CHECK_IPC_SOCK (g_dp_client == NULL ? -1 : g_dp_client->channel)
+
+static void __dp_ipc_clear_garbage(int sock, const size_t length)
+{
+ if (length > 0) {
+ char garbage[length];
+ if (read(sock, &garbage, length) == 0) {
+ TRACE_ERROR("sock:%d closed peer", sock);
+ }
+ }
+}
+
+static int __dp_ipc_response(int sock, int download_id, short section,
+ unsigned property, size_t *size)
+{
+ dp_ipc_fmt *ipc_info = dp_ipc_get_fmt(sock);
+ if (ipc_info == NULL || ipc_info->section != section ||
+ ipc_info->property != property ||
+ (download_id >= 0 && ipc_info->id != download_id)) {
+ TRACE_STRERROR("socket read ipcinfo");
+ free(ipc_info);
+ return DP_ERROR_IO_ERROR;
+ }
+ int errorcode = ipc_info->errorcode;
+ if (size != NULL)
+ *size = ipc_info->size;
+ free(ipc_info);
+ return errorcode;
+}
+
static int __connect_to_provider()
{
- pthread_mutex_lock(&g_clear_mutex);
- if (g_interface_info == NULL) {
+ int errorcode = DP_ERROR_NONE;
- g_interface_info =
- (dp_interface_info *) calloc(1, sizeof(dp_interface_info));
+ CLIENT_MUTEX_LOCK(&g_clear_mutex);
+
+ if (g_dp_client == NULL) {
+ g_dp_client =
+ (dp_interface_ipc *)calloc(1, sizeof(dp_interface_ipc));
+
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+ TRACE_ERROR("failed to ignore SIGPIPE signal");
+ }
}
- if (g_interface_info != NULL) {
+ if (g_dp_client != 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;
- pthread_mutex_unlock(&g_clear_mutex);
- 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;
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
- }
-#ifndef SO_PEERCRED
- // send PID. Not support SO_PEERCRED
- if (__ipc_send_int(g_interface_info->cmd_socket, getpid()) < 0) {
- close(g_interface_info->cmd_socket);
- free(g_interface_info);
- g_interface_info = NULL;
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
- }
- if (__ipc_send_int(g_interface_info->cmd_socket, getuid()) < 0) {
- close(g_interface_info->cmd_socket);
- free(g_interface_info);
- g_interface_info = NULL;
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
- }
- if (__ipc_send_int(g_interface_info->cmd_socket, getgid()) < 0) {
- close(g_interface_info->cmd_socket);
- free(g_interface_info);
- g_interface_info = NULL;
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
+ g_dp_client->channel = -1;
+ while(g_dp_client->channel < 0 && connect_retry-- > 0) {
+ int ret = __create_socket();
+ if (ret == -1) {
+ TRACE_STRERROR("failed to connect to provider(remains:%d)", connect_retry);
+ struct timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 20000000;
+ nanosleep(&ts, NULL);
+ } else if (ret >= 0) {
+ struct timeval tv_timeo = { 1, 500000 }; // 1.5 second
+ g_dp_client->channel = ret;
+ if (setsockopt(g_dp_client->channel, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo, sizeof(tv_timeo)) < 0) {
+ TRACE_STRERROR("[CRITICAL] setsockopt SO_RCVTIMEO");
+ }
+ } else {
+ errorcode = -ret;
+ TRACE_STRERROR("check error:%d", errorcode);
+ goto EXIT_CONNECT;
+ }
}
-#endif
- g_interface_info->event_socket = __create_socket();
- if (g_interface_info->event_socket < 0) {
+ if (g_dp_client->channel < 0) {
TRACE_STRERROR("[CRITICAL] connect system error");
- close(g_interface_info->cmd_socket);
- free(g_interface_info);
- g_interface_info = NULL;
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
+ errorcode = DP_ERROR_IO_ERROR;
+ goto EXIT_CONNECT;
}
- // 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;
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
+
+ if (dp_ipc_query(g_dp_client->channel, -1, DP_SEC_INIT,
+ DP_PROP_NONE, DP_ERROR_NONE, 0) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ goto EXIT_CONNECT;
}
#ifndef SO_PEERCRED
+ dp_credential cred;
+ cred.pid = getpid();
+ cred.uid = getuid();
+ cred.gid = getgid();
// send PID. Not support SO_PEERCRED
- if (__ipc_send_int
- (g_interface_info->event_socket, getpid()) < 0) {
- close(g_interface_info->cmd_socket);
- close(g_interface_info->event_socket);
- free(g_interface_info);
- g_interface_info = NULL;
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
+ if (dp_ipc_write(g_dp_client->channel,
+ &cred, sizeof(dp_credential)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ goto EXIT_CONNECT;
}
#endif
- int ret = pthread_mutex_init(&g_interface_info->mutex, NULL);
- if (ret != 0) {
- TRACE_STRERROR("ERR:pthread_mutex_init FAIL with %d.", ret);
- __clear_interface();
- pthread_mutex_unlock(&g_clear_mutex);
- return DP_ERROR_IO_ERROR;
+ errorcode = __dp_ipc_response(g_dp_client->channel,
+ -1, DP_SEC_INIT, DP_PROP_NONE, NULL);
+ // Commented by justine.bang
+ // Above ipc_query call try to wake up download-provider.
+ // But, we can sometimes meet EINTR, EAGAIN or EINPROGRESS signal if systemd is slow.
+ // So, If meet EINTR ,EAGAIN or EINPROGRESS in this line, it's better to wait response from download-provider one more time.
+ if (errorcode == DP_ERROR_IO_ERROR && (errno == EINTR || errno == EAGAIN || errno == EINPROGRESS)) {
+ errorcode = __dp_ipc_response(g_dp_client->channel,
+ -1, DP_SEC_INIT, DP_PROP_NONE, NULL);
}
- }
- pthread_mutex_unlock(&g_clear_mutex);
- 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");
- __clear_interface();
- g_interface_event_thread_id = 0;
- return DP_ERROR_IO_ERROR;
+ if (errorcode == DP_ERROR_NONE && g_dp_event_thread_id <= 0) {
+ if (pthread_create(&g_dp_event_thread_id, NULL,
+ __dp_event_manager, g_dp_client) != 0) {
+ TRACE_STRERROR("failed to create event-manager");
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ pthread_detach(g_dp_event_thread_id);
+ }
}
+
}
- return DP_ERROR_NONE;
+
+EXIT_CONNECT:
+ CLIENT_MUTEX_UNLOCK(&g_clear_mutex);
+ if (errorcode != DP_ERROR_NONE)
+ __bp_disconnect(__FUNCTION__);
+
+ return errorcode;
}
static dp_error_type __check_connections()
{
int ret = 0;
- if (g_interface_info == NULL)
+ if (g_dp_client == NULL)
if ((ret = __connect_to_provider()) != DP_ERROR_NONE)
return ret;
- if (g_interface_info == NULL || g_interface_info->cmd_socket < 0) {
+ if (g_dp_client == NULL || g_dp_client->channel < 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;
- 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;
-
- int fd = g_interface_info->cmd_socket;
-
- // send commnad with ID
- errorcode = __ipc_send_command_return(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)
+static int __dp_ipc_set_binary(const int id, const unsigned property,
+ const bundle_raw *string, const size_t length, const char *funcname)
{
- dp_error_type errorcode = DP_ERROR_NONE;
- if (strings == NULL || count == 0) {
- TRACE_ERROR("[CHECK strings]");
+ int errorcode = DP_ERROR_NONE;
+ if (string == NULL || length <= 0) {
+ TRACE_ERROR("%s check binary (%d)", funcname, length);
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
DP_PRE_CHECK_ID;
-
- pthread_mutex_lock(&g_function_mutex);
-
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
DP_CHECK_CONNECTION;
- pthread_mutex_lock(&g_interface_info->mutex);
-
- DP_CHECK_PROVIDER_STATUS;
-
- int fd = g_interface_info->cmd_socket;
-
- // send commnad with ID
- errorcode = __ipc_send_command_return(id, cmd);
- if (errorcode == DP_ERROR_NONE) {
- if (__ipc_send_int(fd, (int)count) == 0) {
- int i = 0;
- for (; i < count; i++) {
- // send string
- errorcode = __ipc_send_string(fd, strings[i]);
- if (errorcode != DP_ERROR_NONE)
- break;
- }
- } else {
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, DP_SEC_SET, property, DP_ERROR_NONE, length * sizeof(unsigned char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ if (dp_ipc_write(sock, (void*)string, length * sizeof(unsigned char)) < 0) {
errorcode = DP_ERROR_IO_ERROR;
- }
- if (errorcode == DP_ERROR_NONE) {
- // return from provider.
- errorcode = __ipc_return(fd);
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ errorcode = __dp_ipc_response(sock, id, DP_SEC_SET, property, NULL);
}
}
- pthread_mutex_unlock(&g_interface_info->mutex);
if (errorcode == DP_ERROR_IO_ERROR)
- __disconnect_from_provider();
- pthread_mutex_unlock(&g_function_mutex);
+ __bp_disconnect(funcname);
+ CLIENT_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)
+static int __dp_ipc_set_string(const int id, const short section, const unsigned property,
+ const char *string, const char *funcname)
{
int errorcode = DP_ERROR_NONE;
- char *recv_str = NULL;
-
- if (value == NULL) {
- TRACE_ERROR("[CHECK buffer]");
+ size_t length = 0;
+ if (string == NULL || (length = strlen(string)) <= 0 ||
+ length > DP_MAX_STR_LEN) {
+ TRACE_ERROR("%s check string (%d:%s)", funcname, length, string);
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
DP_PRE_CHECK_ID;
-
- pthread_mutex_lock(&g_function_mutex);
-
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
DP_CHECK_CONNECTION;
- pthread_mutex_lock(&g_interface_info->mutex);
-
- DP_CHECK_PROVIDER_STATUS;
-
- int fd = g_interface_info->cmd_socket;
-
- 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;
- else
- errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR);
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ if (dp_ipc_write(sock, (void*)string, length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ errorcode = __dp_ipc_response(sock, id, section, property, NULL);
+ }
}
- pthread_mutex_unlock(&g_interface_info->mutex);
if (errorcode == DP_ERROR_IO_ERROR)
- __disconnect_from_provider();
- pthread_mutex_unlock(&g_function_mutex);
+ __bp_disconnect(funcname);
+ CLIENT_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)
+static int __dp_ipc_get_string(const int id, const unsigned property,
+ char **string, const char *funcname)
{
int errorcode = DP_ERROR_NONE;
- int i = 0;
- int recv_str_index = 0;
- char **recv_strings = NULL;
- if (values == NULL || count == NULL) {
- TRACE_ERROR("[CHECK buffer]");
+ if (string == NULL) {
+ TRACE_ERROR("%s check buffer", funcname);
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
-
DP_PRE_CHECK_ID;
-
- pthread_mutex_lock(&g_function_mutex);
-
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
DP_CHECK_CONNECTION;
- pthread_mutex_lock(&g_interface_info->mutex);
-
- DP_CHECK_PROVIDER_STATUS;
-
- int fd = g_interface_info->cmd_socket;
-
- errorcode = __ipc_send_command_return(id, cmd);
- if (errorcode == DP_ERROR_NONE) {
- if (length > 0 && strings != NULL) {
- if (__ipc_send_int(fd, (int)length) == 0) {
- for (i = 0; i < length; i++) {
- // send string
- errorcode = __ipc_send_string(fd, strings[i]);
- if (errorcode != DP_ERROR_NONE)
- break;
- }
- } else {
- errorcode = DP_ERROR_IO_ERROR;
- }
- }
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, DP_SEC_GET, property, DP_ERROR_NONE, 0) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ size_t string_length = 0;
+ *string = NULL;
+ errorcode = __dp_ipc_response(sock, id, DP_SEC_GET, property, &string_length);
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;
+ if (string_length > 0) {
+ char *recv_str = (char *)calloc((string_length + (size_t)1), sizeof(char));
+ if (recv_str == NULL) {
+ TRACE_STRERROR("check memory length:%d", string_length);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ __dp_ipc_clear_garbage(sock, string_length);
+ } else {
+ if (dp_ipc_read(sock, recv_str, string_length, funcname) <= 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ free(recv_str);
} else {
- recv_strings[recv_str_index++] = recv_str;
+ recv_str[string_length] = '\0';
+ *string = recv_str;
}
}
+ } else {
+ errorcode = DP_ERROR_IO_ERROR;
}
}
- 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);
+ __bp_disconnect(funcname);
+ CLIENT_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)
+// send command and int & return errorcode
+static int __dp_ipc_set_int(const int id, const unsigned section, const unsigned property,
+ const int value, const char *funcname)
{
int errorcode = DP_ERROR_NONE;
- int recv_int = -1;
-
- if (value == NULL) {
- TRACE_ERROR("[CHECK buffer]");
- return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
- }
DP_PRE_CHECK_ID;
-
- pthread_mutex_lock(&g_function_mutex);
-
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
DP_CHECK_CONNECTION;
- pthread_mutex_lock(&g_interface_info->mutex);
-
- DP_CHECK_PROVIDER_STATUS;
-
- int fd = g_interface_info->cmd_socket;
-
- 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_DEBUG("ID : %d recv_int : %d", id, *value);
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, sizeof(int)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ if (dp_ipc_write(sock, (void *)&value, sizeof(int)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
} else {
- errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR);
+ errorcode = __dp_ipc_response(sock, id, section, property, NULL);
}
}
- pthread_mutex_unlock(&g_interface_info->mutex);
if (errorcode == DP_ERROR_IO_ERROR)
- __disconnect_from_provider();
- pthread_mutex_unlock(&g_function_mutex);
+ __bp_disconnect(funcname);
+ CLIENT_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)
+// send command & return errorcode and int
+static int __dp_ipc_get_int(const int id, const unsigned property,
+ int *value, const char *funcname)
{
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;
-
- int fd = g_interface_info->cmd_socket;
-
- // send commnad with ID
- errorcode = __ipc_send_command_return(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);
-}
-
-static dp_error_type __dp_interface_set_raw_bundle
- (const int id, const dp_command_type cmd, int type, const bundle_raw *b, int len)
-{
- dp_error_type errorcode = DP_ERROR_NONE;
- if (b == NULL) {
- TRACE_ERROR("[CHECK bundle]");
+ if (value == NULL) {
+ TRACE_ERROR("%s check buffer", funcname);
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
DP_PRE_CHECK_ID;
-
- pthread_mutex_lock(&g_function_mutex);
-
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
DP_CHECK_CONNECTION;
- pthread_mutex_lock(&g_interface_info->mutex);
-
- DP_CHECK_PROVIDER_STATUS;
-
- int fd = g_interface_info->cmd_socket;
-
- // send commnad with ID
- errorcode = __ipc_send_command_return(id, cmd);
- if (errorcode == DP_ERROR_NONE) {
- // send raw bundle
- errorcode = __ipc_send_raw_bundle(fd, type, b, len);
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, DP_SEC_GET, property, DP_ERROR_NONE, 0) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ size_t extra_size = 0;
+ errorcode = __dp_ipc_response(sock, id, DP_SEC_GET, property, &extra_size);
if (errorcode == DP_ERROR_NONE) {
- // return from provider.
- errorcode = __ipc_return(fd);
+ if (extra_size == sizeof(int)) {
+ if (dp_ipc_read(sock, value, extra_size, funcname) < 0)
+ errorcode = DP_ERROR_IO_ERROR;
+ } 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);
+ __bp_disconnect(funcname);
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
return __dp_interface_convert_errorcode(errorcode);
}
-static dp_error_type __dp_interface_get_raw_bundle
- (const int id, const dp_command_type cmd, int type, bundle_raw **value, int *len)
+// send command & return errorcode.
+int __dp_ipc_echo(const int id, const short section,
+ const unsigned property, const char *funcname)
{
int errorcode = DP_ERROR_NONE;
- if (value == NULL) {
- TRACE_ERROR("[CHECK buffer]");
- return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
- }
-
DP_PRE_CHECK_ID;
-
- pthread_mutex_lock(&g_function_mutex);
-
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
DP_CHECK_CONNECTION;
- pthread_mutex_lock(&g_interface_info->mutex);
-
- DP_CHECK_PROVIDER_STATUS;
-
- int fd = g_interface_info->cmd_socket;
-
- errorcode = __ipc_send_command_return(id, cmd);
- if (errorcode == DP_ERROR_NONE) {
- errorcode = __ipc_send_int(fd, type);
- if(errorcode == 0) {
- errorcode = __ipc_return(g_interface_info->cmd_socket);
- if (errorcode == DP_ERROR_NONE) {
- *len = __ipc_read_bundle(fd, value);
- if (*len <= 0)
- errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR);
- } else {
- TRACE_ERROR("[ERROR] Fail to get result for sending type value]");
- errorcode = DP_ERROR_IO_ERROR;
- }
- } else {
- TRACE_ERROR("[ERROR] Fail to send type]");
- errorcode = DP_ERROR_IO_ERROR;
- }
- } else {
- TRACE_ERROR("[ERROR] Fail to send command]");
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, 0) < 0) {
errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", funcname, sock);
+ } else {
+ errorcode = __dp_ipc_response(sock, id, section, property, NULL);
}
- pthread_mutex_unlock(&g_interface_info->mutex);
+
if (errorcode == DP_ERROR_IO_ERROR)
- __disconnect_from_provider();
- pthread_mutex_unlock(&g_function_mutex);
+ __bp_disconnect(funcname);
+ CLIENT_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;
if (id == NULL) {
@@ -1351,626 +722,267 @@ int dp_interface_create(int *id)
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
- pthread_mutex_lock(&g_function_mutex);
+ CLIENT_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);
+ CLIENT_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_download_id(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;
+ dp_ipc_fmt *ipc_info = NULL;
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, -1, DP_SEC_CONTROL, DP_PROP_CREATE, DP_ERROR_NONE, 0) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ ipc_info = dp_ipc_get_fmt(sock);
+ if (ipc_info == NULL) {
+ TRACE_ERROR("[ERROR] IPC INFO is NULL");
+ errorcode = DP_ERROR_IO_ERROR;
+ } else if (ipc_info->section != DP_SEC_CONTROL ||
+ ipc_info->property != DP_PROP_CREATE ||
+ ipc_info->size != 0) {
+ TRACE_ERROR("sock:%d id:%d section:%d property:%d size:%d",
+ sock, ipc_info->id, ipc_info->section, ipc_info->property,
+ ipc_info->size);
+ errorcode = DP_ERROR_IO_ERROR;
} else {
- errorcode = __get_standard_errorcode(DP_ERROR_IO_ERROR);
+ TRACE_DEBUG("download_id:%d", ipc_info->id);
+ if (errorcode == DP_ERROR_NONE && ipc_info->id > 0) {
+ *id = ipc_info->id;
+ g_interface_slots[index].id = ipc_info->id;
+ g_interface_slots[index].state = NULL;
+ g_interface_slots[index].state_data = NULL;
+ g_interface_slots[index].progress = NULL;
+ g_interface_slots[index].progress_data = NULL;
+ }
}
}
- pthread_mutex_unlock(&g_interface_info->mutex);
+ free(ipc_info);
if (errorcode == DP_ERROR_IO_ERROR)
- __disconnect_from_provider();
- pthread_mutex_unlock(&g_function_mutex);
+ __bp_disconnect(__FUNCTION__);
+ CLIENT_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);
-
+ CLIENT_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.
- // 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);
+ g_interface_slots[index].state = NULL;
+ g_interface_slots[index].state_data = NULL;
+ g_interface_slots[index].progress = NULL;
+ g_interface_slots[index].progress_data = NULL;
+ }
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ return __dp_ipc_echo(id, DP_SEC_CONTROL, DP_PROP_DESTROY, __FUNCTION__);
}
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);
+ return __dp_ipc_echo(id, DP_SEC_CONTROL, DP_PROP_START, __FUNCTION__);
}
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);
+ return __dp_ipc_echo(id, DP_SEC_CONTROL, DP_PROP_PAUSE, __FUNCTION__);
}
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);
+ return __dp_ipc_echo(id, DP_SEC_CONTROL, DP_PROP_CANCEL, __FUNCTION__);
}
int dp_interface_set_url(const int id, const char *url)
{
- return __dp_interface_set_string(id, DP_CMD_SET_URL, url);
+ if (url == NULL)
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_URL, __FUNCTION__);
+ return __dp_ipc_set_string(id, DP_SEC_SET, DP_PROP_URL, url, __FUNCTION__);
}
int dp_interface_get_url(const int id, char **url)
{
- return __dp_interface_get_string(id, DP_CMD_GET_URL, url);
-}
-
-int dp_interface_set_network_type(const int id, int net_type)
-{
- 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)
-{
- if (net_type == NULL) {
- TRACE_ERROR("[CHECK buffer]");
- return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
- }
- 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;
+ return __dp_ipc_get_string(id, DP_PROP_URL, url, __FUNCTION__);
}
int dp_interface_set_destination(const int id, const char *path)
{
- return __dp_interface_set_string(id, DP_CMD_SET_DESTINATION, path);
+ if (path == NULL)
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_DESTINATION, __FUNCTION__);
+ return __dp_ipc_set_string(id, DP_SEC_SET, DP_PROP_DESTINATION, path, __FUNCTION__);
}
-
int dp_interface_get_destination(const int id, char **path)
{
- return __dp_interface_get_string(id, DP_CMD_GET_DESTINATION, path);
+ return __dp_ipc_get_string(id, DP_PROP_DESTINATION, path, __FUNCTION__);
}
int dp_interface_set_file_name(const int id, const char *file_name)
{
- return __dp_interface_set_string(id, DP_CMD_SET_FILENAME, file_name);
+ if (file_name == NULL)
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_FILENAME, __FUNCTION__);
+ return __dp_ipc_set_string(id, DP_SEC_SET, DP_PROP_FILENAME, file_name, __FUNCTION__);
}
int dp_interface_get_file_name(const int id, char **file_name)
{
- return __dp_interface_get_string(id, DP_CMD_GET_FILENAME, file_name);
+ return __dp_ipc_get_string(id, DP_PROP_FILENAME, file_name, __FUNCTION__);
}
-int dp_interface_set_ongoing_notification(const int id, int enable)
+int dp_interface_get_downloaded_file_path(const int id, char **path)
{
- return dp_interface_set_notification(id, enable);
+ return __dp_ipc_get_string(id, DP_PROP_SAVED_PATH, path, __FUNCTION__);
}
-int dp_interface_set_notification(const int id, int enable)
+int dp_interface_get_temp_path(const int id, char **temp_path)
{
- return __dp_interface_set_int(id, DP_CMD_SET_NOTIFICATION, enable);
+ return __dp_ipc_get_string(id, DP_PROP_TEMP_SAVED_PATH, temp_path, __FUNCTION__);
}
-int dp_interface_get_ongoing_notification(const int id, int *enable)
+int dp_interface_get_content_name(const int id, char **content_name)
{
- return dp_interface_get_notification(id, enable);
+ return __dp_ipc_get_string(id, DP_PROP_CONTENT_NAME, content_name, __FUNCTION__);
}
-int dp_interface_get_notification(const int id, int *enable)
+int dp_interface_get_etag(const int id, char **etag)
{
- return __dp_interface_get_int(id, DP_CMD_GET_NOTIFICATION, enable);
+ return __dp_ipc_get_string(id, DP_PROP_ETAG, etag, __FUNCTION__);
}
-int dp_interface_get_downloaded_file_path(const int id, char **path)
+int dp_interface_set_temp_file_path(const int id, const char *path)
{
- return __dp_interface_get_string(id, DP_CMD_GET_SAVED_PATH, path);
+ return __dp_ipc_set_string(id, DP_SEC_SET, DP_PROP_TEMP_SAVED_PATH, path, __FUNCTION__);
}
-int dp_interface_set_notification_extra_param(const int id, char *key,
- char *value)
+int dp_interface_set_network_type(const int id, int net_type)
{
-#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;
+ return __dp_ipc_set_int(id, DP_SEC_SET, DP_PROP_NETWORK_TYPE,
+ net_type, __FUNCTION__);
}
-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;
- 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 dp_interface_get_network_type(const int id, int *net_type)
{
- int errorcode = DP_ERROR_NONE;
-
- DP_PRE_CHECK_ID;
-
- if (field == NULL || value == NULL) {
- TRACE_ERROR("[CHECK field or value]");
+ if (net_type == NULL) {
+ TRACE_ERROR("check buffer");
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_return(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);
+ return __dp_ipc_get_int(id, DP_PROP_NETWORK_TYPE, net_type, __FUNCTION__);
}
-int dp_interface_get_http_header_field(const int id, const char *field,
- char **value)
+int dp_interface_get_network_bonding(const int id, int *enable)
{
- int errorcode = DP_ERROR_NONE;
- char *str = NULL;
-
- DP_PRE_CHECK_ID;
-
- if (field == NULL || value == NULL) {
- TRACE_ERROR("[CHECK field or value]");
+ if (enable == NULL) {
+ TRACE_ERROR("check buffer");
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_return(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;
- } 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);
+ return __dp_ipc_get_int(id, DP_PROP_NETWORK_BONDING, enable, __FUNCTION__);
}
-int dp_interface_get_http_header_field_list(const int id, char ***fields,
- int *length)
-{
- return __dp_interface_get_strings(id, DP_CMD_GET_HTTP_HEADER_LIST,
- NULL, 0, fields, (unsigned *)length);
-}
-
-int dp_interface_remove_http_header_field(const int id,
- const char *field)
+int dp_interface_set_network_bonding(const int id, int enable)
{
- 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_return(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);
+ return __dp_ipc_set_int(id, DP_SEC_SET, DP_PROP_NETWORK_BONDING,
+ enable, __FUNCTION__);
}
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);
+ int errorcode = __dp_ipc_echo(id, DP_SEC_SET, DP_PROP_STATE_CALLBACK, __FUNCTION__);
if (errorcode == DOWNLOAD_ADAPTOR_ERROR_NONE) {
- pthread_mutex_lock(&g_function_mutex);
- // search same info in array.
- index = __get_my_slot_index(id);
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ int 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]",
+ TRACE_ERROR("too many download limit:%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;
+ g_interface_slots[index].state = callback;
+ g_interface_slots[index].state_data = user_data;
}
- pthread_mutex_unlock(&g_function_mutex);
+ CLIENT_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;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ int index = __get_my_slot_index(id);
+ if (index >= 0) {
+ g_interface_slots[index].state = NULL;
+ g_interface_slots[index].state_data = NULL;
}
- pthread_mutex_unlock(&g_function_mutex);
- return errorcode;
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ if (index < 0)
+ return DOWNLOAD_ADAPTOR_ERROR_ID_NOT_FOUND;
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_STATE_CALLBACK, __FUNCTION__);
}
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);
+ int errorcode = __dp_ipc_echo(id, DP_SEC_SET, DP_PROP_PROGRESS_CALLBACK, __FUNCTION__);
if (errorcode == DOWNLOAD_ADAPTOR_ERROR_NONE) {
- pthread_mutex_lock(&g_function_mutex);
- // search same info in array.
- index = __get_my_slot_index(id);
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ int 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]",
+ TRACE_ERROR("too many download limit:%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;
+ g_interface_slots[index].progress = callback;
+ g_interface_slots[index].progress_data = user_data;
}
- pthread_mutex_unlock(&g_function_mutex);
+ CLIENT_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;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ int index = __get_my_slot_index(id);
+ if (index >= 0) {
+ g_interface_slots[index].progress = NULL;
+ g_interface_slots[index].progress_data = NULL;
}
- pthread_mutex_unlock(&g_function_mutex);
- return errorcode;
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ if (index < 0)
+ return DOWNLOAD_ADAPTOR_ERROR_ID_NOT_FOUND;
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_PROGRESS_CALLBACK, __FUNCTION__);
}
int dp_interface_get_state(const int id, int *state)
{
if (state == NULL) {
- TRACE_ERROR("[CHECK buffer]");
+ TRACE_ERROR("check buffer");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
- 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)
-{
- 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)
-{
- return __dp_interface_get_string
- (id, DP_CMD_GET_CONTENT_NAME, content_name);
+ int dp_state = DP_STATE_NONE;
+ int errorcode = __dp_ipc_get_int(id, DP_PROP_STATE, &dp_state, __FUNCTION__);
+ if (errorcode == DOWNLOAD_ADAPTOR_ERROR_NONE)
+ *state = __dp_interface_convert_state(dp_state);
+ return errorcode;
}
int dp_interface_get_content_size(const int id,
@@ -1979,60 +991,72 @@ int dp_interface_get_content_size(const int id,
int errorcode = DP_ERROR_NONE;
if (content_size == NULL) {
- TRACE_ERROR("[CHECK buffer content_size]");
+ TRACE_ERROR("check buffer");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
DP_PRE_CHECK_ID;
-
- pthread_mutex_lock(&g_function_mutex);
-
+ CLIENT_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);
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, DP_SEC_GET, DP_PROP_TOTAL_FILE_SIZE, DP_ERROR_NONE, 0) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("%s check ipc sock:%d", __FUNCTION__, sock);
+ } else {
+ size_t extra_size = 0;
+ errorcode = __dp_ipc_response(sock, id, DP_SEC_GET, DP_PROP_TOTAL_FILE_SIZE, &extra_size);
+ if (errorcode == DP_ERROR_NONE) {
+ if (extra_size == sizeof(unsigned long long)) {
+ if (dp_ipc_read(sock, content_size, extra_size, __FUNCTION__) < 0)
+ errorcode = DP_ERROR_IO_ERROR;
+ } 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);
+ __bp_disconnect(__FUNCTION__);
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
return __dp_interface_convert_errorcode(errorcode);
}
int dp_interface_get_mime_type(const int id, char **mime_type)
{
- return __dp_interface_get_string
- (id, DP_CMD_GET_MIME_TYPE, mime_type);
+ if (mime_type == NULL) {
+ TRACE_ERROR("check buffer");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ return __dp_ipc_get_string(id, DP_PROP_MIME_TYPE, mime_type,
+ __FUNCTION__);
}
int dp_interface_set_auto_download(const int id, int enable)
{
- return __dp_interface_set_int(id, DP_CMD_SET_AUTO_DOWNLOAD, enable);
+ short section = DP_SEC_SET;
+ if (enable <= 0)
+ section = DP_SEC_UNSET;
+ return __dp_ipc_echo(id, section, DP_PROP_AUTO_DOWNLOAD, __FUNCTION__);
}
int dp_interface_get_auto_download(const int id, int *enable)
{
- return __dp_interface_get_int(id, DP_CMD_GET_AUTO_DOWNLOAD, enable);
+ if (enable == NULL) {
+ TRACE_ERROR("check buffer");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ return __dp_ipc_get_int(id, DP_PROP_AUTO_DOWNLOAD, enable, __FUNCTION__);
}
int dp_interface_get_error(const int id, int *error)
{
if (error == NULL) {
- TRACE_ERROR("[CHECK buffer error]");
+ TRACE_ERROR("check buffer");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
int errorcode = DP_ERROR_NONE;
- int ret = __dp_interface_get_int(id, DP_CMD_GET_ERROR, &errorcode);
+ int ret = __dp_ipc_get_int(id, DP_PROP_ERROR, &errorcode, __FUNCTION__);
if (ret == DOWNLOAD_ADAPTOR_ERROR_NONE)
*error = __dp_interface_convert_errorcode(errorcode);
return ret;
@@ -2040,107 +1064,497 @@ int dp_interface_get_error(const int id, int *error)
int dp_interface_get_http_status(const int id, int *http_status)
{
- return __dp_interface_get_int
- (id, DP_CMD_GET_HTTP_STATUS, http_status);
+ if (http_status == NULL) {
+ TRACE_ERROR("check buffer");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ return __dp_ipc_get_int(id, DP_PROP_HTTP_STATUS, http_status,
+ __FUNCTION__);
}
-int dp_interface_add_noti_extra(const int id, const char *key,
- const char **values, const unsigned length)
+int dp_interface_set_notification_title(const int id, const char *title)
{
- int i = 0;
+ if (title == NULL)
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_NOTIFICATION_SUBJECT, __FUNCTION__);
+ return __dp_ipc_set_string(id, DP_SEC_SET, DP_PROP_NOTIFICATION_SUBJECT, title, __FUNCTION__);
+}
- 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);
+int dp_interface_get_notification_title(const int id, char **title)
+{
+ if (title == NULL) {
+ TRACE_ERROR("check buffer");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
+ return __dp_ipc_get_string(id, DP_PROP_NOTIFICATION_SUBJECT, title, __FUNCTION__);
+}
- 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_set_notification_description(const int id, const char *description)
+{
+ if (description == NULL)
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_NOTIFICATION_DESCRIPTION, __FUNCTION__);
+ return __dp_ipc_set_string(id, DP_SEC_SET, DP_PROP_NOTIFICATION_DESCRIPTION, description, __FUNCTION__);
}
-int dp_interface_get_noti_extra_values(const int id, const char *key,
- char ***values, unsigned *length)
+int dp_interface_get_notification_description(const int id, char **description)
{
- return __dp_interface_get_strings(id, DP_CMD_GET_EXTRA_PARAM,
- &key, 1, values, length);
+ if (description == NULL) {
+ TRACE_ERROR("check buffer");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ return __dp_ipc_get_string(id, DP_PROP_NOTIFICATION_DESCRIPTION, description, __FUNCTION__);
}
-int dp_interface_remove_noti_extra_key(const int id, const char *key)
+int dp_interface_set_notification_type(const int id, int type)
{
- return __dp_interface_set_string
- (id, DP_CMD_REMOVE_EXTRA_PARAM, key);
+ if (type == DP_NOTIFICATION_TYPE_NONE)
+ return __dp_ipc_echo(id, DP_SEC_UNSET, DP_PROP_NOTIFICATION_TYPE, __FUNCTION__);
+ return __dp_ipc_set_int(id, DP_SEC_SET, DP_PROP_NOTIFICATION_TYPE, type, __FUNCTION__);
}
-int dp_interface_set_notification_bundle(const int id, int type, bundle *b)
+int dp_interface_get_notification_type(const int id, int *type)
{
- bundle_raw *r = NULL;
- int len = 0;
- int retval = -1;
- retval = bundle_encode_raw(b, &r, &len);
- if (retval == 0)
- retval = __dp_interface_set_raw_bundle(id, DP_CMD_SET_NOTIFICATION_BUNDLE, type, r, len);
- else {
- bundle_free_encoded_rawdata(&r);
+ if (type == NULL) {
+ TRACE_ERROR("check buffer");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
- bundle_free_encoded_rawdata(&r);
- return retval;
+ return __dp_ipc_get_int(id, DP_PROP_NOTIFICATION_TYPE, type, __FUNCTION__);
+}
+
+int dp_interface_set_notification_bundle(const int id, const int type, void *bundle_param)
+{
+ int errorcode = DOWNLOAD_ADAPTOR_ERROR_NONE;
+ if (type != DP_NOTIFICATION_BUNDLE_TYPE_ONGOING &&
+ type != DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE &&
+ type != DP_NOTIFICATION_BUNDLE_TYPE_FAILED) {
+ TRACE_ERROR("check type:%d id:%d", type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ return errorcode;
+ }
+ if (bundle_param == NULL) { // unset
+ return __dp_ipc_set_int(id, DP_SEC_UNSET, DP_PROP_NOTIFICATION_RAW, type, __FUNCTION__);
+ } else { // set
+ int length = 0;
+ bundle_raw *raw_buffer = NULL;
+ int result = bundle_encode_raw(bundle_param, &raw_buffer, &length);
+ if (result == 0 && length > 0) {
+ errorcode = __dp_ipc_set_int(id, DP_SEC_SET, DP_PROP_NOTIFICATION_RAW, type, __FUNCTION__);
+ if (errorcode == DOWNLOAD_ADAPTOR_ERROR_NONE) {
+ errorcode = __dp_ipc_set_binary(id, DP_PROP_NOTIFICATION_RAW, raw_buffer, (size_t)length, __FUNCTION__);
+ }
+ } else {
+ TRACE_ERROR("failed to encode raws error:%d type:%d id:%d", result, type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ if (raw_buffer != NULL)
+ bundle_free_encoded_rawdata(&raw_buffer);
+ }
+ return errorcode;
}
-int dp_interface_get_notification_bundle(const int id, int type, bundle **b)
+int dp_interface_get_notification_bundle(const int id, const int type, void **bundle_param)
{
- bundle_raw *r = NULL;
- int len = 0;
- download_adaptor_error_e error = DOWNLOAD_ADAPTOR_ERROR_NONE;
-
- if (b == NULL) {
- TRACE_ERROR("[CHECK bundle] (%d)", id);
+ if (bundle_param == NULL) {
+ TRACE_ERROR("check buffer");
return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
}
+ int errorcode = DOWNLOAD_ADAPTOR_ERROR_NONE;
+ if (type != DP_NOTIFICATION_BUNDLE_TYPE_ONGOING &&
+ type != DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE &&
+ type != DP_NOTIFICATION_BUNDLE_TYPE_FAILED) {
+ TRACE_ERROR("check type:%d id:%d", type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ return errorcode;
+ }
+
+ // send type, get errorcode with extra_size, get bundle binary
+
+ errorcode = DP_ERROR_NONE;
- error = __dp_interface_get_raw_bundle(id, DP_CMD_GET_NOTIFICATION_BUNDLE, type, &r, &len);
- if (error == DOWNLOAD_ADAPTOR_ERROR_NONE) {
- *b = bundle_decode_raw(r, len);
+ DP_PRE_CHECK_ID;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ DP_CHECK_CONNECTION;
+
+ const unsigned section = DP_SEC_GET;
+ const unsigned property = DP_PROP_NOTIFICATION_RAW;
+ size_t extra_size = 0;
+
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, sizeof(int)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ if (dp_ipc_write(sock, (void *)&type, sizeof(int)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ errorcode = __dp_ipc_response(sock, id, section, property, &extra_size);
+ }
+ }
+ if (errorcode == DP_ERROR_NONE && extra_size > 0) {
+ unsigned char *recv_raws = (unsigned char *)calloc(extra_size, sizeof(unsigned char));
+ if (recv_raws == NULL) {
+ TRACE_STRERROR("sock:%d check memory length:%d", sock, extra_size);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ __dp_ipc_clear_garbage(sock, extra_size);
+ } else {
+ if (dp_ipc_read(sock, recv_raws, extra_size, __FUNCTION__) <= 0) {
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, extra_size);
+ errorcode = DP_ERROR_IO_ERROR;
+ free(recv_raws);
+ } else {
+ TRACE_DEBUG("sock:%d length:%d raws", sock, extra_size);
+ *bundle_param = bundle_decode_raw(recv_raws, extra_size);
+ free(recv_raws);
+ }
+ }
}
- bundle_free_encoded_rawdata(&r);
- return error;
+ if (errorcode == DP_ERROR_IO_ERROR)
+ __bp_disconnect(__FUNCTION__);
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ return __dp_interface_convert_errorcode(errorcode);
}
-int dp_interface_set_notification_title(const int id, const char *title)
-{
- return __dp_interface_set_string(id, DP_CMD_SET_NOTIFICATION_TITLE, title);
+int dp_interface_set_notification_service_handle(const int id, const int type, void *handle)
+{
+ int errorcode = DOWNLOAD_ADAPTOR_ERROR_NONE;
+ if (type != DP_NOTIFICATION_SERVICE_TYPE_ONGOING &&
+ type != DP_NOTIFICATION_SERVICE_TYPE_COMPLETE &&
+ type != DP_NOTIFICATION_SERVICE_TYPE_FAILED) {
+ TRACE_ERROR("check type:%d id:%d", type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ return errorcode;
+ }
+ if (handle == NULL) { // unset
+ return __dp_ipc_set_int(id, DP_SEC_UNSET, DP_PROP_NOTIFICATION_RAW, type, __FUNCTION__);
+ } else { // set
+ int length = 0;
+ bundle_raw *raw_buffer = NULL;
+ bundle *bundle_data = NULL;
+ int result = app_control_export_as_bundle((app_control_h) handle, &bundle_data);
+ if (result == APP_CONTROL_ERROR_NONE) {
+ result = bundle_encode_raw(bundle_data, &raw_buffer, &length);
+ if (result == 0 && length > 0) {
+ errorcode = __dp_ipc_set_int(id, DP_SEC_SET, DP_PROP_NOTIFICATION_RAW, type, __FUNCTION__);
+ if (errorcode == DOWNLOAD_ADAPTOR_ERROR_NONE) {
+ errorcode = __dp_ipc_set_binary(id, DP_PROP_NOTIFICATION_RAW, raw_buffer, (size_t)length, __FUNCTION__);
+ }
+ } else {
+ TRACE_ERROR("failed to encode raws error:%d type:%d id:%d", result, type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ } else {
+ TRACE_ERROR("failed to encode service handle error:%d type:%d id:%d", result, type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ if (raw_buffer != NULL)
+ bundle_free_encoded_rawdata(&raw_buffer);
+ if (bundle_data != NULL)
+ bundle_free(bundle_data);
+ }
+ return errorcode;
}
-int dp_interface_get_notification_title(const int id, char **title)
+int dp_interface_get_notification_service_handle(const int id, const int type, void **handle)
{
- return __dp_interface_get_string(id, DP_CMD_GET_NOTIFICATION_TITLE, title);
+ bundle *bundle_data = NULL;
+ if (handle == NULL) {
+ TRACE_ERROR("check buffer");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ int errorcode = DOWNLOAD_ADAPTOR_ERROR_NONE;
+ if (type != DP_NOTIFICATION_SERVICE_TYPE_ONGOING &&
+ type != DP_NOTIFICATION_SERVICE_TYPE_COMPLETE &&
+ type != DP_NOTIFICATION_SERVICE_TYPE_FAILED) {
+ TRACE_ERROR("check type:%d id:%d", type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ return errorcode;
+ }
+
+ // send type, get errorcode with extra_size, get bundle binary
+
+ errorcode = DP_ERROR_NONE;
+
+ DP_PRE_CHECK_ID;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ DP_CHECK_CONNECTION;
+
+ const unsigned section = DP_SEC_GET;
+ const unsigned property = DP_PROP_NOTIFICATION_RAW;
+ size_t extra_size = 0;
+
+ int sock = DP_CHECK_IPC_SOCK;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, sizeof(int)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ if (dp_ipc_write(sock, (void *)&type, sizeof(int)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ errorcode = __dp_ipc_response(sock, id, section, property, &extra_size);
+ }
+ }
+ if (errorcode == DP_ERROR_NONE && extra_size > 0) {
+ unsigned char *recv_raws = (unsigned char *)calloc(extra_size, sizeof(unsigned char));
+ if (recv_raws == NULL) {
+ TRACE_STRERROR("sock:%d check memory length:%d", sock, extra_size);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ __dp_ipc_clear_garbage(sock, extra_size);
+ } else {
+ if (dp_ipc_read(sock, recv_raws, extra_size, __FUNCTION__) <= 0) {
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, extra_size);
+ errorcode = DP_ERROR_IO_ERROR;
+ free(recv_raws);
+ } else {
+ TRACE_DEBUG("sock:%d length:%d raws", sock, extra_size);
+
+ bundle_data = bundle_decode_raw(recv_raws, extra_size);
+ if (bundle_data) {
+ int result = 0;
+ result = app_control_create((app_control_h *)handle);
+ if (result == APP_CONTROL_ERROR_NONE) {
+ result = app_control_import_from_bundle((app_control_h)*handle, bundle_data);
+ if (result != APP_CONTROL_ERROR_NONE) {
+ TRACE_ERROR("failed to import service handle error:%d type:%d id:%d", result, type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ } else {
+ TRACE_ERROR("failed to create service handle error:%d type:%d id:%d", result, type, id);
+ errorcode = DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ bundle_free(bundle_data);
+ }
+ free(recv_raws);
+ }
+ }
+ }
+ if (errorcode == DP_ERROR_IO_ERROR)
+ __bp_disconnect(__FUNCTION__);
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ return __dp_interface_convert_errorcode(errorcode);
}
-int dp_interface_set_notification_description(const int id, const char *description)
+int dp_interface_add_http_header_field(const int id, const char *field,
+ const char *value)
{
- return __dp_interface_set_string(id, DP_CMD_SET_NOTIFICATION_DESCRIPTION, description);
+ // cmd + field string + value string
+ // wait response
+ int errorcode = DP_ERROR_NONE;
+ size_t field_length = 0;
+ size_t value_length = 0;
+ if (field == NULL || (field_length = strlen(field)) <= 0 ||
+ field_length > DP_MAX_STR_LEN) {
+ TRACE_ERROR("check field (%d:%s)", field_length, field);
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ if (value == NULL || (value_length = strlen(value)) <= 0 ||
+ value_length > DP_MAX_STR_LEN) {
+ TRACE_ERROR("check value (%d:%s)", value_length, value);
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+
+ DP_PRE_CHECK_ID;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ DP_CHECK_CONNECTION;
+
+ int sock = DP_CHECK_IPC_SOCK;
+ short section = DP_SEC_SET;
+ unsigned property = DP_PROP_HTTP_HEADER;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, field_length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ if (dp_ipc_write(sock, (void*)field, field_length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ errorcode = __dp_ipc_response(sock, id, section, property, NULL);
+ if (errorcode == DP_ERROR_NONE) {
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, value_length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ if (dp_ipc_write(sock, (void*)value, value_length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ errorcode = __dp_ipc_response(sock, id, section, property, NULL);
+ }
+ }
+ }
+ }
+ }
+ if (errorcode == DP_ERROR_IO_ERROR)
+ __bp_disconnect(__FUNCTION__);
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ return __dp_interface_convert_errorcode(errorcode);
}
-int dp_interface_get_notification_description(const int id, char **description)
+int dp_interface_get_http_header_field(const int id, const char *field,
+ char **value)
{
- return __dp_interface_get_string(id, DP_CMD_GET_NOTIFICATION_DESCRIPTION, description);
+ // cmd + field string
+ // wait response + value string
+ int errorcode = DP_ERROR_NONE;
+ size_t length = 0;
+ if (field == NULL || (length = strlen(field)) <= 0 ||
+ length > DP_MAX_STR_LEN) {
+ TRACE_ERROR("check field (%d:%s)", length, field);
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ if (value == NULL) {
+ TRACE_ERROR("check pointer for value");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+
+ DP_PRE_CHECK_ID;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ DP_CHECK_CONNECTION;
+
+ int sock = DP_CHECK_IPC_SOCK;
+ short section = DP_SEC_GET;
+ unsigned property = DP_PROP_HTTP_HEADER;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ if (dp_ipc_write(sock, (void*)field, length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+ size_t string_length = 0;
+ *value = NULL;
+ errorcode = __dp_ipc_response(sock, id, section, property, &string_length);
+ if (errorcode == DP_ERROR_NONE) {
+ if (string_length > 0) {
+ char *recv_str = (char *)calloc((string_length + (size_t)1), sizeof(char));
+ if (recv_str == NULL) {
+ TRACE_STRERROR("check memory length:%d", string_length);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ __dp_ipc_clear_garbage(sock, string_length);
+ } else {
+ if (dp_ipc_read(sock, recv_str, string_length, __FUNCTION__) <= 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ free(recv_str);
+ } else {
+ recv_str[string_length] = '\0';
+ *value = recv_str;
+ }
+ }
+ } else {
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ }
+ }
+ }
+ if (errorcode == DP_ERROR_IO_ERROR)
+ __bp_disconnect(__FUNCTION__);
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ return __dp_interface_convert_errorcode(errorcode);
}
-int dp_interface_set_notification_type(const int id, int type)
+int dp_interface_get_http_header_field_list(const int id, char ***fields,
+ int *length)
{
- return __dp_interface_set_int(id, DP_CMD_SET_NOTIFICATION_TYPE, type);
+ // cmd
+ // wait response
+ // wait size
+ // wait strings
+ int errorcode = DP_ERROR_NONE;
+ if (fields == NULL) {
+ TRACE_ERROR("check pointer for fields");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+ if (length == NULL) {
+ TRACE_ERROR("check pointer for length");
+ return DOWNLOAD_ADAPTOR_ERROR_INVALID_PARAMETER;
+ }
+
+ DP_PRE_CHECK_ID;
+ CLIENT_MUTEX_LOCK(&g_function_mutex);
+ DP_CHECK_CONNECTION;
+
+ int sock = DP_CHECK_IPC_SOCK;
+ short section = DP_SEC_GET;
+ unsigned property = DP_PROP_HTTP_HEADERS;
+ if (dp_ipc_query(sock, id, section, property, DP_ERROR_NONE, 0) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", sock);
+ } else {
+
+ int array_size = 0;
+ size_t extra_size = 0;
+ errorcode = __dp_ipc_response(sock, id, section, property, &extra_size);
+ if (errorcode == DP_ERROR_NONE) {
+ if (extra_size == sizeof(int)) {
+ if (dp_ipc_read(sock, &array_size, extra_size, __FUNCTION__) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ if (array_size <= 0) {
+ errorcode = DP_ERROR_NO_DATA;
+ *length = 0;
+ } else {
+ int i = 0;
+ char **recv_strings = NULL;
+ recv_strings = (char **)calloc(array_size, sizeof(char *));
+ if (recv_strings == NULL) {
+ TRACE_STRERROR("check memory size:%d", array_size);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ *length = 0;
+ } else {
+ // get strings.
+ for (; i < array_size; i++) {
+ size_t string_length = 0;
+ errorcode = __dp_ipc_response(sock, id, section, property, &string_length);
+ recv_strings[i] = NULL;
+ if (errorcode == DP_ERROR_NONE && string_length > 0) {
+ char *recv_str = (char *)calloc((string_length + (size_t)1), sizeof(char));
+ if (recv_str == NULL) {
+ TRACE_STRERROR("check memory length:%d", string_length * sizeof(char));
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ break;
+ } else {
+ if (dp_ipc_read(sock, recv_str, string_length, __FUNCTION__) <= 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ free(recv_str);
+ } else {
+ recv_str[string_length] = '\0';
+ recv_strings[i] = recv_str;
+ }
+ }
+ }
+ }
+ *fields = recv_strings;
+ }
+ if (errorcode != DP_ERROR_NONE) { // if error, free all allocated memories
+ int j = 0;
+ for (; j < i; j++) {
+ free(recv_strings[j]);
+ }
+ free(recv_strings);
+ *length = 0;
+ *fields = NULL;
+ if (errorcode != DP_ERROR_IO_ERROR)
+ __bp_disconnect(__FUNCTION__); // clear IPC, can not expect the size of futher packets
+ }
+ *length = i;
+ }
+ }
+ } else {
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ }
+
+
+ }
+ if (errorcode == DP_ERROR_IO_ERROR)
+ __bp_disconnect(__FUNCTION__);
+ CLIENT_MUTEX_UNLOCK(&g_function_mutex);
+ return __dp_interface_convert_errorcode(errorcode);
}
-int dp_interface_get_notification_type(const int id, int *type)
+int dp_interface_remove_http_header_field(const int id,
+ const char *field)
{
- return __dp_interface_get_int(id, DP_CMD_GET_NOTIFICATION_TYPE, type);
+ return __dp_ipc_set_string(id, DP_SEC_UNSET, DP_PROP_HTTP_HEADER, field, __FUNCTION__);
}
diff --git a/provider-interface/download-provider-interface.pc.in b/provider-interface/download-provider-interface.pc.in
index b6e579c..35e1cc9 100644
--- a/provider-interface/download-provider-interface.pc.in
+++ b/provider-interface/download-provider-interface.pc.in
@@ -4,5 +4,5 @@ Name: @PROJECT_NAME@
Description: @PACKAGE_DESCRIPTION@
Version: @VERSION@
Requires: @PC_REQUIRED@
-Libs: -L@LIB_INSTALL_DIR@ -l@PROJECT_NAME@
+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
index eb96e19..e9d3d59 100755
--- a/provider-interface/include/download-provider-interface.h
+++ b/provider-interface/include/download-provider-interface.h
@@ -22,7 +22,6 @@
#endif
#include <tizen.h>
-#include <bundle.h>
#ifdef __cplusplus
extern "C"
@@ -58,25 +57,27 @@ typedef enum
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_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
- 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_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */
+ DOWNLOAD_ADAPTOR_ERROR_INVALID_STATE = TIZEN_ERROR_DOWNLOAD | 0x21, /**< Invalid state */
+ DOWNLOAD_ADAPTOR_ERROR_CONNECTION_FAILED = TIZEN_ERROR_DOWNLOAD | 0x22, /**< Connection failed */
+ DOWNLOAD_ADAPTOR_ERROR_INVALID_URL = TIZEN_ERROR_DOWNLOAD | 0x24, /**< Invalid URL */
+ DOWNLOAD_ADAPTOR_ERROR_INVALID_DESTINATION = TIZEN_ERROR_DOWNLOAD | 0x25, /**< Invalid destination */
+ DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_DOWNLOADS = TIZEN_ERROR_DOWNLOAD | 0x26, /**< Full of available simultaneous downloads */
+ DOWNLOAD_ADAPTOR_ERROR_QUEUE_FULL = TIZEN_ERROR_DOWNLOAD | 0x27, /**< Full of available downloading items from server*/
+ DOWNLOAD_ADAPTOR_ERROR_ALREADY_COMPLETED = TIZEN_ERROR_DOWNLOAD | 0x28, /**< The download is already completed */
+ DOWNLOAD_ADAPTOR_ERROR_FILE_ALREADY_EXISTS = TIZEN_ERROR_DOWNLOAD | 0x29, /**< It is failed to rename the downloaded file */
+ DOWNLOAD_ADAPTOR_ERROR_CANNOT_RESUME = TIZEN_ERROR_DOWNLOAD | 0x2a, /**< It cannot resume */
+ DOWNLOAD_ADAPTOR_ERROR_FIELD_NOT_FOUND = TIZEN_ERROR_DOWNLOAD | 0x2b, /**< Specified field not found */
+ DOWNLOAD_ADAPTOR_ERROR_TOO_MANY_REDIRECTS = TIZEN_ERROR_DOWNLOAD | 0x30, /**< In case of too may redirects from http response header*/
+ DOWNLOAD_ADAPTOR_ERROR_UNHANDLED_HTTP_CODE = TIZEN_ERROR_DOWNLOAD | 0x31, /**< The download cannot handle the http status value */
+ DOWNLOAD_ADAPTOR_ERROR_REQUEST_TIMEOUT = TIZEN_ERROR_DOWNLOAD | 0x32, /**< There are no action after client create a download id*/
+ DOWNLOAD_ADAPTOR_ERROR_RESPONSE_TIMEOUT = TIZEN_ERROR_DOWNLOAD | 0x33, /**< It does not call start API in some time although the download is created*/
+ DOWNLOAD_ADAPTOR_ERROR_SYSTEM_DOWN = TIZEN_ERROR_DOWNLOAD | 0x34, /**< There are no response from client after rebooting download daemon*/
+ DOWNLOAD_ADAPTOR_ERROR_ID_NOT_FOUND = TIZEN_ERROR_DOWNLOAD | 0x35, /**< The download id is not existed in download service module*/
+ DOWNLOAD_ADAPTOR_ERROR_INVALID_NETWORK_TYPE = TIZEN_ERROR_DOWNLOAD | 0x36, /**< error when setting network bonding and network all is not set */
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_IO_ERROR = TIZEN_ERROR_IO_ERROR /**< Internal I/O error */
} download_adaptor_error_e;
// sync types with url-download..
@@ -98,40 +99,37 @@ 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_destination(const int id, const char *path);
+EXPORT_API int dp_interface_set_file_name(const int id, const char *file_name);
EXPORT_API int dp_interface_set_network_type(const int id, int net_type);
+EXPORT_API int dp_interface_set_network_bonding(const int id, int enable);
+EXPORT_API int dp_interface_set_auto_download(const int id, int enable);
+EXPORT_API int dp_interface_get_url(const int id, char **url);
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_network_bonding(const int id, int *enable);
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_get_http_header_field_list(const int id, char ***fields, int *length);
-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);
+EXPORT_API int dp_interface_get_etag(const int id, char **etag);
+EXPORT_API int dp_interface_set_temp_file_path(const int id, const char *path);
-// 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);
+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_get_http_header_field_list(const int id, char ***fields, int *length);
+EXPORT_API int dp_interface_remove_http_header_field(const int id, const char *field);
-EXPORT_API int dp_interface_set_notification_bundle(const int id, int type, bundle *b);
-EXPORT_API int dp_interface_get_notification_bundle(const int id, int type, bundle **b);
+EXPORT_API int dp_interface_set_notification_bundle(const int id, const int type, void *bundle_param);
+EXPORT_API int dp_interface_get_notification_bundle(const int id, const int type, void **bundle_param);
+EXPORT_API int dp_interface_set_notification_service_handle(const int id, const int type, void *handle);
+EXPORT_API int dp_interface_get_notification_service_handle(const int id, const int type, void **handle);
EXPORT_API int dp_interface_set_notification_title(const int id, const char *title);
EXPORT_API int dp_interface_get_notification_title(const int id, char **title);
EXPORT_API int dp_interface_set_notification_description(const int id, const char *description);
diff --git a/provider/CMakeLists.txt b/provider/CMakeLists.txt
index be89a9d..0c59760 100755
--- a/provider/CMakeLists.txt
+++ b/provider/CMakeLists.txt
@@ -14,8 +14,7 @@ pkg_check_modules(dp2_pkgs REQUIRED glib-2.0
sqlite3
capi-appfw-app-manager
capi-network-connection
- wifi-direct
- notification
+ capi-content-mime-type
appsvc
bundle
libsmack
@@ -26,6 +25,46 @@ FOREACH(flag ${dp2_pkgs_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
+IF(SUPPORT_WIFI_DIRECT)
+MESSAGE("WIFI direct:On")
+pkg_check_modules(dp2_wifi_direct_pkgs REQUIRED
+ capi-network-wifi-direct)
+FOREACH(flag ${dp2_wifi_direct_pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+ELSE (SUPPORT_WIFI_DIRECT)
+MESSAGE("WIFI direct:Off")
+ENDIF(SUPPORT_WIFI_DIRECT)
+
+IF(SUPPORT_SECURITY_PRIVILEGE)
+pkg_check_modules(dp2_security_privilege_pkgs REQUIRED security-server)
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${dp2_security_privilege_pkgs_CFLAGS}")
+ENDIF(SUPPORT_SECURITY_PRIVILEGE)
+
+IF(SUPPORT_NOTIFICATION)
+MESSAGE("Notification:On")
+pkg_check_modules(dp2_noti_pkgs REQUIRED
+ notification)
+FOREACH(flag ${dp2_noti_pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+ADD_DEFINITIONS(-DSUPPORT_NOTIFICATION)
+ELSE (SUPPORT_NOTIFICATION)
+MESSAGE("Notification:Off")
+ENDIF(SUPPORT_NOTIFICATION)
+
+IF(SUPPORT_COMPANION_MODE)
+MESSAGE("Companion:On")
+pkg_check_modules(dp2_companion_pkgs REQUIRED
+ sap-client-stub-api)
+FOREACH(flag ${dp2_companion_pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+ADD_DEFINITIONS(-DSUPPORT_COMPANION_MODE)
+ELSE (SUPPORT_COMPANION_MODE)
+MESSAGE("Companion:Off")
+ENDIF(SUPPORT_COMPANION_MODE)
+
## INCLUDES
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/agent/include)
@@ -38,37 +77,46 @@ set(DP2_LINK_LIBRARIES ${GLIB-2_LIBRARIES}
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -Wall")
-IF(DEFINED DATABASE_FILE)
- ADD_DEFINITIONS(-DDATABASE_FILE=\"${DATABASE_FILE}\")
-ENDIF(DEFINED DATABASE_FILE)
-
-IF(DEFINED DATABASE_SCHEMA_FILE)
- ADD_DEFINITIONS(-DDATABASE_SCHEMA_FILE=\"${DATABASE_SCHEMA_FILE}\")
-ENDIF(DEFINED DATABASE_SCHEMA_FILE)
-
IF(DEFINED IMAGE_DIR)
ADD_DEFINITIONS(-DIMAGE_DIR=\"${IMAGE_DIR}\")
ENDIF(DEFINED IMAGE_DIR)
+IF(DEFINED PROVIDER_DIR)
+ ADD_DEFINITIONS(-DPROVIDER_DIR=\"${PROVIDER_DIR}\")
+ENDIF(DEFINED PROVIDER_DIR)
+
+IF(DEFINED DATABASE_CLIENT_DIR)
+ ADD_DEFINITIONS(-DDATABASE_CLIENT_DIR=\"${DATABASE_CLIENT_DIR}\")
+ENDIF(DEFINED DATABASE_CLIENT_DIR)
+
+IF(DEFINED DATABASE_DIR)
+ ADD_DEFINITIONS(-DDATABASE_DIR=\"${DATABASE_DIR}\")
+ENDIF(DEFINED DATABASE_DIR)
+
IF(DEFINED LOCALE_DIR)
ADD_DEFINITIONS(-DPKG_NAME=\"${PKG_NAME}\")
ADD_DEFINITIONS(-DLOCALE_DIR=\"${LOCALE_DIR}\")
ENDIF(DEFINED LOCALE_DIR)
+ADD_DEFINITIONS(-DDOWNLOAD_PROVIDER_LOG_TAG=\"DOWNLOAD_PROVIDER\")
ADD_EXECUTABLE(${PROJECT_NAME}
- ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-pid.c
- ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-socket.c
- ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-slots.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-pthread.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-ipc.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-utils.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-notify.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-smack.c
${CMAKE_CURRENT_SOURCE_DIR}/download-provider-network.c
${CMAKE_CURRENT_SOURCE_DIR}/download-provider-db.c
- ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-request.c
- ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-da-interface.c
- ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-thread-request.c
- ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-thread-queue.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-plugin-download-agent.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-queue.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-queue-manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-client.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-client-manager.c
${CMAKE_CURRENT_SOURCE_DIR}/download-provider-notification.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/download-provider-notification-manager.c
${CMAKE_CURRENT_SOURCE_DIR}/download-provider-main.c )
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${dp2_pkgs_LDFLAGS} ${DP2_LINK_LIBRARIES} -ldl)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${dp2_pkgs_LDFLAGS} ${DP2_LINK_LIBRARIES} ${dp2_noti_pkgs_LDFLAGS} ${dp2_companion_pkgs_LDFLAGS} ${dp2_wifi_direct_pkgs_LDFLAGS} ${dp2_security_privilege_pkgs_LDFLAGS} -ldl)
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BIN_INSTALL_DIR})
-INSTALL(FILES include/download-provider-defs.h DESTINATION ${INCLUDE_INSTALL_DIR}/${PKG_NAME})
+INSTALL(FILES include/download-provider.h DESTINATION ${INCLUDE_INSTALL_DIR}/${PKG_NAME})
diff --git a/provider/download-provider-client-manager.c b/provider/download-provider-client-manager.c
new file mode 100644
index 0000000..28ecaf3
--- /dev/null
+++ b/provider/download-provider-client-manager.c
@@ -0,0 +1,741 @@
+/*
+ * 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 <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#include <app_manager.h>
+#include <systemd/sd-daemon.h>
+#include <glib-object.h>
+
+#include <download-provider.h>
+#include <download-provider-log.h>
+#include <download-provider-config.h>
+#include <download-provider-pthread.h>
+#include <download-provider-smack.h>
+#include <download-provider-client.h>
+#include <download-provider-notification.h>
+#include <download-provider-notification-manager.h>
+#include <download-provider-utils.h>
+#include <download-provider-ipc.h>
+#include <download-provider-notify.h>
+#include <download-provider-db-defs.h>
+#include <download-provider-db.h>
+#include <download-provider-queue-manager.h>
+#include <download-provider-client-manager.h>
+#include <download-provider-plugin-download-agent.h>
+#include <download-provider-network.h>
+
+int g_dp_sock = -1;
+dp_client_slots_fmt *g_dp_client_slots = NULL;
+static void *g_db_handle = 0;
+static pthread_mutex_t g_db_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void dp_terminate(int signo)
+{
+ TRACE_DEBUG("Received SIGTERM:%d", signo);
+ close(g_dp_sock);
+ g_dp_sock = -1;
+}
+
+void dp_broadcast_signal()
+{
+ TRACE_INFO("broadcast");
+ // announce to all thread for clients
+ // signo 10 : ip changed
+ if (g_dp_client_slots != NULL) {
+ int i = 0;
+ for (; i < DP_MAX_CLIENTS; i++) {
+ if (g_dp_client_slots[i].thread > 0 &&
+ pthread_kill(g_dp_client_slots[i].thread, 0) != ESRCH)
+ pthread_kill(g_dp_client_slots[i].thread, SIGUSR1);
+ }
+ }
+
+}
+
+char *dp_db_get_client_smack_label(const char *pkgname)
+{
+ char *smack_label = NULL;
+ unsigned length = 0;
+ int errorcode = DP_ERROR_NONE;
+
+ CLIENT_MUTEX_LOCK(&g_db_mutex);
+ if (dp_db_get_client_property_string(g_db_handle, pkgname, DP_DB_COL_SMACK_LABEL, (unsigned char **)&smack_label, &length, &errorcode) < 0) {
+ TRACE_SECURE_ERROR("failed to get smack label for %s", pkgname);
+ }
+ CLIENT_MUTEX_UNLOCK(&g_db_mutex);
+
+ return smack_label;
+}
+
+static int __dp_db_open_client_manager()
+{
+ CLIENT_MUTEX_LOCK(&g_db_mutex);
+ if (dp_db_open_client_manager(&g_db_handle) < 0) {
+ TRACE_ERROR("[CRITICAL] can not open SQL");
+ CLIENT_MUTEX_UNLOCK(&g_db_mutex);
+ return -1;
+ }
+ CLIENT_MUTEX_UNLOCK(&g_db_mutex);
+ return 0;
+}
+
+static void __dp_db_free_client_manager()
+{
+ CLIENT_MUTEX_LOCK(&g_db_mutex);
+ if (g_db_handle != 0) {
+ TRACE_SECURE_DEBUG("TRY to close [%s]", DP_DBFILE_CLIENTS);
+ dp_db_close(g_db_handle);
+ g_db_handle = 0;
+ }
+ CLIENT_MUTEX_UNLOCK(&g_db_mutex);
+}
+
+static int __dp_accept_socket_new()
+{
+ int fd_base, listen_fds = sd_listen_fds(1);
+ TRACE_DEBUG("sd_listen_fds:%d", listen_fds);
+ for (fd_base = 0 ; fd_base < listen_fds; fd_base++) {
+ if (sd_is_socket_unix(fd_base + SD_LISTEN_FDS_START, SOCK_STREAM, 1, IPC_SOCKET, 0) >= 0) {
+ TRACE_INFO("listen systemd socket:%d", fd_base + SD_LISTEN_FDS_START);
+ return fd_base + SD_LISTEN_FDS_START;
+ }
+ }
+ return -1;
+}
+
+int dp_client_slot_free(dp_client_slots_fmt *slot)
+{
+ if (slot->client.channel >= 0) {
+ close(slot->client.channel);
+ slot->client.channel = -1;
+ }
+ if (slot->client.dbhandle != 0) {
+ dp_db_close(slot->client.dbhandle);
+ slot->client.dbhandle = 0;
+ }
+ // free all requests
+ // remove notify fifo
+ if (slot->client.notify >= 0) {
+ close(slot->client.notify);
+ slot->client.notify = -1;
+ }
+ dp_notify_deinit(slot->credential.pid);
+ // kill thread
+ if (slot->thread != 0)
+ pthread_cancel(slot->thread);
+ slot->thread = 0;
+ if (slot->pkgname != NULL) {
+ TRACE_SECURE_DEBUG("TRY to close [%s]", slot->pkgname);
+ free(slot->pkgname);
+ slot->pkgname = NULL;
+ }
+ return 0;
+}
+
+// precondition : all slots are empty
+static int __dp_manage_client_requests(dp_client_slots_fmt *clients)
+{
+ int errorcode = DP_ERROR_NONE;
+ int i = 0;
+ int slot_index = 0;
+
+ dp_notification_manager_kill();
+ dp_queue_manager_kill();
+
+ // get all clients info from clients database.
+
+ int *ids = (int *)calloc(DP_MAX_CLIENTS, sizeof(int));
+ if (ids == NULL) {
+ TRACE_ERROR("failed to allocate the clients");
+ return -1;
+ }
+ // getting ids of clients
+ int rows_count = dp_db_get_ids(g_db_handle, DP_TABLE_CLIENTS, NULL, ids, NULL, DP_MAX_CLIENTS, DP_DB_COL_ACCESS_TIME, "ASC", &errorcode);
+ for (; i < rows_count; i++) {
+ char *pkgname = NULL;
+ unsigned length = 0;
+ errorcode = DP_ERROR_NONE;
+ if (dp_db_get_property_string(g_db_handle, ids[i], DP_TABLE_CLIENTS, DP_DB_COL_PACKAGE, (unsigned char **)&pkgname, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get pkgname for id:%d", ids[i]);
+ continue;
+ }
+
+ if (pkgname != NULL) {
+ if (dp_db_remove_database(pkgname, time(NULL), DP_CARE_CLIENT_INFO_PERIOD * 3600) == 0) { // old database
+ // remove info from client database;
+ if (dp_db_delete(g_db_handle, ids[i], DP_TABLE_CLIENTS, &errorcode) == 0) {
+ TRACE_SECURE_ERROR("clear info for %s", pkgname);
+ // remove database file
+ }
+ TRACE_SECURE_INFO("remove database for %s", pkgname);
+ free(pkgname);
+ continue;
+ }
+
+ dp_credential credential;
+ credential.pid = 0;
+ if (dp_db_get_property_int(g_db_handle, ids[i], DP_TABLE_CLIENTS, DP_DB_COL_UID, &credential.uid, &errorcode) < 0 ||
+ dp_db_get_property_int(g_db_handle, ids[i], DP_TABLE_CLIENTS, DP_DB_COL_GID, &credential.gid, &errorcode) < 0) {
+ TRACE_SECURE_ERROR("failed to get credential for %s", pkgname);
+ free(pkgname);
+ continue;
+ }
+ if (dp_mutex_init(&clients[slot_index].mutex, NULL) != 0) {
+ TRACE_SECURE_ERROR("failed to initialize mutex for %s", pkgname);
+ free(pkgname);
+ continue;
+ }
+ // open database of a clients
+ if (dp_db_open_client_v2(&clients[slot_index].client.dbhandle, pkgname) < 0) {
+ TRACE_SECURE_ERROR("failed to open database for %s", pkgname);
+ // remove this client from clients database
+ if (dp_db_delete(g_db_handle, ids[i], DP_TABLE_CLIENTS, &errorcode) == 0) {
+ TRACE_SECURE_ERROR("clear info for %s", pkgname);
+ // remove database file
+ if (dp_db_remove_database(pkgname, time(NULL), 0) == 0) {
+ TRACE_SECURE_INFO("remove database for %s", pkgname);
+ } else {
+ TRACE_SECURE_ERROR("failed to remove database for %s", pkgname);
+ }
+ }
+ free(pkgname);
+ continue;
+ }
+
+ // get ids if state is QUEUED, CONNECTING or DOWNLOADING with auto_download
+ int *request_ids = (int *)calloc(DP_MAX_REQUEST, sizeof(int));
+ if (request_ids == NULL) {
+ TRACE_SECURE_ERROR("failed to allocate the requests for %s", pkgname);
+ free(pkgname);
+ continue;
+ }
+ int request_count = dp_db_get_crashed_ids(clients[slot_index].client.dbhandle, DP_TABLE_LOGGING, request_ids, DP_MAX_REQUEST, &errorcode);
+ TRACE_DEBUG("client: %s requests:%d", pkgname, request_count);
+ int ids_i = 0;
+ if (request_count > 0) {
+ clients[slot_index].pkgname = pkgname;
+ clients[slot_index].client.channel = -1;
+ clients[slot_index].client.notify = -1;
+ clients[slot_index].credential.pid = credential.pid;
+ clients[slot_index].credential.uid = credential.uid;
+ clients[slot_index].credential.gid = credential.gid;
+ for (ids_i = 0; ids_i < request_count; ids_i++) {
+ // loading requests from client's database... attach to client.requests
+ dp_request_fmt *request = (dp_request_fmt *) calloc(1, sizeof(dp_request_fmt));
+ if (request == NULL) {
+ TRACE_ERROR("check memory download-id:%d", request_ids[ids_i]);
+ break;
+ }
+ request->id = request_ids[ids_i];
+ request->agent_id = -1;
+ request->state = DP_STATE_QUEUED;
+ request->error = DP_ERROR_NONE;
+ if (dp_db_get_property_int(clients[slot_index].client.dbhandle, request->id, DP_TABLE_REQUEST, DP_DB_COL_NETWORK_TYPE, &request->network_type, &errorcode) < 0) {
+ TRACE_ERROR("failed to get network type for id:%d", request->id);
+ request->network_type = DP_NETWORK_WIFI;
+ }
+ request->access_time = (int)time(NULL);
+ request->state_cb = 0;
+ request->progress_cb = 0;
+ if (dp_db_get_property_int(clients[slot_index].client.dbhandle, request->id, DP_TABLE_LOGGING, DP_DB_COL_STARTCOUNT, &request->startcount, &errorcode) < 0) {
+ TRACE_ERROR("failed to get start count for id:%d", request->id);
+ request->startcount = 0;
+ }
+ request->startcount++;
+ request->noti_type = DP_NOTIFICATION_TYPE_NONE;
+ if (dp_db_get_property_int(clients[slot_index].client.dbhandle, request->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE, &request->noti_type, &errorcode) < 0) {
+ TRACE_ERROR("failed to get notification type for id:%d", request->id);
+ }
+ if (request->noti_type == DP_NOTIFICATION_TYPE_NONE) {
+ TRACE_INFO("enable notification for id:%d", request->id);
+ request->noti_type = DP_NOTIFICATION_TYPE_COMPLETE_ONLY;
+ }
+ request->progress_lasttime = 0;
+ request->received_size = 0; // ?
+ request->content_type = DP_CONTENT_UNKNOWN;
+ request->file_size = 0; // ?
+ if (dp_db_get_property_int(clients[slot_index].client.dbhandle, request->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_PRIV_ID, &request->noti_priv_id, &errorcode) < 0) {
+ TRACE_ERROR("failed to get notification noti_priv_id for id:%d", request->id);
+ request->noti_priv_id = -1;
+ }
+
+ dp_request_create(&clients[slot_index].client, request);
+
+ if (dp_db_update_logging(clients[slot_index].client.dbhandle, request->id, DP_STATE_QUEUED, DP_ERROR_NONE, &errorcode) < 0) {
+ TRACE_ERROR("update log download-id:%d", request->id);
+ errorcode = DP_ERROR_DISK_BUSY;
+ break;
+ }
+ if (dp_queue_manager_push_queue((void *)&clients[slot_index], (void *)request) < 0) {
+ errorcode = DP_ERROR_QUEUE_FULL;
+ TRACE_INFO("failed to push to queue for id:%d", request->id);
+ dp_request_destroy(&(clients[slot_index].client), NULL, request);
+ break;
+ }
+ // notification
+ if (dp_notification_manager_push_notification((void *)&clients[slot_index], (void *)request, DP_NOTIFICATION_ONGOING) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", request->id);
+ }
+
+ }
+
+ slot_index++;
+
+ } else {
+ free(pkgname);
+ }
+ free(request_ids);
+ }
+ }
+ free(ids);
+ TRACE_DEBUG("slot_index:%d", slot_index);
+ if (slot_index > 0)
+ dp_queue_manager_wake_up();
+ return slot_index;
+}
+
+static int __dp_client_run(int clientfd, dp_client_slots_fmt *slot,
+ dp_credential credential)
+{
+ int errorcode = DP_ERROR_NONE;
+ // make notify fifo
+ slot->client.notify = dp_notify_init(credential.pid);
+ if (slot->client.notify < 0) {
+ TRACE_STRERROR("failed to open fifo slot:%d", clientfd);
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ char *smack_label = NULL;
+ if (dp_smack_is_mounted() == 1) {
+ smack_label = dp_smack_get_label_from_socket(clientfd);
+ if (smack_label == NULL) {
+ TRACE_SECURE_ERROR("smack_new_label_from_socket");
+ }
+ }
+ // save client info to database
+ CLIENT_MUTEX_LOCK(&g_db_mutex);
+ if (dp_db_update_client_info(g_db_handle,
+ slot->pkgname, smack_label,
+ credential.uid, credential.gid, &errorcode) < 0) {
+ TRACE_ERROR("check error:%s", dp_print_errorcode(errorcode));
+ }
+ CLIENT_MUTEX_UNLOCK(&g_db_mutex);
+ free(smack_label);
+ }
+ if (errorcode == DP_ERROR_NONE) {
+
+ // create a thread for client
+ if (pthread_create(&slot->thread, NULL,
+ dp_client_request_thread, (void *)slot) != 0) {
+ TRACE_ERROR("failed to create client thread slot:%d", clientfd);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ slot->thread = 0;
+ dp_client_slot_free(slot); // => make pkgname as NULL
+ } else {
+ pthread_detach(slot->thread);
+ TRACE_SECURE_INFO("accept client[%s] pid:%d sock:%d",
+ slot->pkgname, credential.pid, clientfd);
+ slot->client.channel = clientfd;
+ slot->credential.pid = credential.pid;
+ slot->credential.uid = credential.uid;
+ slot->credential.gid = credential.gid;
+ }
+ }
+ return errorcode;
+}
+
+
+static int __dp_client_new(int clientfd, dp_client_slots_fmt *clients,
+ dp_credential credential)
+{
+ // search in clients list.
+ // if same pkgname. update it.
+ // search same pkg or pid in clients
+ int errorcode = DP_ERROR_NONE;
+ int i = 0;
+ int pkg_len = 0;
+ char *pkgname = NULL;
+
+ // getting the package name via pid
+ if (app_manager_get_package(credential.pid, &pkgname) !=
+ APP_MANAGER_ERROR_NONE)
+ TRACE_ERROR("[CRITICAL] app_manager_get_package");
+
+ //// TEST CODE ... to allow sample client ( no package name ).
+ if (pkgname == NULL) {
+ //pkgname = dp_strdup("unknown_app");
+ char *temp_pkgname = (char *)calloc(41, sizeof(char));
+ if (temp_pkgname == NULL ||
+ snprintf(temp_pkgname, 41,"unknown_app_%d", credential.pid) < 0) {
+ pkgname = dp_strdup("unknown_app");
+ } else {
+ pkgname = temp_pkgname;
+ }
+ }
+
+ if (pkgname == NULL) {
+ TRACE_ERROR("[CRITICAL] app_manager_get_package");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+ if ((pkg_len = strlen(pkgname)) <= 0) {
+ TRACE_ERROR("[CRITICAL] pkgname:%s", pkgname);
+ free(pkgname);
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+
+#ifdef SUPPORT_SECURITY_PRIVILEGE
+ int result = security_server_check_privilege_by_sockfd(clientfd, SECURITY_PRIVILEGE_INTERNET, "w");
+ if (result != SECURITY_SERVER_API_SUCCESS) {
+ TRACE_ERROR("check privilege permission:%d", result);
+ return DP_ERROR_PERMISSION_DENIED;
+ }
+#endif
+
+ // EINVAL: empty slot
+ // EBUSY : occupied slot
+ // locked & thread == 0 : downloading without client <= check target
+ // thread == 0, requests == NULL : clear target
+
+ // Have this client ever been connected before ?
+ for (i = 0; i < DP_MAX_CLIENTS; i++) {
+
+ int locked = CLIENT_MUTEX_TRYLOCK(&clients[i].mutex);
+ if (locked != 0) { // empty or used by other thread. it would be same client, but it's busy
+ continue;
+ }
+ TRACE_DEBUG("locked slot:%d", i);
+ if (locked == 0 && clients[i].thread == 0) { // this slot has run without the client
+ if (clients[i].pkgname != NULL) {
+ // check package name.
+ TRACE_DEBUG("check client[%s] slot:%d", clients[i].pkgname, i);
+ int cname_len = strlen(clients[i].pkgname);
+ if (pkg_len == cname_len &&
+ strncmp(clients[i].pkgname, pkgname, pkg_len) == 0) {
+ TRACE_SECURE_INFO("update client[%s] slot:%d pid:%d sock:%d",
+ pkgname, i, credential.pid, clientfd);
+ if (clients[i].client.channel >= 0 &&
+ clients[i].client.channel != clientfd) {
+ dp_ipc_socket_free(clients[i].client.channel);
+ if (clients[i].client.notify >= 0)
+ close(clients[i].client.notify);
+ dp_notify_deinit(clients[i].credential.pid);
+ }
+ errorcode = __dp_client_run(clientfd, &clients[i], credential);
+ CLIENT_MUTEX_UNLOCK(&clients[i].mutex);
+ if (errorcode != DP_ERROR_NONE)
+ dp_mutex_destroy(&clients[i].mutex);
+ free(pkgname);
+ return errorcode;
+ }
+ }
+ if (clients[i].client.requests == NULL) { // clear
+ dp_client_slot_free(&clients[i]);
+ dp_mutex_destroy(&clients[i].mutex);
+ continue;
+ }
+ }
+ CLIENT_MUTEX_UNLOCK(&clients[i].mutex);
+ }
+
+ TRACE_DEBUG("search empty client[%s] slot:%d", pkgname, i);
+ // search empty slot
+ for (i = 0; i < DP_MAX_CLIENTS; i++) {
+ int locked = CLIENT_MUTEX_TRYLOCK(&clients[i].mutex);
+ if (locked == EINVAL) {
+ if (dp_mutex_init(&clients[i].mutex, NULL) == 0) {
+ CLIENT_MUTEX_LOCK(&clients[i].mutex);
+ TRACE_DEBUG("found empty client[%s] slot:%d", pkgname, i);
+ clients[i].pkgname = pkgname;
+ clients[i].client.dbhandle = 0;
+ clients[i].client.requests = NULL;
+ errorcode = __dp_client_run(clientfd, &clients[i], credential);
+ CLIENT_MUTEX_UNLOCK(&clients[i].mutex);
+ if (errorcode != DP_ERROR_NONE)
+ dp_mutex_destroy(&clients[i].mutex);
+ return errorcode;
+ }
+ }
+ if (locked == 0)
+ CLIENT_MUTEX_UNLOCK(&clients[i].mutex);
+ }
+
+ TRACE_SECURE_INFO("busy client[%s] pid:%d sock:%d", pkgname,
+ credential.pid, clientfd);
+ free(pkgname);
+ return DP_ERROR_TOO_MANY_DOWNLOADS;
+}
+
+void *dp_client_manager(void *arg)
+{
+ fd_set rset, eset, listen_fdset, except_fdset;
+ struct timeval timeout; // for timeout of select
+ socklen_t clientlen;
+ struct sockaddr_un clientaddr;
+ dp_credential credential;
+ unsigned i;
+ int errorcode = DP_ERROR_NONE;
+ GMainLoop *event_loop = (GMainLoop *)arg;
+
+ g_dp_sock = __dp_accept_socket_new();
+ if (g_dp_sock < 0) {
+ TRACE_STRERROR("failed to open listen socket");
+ g_main_loop_quit(event_loop);
+ return 0;
+ }
+
+ if (signal(SIGTERM, dp_terminate) == SIG_ERR ||
+ signal(SIGPIPE, SIG_IGN) == SIG_ERR ||
+ signal(SIGINT, dp_terminate) == SIG_ERR) {
+ TRACE_ERROR("failed to register signal callback");
+ g_main_loop_quit(event_loop);
+ return 0;
+ }
+
+ dp_notification_clear_ongoings();
+
+#ifdef PROVIDER_DIR
+ dp_rebuild_dir(PROVIDER_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+#endif
+#ifdef DATABASE_DIR
+ dp_rebuild_dir(DATABASE_DIR, S_IRWXU);
+#endif
+#ifdef DATABASE_CLIENT_DIR
+ dp_rebuild_dir(DATABASE_CLIENT_DIR, S_IRWXU);
+#endif
+#ifdef NOTIFY_DIR
+ dp_rebuild_dir(NOTIFY_DIR, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+#endif
+
+ if (__dp_db_open_client_manager() < 0) {
+ TRACE_STRERROR("failed to open database for client-manager");
+ g_main_loop_quit(event_loop);
+ return 0;
+ }
+
+ dp_client_slots_fmt *clients =
+ (dp_client_slots_fmt *)calloc(DP_MAX_CLIENTS,
+ sizeof(dp_client_slots_fmt));
+ if (clients == NULL) {
+ TRACE_ERROR("failed to allocate client slots");
+ g_main_loop_quit(event_loop);
+ return 0;
+ }
+ g_dp_client_slots = clients;
+ for (i = 0; i < DP_MAX_CLIENTS; i++) {
+ dp_mutex_destroy(&clients[i].mutex); // clear mutex init
+ }
+
+ int maxfd = g_dp_sock;
+ FD_ZERO(&listen_fdset);
+ FD_ZERO(&except_fdset);
+ FD_SET(g_dp_sock, &listen_fdset);
+ FD_SET(g_dp_sock, &except_fdset);
+
+ while (g_dp_sock >= 0) {
+
+ int clientfd = -1;
+
+ // initialize timeout structure for calling timeout exactly
+ memset(&timeout, 0x00, sizeof(struct timeval));
+ timeout.tv_sec = DP_CARE_CLIENT_MANAGER_INTERVAL;
+ credential.pid = -1;
+ credential.uid = -1;
+ credential.gid = -1;
+
+ rset = listen_fdset;
+ eset = except_fdset;
+
+ if (select((maxfd + 1), &rset, 0, &eset, &timeout) < 0) {
+ TRACE_STRERROR("interrupted by terminating");
+ break;
+ }
+
+ if (g_dp_sock < 0) {
+ TRACE_DEBUG("queue-manager is closed by other thread");
+ break;
+ }
+
+ if (FD_ISSET(g_dp_sock, &eset) > 0) {
+ TRACE_STRERROR("exception of socket");
+ break;
+ } else if (FD_ISSET(g_dp_sock, &rset) > 0) {
+
+ // Anyway accept client.
+ clientlen = sizeof(clientaddr);
+ clientfd = accept(g_dp_sock, (struct sockaddr *)&clientaddr,
+ &clientlen);
+ if (clientfd < 0) {
+ TRACE_STRERROR("too many client ? accept failure");
+ // provider need the time of refresh.
+ break;
+ }
+
+ // blocking & timeout to prevent the lockup by client.
+ struct timeval tv_timeo = {1, 500000}; // 1.5 sec
+ if (setsockopt(clientfd, SOL_SOCKET, SO_RCVTIMEO, &tv_timeo,
+ sizeof(tv_timeo)) < 0) {
+ TRACE_ERROR("failed to set timeout in blocking socket");
+ close(clientfd);
+ continue;
+ }
+
+ dp_ipc_fmt ipc_info;
+ memset(&ipc_info, 0x00, sizeof(dp_ipc_fmt));
+ if (read(clientfd, &ipc_info, sizeof(dp_ipc_fmt)) <= 0 ||
+ ipc_info.section == DP_SEC_NONE ||
+ ipc_info.property != DP_PROP_NONE ||
+ ipc_info.id != -1 ||
+ ipc_info.size != 0) {
+ TRACE_ERROR("peer terminate ? ignore this connection");
+ close(clientfd);
+ continue;
+ }
+
+#ifdef SO_PEERCRED // getting the info of client
+ socklen_t cr_len = sizeof(credential);
+ if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED,
+ &credential, &cr_len) < 0) {
+ TRACE_ERROR("failed to cred from sock:%d", clientfd);
+ close(clientfd);
+ continue;
+ }
+#else // In case of not supported SO_PEERCRED
+ if (read(clientfd, &credential, sizeof(dp_credential)) <= 0) {
+ TRACE_ERROR("failed to cred from client:%d", clientfd);
+ close(clientfd);
+ continue;
+ }
+#endif
+
+ CLIENT_MUTEX_LOCK(&g_db_mutex);
+ if (dp_db_check_connection(g_db_handle) < 0) {
+ TRACE_ERROR("check database, provider can't work anymore");
+ CLIENT_MUTEX_UNLOCK(&g_db_mutex);
+ close(clientfd);
+ break;
+ }
+ CLIENT_MUTEX_UNLOCK(&g_db_mutex);
+
+ if (ipc_info.section == DP_SEC_INIT) {
+
+ // new client
+ errorcode = __dp_client_new(clientfd, clients, credential);
+
+ } else {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ }
+ if (dp_ipc_query(clientfd, -1, DP_SEC_INIT, DP_PROP_NONE, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", clientfd);
+ }
+ if (errorcode == DP_ERROR_NONE) {
+ // write client info into database
+
+ } else {
+ TRACE_ERROR("sock:%d id:%d section:%s property:%s errorcode:%s size:%d",
+ clientfd, ipc_info.id,
+ dp_print_section(ipc_info.section),
+ dp_print_property(ipc_info.property),
+ dp_print_errorcode(ipc_info.errorcode),
+ ipc_info.size);
+ close(clientfd); // ban this client
+ }
+
+ } else {
+
+ // take care zombie client, slots
+ unsigned connected_clients = 0;
+ int i = 0;
+ for (; i < DP_MAX_CLIENTS; i++) {
+
+ int locked = CLIENT_MUTEX_TRYLOCK(&clients[i].mutex);
+ if (locked == EINVAL) { // not initialized
+ continue;
+ } else if (locked == EBUSY) { // already locked
+ connected_clients++;
+ continue;
+ }
+
+ if (locked == 0) { // locked
+
+ // if no client thread, requests should be checked here
+ // if no queued, connecting or downloading, close the slot
+ if (clients[i].pkgname != NULL) {
+ if (clients[i].thread == 0) {
+ dp_client_clear_requests(&clients[i]);
+ if (clients[i].client.requests == NULL) {
+ dp_client_slot_free(&clients[i]);
+ CLIENT_MUTEX_UNLOCK(&clients[i].mutex);
+ dp_mutex_destroy(&clients[i].mutex);
+ continue;
+ }
+ }
+ connected_clients++;
+ }
+ CLIENT_MUTEX_UNLOCK(&clients[i].mutex);
+ }
+ }
+ TRACE_DEBUG("%d clients are active now", connected_clients);
+ // terminating download-provider if no clients.
+ if (connected_clients == 0) {
+ if (__dp_manage_client_requests(clients) <= 0) // if no crashed job
+ break;
+ } else {
+ dp_queue_manager_wake_up();
+ dp_notification_manager_wake_up();
+ }
+ }
+
+ }
+ if (g_dp_sock >= 0)
+ close(g_dp_sock);
+ g_dp_sock = -1;
+
+ dp_queue_manager_kill();
+ dp_notification_clear_ongoings();
+ dp_notification_manager_kill();
+
+ __dp_db_free_client_manager();
+
+ // kill other clients
+ TRACE_DEBUG("try to deallocate the resources for all clients");
+ for (i = 0; i < DP_MAX_CLIENTS; i++) {
+ int locked = CLIENT_MUTEX_TRYLOCK(&clients[i].mutex);
+ if (locked == EBUSY) { // already locked
+ CLIENT_MUTEX_LOCK(&clients[i].mutex);
+ } else if (locked == EINVAL) { // not initialized, empty slot
+ continue;
+ }
+ dp_client_slot_free(&clients[i]);
+ CLIENT_MUTEX_UNLOCK(&clients[i].mutex);
+ dp_mutex_destroy(&clients[i].mutex);
+ }
+ free(clients);
+ // free all resources
+
+ TRACE_INFO("client-manager's working is done");
+ g_main_loop_quit(event_loop);
+ return 0;
+}
diff --git a/provider/download-provider-client.c b/provider/download-provider-client.c
new file mode 100644
index 0000000..53c5909
--- /dev/null
+++ b/provider/download-provider-client.c
@@ -0,0 +1,2110 @@
+/*
+ * 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 <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include <download-provider-log.h>
+#include <download-provider-config.h>
+#include <download-provider-ipc.h>
+#include <download-provider-network.h>
+#include <download-provider-client.h>
+#include <download-provider-pthread.h>
+#include <download-provider-notify.h>
+#include <download-provider-notification-manager.h>
+#include <download-provider-queue-manager.h>
+#include <download-provider-client-manager.h>
+#include <download-provider-db-defs.h>
+#include <download-provider-db.h>
+#include <download-provider-plugin-download-agent.h>
+#include <download-provider-smack.h>
+
+char *dp_print_state(int state)
+{
+ switch(state)
+ {
+ case DP_STATE_NONE :
+ return "NONE";
+ case DP_STATE_READY :
+ return "READY";
+ case DP_STATE_QUEUED :
+ return "QUEUED";
+ case DP_STATE_CONNECTING :
+ return "CONNECTING";
+ case DP_STATE_DOWNLOADING :
+ return "DOWNLOADING";
+ case DP_STATE_PAUSED :
+ return "PAUSED";
+ case DP_STATE_COMPLETED :
+ return "COMPLETED";
+ case DP_STATE_CANCELED :
+ return "CANCELED";
+ case DP_STATE_FAILED :
+ return "FAILED";
+ default :
+ break;
+ }
+ return "UNKNOWN";
+}
+
+char *dp_print_errorcode(int errorcode)
+{
+ switch(errorcode)
+ {
+ case DP_ERROR_NONE :
+ return "NONE";
+ case DP_ERROR_INVALID_PARAMETER :
+ return "INVALID_PARAMETER";
+ case DP_ERROR_OUT_OF_MEMORY :
+ return "OUT_OF_MEMORY";
+ case DP_ERROR_IO_ERROR :
+ return "IO_ERROR";
+ case DP_ERROR_NETWORK_UNREACHABLE :
+ return "NETWORK_UNREACHABLE";
+ case DP_ERROR_CONNECTION_TIMED_OUT :
+ return "CONNECTION_TIMED_OUT";
+ case DP_ERROR_NO_SPACE :
+ return "NO_SPACE";
+ case DP_ERROR_FIELD_NOT_FOUND :
+ return "FIELD_NOT_FOUND";
+ case DP_ERROR_INVALID_STATE :
+ return "INVALID_STATE";
+ case DP_ERROR_CONNECTION_FAILED :
+ return "CONNECTION_FAILED";
+ case DP_ERROR_INVALID_URL :
+ return "INVALID_URL";
+ case DP_ERROR_INVALID_DESTINATION :
+ return "INVALID_DESTINATION";
+ case DP_ERROR_QUEUE_FULL :
+ return "QUEUE_FULL";
+ case DP_ERROR_ALREADY_COMPLETED :
+ return "ALREADY_COMPLETED";
+ case DP_ERROR_FILE_ALREADY_EXISTS :
+ return "FILE_ALREADY_EXISTS";
+ case DP_ERROR_TOO_MANY_DOWNLOADS :
+ return "TOO_MANY_DOWNLOADS";
+ case DP_ERROR_NO_DATA :
+ return "NO_DATA";
+ case DP_ERROR_UNHANDLED_HTTP_CODE :
+ return "UNHANDLED_HTTP_CODE";
+ case DP_ERROR_CANNOT_RESUME :
+ return "CANNOT_RESUME";
+ case DP_ERROR_PERMISSION_DENIED :
+ return "PERMISSION_DENIED";
+ case DP_ERROR_RESPONSE_TIMEOUT :
+ return "RESPONSE_TIMEOUT";
+ case DP_ERROR_REQUEST_TIMEOUT :
+ return "REQUEST_TIMEOUT";
+ case DP_ERROR_SYSTEM_DOWN :
+ return "SYSTEM_DOWN";
+ case DP_ERROR_CLIENT_DOWN :
+ return "CLIENT_DOWN";
+ case DP_ERROR_DISK_BUSY:
+ return "DISK_BUSY";
+ case DP_ERROR_ID_NOT_FOUND :
+ return "ID_NOT_FOUND";
+ default :
+ break;
+ }
+ return "UNKNOWN";
+}
+
+char *dp_print_section(short section)
+{
+ switch (section) {
+ case DP_SEC_NONE:
+ return "NONE";
+ case DP_SEC_INIT:
+ return "INIT";
+ case DP_SEC_DEINIT:
+ return "DEINIT";
+ case DP_SEC_CONTROL:
+ return "CONTROL";
+ case DP_SEC_GET:
+ return "GET";
+ case DP_SEC_SET:
+ return "SET";
+ case DP_SEC_UNSET:
+ return "UNSET";
+ default:
+ break;
+ }
+ return "UNKNOWN";
+}
+
+char *dp_print_property(unsigned property)
+{
+ switch (property) {
+ case DP_PROP_NONE:
+ return "NONE";
+ case DP_PROP_CREATE:
+ return "CREATE";
+ case DP_PROP_START:
+ return "START";
+ case DP_PROP_PAUSE:
+ return "PAUSE";
+ case DP_PROP_CANCEL:
+ return "CANCEL";
+ case DP_PROP_DESTROY:
+ return "DESTROY";
+ case DP_PROP_URL:
+ return "URL";
+ case DP_PROP_DESTINATION:
+ return "DESTINATION";
+ case DP_PROP_FILENAME:
+ return "FILENAME";
+ case DP_PROP_STATE_CALLBACK:
+ return "STATE_CB";
+ case DP_PROP_PROGRESS_CALLBACK:
+ return "PROGRESS_CB";
+ case DP_PROP_AUTO_DOWNLOAD:
+ return "AUTO_DOWNLOAD";
+ case DP_PROP_NETWORK_TYPE:
+ return "NETWORK_TYPE";
+ case DP_PROP_NETWORK_BONDING:
+ return "NETWORK_BONDING";
+ case DP_PROP_SAVED_PATH:
+ return "SAVED_PATH";
+ case DP_PROP_TEMP_SAVED_PATH:
+ return "TEMP_SAVED_PATH";
+ case DP_PROP_MIME_TYPE:
+ return "MIME_TYPE";
+ case DP_PROP_RECEIVED_SIZE:
+ return "RECEIVED_SIZE";
+ case DP_PROP_TOTAL_FILE_SIZE:
+ return "TOTAL_FILE_SIZE";
+ case DP_PROP_CONTENT_NAME:
+ return "CONTENT_NAME";
+ case DP_PROP_HTTP_STATUS:
+ return "HTTP_STATUS";
+ case DP_PROP_ETAG:
+ return "ETAG";
+ case DP_PROP_STATE:
+ return "STATE";
+ case DP_PROP_ERROR:
+ return "ERROR";
+ case DP_PROP_NOTIFICATION_RAW:
+ return "NOTIFICATION_RAW";
+ case DP_PROP_NOTIFICATION_SUBJECT:
+ return "NOTIFICATION_SUBJECT";
+ case DP_PROP_NOTIFICATION_DESCRIPTION:
+ return "NOTIFICATION_DESCRIPTION";
+ case DP_PROP_NOTIFICATION_TYPE:
+ return "NOTIFICATION_TYPE";
+ case DP_PROP_HTTP_HEADERS:
+ return "HTTP_HEADERS";
+ case DP_PROP_HTTP_HEADER:
+ return "HTTP_HEADER";
+ default:
+ break;
+ }
+ return "UNKNOWN";
+}
+
+static int __dp_get_download_id(dp_client_fmt *client)
+{
+ int download_id = -1;
+ static int last_download_id = 0;
+ int check_duplicate = 0;
+ int errorcode = DP_ERROR_NONE;
+
+ do {
+ do {
+ struct timeval tval;
+ int cipher = 1;
+ int c = 0;
+
+ download_id = -1;
+ gettimeofday(&tval, NULL);
+
+ int usec = tval.tv_usec;
+ for (c = 0; ; c++, cipher++) {
+ if ((usec /= 10) <= 0)
+ break;
+ }
+ if (tval.tv_usec == 0)
+ tval.tv_usec = (tval.tv_sec & 0x0fff);
+ int disit_unit = 10;
+ for (c = 0; c < cipher - 3; c++)
+ disit_unit = disit_unit * 10;
+ download_id = tval.tv_sec + ((tval.tv_usec << 2) * 100) +
+ ((tval.tv_usec >> (cipher - 1)) * disit_unit) +
+ ((tval.tv_usec + (tval.tv_usec % 10)) & 0x0fff);
+ } while (last_download_id == download_id);
+ last_download_id = download_id;
+ check_duplicate = dp_db_check_duplicated_int(client->dbhandle,
+ DP_TABLE_LOGGING, DP_DB_COL_ID, download_id, &errorcode);
+ if (errorcode != DP_ERROR_NONE) {
+ TRACE_ERROR("ERROR [%d]", errorcode);
+ }
+ } while (check_duplicate != 0); // means duplicated id
+ return download_id;
+}
+
+void dp_request_create(dp_client_fmt *client, dp_request_fmt *request)
+{
+ // new request
+ // find the tail of linked list & check limitation
+ int i = 0;
+ dp_request_fmt *tailp = client->requests;
+ dp_request_fmt *prevp = NULL;
+ for (; i < MAX_DOWNLOAD_HANDLE; i++) {
+ if (tailp == NULL)
+ break;
+ TRACE_DEBUG("link %d info: id:%d access-time:%d", i, tailp->id, tailp->access_time);
+ prevp = tailp;
+ tailp = tailp->next;
+ }
+ request->next = NULL;
+ if (prevp == NULL) // it's first link
+ client->requests = request;
+ else
+ prevp->next = request; // attach at the tail
+
+ TRACE_DEBUG("sock:%d download-id:%d", client->channel, request->id);
+}
+
+static int __dp_request_create(dp_client_fmt *client, dp_ipc_fmt *ipc_info)
+{
+ int errorcode = DP_ERROR_NONE;
+
+ int download_id = __dp_get_download_id(client);
+
+ // allocation new request.
+ dp_request_fmt *request = (dp_request_fmt *) calloc(1, sizeof(dp_request_fmt));
+ if (request == NULL) {
+ TRACE_ERROR("check memory sock:%d download-id:%d", client->channel, download_id);
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (dp_db_new_logging(client->dbhandle, download_id, DP_STATE_READY, DP_ERROR_NONE, &errorcode) < 0) {
+ TRACE_ERROR("new log sock:%d download-id:%d", client->channel, download_id);
+ free(request);
+ return DP_ERROR_DISK_BUSY;
+ }
+
+ request->id = download_id;
+ request->agent_id = -1;
+ request->state = DP_STATE_READY;
+ request->error = DP_ERROR_NONE;
+ request->network_type = DP_NETWORK_ALL;
+ request->access_time = (int)time(NULL);
+ request->state_cb = 0;
+ request->progress_cb = 0;
+ request->startcount = 0;
+ request->noti_type = DP_NOTIFICATION_TYPE_NONE;
+ request->progress_lasttime = 0;
+ request->received_size = 0;
+ request->content_type = DP_CONTENT_UNKNOWN;
+ request->file_size = 0;
+ request->noti_priv_id = -1;
+
+ dp_request_create(client, request);
+ ipc_info->id = download_id;
+ return errorcode;
+}
+
+void dp_request_free(dp_request_fmt *request)
+{
+ // free notification handle here
+ TRACE_DEBUG("destory id:%d", request->id);
+ free(request);
+}
+
+void dp_client_clear_requests(void *slotp)
+{
+ dp_client_slots_fmt *slot = (dp_client_slots_fmt *)slotp;
+ if (slot == NULL) {
+ TRACE_ERROR("check slot memory");
+ return ;
+ }
+ dp_client_fmt *client = &slot->client;
+ if (client == NULL) {
+ TRACE_ERROR("check client memory");
+ return ;
+ }
+
+ int now_time = (int)time(NULL);
+ int i = 0;
+ unsigned queued_count = 0;
+ unsigned ongoing_count = 0;
+ dp_request_fmt *tailp = client->requests;
+ dp_request_fmt *prevp = NULL;
+ for (; tailp != NULL; i++) {
+
+ unsigned can_unload = 0;
+ if (tailp->id <= 0 || tailp->state == DP_STATE_NONE) {
+ TRACE_ERROR("id:%d unexpected request (%ld/%ld)", tailp->id, tailp->access_time, now_time);
+ can_unload = 1;
+ } else if (tailp->access_time > 0 &&
+ (now_time - tailp->access_time) > DP_CARE_CLIENT_CLEAR_INTERVAL) {
+ // check accesstime. if difference is bigger than DP_CARE_CLIENT_CLEAR_INTERVAL, clear.
+
+ if (tailp->state == DP_STATE_READY ||
+ tailp->state == DP_STATE_COMPLETED ||
+ tailp->state == DP_STATE_CANCELED ||
+ tailp->state == DP_STATE_FAILED) {
+ can_unload = 1;
+ } else if (tailp->state == DP_STATE_CONNECTING) { // it take 120 sec over to connect. it means zombie.
+ TRACE_ERROR("id:%d connection timeout (%ld/%ld)", tailp->id, tailp->access_time, now_time);
+ if (dp_cancel_agent_download_without_update(tailp->agent_id) < 0) {
+ TRACE_ERROR("failed to cancel download(%d) id:%d", tailp->agent_id, tailp->id);
+ }
+ tailp->state = DP_STATE_FAILED;
+ tailp->error = DP_ERROR_CONNECTION_TIMED_OUT;
+ if (tailp->noti_type == DP_NOTIFICATION_TYPE_COMPLETE_ONLY ||
+ tailp->noti_type == DP_NOTIFICATION_TYPE_ALL) {
+ if (dp_notification_manager_push_notification(slot, tailp, DP_NOTIFICATION) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", tailp->id);
+ }
+ }
+ }
+ } else if (tailp->state == DP_STATE_PAUSED &&
+ dp_is_alive_download(tailp->agent_id) == 0) {
+ // paused & agent_id not exist.... unload from memory.
+ TRACE_ERROR("id:%d hanged as paused (%ld/%ld)", tailp->id, tailp->access_time, now_time);
+ can_unload = 1;
+ }
+
+ if (can_unload == 1) {
+ dp_request_fmt *removep = tailp;
+ if (prevp == NULL) // first request.
+ client->requests = tailp->next;
+ else
+ prevp->next = tailp->next;
+ tailp = tailp->next;
+ TRACE_DEBUG("request %d clear: id:%d state:%s", i, removep->id, dp_print_state(removep->state));
+ dp_request_free(removep);
+ continue;
+ } else {
+ ongoing_count++;
+ }
+
+ if (tailp->state == DP_STATE_QUEUED)
+ queued_count++;
+
+ prevp = tailp;
+ tailp = tailp->next;
+ }
+ TRACE_DEBUG("info requests:%d queued:%d", ongoing_count, queued_count);
+ if (queued_count > 0)
+ dp_queue_manager_wake_up();
+}
+
+int dp_request_destroy(dp_client_fmt *client, dp_ipc_fmt *ipc_info, dp_request_fmt *requestp)
+{
+ int errorcode = DP_ERROR_NONE;
+
+ if (requestp != NULL && client->requests != NULL) {
+ if (requestp == client->requests) {
+ // cancel downloading ... after checking status
+ client->requests = requestp->next;
+ dp_request_free(requestp);
+ } else {
+ int i = 1;
+ dp_request_fmt *prevp = client->requests;
+ dp_request_fmt *removep = client->requests->next;
+ for (; i < MAX_DOWNLOAD_HANDLE; i++) {
+ if (removep == NULL) {
+ errorcode = DP_ERROR_ID_NOT_FOUND;
+ break;
+ }
+ if (removep == requestp) {
+ // cancel downloading ... after checking status
+ prevp->next = removep->next;
+ dp_request_free(removep);
+ break;
+ }
+ prevp = removep;
+ removep = removep->next;
+ }
+ }
+ }
+
+ TRACE_DEBUG("sock:%d id:%d errorcode:%s", client->channel,
+ (ipc_info) ? ipc_info->id : -1, dp_print_errorcode(errorcode));
+
+ return errorcode;
+}
+
+static int __dp_request_read_int(int sock, dp_ipc_fmt *ipc_info, int *value)
+{
+ int errorcode = DP_ERROR_NONE;
+ if (ipc_info->size == sizeof(int)) {
+ if (dp_ipc_read(sock, value, ipc_info->size, __FUNCTION__) < 0) {
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, ipc_info->size);
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ } else {
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ return errorcode;
+}
+
+static int __dp_request_feedback_string(int sock, dp_ipc_fmt *ipc_info, void *string, size_t length, int errorvalue)
+{
+ int errorcode = DP_ERROR_NONE;
+
+ if (length == 0 && errorvalue == DP_ERROR_NONE)
+ errorvalue = DP_ERROR_NO_DATA;
+
+ if (dp_ipc_query(sock, ipc_info->id, ipc_info->section, ipc_info->property, errorvalue, length * sizeof(char)) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, length);
+ }
+ if (errorvalue == DP_ERROR_NONE && errorcode == DP_ERROR_NONE) {
+ if (dp_ipc_write(sock, string, sizeof(char) * length) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, length);
+ }
+ }
+ return errorcode;
+}
+
+static int __dp_request_read_string(int sock, dp_ipc_fmt *ipc_info, char **string)
+{
+ int errorcode = DP_ERROR_NONE;
+ if (ipc_info->size > 0) {
+ char *recv_str = (char *)calloc((ipc_info->size + (size_t)1), sizeof(char));
+ if (recv_str == NULL) {
+ TRACE_STRERROR("sock:%d check memory length:%d", sock, ipc_info->size);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ } else {
+ if (dp_ipc_read(sock, recv_str, ipc_info->size, __FUNCTION__) <= 0) {
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, ipc_info->size);
+ errorcode = DP_ERROR_IO_ERROR;
+ free(recv_str);
+ } else {
+ recv_str[ipc_info->size] = '\0';
+ TRACE_DEBUG("sock:%d length:%d string:%s", sock, ipc_info->size, recv_str);
+ *string = recv_str;
+ }
+ }
+ } else {
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ return errorcode;
+}
+
+static int __dp_request_feedback_int(int sock, dp_ipc_fmt *ipc_info, void *value, int errorvalue, size_t extra_size)
+{
+ int errorcode = DP_ERROR_NONE;
+ if (errorvalue != DP_ERROR_NONE)
+ extra_size = 0;
+ if (dp_ipc_query(sock, ipc_info->id, ipc_info->section, ipc_info->property, errorvalue, extra_size) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, extra_size);
+ }
+ if (errorvalue == DP_ERROR_NONE && errorcode == DP_ERROR_NONE) {
+ if (dp_ipc_write(sock, value, extra_size) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("sock:%d check ipc length:%d", sock, extra_size);
+ }
+ }
+ return errorcode;
+}
+
+static int __dp_request_get_info(dp_client_fmt *client, dp_ipc_fmt *ipc_info, dp_request_fmt *requestp)
+{
+ int errorcode = DP_ERROR_NONE;
+ switch (ipc_info->property) {
+ case DP_PROP_URL:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_URL, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_DESTINATION:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_DESTINATION, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_FILENAME:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_FILENAME, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_STATE_CALLBACK:
+ {
+ int callback = 0;
+ if (requestp != NULL) {
+ callback = requestp->state_cb;
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_STATE_EVENT, &callback, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&callback, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_PROGRESS_CALLBACK:
+ {
+ int callback = 0;
+ if (requestp != NULL) {
+ callback = requestp->progress_cb;
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_PROGRESS_EVENT, &callback, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&callback, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_AUTO_DOWNLOAD:
+ {
+ int autodownload = 0;
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_LOGGING, DP_DB_COL_AUTO_DOWNLOAD, &autodownload, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&autodownload, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_NETWORK_TYPE:
+ {
+ int network = 0;
+ if (requestp != NULL) {
+ network = requestp->network_type;
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_NETWORK_TYPE, &network, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&network, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_NETWORK_BONDING:
+ {
+ int network_bonding = 0;
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_NETWORK_BONDING, &network_bonding, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&network_bonding, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_SAVED_PATH:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_DOWNLOAD, DP_DB_COL_SAVED_PATH, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_TEMP_SAVED_PATH:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_DOWNLOAD, DP_DB_COL_TMP_SAVED_PATH, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_MIME_TYPE:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_DOWNLOAD, DP_DB_COL_MIMETYPE, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_RECEIVED_SIZE:
+ {
+ unsigned long long recv_size = 0;
+ if (requestp != NULL) {
+ recv_size = requestp->received_size;
+ } else {
+ errorcode = DP_ERROR_INVALID_STATE;
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&recv_size, errorcode, sizeof(unsigned long long));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_TOTAL_FILE_SIZE:
+ {
+ unsigned long long file_size = 0;
+ if (requestp != NULL) {
+ file_size = requestp->file_size;
+ } else {
+ // load content_size(INT64) from database;
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_SIZE, &file_size, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&file_size, errorcode, sizeof(unsigned long long));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_CONTENT_NAME:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_NAME, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_HTTP_STATUS:
+ {
+ int httpstatus = 0;
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_DOWNLOAD, DP_DB_COL_HTTP_STATUS, &httpstatus, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&httpstatus, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_ETAG:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_DOWNLOAD, DP_DB_COL_ETAG, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_STATE:
+ {
+ int state = DP_STATE_NONE;
+ if (requestp != NULL) {
+ state = requestp->state;
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_LOGGING, DP_DB_COL_STATE, &state, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_ID_NOT_FOUND;
+ }
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&state, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_ERROR:
+ {
+ int errorvalue = DP_ERROR_NONE;
+ if (requestp != NULL) {
+ errorvalue = requestp->error;
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_LOGGING, DP_DB_COL_ERRORCODE, &errorvalue, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_ID_NOT_FOUND;
+ }
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&errorvalue, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_TYPE:
+ {
+ int noti_type = 0;
+ if (requestp != NULL) {
+ noti_type = requestp->noti_type;
+ // if already notification, unregister from notification bar.
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE, &noti_type, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&noti_type, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_SUBJECT:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_SUBJECT, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_NOTIFICATION_DESCRIPTION:
+ {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_DESCRIPTION, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(string);
+ break;
+ }
+ case DP_PROP_NOTIFICATION_RAW: // read type, send raw binary for type
+ {
+ int bundle_type = -1;
+ errorcode = __dp_request_read_int(client->channel, ipc_info, &bundle_type);
+ TRACE_DEBUG("read %s type:%d", dp_print_property(ipc_info->property), bundle_type);
+ char *raw_column = NULL;
+ if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_ONGOING)
+ raw_column = DP_DB_COL_NOTI_RAW_ONGOING;
+ else if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE)
+ raw_column = DP_DB_COL_NOTI_RAW_COMPLETE;
+ else if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_FAILED)
+ raw_column = DP_DB_COL_NOTI_RAW_FAIL;
+
+ if (raw_column == NULL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ TRACE_ERROR("invalid type %d type:%d", dp_print_property(ipc_info->property), bundle_type);
+ if (dp_ipc_query(client->channel, ipc_info->id, ipc_info->section, ipc_info->property, errorcode, 0) < 0) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ }
+ if (errorcode == DP_ERROR_NONE) {
+ unsigned char *raws_buffer = NULL;
+ unsigned length = 0;
+ // get blob binary from database by raw_column
+ if (dp_db_get_property_string(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, raw_column, &raws_buffer, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, raws_buffer, (size_t)length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(raws_buffer);
+ }
+ break;
+ }
+ case DP_PROP_HTTP_HEADERS:
+ {
+ // 1. response
+ // 2. send the number of header fields by id
+ // 3. send response & field string for each fields
+ int field_count = dp_db_check_duplicated_int(client->dbhandle, DP_TABLE_HEADERS, DP_DB_COL_ID, ipc_info->id, &errorcode);
+ if (field_count < 0 ) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ field_count = 0;
+ }
+ int result = __dp_request_feedback_int(client->channel, ipc_info, (void *)&field_count, errorcode, sizeof(int));
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ } else if (field_count > 0) {
+ // get fields from database.
+ int *ids = (int *)calloc(field_count, sizeof(int));
+ if (ids == NULL) {
+ TRACE_ERROR("failed to allocate the clients");
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ } else {
+ // getting ids of clients
+ int i = 0;
+ int rows_count = dp_db_get_cond_ids(client->dbhandle, DP_TABLE_HEADERS, DP_DB_COL_ROW_ID, DP_DB_COL_ID, ipc_info->id, ids, field_count, &errorcode);
+ for (; i < rows_count; i++) {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_cond_string(client->dbhandle, DP_TABLE_HEADERS, DP_DB_COL_ROW_ID, ids[i], DP_DB_COL_HEADER_FIELD, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %d", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ free(string);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ case DP_PROP_HTTP_HEADER:
+ {
+ // 1. read field string
+ // 2. response with extra size
+ // 3. send string.
+ char *header_field = NULL;
+ char *string = NULL;
+ unsigned length = 0;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &header_field);
+ if (errorcode == DP_ERROR_NONE && header_field != NULL) {
+ if (dp_db_get_header_value(client->dbhandle, ipc_info->id, header_field, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_NO_DATA;
+ }
+ } else {
+ if (errorcode != DP_ERROR_NONE) {
+ TRACE_ERROR("failed to set %s, error:%s", dp_print_property(ipc_info->property), dp_print_errorcode(errorcode));
+ }
+ if (header_field == NULL) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ }
+ }
+ int result = __dp_request_feedback_string(client->channel, ipc_info, string, length, errorcode);
+ if (result == DP_ERROR_IO_ERROR) {
+ errorcode = DP_ERROR_IO_ERROR;
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ free(header_field);
+ free(string);
+ break;
+ }
+ default:
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ break;
+ }
+ return errorcode;
+}
+
+static int __dp_request_set_info(dp_client_slots_fmt *slot, dp_ipc_fmt *ipc_info, dp_request_fmt *requestp)
+{
+ if (slot == NULL) {
+ TRACE_ERROR("check slot memory");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+ dp_client_fmt *client = &slot->client;
+ if (client == NULL || ipc_info == NULL) {
+ TRACE_ERROR("check client or ipc info.");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+
+ int errorcode = DP_ERROR_NONE;
+
+ // if completed or downloading, invalid state.
+ int download_state = DP_STATE_NONE;
+ if (requestp != NULL) {
+ download_state = requestp->state;
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_LOGGING, DP_DB_COL_STATE, &download_state, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_ID_NOT_FOUND;
+ // feedback
+ if (dp_ipc_query(client->channel, ipc_info->id, DP_SEC_SET,
+ ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ return errorcode;
+ }
+ }
+ // should the state be checked ?
+ TRACE_DEBUG("state:%s set property:%s", dp_print_state(download_state), dp_print_property(ipc_info->property));
+
+ switch (ipc_info->property) {
+ case DP_PROP_URL:
+ {
+ char *recv_str = NULL;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &recv_str);
+ if (errorcode == DP_ERROR_NONE) {
+ if (recv_str == NULL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ } else {
+ // write to database here
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_URL, (void *)recv_str, ipc_info->size, 2, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ free(recv_str);
+ }
+ }
+ break;
+ }
+ case DP_PROP_DESTINATION:
+ {
+ char *recv_str = NULL;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &recv_str);
+ if (errorcode == DP_ERROR_NONE) {
+ if (recv_str == NULL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ } else {
+ if (dp_smack_is_mounted() == 1) {
+ // check here destination is available. with checking smack
+ char *smack_label = dp_db_get_client_smack_label(slot->pkgname);
+ if (smack_label == NULL) {
+ TRACE_SECURE_ERROR("[SMACK][%d] no label", ipc_info->id);
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ } else if (dp_is_valid_dir(recv_str) != 0) {
+ errorcode = DP_ERROR_INVALID_DESTINATION;
+ } else if (dp_smack_is_valid_dir(slot->credential.uid, slot->credential.gid, smack_label, recv_str) != 0) {
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ }
+ free(smack_label);
+ }
+ if (errorcode == DP_ERROR_NONE &&
+ dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_DESTINATION, (void *)recv_str, ipc_info->size, 2, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ free(recv_str);
+ }
+ }
+ break;
+ }
+ case DP_PROP_TEMP_SAVED_PATH:
+ {
+ char *recv_str = NULL;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &recv_str);
+ if (errorcode == DP_ERROR_NONE) {
+ if (recv_str == NULL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ } else {
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_TEMP_FILE_PATH, (void *)recv_str, ipc_info->size, 2, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ free(recv_str);
+ }
+ }
+ break;
+ }
+ case DP_PROP_FILENAME:
+ {
+ char *recv_str = NULL;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &recv_str);
+ if (errorcode == DP_ERROR_NONE) {
+ if (recv_str == NULL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ } else {
+ // write to database here
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_FILENAME, (void *)recv_str, ipc_info->size, 2, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ free(recv_str);
+ }
+ }
+ break;
+ }
+ case DP_PROP_STATE_CALLBACK:
+ {
+ // check state here
+ // DP_ERROR_INVALID_STATE if downloading or finished
+ // update database here
+ if (requestp != NULL) {
+ requestp->state_cb = 1;
+ }
+ int enable_cb = 1;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_STATE_EVENT, (void *)&enable_cb, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_PROGRESS_CALLBACK:
+ {
+ // check state here
+ // DP_ERROR_INVALID_STATE if downloading or finished
+ // update database here
+ if (requestp != NULL) {
+ requestp->progress_cb = 1;
+ }
+ int enable_cb = 1;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_PROGRESS_EVENT, (void *)&enable_cb, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_AUTO_DOWNLOAD:
+ {
+ // update autodownload property as 1 in database
+ int enable_cb = 1;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_LOGGING, DP_DB_COL_AUTO_DOWNLOAD, (void *)&enable_cb, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_NETWORK_TYPE:
+ {
+ int recv_int = -1;
+ errorcode = __dp_request_read_int(client->channel, ipc_info, &recv_int);
+ if (recv_int <= DP_NETWORK_OFF ||
+ recv_int > DP_NETWORK_ALL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ } else {
+ // update in database
+ if (requestp != NULL) {
+ if (requestp->state == DP_STATE_QUEUED) {
+ dp_queue_manager_clear_queue(requestp);
+ } else {
+ requestp->network_type = recv_int;
+ if (requestp->state == DP_STATE_CONNECTING ||
+ requestp->state == DP_STATE_DOWNLOADING) {
+ // pause & push queue
+ if (dp_pause_agent_download_without_update(requestp->agent_id) < 0) {
+ TRACE_ERROR("failed to pause download(%d) id:%d", requestp->agent_id, ipc_info->id);
+ } else {
+ requestp->state = DP_STATE_PAUSED;
+ requestp->error = DP_ERROR_NONE;
+ if (dp_queue_manager_push_queue(slot, requestp) < 0) {
+ if (dp_db_update_logging(client->dbhandle, ipc_info->id, DP_STATE_FAILED, DP_ERROR_QUEUE_FULL, &errorcode) < 0) {
+ TRACE_ERROR("update log sock:%d download-id:%d", client->channel, ipc_info->id);
+ }
+ requestp->state = DP_STATE_FAILED;
+ requestp->error = DP_ERROR_QUEUE_FULL;
+ errorcode = DP_ERROR_QUEUE_FULL;
+ }
+ }
+ }
+ }
+ }
+ int enable_cb = recv_int;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_NETWORK_TYPE, (void *)&enable_cb, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ }
+ break;
+ }
+ case DP_PROP_NETWORK_BONDING:
+ {
+ int recv_int = -1;
+ errorcode = __dp_request_read_int(client->channel, ipc_info, &recv_int);
+ if (errorcode == DP_ERROR_NONE) {
+ if(requestp != NULL && requestp->network_type != DP_NETWORK_ALL) {
+ errorcode = DP_ERROR_INVALID_NETWORK_TYPE;
+ TRACE_ERROR("[ERROR] wrong network type");
+ } else if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_NETWORK_BONDING, (void *)&recv_int, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_TYPE:
+ {
+ int recv_int = -1;
+ errorcode = __dp_request_read_int(client->channel, ipc_info, &recv_int);
+ if (recv_int == DP_NOTIFICATION_TYPE_NONE ||
+ recv_int == DP_NOTIFICATION_TYPE_COMPLETE_ONLY ||
+ recv_int == DP_NOTIFICATION_TYPE_ALL) {
+ // check state request->state == DP_STATE_COMPLETED
+ // DP_ERROR_INVALID_STATE
+ // update notificatio type in database
+ int noti_type = recv_int;
+ if (requestp != NULL) {
+ if (recv_int < requestp->noti_type) {
+ // if already notification, unregister from notification bar.
+ if (recv_int == DP_NOTIFICATION_TYPE_NONE) {
+ if (dp_notification_manager_clear_notification(slot, requestp, DP_NOTIFICATION) < 0) {
+ TRACE_ERROR("failed to clear notification %s", dp_print_property(ipc_info->property));
+ }
+ }
+ if (dp_notification_manager_clear_notification(slot, requestp, DP_NOTIFICATION_ONGOING) < 0) {
+ TRACE_ERROR("failed to clear ongoing %s", dp_print_property(ipc_info->property));
+ }
+ }
+ requestp->noti_type = recv_int;
+ }
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE, (void *)&noti_type, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ } else {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_SUBJECT:
+ {
+ char *recv_str = NULL;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &recv_str);
+ if (errorcode == DP_ERROR_NONE) {
+ if (recv_str == NULL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ } else {
+ // write to database here
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_SUBJECT, (void *)recv_str, ipc_info->size, 2, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ free(recv_str);
+ }
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_DESCRIPTION:
+ {
+ char *recv_str = NULL;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &recv_str);
+ if (errorcode == DP_ERROR_NONE) {
+ if (recv_str == NULL) {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ } else {
+ // write to database here
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_DESCRIPTION, (void *)recv_str, ipc_info->size, 2, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ free(recv_str);
+ }
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_RAW: // bundle_type(db column) + bundle_binary
+ {
+ int bundle_type = -1;
+ errorcode = __dp_request_read_int(client->channel, ipc_info, &bundle_type);
+ TRACE_DEBUG("read %s type:%d", dp_print_property(ipc_info->property), bundle_type);
+ char *raw_column = NULL;
+ if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_ONGOING)
+ raw_column = DP_DB_COL_NOTI_RAW_ONGOING;
+ else if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE)
+ raw_column = DP_DB_COL_NOTI_RAW_COMPLETE;
+ else if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_FAILED)
+ raw_column = DP_DB_COL_NOTI_RAW_FAIL;
+ else
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ // feedback
+ if (dp_ipc_query(client->channel, ipc_info->id, DP_SEC_SET,
+ ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ if (errorcode == DP_ERROR_NONE) {
+ dp_ipc_fmt *raw_info = dp_ipc_get_fmt(client->channel);
+ if (raw_info == NULL || raw_info->section != ipc_info->section ||
+ raw_info->property != ipc_info->property ||
+ (raw_info->id != ipc_info->id)) {
+ TRACE_ERROR("there is a confusion waiting raw binary in %s section", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ if (raw_info != NULL && raw_info->size > 0) {
+ unsigned char *recv_raws = (unsigned char *)calloc(raw_info->size, sizeof(unsigned char));
+ if (recv_raws == NULL) {
+ TRACE_STRERROR("sock:%d check memory length:%d", client->channel, raw_info->size);
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ } else {
+ if (dp_ipc_read(client->channel, recv_raws, raw_info->size, __FUNCTION__) <= 0) {
+ TRACE_ERROR("sock:%d check ipc length:%d", client->channel, raw_info->size);
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ TRACE_DEBUG("sock:%d length:%d raws", client->channel, raw_info->size);
+ // save to database
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, raw_column, (void *)recv_raws, raw_info->size, 3, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ }
+ free(recv_raws);
+ }
+ } else {
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ free(raw_info);
+ }
+ break;
+ }
+ case DP_PROP_HTTP_HEADER: // a request can have one or more fields, a fields can have only one value.
+ {
+ char *header_field = NULL;
+ char *header_value = NULL;
+ // 1. read field string
+ // 2. response after checking sql status
+ // 3. read query IPC for checking IPC
+ // 4. read value string
+ // 5. response
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &header_field);
+ if (errorcode == DP_ERROR_NONE && header_field != NULL) {
+ // check sql
+ int check_field = dp_db_check_duplicated_string(client->dbhandle, ipc_info->id, DP_TABLE_HEADERS, DP_DB_COL_HEADER_FIELD, 0, header_field, &errorcode);
+ if (check_field < 0) {
+ errorcode = DP_ERROR_DISK_BUSY;
+ } else {
+ errorcode = DP_ERROR_NONE;
+ // feedback
+ if (dp_ipc_query(client->channel, ipc_info->id, ipc_info->section,
+ ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ dp_ipc_fmt *header_ipc = dp_ipc_get_fmt(client->channel);
+ if (header_ipc == NULL || header_ipc->section != ipc_info->section ||
+ header_ipc->property != ipc_info->property ||
+ (header_ipc->id != ipc_info->id)) {
+ TRACE_ERROR("there is a confusion during waiting http string in %s section", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ errorcode = __dp_request_read_string(client->channel, header_ipc, &header_value);
+ if (errorcode == DP_ERROR_NONE && header_value != NULL) {
+ if (check_field == 0) { // insert
+ if (dp_db_new_header(client->dbhandle, ipc_info->id, header_field, header_value, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ } else { // update
+ if (dp_db_update_header(client->dbhandle, ipc_info->id, header_field, header_value, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ }
+ } else {
+ if (errorcode != DP_ERROR_NONE) {
+ TRACE_ERROR("failed to set %s, error:%s", dp_print_property(ipc_info->property), dp_print_errorcode(errorcode));
+ }
+ if (header_value == NULL) {
+ TRACE_ERROR("failed to set %s, do you want to run as unset?", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ }
+ }
+ }
+ free(header_ipc);
+ }
+ }
+ } else {
+ if (errorcode != DP_ERROR_NONE) {
+ TRACE_ERROR("failed to set %s, error:%s", dp_print_property(ipc_info->property), dp_print_errorcode(errorcode));
+ }
+ if (header_field == NULL) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ }
+ }
+ free(header_field);
+ free(header_value);
+ break;
+ }
+ default:
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ break;
+ }
+ // feedback
+ if (dp_ipc_query(client->channel, ipc_info->id, DP_SEC_SET,
+ ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ return errorcode;
+}
+
+static int __dp_request_unset_info(dp_client_fmt *client, dp_ipc_fmt *ipc_info, dp_request_fmt *requestp)
+{
+ if (client == NULL || ipc_info == NULL) {
+ TRACE_ERROR("check client or ipc info.");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+
+ int errorcode = DP_ERROR_NONE;
+
+ switch (ipc_info->property) {
+ case DP_PROP_URL:
+ // it would be run like cancel operation
+ if (dp_db_unset_property_string(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_URL, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ }
+ break;
+ case DP_PROP_DESTINATION:
+ // if downloading, change destination to da_agent
+ if (dp_db_unset_property_string(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_DESTINATION, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ }
+ break;
+ case DP_PROP_FILENAME:
+ if (dp_db_unset_property_string(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_FILENAME, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ }
+ break;
+ case DP_PROP_STATE_CALLBACK:
+ {
+ if (requestp != NULL) {
+ requestp->state_cb = 0;
+ }
+ int enable_cb = 0;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_STATE_EVENT, (void *)&enable_cb, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_PROGRESS_CALLBACK:
+ {
+ if (requestp != NULL) {
+ requestp->progress_cb = 0;
+ }
+ int enable_cb = 0;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_PROGRESS_EVENT, (void *)&enable_cb, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_AUTO_DOWNLOAD:
+ {
+ // update autodownload property as 0 in database
+ int enable_cb = 0;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_LOGGING, DP_DB_COL_AUTO_DOWNLOAD, (void *)&enable_cb, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_NETWORK_TYPE:
+ {
+ // check state here
+ // update database here
+ if (requestp != NULL) {
+ requestp->network_type = DP_NETWORK_OFF;
+ }
+ int enable_cb = DP_NETWORK_OFF;
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_REQUEST, DP_DB_COL_NETWORK_TYPE, (void *)&enable_cb, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_TYPE:
+ {
+ int noti_type = DP_NOTIFICATION_TYPE_NONE;
+ if (requestp != NULL) {
+ requestp->noti_type = noti_type;
+ }
+ if (dp_db_replace_property(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE, (void *)&noti_type, ipc_info->size, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_SUBJECT:
+ {
+ if (dp_db_unset_property_string(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_SUBJECT, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_DESCRIPTION:
+ {
+ if (dp_db_unset_property_string(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_DESCRIPTION, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ }
+ break;
+ }
+ case DP_PROP_NOTIFICATION_RAW:
+ {
+ int bundle_type = -1;
+ errorcode = __dp_request_read_int(client->channel, ipc_info, &bundle_type);
+ TRACE_DEBUG("read %s type:%d", dp_print_property(ipc_info->property), bundle_type);
+ char *raw_column = NULL;
+ if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_ONGOING)
+ raw_column = DP_DB_COL_NOTI_RAW_ONGOING;
+ else if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE)
+ raw_column = DP_DB_COL_NOTI_RAW_COMPLETE;
+ else if (bundle_type == DP_NOTIFICATION_BUNDLE_TYPE_FAILED)
+ raw_column = DP_DB_COL_NOTI_RAW_FAIL;
+ if (raw_column != NULL) {
+ if (dp_db_unset_property_string(client->dbhandle, ipc_info->id, DP_TABLE_NOTIFICATION, raw_column, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s", dp_print_property(ipc_info->property));
+ }
+ } else {
+ TRACE_ERROR("invalid param set: %s type:%d", dp_print_property(ipc_info->property), bundle_type);
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ }
+ break;
+ }
+ case DP_PROP_HTTP_HEADER: // unset value by field
+ {
+ char *header_field = NULL;
+ errorcode = __dp_request_read_string(client->channel, ipc_info, &header_field);
+ if (errorcode == DP_ERROR_NONE && header_field != NULL) {
+ int is_present = dp_db_check_duplicated_string(client->dbhandle, ipc_info->id, DP_TABLE_HEADERS, DP_DB_COL_HEADER_FIELD, 0, header_field, &errorcode);
+ if (is_present < 0)
+ errorcode = DP_ERROR_DISK_BUSY;
+ else if (is_present == 0)
+ errorcode = DP_ERROR_FIELD_NOT_FOUND;
+ else if (dp_db_cond_delete(client->dbhandle, ipc_info->id, DP_TABLE_HEADERS, DP_DB_COL_HEADER_FIELD, header_field, 2, &errorcode) < 0) {
+ TRACE_ERROR("failed to unset %s for %s", dp_print_property(ipc_info->property), header_field);
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ } else {
+ if (errorcode != DP_ERROR_NONE) {
+ TRACE_ERROR("failed to set %s, error:%s", dp_print_property(ipc_info->property), dp_print_errorcode(errorcode));
+ }
+ if (header_field == NULL) {
+ TRACE_ERROR("failed to set %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ }
+ }
+ free(header_field);
+ break;
+ }
+ default:
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ break;
+ }
+ // feedback
+ if (dp_ipc_query(client->channel, ipc_info->id, DP_SEC_UNSET,
+ ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ return errorcode;
+}
+
+static int __dp_call_cancel_agent(dp_request_fmt *request)
+{
+ int ret = -1;
+ if (request != NULL) {
+ if (request->agent_id >= 0) {
+ TRACE_INFO("cancel download(%d) id: %d state:%s", request->agent_id,
+ request->id, dp_print_state(request->state));
+ if (dp_cancel_agent_download_without_update(request->agent_id) == 0)
+ ret = 0;
+ } else {
+ TRACE_ERROR("invalid agent-id:%d id:%d", request->agent_id,
+ request->id);
+ }
+ }
+ return ret;
+}
+
+static int __dp_request_controls(dp_client_slots_fmt *slot, dp_ipc_fmt *ipc_info, dp_request_fmt *requestp)
+{
+ if (slot == NULL) {
+ TRACE_ERROR("check slot memory");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+ dp_client_fmt *client = &slot->client;
+ if (client == NULL || ipc_info == NULL) {
+ TRACE_ERROR("check client or ipc info.");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+
+ int errorcode = DP_ERROR_NONE;
+
+ if (ipc_info->property == DP_PROP_CREATE) {
+ // check packets again
+ if (ipc_info->size != 0 || ipc_info->id != -1) {
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ errorcode = __dp_request_create(client, ipc_info);
+ }
+ } else {
+
+ // get now state.
+ int download_state = DP_STATE_NONE;
+ if (requestp != NULL) {
+ download_state = requestp->state;
+ } else {
+ if (dp_db_get_property_int(client->dbhandle, ipc_info->id, DP_TABLE_LOGGING, DP_DB_COL_STATE, &download_state, &errorcode) < 0) {
+ TRACE_ERROR("failed to get %s", dp_print_property(ipc_info->property));
+ errorcode = DP_ERROR_ID_NOT_FOUND;
+ // feedback
+ if (dp_ipc_query(client->channel, ipc_info->id, DP_SEC_SET,
+ ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+ return errorcode;
+ }
+ }
+ TRACE_DEBUG("id:%d state:%s set property:%s", ipc_info->id, dp_print_state(download_state), dp_print_property(ipc_info->property));
+
+ if (ipc_info->property == DP_PROP_START) {
+
+ if (download_state == DP_STATE_COMPLETED ||
+ download_state == DP_STATE_DOWNLOADING) {
+ errorcode = DP_ERROR_INVALID_STATE;
+ } else {
+
+ if (requestp == NULL) { // load from databse
+ // check state
+ // load and add new request to client->requests.
+ }
+ if (requestp == NULL) {
+ TRACE_ERROR("failed to load id:%d from database sock:%d", ipc_info->id, client->channel);
+ errorcode = DP_ERROR_DISK_BUSY;
+ }
+ if (errorcode == DP_ERROR_NONE) {
+ // update database
+ if (dp_db_update_logging(client->dbhandle, ipc_info->id, DP_STATE_QUEUED, DP_ERROR_NONE, &errorcode) < 0) {
+ TRACE_ERROR("update log sock:%d download-id:%d", client->channel, ipc_info->id);
+ errorcode = DP_ERROR_DISK_BUSY;
+ } else {
+ requestp->state = DP_STATE_QUEUED;
+ requestp->error = DP_ERROR_NONE;
+ // if it's the first request for this client-> push a request at the head of queue.
+ // check count queued, connecting.downloading in requets of client
+ // else push at the tail of queue.
+ // push to queue
+ if (dp_queue_manager_push_queue(slot, requestp) < 0) {
+ if (dp_db_update_logging(client->dbhandle, ipc_info->id, DP_STATE_FAILED, DP_ERROR_QUEUE_FULL, &errorcode) < 0) {
+ TRACE_ERROR("update log sock:%d download-id:%d", client->channel, ipc_info->id);
+ }
+ requestp->state = DP_STATE_FAILED;
+ requestp->error = DP_ERROR_QUEUE_FULL;
+ errorcode = DP_ERROR_QUEUE_FULL;
+ } else { // push ok
+ dp_queue_manager_wake_up();
+ // notification
+ if (requestp->noti_type == DP_NOTIFICATION_TYPE_ALL) {
+ if (dp_notification_manager_push_notification(slot, requestp, DP_NOTIFICATION_ONGOING) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", ipc_info->id);
+ }
+ }
+ }
+ }
+ }
+ TRACE_DEBUG("id:%d check start error:%s", ipc_info->id, dp_print_errorcode(errorcode));
+ }
+
+ } else if (ipc_info->property == DP_PROP_PAUSE) {
+
+ if (download_state > DP_STATE_DOWNLOADING) {
+ errorcode = DP_ERROR_INVALID_STATE;
+ } else { // change state regardless it's on memory or not.
+ if (dp_db_update_logging(client->dbhandle, ipc_info->id, DP_STATE_PAUSED, DP_ERROR_NONE, &errorcode) < 0) {
+ TRACE_ERROR("update log sock:%d download-id:%d", client->channel, ipc_info->id);
+ errorcode = DP_ERROR_DISK_BUSY;
+ } else {
+ // call da_pause API
+ if (requestp != NULL) {
+ // pop from queue. if state is queued.
+ if (requestp->state == DP_STATE_QUEUED) {
+ dp_queue_manager_clear_queue(requestp);
+ } else if (requestp->state == DP_STATE_CONNECTING ||
+ requestp->state == DP_STATE_DOWNLOADING) {
+ if (dp_pause_agent_download_without_update(requestp->agent_id) < 0) {
+ TRACE_ERROR("failed to pause download(%d) id:%d", requestp->agent_id, ipc_info->id);
+ }
+ }
+ requestp->state = DP_STATE_PAUSED;
+ requestp->error = DP_ERROR_NONE;
+ }
+ }
+ }
+
+ } else if (ipc_info->property == DP_PROP_CANCEL) {
+
+ if (download_state > DP_STATE_COMPLETED) {
+ errorcode = DP_ERROR_INVALID_STATE;
+ } else { // change state regardless it's on memory or not.
+ if (dp_db_update_logging(client->dbhandle, ipc_info->id, DP_STATE_CANCELED, DP_ERROR_NONE, &errorcode) < 0) {
+ TRACE_ERROR("update log sock:%d download-id:%d", client->channel, ipc_info->id);
+ errorcode = DP_ERROR_DISK_BUSY;
+ } else {
+ // call da_cancel API
+ if (requestp != NULL) {
+ // pop from queue. if state is queued.
+ if (requestp->state == DP_STATE_QUEUED) {
+ dp_queue_manager_clear_queue(requestp);
+ } else if (requestp->state == DP_STATE_CONNECTING ||
+ requestp->state == DP_STATE_DOWNLOADING) {
+ if (__dp_call_cancel_agent(requestp) < 0) {
+ TRACE_ERROR("failed to cancel download(%d) id:%d", requestp->agent_id, ipc_info->id);
+ }
+ }
+ requestp->agent_id = -1;
+ requestp->state = DP_STATE_CANCELED;
+ requestp->error = DP_ERROR_NONE;
+ if (requestp->noti_type == DP_NOTIFICATION_TYPE_COMPLETE_ONLY ||
+ requestp->noti_type == DP_NOTIFICATION_TYPE_ALL) {
+ if (dp_notification_manager_push_notification(slot, requestp, DP_NOTIFICATION) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", ipc_info->id);
+ }
+ }
+ }
+ }
+ }
+
+ } else if (ipc_info->property == DP_PROP_DESTROY) {
+
+ // check state
+ // pop from queue. if state is queued.
+ if (requestp != NULL) {
+ if (requestp->state == DP_STATE_QUEUED)
+ dp_queue_manager_clear_queue(requestp);
+ if (requestp->state == DP_STATE_CONNECTING ||
+ requestp->state == DP_STATE_DOWNLOADING) {
+ // update state property database;
+ if (dp_db_update_logging(client->dbhandle, ipc_info->id, DP_STATE_CANCELED, DP_ERROR_NONE, &errorcode) < 0) {
+ TRACE_ERROR("update log sock:%d download-id:%d", client->channel, ipc_info->id);
+ } else {
+ // call da_cancel API
+ if (__dp_call_cancel_agent(requestp) < 0) {
+ TRACE_ERROR("failed to cancel download(%d) id:%d", requestp->agent_id, ipc_info->id);
+ }
+ }
+ requestp->state = DP_STATE_CANCELED;
+ }
+ if (requestp->state == DP_STATE_QUEUED || requestp->state == DP_STATE_CANCELED) {
+
+ if (requestp->noti_type == DP_NOTIFICATION_TYPE_COMPLETE_ONLY ||
+ requestp->noti_type == DP_NOTIFICATION_TYPE_ALL) {
+ if (dp_notification_manager_push_notification(slot, requestp, DP_NOTIFICATION) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", ipc_info->id);
+ }
+ }
+ }
+ requestp->agent_id = -1;
+ }
+ errorcode = dp_request_destroy(client, ipc_info, requestp);
+
+ } else {
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ TRACE_ERROR("invalid param - id:%d set property:%s", ipc_info->id, dp_print_property(ipc_info->property));
+ }
+ }
+
+ // feedback
+ if (dp_ipc_query(client->channel, ipc_info->id, DP_SEC_CONTROL,
+ ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ }
+
+ // workaround. client still request the feedback by cancelation
+ if (ipc_info->property == DP_PROP_CANCEL ||
+ ipc_info->property == DP_PROP_PAUSE) {
+ if (requestp != NULL && requestp->state_cb == 1) {
+ if (slot->client.notify < 0 ||
+ dp_notify_feedback(slot->client.notify, slot, ipc_info->id, requestp->state, errorcode, 0) < 0) {
+ TRACE_ERROR("id:%d disable state callback by IO_ERROR", ipc_info->id);
+ requestp->state_cb = 0;
+ }
+ }
+ }
+
+ return errorcode;
+}
+
+static int __dp_client_requests(dp_client_slots_fmt *slot, dp_ipc_fmt *ipc_info)
+{
+ if (slot == NULL) {
+ TRACE_ERROR("check slot memory");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+ dp_client_fmt *client = &slot->client;
+ if (client == NULL || ipc_info == NULL) {
+ TRACE_ERROR("check client or ipc info.");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+
+ int errorcode = DP_ERROR_NONE;
+
+ // check id except create command /////////// DP_ERROR_ID_NOT_FOUND
+ dp_request_fmt *requestp = NULL;
+ if (ipc_info->section != DP_SEC_CONTROL ||
+ ipc_info->property != DP_PROP_CREATE) {
+ // check on requests
+ int i = 0;
+ requestp = client->requests;
+ errorcode = DP_ERROR_ID_NOT_FOUND;
+ for (; i < MAX_DOWNLOAD_HANDLE; i++) {
+ if (requestp == NULL)
+ break;
+ //TRACE_DEBUG("link %d info: id:%d access-time:%d", i, requestp->id, requestp->access_time);
+ if (requestp->id == ipc_info->id) {
+ errorcode = DP_ERROR_NONE;
+ break;
+ }
+ requestp = requestp->next;
+ }
+ if (errorcode == DP_ERROR_ID_NOT_FOUND) {
+ // check in database
+ if (dp_db_check_duplicated_int(client->dbhandle, DP_TABLE_LOGGING, DP_DB_COL_ID, ipc_info->id, &errorcode) > 0) {
+ //TRACE_DEBUG("found %d from database", ipc_info->id);
+ errorcode = DP_ERROR_NONE;
+ }
+ }
+ }
+
+ // Check size for prevent
+ if (ipc_info->size > 4294967295U) {
+ TRACE_ERROR("Check socket. Invalid size value. sock:%d", client->channel);
+ return DP_ERROR_IO_ERROR;
+ }
+ if (errorcode != DP_ERROR_NONE) { // prechecking
+ TRACE_ERROR("precheck errorcode:%s sock:%d id:%d section:%s property:%s",
+ dp_print_errorcode(errorcode),
+ client->channel, ipc_info->id,
+ dp_print_section(ipc_info->section),
+ dp_print_property(ipc_info->property));
+
+ // clear followed packets.
+ if (ipc_info->size > 0) {
+ char garbage[ipc_info->size];
+ if (read(client->channel, &garbage, ipc_info->size) == 0) {
+ TRACE_ERROR("sock:%d closed peer", client->channel);
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ }
+
+ if (dp_ipc_query(client->channel, ipc_info->id,
+ ipc_info->section, ipc_info->property, errorcode, 0) < 0) {
+ TRACE_ERROR("check ipc sock:%d", client->channel);
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ return errorcode;
+ }
+
+ switch (ipc_info->section) {
+ case DP_SEC_CONTROL:
+ errorcode = __dp_request_controls(slot, ipc_info, requestp);
+ break;
+ case DP_SEC_GET:
+ errorcode = __dp_request_get_info(client, ipc_info, requestp);
+ break;
+ case DP_SEC_SET:
+ errorcode = __dp_request_set_info(slot, ipc_info, requestp);
+ break;
+ case DP_SEC_UNSET:
+ errorcode = __dp_request_unset_info(client, ipc_info, requestp);
+ break;
+ default:
+ errorcode = DP_ERROR_INVALID_PARAMETER;
+ break;
+ }
+ return errorcode;
+}
+
+static void __dp_client_stop_all_requests(dp_client_slots_fmt *slot)
+{
+ unsigned push_count = 0;
+ int errorcode = DP_ERROR_NONE;
+ int i = 0;
+ dp_request_fmt *tailp = slot->client.requests;
+ for (; tailp != NULL; i++) {
+ TRACE_DEBUG("request %d stop id:%d state:%s", i, tailp->id, dp_print_state(tailp->state));
+ int state = tailp->state;
+ if (state == DP_STATE_CONNECTING) {
+ if (dp_cancel_agent_download_without_update(tailp->agent_id) < 0) {
+ TRACE_ERROR("failed to cancel download(%d) id:%d", tailp->agent_id, tailp->id);
+ }
+ } else if (state == DP_STATE_DOWNLOADING) {
+ if (dp_pause_agent_download(tailp->agent_id) < 0) {
+ TRACE_ERROR("failed to pause download(%d) id:%d", tailp->agent_id, tailp->id);
+ }
+ }
+ if (state == DP_STATE_DOWNLOADING || state == DP_STATE_CONNECTING) {
+ tailp->state = DP_STATE_QUEUED;
+ // This is error code for checking the reason when changing ip configuration process
+ tailp->error = DP_ERROR_IO_EAGAIN;
+ // push to queue now
+ // in da callback, check DP_ERROR_IO_EAGAIN, then ignore.
+ if (dp_db_update_logging(slot->client.dbhandle, tailp->id, tailp->state, DP_ERROR_NONE, &errorcode) < 0) {
+ TRACE_ERROR("update log sock:%d download-id:%d", slot->client.channel, tailp->id);
+ }
+ if (dp_queue_manager_push_queue(slot, tailp) < 0) {
+ TRACE_ERROR("Fail to push queueg sock:%d download-id:%d", slot->client.channel, tailp->id);
+ // FIXME later : error case. How can handle this item?
+ } else {
+ push_count++;
+ }
+ }
+ tailp = tailp->next;
+ }
+ if (push_count > 0)
+ dp_queue_manager_wake_up();
+}
+
+void dp_client_sig_handler(int signo)
+{
+ TRACE_INFO("thread:%0x signal:%d", pthread_self(), signo);
+}
+
+void *dp_client_request_thread(void *arg)
+{
+ dp_client_slots_fmt *slot = (dp_client_slots_fmt *)arg;
+ if (slot == NULL) {
+ TRACE_ERROR("slot null, can not launch the thread for client");
+ return 0;
+ }
+
+ // wait detaching thread
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+
+ TRACE_INFO("slot %p thread:%0x", slot, slot->thread);
+
+ struct sigaction act = {{0},};
+ sigset_t newmask;
+ sigemptyset(&newmask);
+ sigaddset(&newmask, SIGUSR1);
+ act.sa_handler = dp_client_sig_handler;
+ sigaction(SIGUSR1, &act, NULL);
+
+ fd_set imask, emask;
+ int errorcode = DP_ERROR_NONE;
+ dp_client_fmt *client = &slot->client;
+ int client_sock = client->channel;
+ struct timeval timeout; // for timeout of select
+
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+
+ while (slot != NULL && client_sock >= 0 &&
+ client_sock == slot->client.channel) {
+
+ memset(&timeout, 0x00, sizeof(struct timeval));
+ timeout.tv_sec = DP_CARE_CLIENT_REQUEST_INTERVAL;
+ FD_ZERO(&imask );
+ FD_ZERO(&emask );
+ FD_SET(client_sock, &imask);
+ FD_SET(client_sock, &emask);
+ if (select(client_sock + 1, &imask, 0, &emask, &timeout) < 0 ) {
+ if (slot != NULL && slot->client.channel >= 0) {
+ TRACE_INFO("broadcast by client-manager");
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+ // check all requests
+ __dp_client_stop_all_requests(slot);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ continue;
+ } else {
+ TRACE_STRERROR("interrupted by client-manager sock:%d", client_sock);
+ break;
+ }
+ }
+ if (FD_ISSET(client_sock, &imask) > 0) {
+
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+
+ if (client->dbhandle == 0 || dp_db_check_connection(client->dbhandle) < 0) {
+ if (dp_db_open_client(&client->dbhandle, slot->pkgname) < 0) {
+ TRACE_ERROR("failed to open database for sock:%d", client_sock);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ break;
+ }
+ }
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ client->access_time = (int)time(NULL);
+
+ // read ipc_fmt first. below func will deal followed packets
+ dp_ipc_fmt *ipc_info = dp_ipc_get_fmt(client_sock);
+ if (ipc_info == NULL) {
+ TRACE_STRERROR("sock:%d maybe closed", client_sock);
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ TRACE_DEBUG("sock:%d id:%d section:%s property:%s errorcode:%s size:%d",
+ client_sock, ipc_info->id,
+ dp_print_section(ipc_info->section),
+ dp_print_property(ipc_info->property),
+ dp_print_errorcode(ipc_info->errorcode),
+ ipc_info->size);
+
+ // JOB
+ errorcode = __dp_client_requests(slot, ipc_info);
+ }
+ free(ipc_info);
+
+ pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+
+ if (errorcode == DP_ERROR_IO_ERROR ||
+ errorcode == DP_ERROR_OUT_OF_MEMORY ||
+ errorcode == DP_ERROR_INVALID_PARAMETER) {
+ TRACE_ERROR("disconnect client errorcode:%s sock:%d",
+ dp_print_errorcode(errorcode), client_sock);
+ break;
+ }
+
+ } else if (FD_ISSET(client_sock, &emask) > 0) {
+ TRACE_ERROR("[EXCEPTION]");
+ break;
+ } else {
+
+ // timeout
+ if (CLIENT_MUTEX_TRYLOCK(&slot->mutex) == 0) {
+ // 1. clear zombie requests. clean requests finished. paused or ready for long time
+ dp_client_clear_requests(slot);
+
+ int sql_errorcode = DP_ERROR_NONE;
+
+ // 2. maintain only 1000 rows for each client
+ if (dp_db_limit_rows(client->dbhandle, DP_TABLE_LOGGING, DP_LOG_DB_LIMIT_ROWS, &sql_errorcode) < 0) {
+ TRACE_INFO("limit rows error:%s", dp_print_errorcode(sql_errorcode));
+ }
+ // 3. maintain for 48 hours
+ if (dp_db_limit_time(client->dbhandle, DP_TABLE_LOGGING, DP_CARE_CLIENT_INFO_PERIOD, &sql_errorcode) < 0) {
+ TRACE_INFO("limit rows error:%s", dp_print_errorcode(sql_errorcode));
+ }
+ // 4. if no requests, exit by itself.
+ if (slot->client.requests == NULL) {
+ TRACE_DEBUG("no requests");
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ break;
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ }
+ }
+ }
+
+ FD_CLR(client_sock, &imask);
+ FD_CLR(client_sock, &emask);
+
+ // if no requests, clear slot after disconnect with client.
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+
+ TRACE_INFO("thread done slot %p thread:%0x sock:%d", slot, slot->thread, client_sock);
+
+ slot->thread = 0;// to prevent kill thread twice
+
+ int i = 0;
+ dp_request_fmt *tailp = slot->client.requests;
+ dp_request_fmt *prevp = NULL;
+ for (; tailp != NULL; i++) {
+ if (tailp->state != DP_STATE_QUEUED &&
+ tailp->state != DP_STATE_CONNECTING &&
+ tailp->state != DP_STATE_DOWNLOADING) {
+ dp_request_fmt *removep = tailp;
+ if (prevp == NULL) // first request.
+ client->requests = tailp->next;
+ else
+ prevp->next = tailp->next;
+ tailp = tailp->next;
+ TRACE_DEBUG("request %d remove: id:%d state:%s", i, removep->id, dp_print_state(removep->state));
+ dp_request_free(removep);
+ continue;
+ }
+ TRACE_DEBUG("request %d remain: id:%d state:%s", i, tailp->id, dp_print_state(tailp->state));
+ prevp = tailp;
+ tailp = tailp->next;
+
+ }
+ // if no requests after clear finished requests.
+ if (slot->client.requests == NULL) {
+ dp_client_slot_free(slot);
+ } else {
+ if (slot->client.notify >= 0)
+ close(slot->client.notify);
+ dp_notify_deinit(slot->credential.pid);
+ slot->client.notify = -1;
+ if (slot->client.channel > 0)
+ close(slot->client.channel);
+ slot->client.channel = -1;
+ }
+ TRACE_INFO("thread done slot %p thread:%0x sock:%d", slot, slot->thread, client_sock);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ return 0;
+}
+
diff --git a/provider/download-provider-da-interface.c b/provider/download-provider-da-interface.c
deleted file mode 100755
index f0b222a..0000000
--- a/provider/download-provider-da-interface.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/time.h>
-#include <string.h>
-#include <dlfcn.h> // dlopen
-
-#include <sys/smack.h>
-#include "download-provider.h"
-#include "download-provider-log.h"
-#include "download-provider-pthread.h"
-#include "download-provider-socket.h"
-#include "download-provider-db.h"
-#include "download-provider-queue.h"
-#include "download-provider-notification.h"
-#include "download-provider-request.h"
-#include "download-provider-network.h"
-#include "download-provider-da-interface.h"
-
-#include "download-agent-defs.h"
-#include "download-agent-interface.h"
-
-#define DP_SDCARD_MNT_POINT "/opt/storage/sdcard"
-
-static void *g_da_handle = NULL;
-static int (*download_agent_init)(da_client_cb_t *) = NULL; // int da_init(da_client_cb_t *da_client_callback);
-static int (*download_agent_deinit)() = NULL; // int da_deinit();
-static int (*download_agent_is_alive)(int) = NULL; // int da_is_valid_download_id(int download_id);
-static int (*download_agent_suspend)(int) = NULL; // int da_suspend_download(int download_id);
-static int (*download_agent_resume)(int) = NULL; // int da_resume_download(int download_id);
-static int (*download_agent_cancel)(int) = NULL; // int da_cancel_download(int download_id);
-static int (*download_agent_start)(const char *, extension_data_t *, int *) = NULL; // int da_start_download_with_extension(const char *url, extension_data_t *ext_data, int *download_id);
-
-
-int dp_is_file_exist(const char *file_path)
-{
- struct stat file_state;
- int stat_ret;
-
- if (file_path == NULL) {
- TRACE_ERROR("[NULL-CHECK] file path is NULL");
- return -1;
- }
-
- stat_ret = stat(file_path, &file_state);
-
- if (stat_ret == 0)
- if (file_state.st_mode & S_IFREG)
- return 0;
-
- return -1;
-}
-
-static int __change_error(int err)
-{
- int ret = DP_ERROR_NONE;
- switch (err) {
- case DA_RESULT_OK:
- ret = DP_ERROR_NONE;
- break;
- case DA_ERR_INVALID_ARGUMENT:
- ret = DP_ERROR_INVALID_PARAMETER;
- break;
- case DA_ERR_FAIL_TO_MEMALLOC:
- ret = DP_ERROR_OUT_OF_MEMORY;
- break;
- case DA_ERR_UNREACHABLE_SERVER:
- ret = DP_ERROR_NETWORK_UNREACHABLE;
- break;
- case DA_ERR_HTTP_TIMEOUT:
- ret = DP_ERROR_CONNECTION_TIMED_OUT;
- break;
- case DA_ERR_DISK_FULL:
- ret = DP_ERROR_NO_SPACE;
- break;
- case DA_ERR_INVALID_STATE:
- ret = DP_ERROR_INVALID_STATE;
- break;
- case DA_ERR_NETWORK_FAIL:
- ret = DP_ERROR_CONNECTION_FAILED;
- break;
- case DA_ERR_INVALID_URL:
- ret = DP_ERROR_INVALID_URL;
- break;
- case DA_ERR_INVALID_INSTALL_PATH:
- ret = DP_ERROR_INVALID_DESTINATION;
- break;
- case DA_ERR_ALREADY_MAX_DOWNLOAD:
- ret = DP_ERROR_TOO_MANY_DOWNLOADS;
- break;
- case DA_ERR_FAIL_TO_CREATE_THREAD:
- case DA_ERR_FAIL_TO_OBTAIN_MUTEX:
- 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;
- }
- return ret;
-}
-
-static void __download_info_cb(user_download_info_t *info, void *user_data)
-{
- if (!info) {
- TRACE_ERROR("[NULL-CHECK] Agent info");
- return ;
- }
- dp_request_slots *request_slot = (dp_request_slots *) user_data;
- if (request_slot == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- return ;
- }
- CLIENT_MUTEX_LOCK(&request_slot->mutex);
- if (request_slot->request == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- dp_request *request = request_slot->request;
- if (request->id < 0 || (request->agent_id != info->download_id)) {
- TRACE_ERROR("[NULL-CHECK] agent_id : %d req_id %d",
- request->agent_id, info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
-
- int request_id = request->id;
-
- // update info before sending event
- if (info->tmp_saved_path != NULL) {
-
- TRACE_SECURE_DEBUG("[STARTED][%d] [%s]", request_id, info->tmp_saved_path);
- int conds_count = 6; // id + tmp_saved_path + file_size + content_name + etag
- int conds_index = 0;
- db_conds_list_fmt conds_p[conds_count];
- memset(&conds_p, 0x00, conds_count * sizeof(db_conds_list_fmt));
-
- conds_p[conds_index].column = DP_DB_COL_TMP_SAVED_PATH;
- conds_p[conds_index].type = DP_DB_COL_TYPE_TEXT;
- conds_p[conds_index].value = info->tmp_saved_path;
- conds_index++;
- if (info->file_type != NULL) {
- conds_p[conds_index].column = DP_DB_COL_MIMETYPE;
- conds_p[conds_index].type = DP_DB_COL_TYPE_TEXT;
- conds_p[conds_index].value = info->file_type;
- conds_index++;
- }
- if (info->content_name != NULL) {
- conds_p[conds_index].column = DP_DB_COL_CONTENT_NAME;
- conds_p[conds_index].type = DP_DB_COL_TYPE_TEXT;
- conds_p[conds_index].value = info->content_name;
- conds_index++;
- }
- if (info->etag != NULL) {
- conds_p[conds_index].column = DP_DB_COL_ETAG;
- conds_p[conds_index].type = DP_DB_COL_TYPE_TEXT;
- conds_p[conds_index].value = info->etag;
- conds_index++;
- }
- if (info->file_size > 0) {
- request->file_size = info->file_size;
- conds_p[conds_index].column = DP_DB_COL_CONTENT_SIZE;
- conds_p[conds_index].type = DP_DB_COL_TYPE_INT64;
- conds_p[conds_index].value = &info->file_size;
- conds_index++;
- }
-
- int check_id = dp_db_get_int_column(request_id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_ID);
- if (check_id == request_id) { // update
- if (dp_db_update_columns(request_id, DP_DB_TABLE_DOWNLOAD_INFO, conds_index, conds_p) < 0) {
- if (dp_db_is_full_error() == 0) {
- request->error = DP_ERROR_NO_SPACE;
- TRACE_ERROR("[SQLITE_FULL][%d]", request_id);
- if (dp_cancel_agent_download(request->agent_id) < 0)
- TRACE_ERROR("[fail][%d]cancel_agent", request_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- }
- } else { // insert
- conds_p[conds_index].column = DP_DB_COL_ID;
- conds_p[conds_index].type = DP_DB_COL_TYPE_INT;
- conds_p[conds_index].value = &request_id;
- conds_index++;
- if (dp_db_insert_columns(DP_DB_TABLE_DOWNLOAD_INFO, conds_index, conds_p) < 0) {
- if (dp_db_is_full_error() == 0) {
- request->error = DP_ERROR_NO_SPACE;
- TRACE_ERROR("[SQLITE_FULL][%d]", request_id);
- if (dp_cancel_agent_download(request->agent_id) < 0)
- TRACE_ERROR("[fail][%d]cancel_agent", request_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- }
- }
-
- }
-
- request->ip_changed = 0;
- request->state = DP_STATE_DOWNLOADING;
- request->error = DP_ERROR_NONE;
- dp_request_state_response(request);
-
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
-}
-
-static void __progress_cb(user_progress_info_t *info, void *user_data)
-{
- if (!info) {
- TRACE_ERROR("[NULL-CHECK] Agent info");
- return ;
- }
- dp_request_slots *request_slot = (dp_request_slots *) user_data;
- if (request_slot == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- return ;
- }
- CLIENT_MUTEX_LOCK(&request_slot->mutex);
- if (request_slot->request == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- dp_request *request = request_slot->request;
- if (request->id < 0 || (request->agent_id != info->download_id)) {
- TRACE_ERROR("[NULL-CHECK] agent_id : %d req_id %d",
- request->agent_id, info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
-
- if (request->state == DP_STATE_DOWNLOADING) {
- request->received_size = info->received_size;
- time_t tt = time(NULL);
- struct tm *localTime = localtime(&tt);
- // send event every 1 second.
- if (request->progress_lasttime != localTime->tm_sec) {
- request->progress_lasttime = localTime->tm_sec;
- if (request->auto_notification) {
- dp_update_downloadinginfo_notification
- (request->noti_priv_id,
- (double)request->received_size,
- (double)request->file_size);
- } else {
- int noti_type = dp_db_get_int_column(request->id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE);
- if(noti_type == DP_NOTIFICATION_TYPE_ALL)
- dp_update_downloadinginfo_notification
- (request->noti_priv_id,
- (double)request->received_size,
- (double)request->file_size);
- }
-
- if (request->progress_cb && request->group != NULL &&
- request->group->event_socket >= 0 &&
- request->received_size > 0)
- dp_ipc_send_event(request->group->event_socket,
- request->id, request->state, request->error,
- request->received_size);
- }
- }
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
-}
-
-static int __is_transmute_smack(char *path)
-{
- char *dir_label = NULL;
- int ret = -1;
- if (smack_getlabel(path, &dir_label, SMACK_LABEL_TRANSMUTE) == 0 &&
- dir_label != NULL) {
- if (strncmp(dir_label, "TRUE", strlen(dir_label)) == 0)
- ret = 0;
- }
- free(dir_label);
- return ret;
-}
-
-static dp_error_type __set_dir_smack_label(char *smack_label, char *dir_path, char *saved_path)
-{
- if (smack_label == NULL || dir_path== NULL || saved_path == NULL)
- return DP_ERROR_PERMISSION_DENIED;
-
- int is_setted_dir_label = 0;
- dp_error_type errorcode = DP_ERROR_NONE;
-
- TRACE_SECURE_INFO("[PARSE] dir path [%s]", dir_path);
- if (__is_transmute_smack(dir_path) < 0) {
- TRACE_DEBUG("[SMACK] no transmute");
- } else {
- char *dir_label = NULL;
- if (smack_getlabel(dir_path, &dir_label,
- SMACK_LABEL_ACCESS) == 0) {
- if (smack_have_access(smack_label, dir_label, "t") > 0) {
- if (smack_setlabel(saved_path, dir_label,
- SMACK_LABEL_ACCESS) != 0) {
- TRACE_SECURE_ERROR("[SMACK ERROR] label:%s",
- dir_label);
- errorcode = DP_ERROR_PERMISSION_DENIED;
- } else {
- is_setted_dir_label = 1;
- }
- } else {
- TRACE_SECURE_ERROR("[SMACK ERROR] access:%s/%s",
- smack_label, dir_label);
- errorcode = DP_ERROR_PERMISSION_DENIED;
- }
- } else {
- TRACE_SECURE_ERROR("[SMACK ERROR] no label:", dir_path);
- errorcode = DP_ERROR_PERMISSION_DENIED;
- }
- free(dir_label);
- }
- if (is_setted_dir_label == 0 &&
- smack_setlabel(saved_path, smack_label,
- SMACK_LABEL_ACCESS) != 0) {
- TRACE_SECURE_ERROR("[SMACK ERROR] label:%s", smack_label);
- errorcode = DP_ERROR_PERMISSION_DENIED;
- // remove file.
- if (dp_is_file_exist(saved_path) == 0)
- unlink(saved_path);
- }
- return errorcode;
-}
-
-static dp_error_type __set_file_permission_to_client(dp_request *request, char *saved_path)
-{
- dp_error_type errorcode = DP_ERROR_NONE;
- char *str = NULL;
- char *smack_label = NULL;
- str = strrchr(saved_path, '/');
- dp_credential cred;
- if (request->group == NULL) {
- cred.uid = dp_db_cond_get_int(DP_DB_TABLE_GROUPS,
- DP_DB_GROUPS_COL_UID,
- DP_DB_GROUPS_COL_PKG,
- DP_DB_COL_TYPE_TEXT, request->packagename);
- cred.gid = dp_db_cond_get_int(DP_DB_TABLE_GROUPS,
- DP_DB_GROUPS_COL_GID,
- DP_DB_GROUPS_COL_PKG,
- DP_DB_COL_TYPE_TEXT, request->packagename);
- } else {
- cred = request->group->credential;
- }
- TRACE_DEBUG
- ("[chown][%d] [%d][%d]", request->id, cred.uid, cred.gid);
- if (chown(saved_path, cred.uid, cred.gid) < 0)
- TRACE_STRERROR("[ERROR][%d] chown", request->id);
- if (chmod(saved_path,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
- TRACE_STRERROR("[ERROR][%d] chmod", request->id);
- if (dp_is_smackfs_mounted() == 1) {
- if (request->group == NULL) {
- // get smack_label from sql
- smack_label =
- dp_db_cond_get_text(DP_DB_TABLE_GROUPS,
- DP_DB_GROUPS_COL_SMACK_LABEL,
- DP_DB_GROUPS_COL_PKG,
- DP_DB_COL_TYPE_TEXT, request->packagename);
- } else {
- smack_label = dp_strdup(request->group->smack_label);
- }
- if (smack_label == NULL) {
- TRACE_SECURE_ERROR("[SMACK][%d] no label", request->id);
- errorcode = DP_ERROR_PERMISSION_DENIED;
- } else {
- size_t len = str - (saved_path);
- char *dir_path = (char *)calloc(len + 1, sizeof(char));
- if (dir_path != NULL) {
- strncpy(dir_path, saved_path, len);
- errorcode =
- __set_dir_smack_label(smack_label, dir_path,
- saved_path);
- free(dir_path);
- } else {
- TRACE_SECURE_ERROR("[ERROR] calloc");
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- }
- free(smack_label);
- }
- }
- return errorcode;
-}
-
-static void __finished_cb(user_finished_info_t *info, void *user_data)
-{
- if (!info) {
- TRACE_ERROR("[NULL-CHECK] Agent info");
- return ;
- }
- dp_request_slots *request_slot = (dp_request_slots *) user_data;
- if (request_slot == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- return ;
- }
- CLIENT_MUTEX_LOCK(&request_slot->mutex);
- if (request_slot->request == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- dp_request *request = request_slot->request;
- if (request->id < 0 || (request->agent_id != info->download_id)) {
- TRACE_ERROR("[NULL-CHECK] agent_id : %d req_id %d",
- request->agent_id, info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
-
- int request_id = request->id;
- dp_state_type state = DP_STATE_NONE;
- dp_error_type errorcode = DP_ERROR_NONE;
-
- if (info->http_status > 0)
- if (dp_db_replace_column(request_id, DP_DB_TABLE_DOWNLOAD_INFO,
- DP_DB_COL_HTTP_STATUS,
- DP_DB_COL_TYPE_INT, &info->http_status) < 0)
- TRACE_ERROR("[ERROR][%d][SQL]", request_id);
-
- if (info->err == DA_RESULT_OK) {
-
- int conds_count = 5; // id + saved_path + content_name + http_status + file_size
- int conds_index = 0;
- db_conds_list_fmt conds_p[conds_count];
- memset(&conds_p, 0x00, conds_count * sizeof(db_conds_list_fmt));
-
- char *content_name = NULL;
- if (info->saved_path != NULL) {
- char *str = NULL;
- if(!(strncmp(DP_SDCARD_MNT_POINT, info->saved_path,
- strlen(DP_SDCARD_MNT_POINT)) == 0)) {
- errorcode = __set_file_permission_to_client(request,
- info->saved_path);
- }
- str = strrchr(info->saved_path, '/');
- if (str != NULL) {
- str++;
- content_name = dp_strdup(str);
- TRACE_SECURE_DEBUG("[PARSE][%d] content_name [%s]",
- request_id, content_name);
- }
-
- conds_p[conds_index].column = DP_DB_COL_SAVED_PATH;
- conds_p[conds_index].type = DP_DB_COL_TYPE_TEXT;
- conds_p[conds_index].value = info->saved_path;
- conds_index++;
- if (content_name != NULL) {
- conds_p[conds_index].column = DP_DB_COL_CONTENT_NAME;
- conds_p[conds_index].type = DP_DB_COL_TYPE_TEXT;
- conds_p[conds_index].value = content_name;
- conds_index++;
- }
-
- if (errorcode == DP_ERROR_NONE) {
- state = DP_STATE_COMPLETED;
- TRACE_SECURE_INFO("[COMPLETED][%d] saved to [%s]",
- request_id, info->saved_path);
- } else {
- state = DP_STATE_FAILED;
- TRACE_SECURE_INFO("[FAILED][%d] saved to [%s]",
- request_id, info->saved_path);
- }
- } else {
- TRACE_ERROR("Cannot enter here");
- TRACE_ERROR("[ERROR][%d] No SavedPath", request_id);
- errorcode = DP_ERROR_INVALID_DESTINATION;
- state = DP_STATE_FAILED;
- }
- if (request->file_size == 0) {
- request->file_size = request->received_size;
- conds_p[conds_index].column = DP_DB_COL_CONTENT_SIZE;
- conds_p[conds_index].type = DP_DB_COL_TYPE_INT64;
- conds_p[conds_index].value = &request->file_size;
- conds_index++;
- }
-
- int check_id = dp_db_get_int_column(request_id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_ID);
- if (check_id == request_id) { // update
- if (dp_db_update_columns(request_id, DP_DB_TABLE_DOWNLOAD_INFO, conds_index, conds_p) < 0) {
- if (dp_db_is_full_error() == 0) {
- request->error = DP_ERROR_NO_SPACE;
- TRACE_ERROR("[SQLITE_FULL][%d]", request_id);
- if (dp_cancel_agent_download(request->agent_id) < 0)
- TRACE_ERROR("[fail][%d]cancel_agent", request_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- }
- } else { // insert
- conds_p[conds_index].column = DP_DB_COL_ID;
- conds_p[conds_index].type = DP_DB_COL_TYPE_INT;
- conds_p[conds_index].value = &request_id;
- conds_index++;
- if (dp_db_insert_columns(DP_DB_TABLE_DOWNLOAD_INFO, conds_index, conds_p) < 0) {
- if (dp_db_is_full_error() == 0) {
- request->error = DP_ERROR_NO_SPACE;
- TRACE_ERROR("[SQLITE_FULL][%d]", request_id);
- if (dp_cancel_agent_download(request->agent_id) < 0)
- TRACE_ERROR("[fail][%d]cancel_agent", request_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- }
- }
- free(content_name);
- } else {
- char *tmp_saved_path =
- dp_request_get_tmpsavedpath(request_id, request, &errorcode);
-
- if (tmp_saved_path != NULL) {
- errorcode = __set_file_permission_to_client(request, tmp_saved_path);
- free(tmp_saved_path);
- } else {
- TRACE_ERROR("Cannot enter here");
- TRACE_ERROR("[ERROR][%d] No SavedPath", request_id);
- }
-
- if (info->err == DA_RESULT_USER_CANCELED) {
- state = DP_STATE_CANCELED;
- errorcode = request->error;
- TRACE_INFO("[CANCELED][%d]", request_id);
- } else {
- state = DP_STATE_FAILED;
- errorcode = __change_error(info->err);
- TRACE_ERROR("[FAILED][%d][%s]", request_id,
- dp_print_errorcode(errorcode));
- }
- }
-
- request->state = state;
- request->error = errorcode;
-
- // auto resume when failed by ip_changed.
- if (state == DP_STATE_FAILED && info->err == DA_ERR_NETWORK_FAIL &&
- request->network_type != DP_NETWORK_TYPE_WIFI_DIRECT) {
- if (request->ip_changed == 1 &&
- dp_get_network_connection_instant_status() !=
- DP_NETWORK_TYPE_OFF) {
- // resume
- TRACE_DEBUG("[RESUME][%d] will be queued", request_id);
- request->state = DP_STATE_QUEUED;
- request->error = DP_ERROR_NONE;
- } else {
- TRACE_DEBUG("[CHECK][%d] check again in timeout", request_id);
- }
- } else {
- // stay on memory till called destroy by client or timeout
- if (request->group != NULL &&
- request->group->event_socket >= 0) {
- /* update the received file size.
- * The last received file size cannot update
- * because of reducing update algorithm*/
- if (request->received_size > 0) {
- dp_ipc_send_event(request->group->event_socket,
- request->id, DP_STATE_DOWNLOADING, request->error,
- request->received_size);
- }
- }
- dp_request_state_response(request);
- }
-
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
-
- dp_thread_queue_manager_wake_up();
-}
-
-static void __paused_cb(user_paused_info_t *info, void *user_data)
-{
- dp_request_slots *request_slot = (dp_request_slots *) user_data;
- if (request_slot == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- return ;
- }
- CLIENT_MUTEX_LOCK(&request_slot->mutex);
- if (request_slot->request == NULL) {
- TRACE_ERROR("[NULL-CHECK] request req_id:%d", info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
- dp_request *request = request_slot->request;
- if (request->id < 0 || (request->agent_id != info->download_id)) {
- TRACE_ERROR("[NULL-CHECK] agent_id : %d req_id %d",
- request->agent_id, info->download_id);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
-
- if (request->state != DP_STATE_PAUSE_REQUESTED) {
- TRACE_ERROR("[CHECK] now status:%d", request->state);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return ;
- }
-
- int request_id = request->id;
-
- if (dp_db_update_date
- (request_id, DP_DB_TABLE_LOG, DP_DB_COL_ACCESS_TIME) < 0)
- TRACE_ERROR("[ERROR][%d][SQL]", request_id);
-
- request->state = DP_STATE_PAUSED;
- request->error = DP_ERROR_NONE;
- dp_request_state_response(request);
-
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
-
- dp_thread_queue_manager_wake_up();
-}
-
-int dp_init_agent()
-{
-
- g_da_handle = dlopen("/usr/lib/libdownloadagent2.so", RTLD_LAZY | RTLD_GLOBAL);
- if (!g_da_handle) {
- TRACE_ERROR("[dlopen] %s", dlerror());
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
- dlerror(); /* Clear any existing error */
-
- *(void **) (&download_agent_init) = dlsym(g_da_handle, "da_init");
- if (download_agent_init == NULL ) {
- TRACE_ERROR("[dlsym] da_init:%s", dlerror());
- dlclose(g_da_handle);
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- *(void **) (&download_agent_deinit) = dlsym(g_da_handle, "da_deinit");
- if (download_agent_deinit == NULL ) {
- TRACE_ERROR("[dlsym] da_deinit:%s", dlerror());
- dlclose(g_da_handle);
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- *(void **) (&download_agent_is_alive) = dlsym(g_da_handle, "da_is_valid_download_id");
- if (download_agent_is_alive == NULL ) {
- TRACE_ERROR("[dlsym] da_is_valid_download_id:%s", dlerror());
- dlclose(g_da_handle);
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- *(void **) (&download_agent_suspend) = dlsym(g_da_handle, "da_suspend_download");
- if (download_agent_suspend == NULL ) {
- TRACE_ERROR("[dlsym] da_suspend_download:%s", dlerror());
- dlclose(g_da_handle);
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- *(void **) (&download_agent_resume) = dlsym(g_da_handle, "da_resume_download");
- if (download_agent_resume == NULL ) {
- TRACE_ERROR("[dlsym] da_resume_download:%s", dlerror());
- dlclose(g_da_handle);
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- *(void **) (&download_agent_cancel) = dlsym(g_da_handle, "da_cancel_download");
- if (download_agent_cancel == NULL ) {
- TRACE_ERROR("[dlsym] da_cancel_download:%s", dlerror());
- dlclose(g_da_handle);
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- *(void **) (&download_agent_start) = dlsym(g_da_handle, "da_start_download_with_extension");
- if (download_agent_start == NULL ) {
- TRACE_ERROR("[dlsym] da_start_download_with_extension:%s", dlerror());
- dlclose(g_da_handle);
- g_da_handle = NULL;
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- int da_ret = -1;
- da_client_cb_t da_cb = {
- __download_info_cb,
- __progress_cb,
- __finished_cb,
- __paused_cb
- };
- da_ret = (*download_agent_init)(&da_cb);
- if (da_ret != DA_RESULT_OK) {
- return DP_ERROR_OUT_OF_MEMORY;
- }
- return DP_ERROR_NONE;
-}
-
-void dp_deinit_agent()
-{
- if (g_da_handle != NULL) {
- if (download_agent_deinit != NULL)
- (*download_agent_deinit)();
-
- dlclose(g_da_handle);
- g_da_handle = NULL;
- }
-}
-
-// 1 : alive
-// 0 : not alive
-int dp_is_alive_download(int req_id)
-{
- int da_ret = 0;
- if (req_id < 0) {
- TRACE_ERROR("[NULL-CHECK] req_id");
- return 0;
- }
- if (download_agent_is_alive != NULL)
- da_ret = (*download_agent_is_alive)(req_id);
- return da_ret;
-}
-
-// 0 : success
-// -1 : failed
-dp_error_type dp_cancel_agent_download(int req_id)
-{
- if (req_id < 0) {
- TRACE_ERROR("[NULL-CHECK] req_id");
- return -1;
- }
- if (dp_is_alive_download(req_id) == 0) {
- TRACE_ERROR("[CHECK agent-id:%d] dead request", req_id);
- return -1;
- }
- if (download_agent_cancel != NULL) {
- if ((*download_agent_cancel)(req_id) == DA_RESULT_OK)
- return 0;
- }
- return -1;
-}
-
-// 0 : success
-// -1 : failed
-dp_error_type dp_pause_agent_download(int req_id)
-{
- if (req_id < 0) {
- TRACE_ERROR("[NULL-CHECK] req_id");
- return -1;
- }
- if (dp_is_alive_download(req_id) == 0) {
- TRACE_ERROR("[CHECK agent-id:%d] dead request", req_id);
- return -1;
- }
- if (download_agent_suspend != NULL) {
- if ((*download_agent_suspend)(req_id) == DA_RESULT_OK)
- return 0;
- }
- return -1;
-}
-
-
-// 0 : success
-// -1 : failed
-// -2 : pended
-dp_error_type dp_start_agent_download(dp_request_slots *request_slot)
-{
- int da_ret = -1;
- int req_dl_id = -1;
- dp_error_type errorcode = DP_ERROR_NONE;
- extension_data_t ext_data = {0,};
- char *etag = NULL;
-
- if (request_slot == NULL) {
- TRACE_ERROR("[NULL-CHECK] download_clientinfo_slot");
- return DP_ERROR_INVALID_PARAMETER;
- }
-
- if (request_slot->request == NULL) {
- TRACE_ERROR("[NULL-CHECK] download_clientinfo_slot");
- return DP_ERROR_INVALID_PARAMETER;
- }
-
- dp_request *request = request_slot->request;
-
- char *url = dp_request_get_url(request->id, &errorcode);
- if (url == NULL) {
- TRACE_ERROR("[ERROR][%d] URL is NULL", request->id);
- return DP_ERROR_INVALID_URL;
- }
- char *destination =
- dp_request_get_destination(request->id, request, &errorcode);
- if (destination != NULL)
- ext_data.install_path = destination;
-
- char *filename =
- dp_request_get_filename(request->id, request, &errorcode);
- if (filename != NULL)
- ext_data.file_name = filename;
-
- // call start_download() of download-agent
-
- char *tmp_saved_path =
- dp_request_get_tmpsavedpath(request->id, request, &errorcode);
- if (tmp_saved_path) {
- etag = dp_request_get_etag(request->id, request, &errorcode);
- if (etag) {
- TRACE_DEBUG("[RESUME][%d]", request->id);
- ext_data.etag = etag;
- ext_data.temp_file_path = tmp_saved_path;
- } else {
- /* FIXME later : It is better to handle the unlink function in download agaent module
- * or in upload the request data to memory after the download provider process is restarted */
- TRACE_SECURE_INFO("[RESTART][%d] try to remove tmp file [%s]",
- request->id, tmp_saved_path);
- if (dp_is_file_exist(tmp_saved_path) == 0)
- if (unlink(tmp_saved_path) != 0)
- TRACE_STRERROR
- ("[ERROR][%d] remove file", request->id);
- }
- }
- char *pkg_name = dp_request_get_pkg_name(request->id, request, &errorcode);
- if (pkg_name != NULL)
- ext_data.pkg_name = pkg_name;
- // get headers list from httpheaders table(DB)
- int headers_count = dp_db_get_cond_rows_count
- (request->id, DP_DB_TABLE_HTTP_HEADERS, NULL, 0, NULL);
- if (headers_count > 0) {
- ext_data.request_header = calloc(headers_count, sizeof(char*));
- if (ext_data.request_header != NULL) {
- ext_data.request_header_count = dp_db_get_http_headers_list
- (request->id, (char**)ext_data.request_header);
- }
- }
-
- ext_data.user_data = (void *)request_slot;
-
- // call start API of agent lib
- if (download_agent_start != NULL)
- da_ret = (*download_agent_start)(url, &ext_data, &req_dl_id);
- if (ext_data.request_header_count > 0) {
- int len = 0;
- int i = 0;
- len = ext_data.request_header_count;
- for (i = 0; i < len; i++) {
- if (ext_data.request_header[i])
- free((void *)(ext_data.request_header[i]));
- }
- free(ext_data.request_header);
- }
- free(url);
- if (destination)
- free(destination);
- if (filename)
- free(filename);
- if (tmp_saved_path)
- free(tmp_saved_path);
- if (etag)
- free(etag);
- if (pkg_name)
- free(pkg_name);
-
- // if start_download() return error cause of maximun download limitation,
- // set state to DOWNLOAD_STATE_PENDED.
- if (da_ret == DA_ERR_ALREADY_MAX_DOWNLOAD) {
- TRACE_DEBUG("[PENDING][%d] DA_ERR_ALREADY_MAX_DOWNLOAD [%d]",
- request->id, da_ret);
- return DP_ERROR_TOO_MANY_DOWNLOADS;
- } else if (da_ret != DA_RESULT_OK) {
- TRACE_ERROR("[ERROR][%d] DP_ERROR_CONNECTION_FAILED [%d]",
- request->id, da_ret);
- return __change_error(da_ret);
- }
- TRACE_DEBUG("[SUCCESS][%d] agent_id [%d]", request->id, req_dl_id);
- request->agent_id = req_dl_id;
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_resume_agent_download(int req_id)
-{
- int da_ret = -1;
- if (req_id < 0) {
- TRACE_ERROR("[NULL-CHECK] req_id");
- return DP_ERROR_INVALID_PARAMETER;
- }
- if (download_agent_resume != NULL)
- da_ret = (*download_agent_resume)(req_id);
- if (da_ret == DA_RESULT_OK)
- return DP_ERROR_NONE;
- else if (da_ret == DA_ERR_INVALID_STATE)
- return DP_ERROR_INVALID_STATE;
- return __change_error(da_ret);
-}
-
diff --git a/provider/download-provider-db.c b/provider/download-provider-db.c
index 4bc1353..d05eabd 100755
--- a/provider/download-provider-db.c
+++ b/provider/download-provider-db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
@@ -14,1722 +14,1288 @@
* limitations under the License.
*/
+//#include <string.h>
+//#include <errno.h>
#include <stdio.h>
-#include <string.h>
-#include <errno.h>
+#include <stdlib.h> // alloc
+//#include <unistd.h> // unlink
-#include <stdlib.h>
#include <sqlite3.h>
-#include "download-provider-config.h"
+#include "download-provider.h"
+#include "download-provider-db-defs.h"
#include "download-provider-db.h"
-#include "download-provider-slots.h"
#include "download-provider-log.h"
-#include "download-provider-pthread.h"
-
-//BASIC
-#define DP_DB_BASIC_GET_QUERY_FORMAT "SELECT %s FROM %s WHERE id = ?"
-#define DP_DB_BASIC_SET_QUERY_FORMAT "UPDATE %s SET %s = ? WHERE id = ?"
-#define DP_DB_BASIC_INSERT_QUERY_FORMAT "INSERT INTO %s (id, %s) VALUES (?, ?)"
-#define DP_DB_BASIC_NOW_DATE_QUERY_FORMAT "UPDATE %s SET %s = DATETIME('now') WHERE id = ?"
-
-// COND
-#define DP_DB_COND_GET_QUERY_FORMAT "SELECT %s FROM %s WHERE id = ? AND %s = ?"
-#define DP_DB_COND_SET_QUERY_FORMAT "UPDATE %s SET %s = ? WHERE id = ? AND %s = ?"
-
-typedef enum {
- DP_DB_QUERY_TYPE_GET = 10,
- DP_DB_QUERY_TYPE_SET = 20,
- DP_DB_QUERY_TYPE_INSERT = 30,
- DP_DB_QUERY_TYPE_NOW_DATE = 40
-} db_query_type;
-
-sqlite3 *g_dp_db_handle = 0;
-sqlite3_stmt *g_dp_db_logging_new_stmt = NULL;
-sqlite3_stmt *g_dp_db_logging_status_stmt = NULL;
-sqlite3_stmt *g_dp_db_logging_get_state_stmt = NULL;
+#include "download-provider-utils.h"
-static void __dp_finalize(sqlite3_stmt *stmt)
-{
- if (sqlite3_finalize(stmt) != SQLITE_OK)
- TRACE_ERROR("failed sqlite3_finalize [%s]",
- sqlite3_errmsg(g_dp_db_handle));
-}
-// called when terminating process
-void dp_db_close()
+static void __basic_property(sqlite3 *handle)
{
- if (g_dp_db_handle) {
- if (g_dp_db_logging_new_stmt != NULL)
- __dp_finalize(g_dp_db_logging_new_stmt);
- if (g_dp_db_logging_status_stmt != NULL)
- __dp_finalize(g_dp_db_logging_status_stmt);
- sqlite3_exec(g_dp_db_handle, "VACUUM;", 0, 0, 0); // remove empty page of db
- sqlite3_close(g_dp_db_handle);
- }
- g_dp_db_handle = 0;
+ if (sqlite3_exec(handle, "PRAGMA journal_mode=PERSIST;", 0, 0, 0) != SQLITE_OK)
+ TRACE_ERROR("check property journal_mode:PERSIST");
+ if (sqlite3_exec(handle, "PRAGMA foreign_keys=ON;", 0, 0, 0) != SQLITE_OK)
+ TRACE_ERROR("check property foreign_keys:ON");
}
-static void __load_sql_schema()
+static void __dp_finalize(sqlite3_stmt *stmt)
{
- char *rebuild_query =
- sqlite3_mprintf("sqlite3 %s '.read %s'", DATABASE_FILE, DATABASE_SCHEMA_FILE);
- if (rebuild_query != NULL) {
- TRACE_SECURE_INFO("[QUERY] %s", rebuild_query);
- system(rebuild_query);
- sqlite3_free(rebuild_query);
+ if (stmt != 0) {
+ if (sqlite3_finalize(stmt) != SQLITE_OK) {
+ sqlite3 *handle = sqlite3_db_handle(stmt);
+ TRACE_ERROR("sqlite3_finalize:%s", sqlite3_errmsg(handle));
+ }
}
}
-static int __dp_sql_open()
+static int __check_table(sqlite3 *handle, char *table)
{
- return dp_db_open();
-}
-
-static int __check_table(char *table)
-{
- //"SELECT name FROM sqlite_master WHERE type='table' AND name='" + table +"'";
sqlite3_stmt *stmt = NULL;
- if (table == NULL) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
+ if (handle == 0 || table == NULL) {
+ TRACE_ERROR("check handle or table:%s", table);
return -1;
}
char *query = sqlite3_mprintf("SELECT name FROM sqlite_master WHERE type='table' AND name='%s'", table);
if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
+ TRACE_ERROR("failed to make query statement");
return -1;
}
-
- int ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &stmt, NULL);
+ int ret = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
sqlite3_free(query);
+ int result = 0;
if (ret != SQLITE_OK) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
+ TRACE_ERROR("sqlite3_prepare:%s", sqlite3_errmsg(handle));
+ result = -1;
}
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- __dp_finalize(stmt);
- return 1;
+ if (result == 0 && sqlite3_step(stmt) != SQLITE_ROW) {
+ TRACE_DEBUG("not found table:%s", table);
+ result = -1;
}
__dp_finalize(stmt);
- return 0;
+ return result;
}
-// called when launching process or in every API
-int dp_db_open()
+static int __rebuild_client_tables(sqlite3 *handle)
{
- if (g_dp_db_handle == 0) {
- TRACE_SECURE_INFO("TRY to open [%s]", DATABASE_FILE);
- if (sqlite3_open_v2(DATABASE_FILE, &g_dp_db_handle,
- SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) {
- TRACE_ERROR("[ERROR][%s][%s]", DATABASE_FILE,
- sqlite3_errmsg(g_dp_db_handle));
- int errorcode = sqlite3_errcode(g_dp_db_handle);
- dp_db_close();
- if (errorcode == SQLITE_CORRUPT) {
- TRACE_SECURE_INFO("unlink [%s]", DATABASE_FILE);
- unlink(DATABASE_FILE);
- errorcode = SQLITE_CANTOPEN;
- }
- if (errorcode == SQLITE_CANTOPEN) {
- __load_sql_schema();
- return dp_db_open();
- }
- return -1;
- }
- sqlite3_exec(g_dp_db_handle, "PRAGMA journal_mode=PERSIST;", 0, 0, 0);
- sqlite3_exec(g_dp_db_handle, "PRAGMA foreign_keys=ON;", 0, 0, 0);
+ int ret = SQLITE_OK;
- // if not found group table. load again. (FOTA)
- // new table(groups) created by smack_label. 2013.07.09
- if (__check_table(DP_DB_TABLE_GROUPS) == 0)
- __load_sql_schema();
+ if (__check_table(handle, DP_TABLE_LOGGING) < 0) {
+ ret = sqlite3_exec(handle, DP_SCHEMA_LOGGING, 0, 0, 0);
+ if (ret == SQLITE_OK) {
+ ret = sqlite3_exec(handle, DP_SCHEMA_LOGGING_INDEX, 0, 0, 0);
+ }
}
- return g_dp_db_handle ? 0 : -1;
-}
-
-int dp_db_is_full_error()
-{
- if (g_dp_db_handle == 0) {
- TRACE_ERROR("HANDLE is null");
+ if (ret == SQLITE_OK && __check_table(handle, DP_TABLE_DOWNLOAD) < 0) {
+ ret = sqlite3_exec(handle, DP_SCHEMA_DOWNLOAD, 0, 0, 0);
+ }
+ if (ret == SQLITE_OK && __check_table(handle, DP_TABLE_REQUEST) < 0) {
+ ret = sqlite3_exec(handle, DP_SCHEMA_REQUEST, 0, 0, 0);
+ }
+ if (ret == SQLITE_OK && __check_table(handle, DP_TABLE_HEADERS) < 0) {
+ ret = sqlite3_exec(handle, DP_SCHEMA_HEADER, 0, 0, 0);
+ }
+ if (ret == SQLITE_OK && __check_table(handle, DP_TABLE_NOTIFICATION) < 0) {
+ ret = sqlite3_exec(handle, DP_SCHEMA_NOTIFICATION, 0, 0, 0);
+ }
+ if (ret != SQLITE_OK) {
+ TRACE_ERROR("create tables:%d error:%s", ret, sqlite3_errmsg(handle));
return -1;
}
- if (sqlite3_errcode(g_dp_db_handle) == SQLITE_FULL)
- return 0;
- return -1;
+ return 0;
}
-int dp_db_get_count_by_limit_time()
+static int __rebuild_client_manager_tables(sqlite3 *handle)
{
- int errorcode = SQLITE_OK;
- sqlite3_stmt *stmt = NULL;
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("db_util_open is failed [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- return -1;
+ int ret = SQLITE_OK;
+ if (__check_table(handle, DP_TABLE_CLIENTS) < 0) {
+ ret = sqlite3_exec(handle, DP_SCHEMA_CLIENTS, 0, 0, 0);
}
-
- errorcode =
- sqlite3_prepare_v2(g_dp_db_handle,
- "SELECT count(id) FROM logging \
- WHERE createtime < DATETIME('now','-48 hours')",
- -1, &stmt, NULL);
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("sqlite3_prepare_v2 is failed. [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
+ if (ret != SQLITE_OK) {
+ TRACE_ERROR("create tables:%d error:%s", ret, sqlite3_errmsg(handle));
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_list_by_limit_time(dp_request_slots *requests, int limit)
+static int __db_open(sqlite3 **handle, char *database)
{
- int errorcode = SQLITE_OK;
- int i = 0;
- sqlite3_stmt *stmt = NULL;
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("db_util_open is failed [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- return -1;
+ if (sqlite3_open_v2(database, handle, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) {
+ int errorcode = sqlite3_errcode(*handle);
+ TRACE_ERROR("error(%d):%s", errorcode, sqlite3_errmsg(*handle));
+ *handle = 0;
+ if (errorcode == SQLITE_CORRUPT) { // remove & re-create
+ TRACE_SECURE_INFO("unlink [%s]", database);
+ unlink(database);
+ errorcode = SQLITE_CANTOPEN;
+ }
+ if (errorcode == SQLITE_CANTOPEN) {
+ // create empty database
+ if (sqlite3_open(database, handle) != SQLITE_OK ) {
+ TRACE_SECURE_INFO("failed to connect:%s", database);
+ unlink(database);
+ *handle = 0;
+ return -1;
+ }
+ } else {
+ TRACE_ERROR("can not handle this error:%d", errorcode);
+ *handle = 0;
+ return -1;
+ }
}
+ __basic_property(*handle);
+ return 0;
+}
- errorcode =
- sqlite3_prepare_v2(g_dp_db_handle,
- "SELECT id, state FROM logging WHERE \
- createtime < DATETIME('now','-48 hours') \
- ORDER BY createtime ASC LIMIT ?",
- -1, &stmt, NULL);
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("sqlite3_prepare_v2 is failed. [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
+int dp_db_check_connection(void *handle)
+{
+ if (handle == 0) {
+ TRACE_ERROR("connection handler is null");
return -1;
}
- if (sqlite3_bind_int(stmt, 1, limit)
- != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int[%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
+ int phighwater = 0;
+ int pcur = 0;
+ int ret = sqlite3_db_status(handle, SQLITE_DBSTATUS_STMT_USED, &pcur, &phighwater, 0);
+ if (ret != SQLITE_OK) {
+ TRACE_INFO("sql(%p) error:%d, used memory:%d, highwater:%d", handle, ret, pcur, phighwater);
return -1;
}
+ return 0;
+}
- while ((errorcode = sqlite3_step(stmt)) == SQLITE_ROW && i < limit) {
- // allocation & initialization
- requests[i].request = dp_request_new();
- // ID
- requests[i].request->id = sqlite3_column_int(stmt, 0);
- // state
- requests[i].request->state = sqlite3_column_int(stmt, 1);
- i++;
+int dp_db_open_client_manager(void **handle)
+{
+ if (*handle == 0) {
+ char *database = sqlite3_mprintf("%s/%s", DATABASE_DIR, DP_DBFILE_CLIENTS);
+ if (database == NULL) {
+ TRACE_ERROR("failed to make clients database file path");
+ return -1;
+ }
+ if (__db_open((sqlite3 **)handle, database) < 0) {
+ TRACE_ERROR("failed to open %s", database);
+ *handle = 0;
+ } else {
+ // whenever open new handle, check all tables. it's simple
+ if (__rebuild_client_manager_tables(*handle) < 0) {
+ dp_db_close(*handle);
+ *handle = 0;
+ }
+ }
+ sqlite3_free(database);
}
-
- __dp_finalize(stmt);
- return i;
+ return *handle ? 0 : -1;
}
-int dp_db_crashed_list(dp_request_slots *requests, int limit)
+static char *__dp_db_get_client_db_path(char *pkgname)
{
- int errorcode = SQLITE_OK;
- int i = 0;
- int buffer_length = 0;
- sqlite3_stmt *stmt = NULL;
- char *buffer = NULL;
+ if (pkgname == NULL)
+ return NULL;
+ return sqlite3_mprintf("%s/clients/.%s", DATABASE_DIR, pkgname);
+}
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("db_util_open is failed [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- return -1;
+// 0 : remove, -1: error or skip by diff_time
+int dp_db_remove_database(char *pkgname, long now_time, long diff_time)
+{
+ // get file name
+ char *database = __dp_db_get_client_db_path(pkgname);
+ if (database == NULL) {
+ TRACE_ERROR("failed to make db file path");
+ return -1;
+ }
+ int result = -1;
+ // get modified time of database file.
+ long modified_time = dp_get_file_modified_time(database);
+ if (modified_time >= now_time) {
+ TRACE_ERROR("check system timezone %ld vs %ld", modified_time, now_time);
+ } else if ((now_time - modified_time) > diff_time) {
+ char *database_journal = sqlite3_mprintf("%s-journal", database);
+ if (database_journal == NULL) {
+ TRACE_ERROR("failed to make db journal file path");
+ } else {
+ if (dp_remove_file(database_journal) < 0) {
+ TRACE_ERROR("failed to remove db journal file path");
+ } else {
+ if (dp_remove_file(database) < 0) {
+ TRACE_ERROR("failed to remove db file path");
+ } else {
+ result = 0;
+ }
+ }
+ sqlite3_free(database_journal);
+ }
}
+ sqlite3_free(database);
+ return result;
+}
- errorcode =
- sqlite3_prepare_v2(g_dp_db_handle,
- "SELECT id, state, packagename FROM logging WHERE \
- (state = ? OR state = ? OR state = ?) \
- AND createtime > DATETIME('now','-48 hours') LIMIT ?",
- -1, &stmt, NULL);
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("sqlite3_prepare_v2 is failed. [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
- if (sqlite3_bind_int(stmt, 1, DP_STATE_QUEUED) != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
- if (sqlite3_bind_int(stmt, 2, DP_STATE_DOWNLOADING) != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
- if (sqlite3_bind_int(stmt, 3, DP_STATE_CONNECTING) != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
+int dp_db_open_client_v2(void **handle, char *pkgname)
+{
+ char *database = __dp_db_get_client_db_path(pkgname);
+ if (database == NULL) {
+ TRACE_ERROR("failed to make db file path");
return -1;
}
-
- if (sqlite3_bind_int(stmt, 4, limit)
- != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int[%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
+ if (sqlite3_open_v2(database, (sqlite3 **)handle, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) {
+ int errorcode = sqlite3_errcode(*handle);
+ TRACE_ERROR("error(%d):%s", errorcode, sqlite3_errmsg(*handle));
+ *handle = 0;
+ sqlite3_free(database);
return -1;
}
+ sqlite3_free(database);
+ __basic_property(*handle);
+ return 0;
+}
- while ((errorcode = sqlite3_step(stmt)) == SQLITE_ROW) {
- // allocation & initialization
- requests[i].request = dp_request_new();
- // ID
- requests[i].request->id = sqlite3_column_int(stmt, 0);
- // state
- requests[i].request->state = sqlite3_column_int(stmt, 1);
- // packagename
- buffer = (char *)(sqlite3_column_text(stmt, 2));
- requests[i].request->packagename = NULL;
- if (buffer) {
- buffer_length = strlen(buffer);
- if (buffer_length > 1) {
- requests[i].request->packagename
- = (char *)calloc(buffer_length + 1, sizeof(char));
- memcpy(requests[i].request->packagename, buffer,
- buffer_length * sizeof(char));
- requests[i].request->packagename[buffer_length] = '\0';
+int dp_db_open_client(void **handle, char *pkgname)
+{
+ if (*handle == 0) {
+ char *database = __dp_db_get_client_db_path(pkgname);
+ if (database == NULL) {
+ TRACE_ERROR("failed to make db file path");
+ return -1;
+ }
+ if (__db_open((sqlite3 **)handle, database) < 0) {
+ TRACE_SECURE_ERROR("failed to open %s", database);
+ *handle = 0;
+ } else {
+ // whenever open new handle, check all tables. it's simple
+ if (__rebuild_client_tables(*handle) < 0) {
+ dp_db_close(*handle);
+ *handle = 0;
}
}
- i++;
+ sqlite3_free(database);
}
-
- __dp_finalize(stmt);
- return i;
+ return *handle ? 0 : -1;
}
-int dp_db_limit_rows(int limit)
+void dp_db_close(void *handle)
{
- int errorcode = SQLITE_OK;
- sqlite3_stmt *stmt = NULL;
-
- if (limit <= 0) {
- TRACE_ERROR("[CHECK LIMIT] %d", limit);
- return -1;
+ if (handle != 0) {
+ // remove empty page of db
+ //sqlite3_exec(handle, "VACUUM;", 0, 0, 0);
+ if (sqlite3_close((sqlite3 *)handle) != SQLITE_OK)
+ TRACE_ERROR("check sqlite close");
}
+}
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("__dp_sql_open[%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
+void dp_db_reset(void *stmt)
+{
+ if (stmt != 0) {
+ sqlite3_stmt *stmtp = stmt;
+ sqlite3_clear_bindings(stmtp);
+ if (sqlite3_reset(stmtp) != SQLITE_OK) {
+ sqlite3 *handle = sqlite3_db_handle(stmtp);
+ TRACE_ERROR("reset:%s", sqlite3_errmsg(handle));
+ }
}
+}
- // apply "ON DELETE CASCADE"
- errorcode =
- sqlite3_prepare_v2(g_dp_db_handle,
- "DELETE FROM logging WHERE id NOT IN \
- (SELECT id FROM logging ORDER BY createtime ASC LIMIT ?)",
- -1, &stmt, NULL);
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("sqlite3_prepare_v2 [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
- if (sqlite3_bind_int(stmt, 1, limit)
- != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int[%s]",
- 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;
+void dp_db_finalize(void *stmt)
+{
+ __dp_finalize((sqlite3_stmt *)stmt);
}
-dp_request *dp_db_load_logging_request(int id)
+int dp_db_get_errorcode(void *handle)
+{
+ if (handle == 0) {
+ TRACE_ERROR("check connection handle");
+ return DP_ERROR_DISK_BUSY;
+ }
+ int errorcode = sqlite3_errcode((sqlite3 *)handle);
+ if (errorcode == SQLITE_FULL) {
+ TRACE_ERROR("SQLITE_FULL-NO_SPACE");
+ return DP_ERROR_NO_SPACE;
+ } else if (errorcode == SQLITE_TOOBIG ||
+ errorcode == SQLITE_LOCKED || errorcode == SQLITE_BUSY) {
+ TRACE_ERROR("DISK_BUSY %s", sqlite3_errmsg((sqlite3 *)handle));
+ return DP_ERROR_DISK_BUSY;
+ }
+ return DP_ERROR_NONE;
+}
+
+
+#define DP_DB_PARAM_NULL_CHECK do {\
+ if (handle == 0) {\
+ TRACE_ERROR("check connection handle");\
+ return -1;\
+ }\
+} while(0)
+
+#define DP_DB_BUFFER_NULL_CHECK(buffer) do {\
+ if (buffer == NULL) {\
+ TRACE_ERROR("check available memory");\
+ return -1;\
+ }\
+} while(0)
+
+#define DP_DB_BASIC_EXCEPTION_CHECK do {\
+ if (errorcode != SQLITE_OK) {\
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)\
+ *error = DP_ERROR_INVALID_PARAMETER;\
+ __dp_finalize(stmt);\
+ return -1;\
+ }\
+} while(0)
+
+#define DP_DB_WRITE_STEP_EXCEPTION_CHECK do {\
+ errorcode = sqlite3_step(stmt);\
+ __dp_finalize(stmt);\
+ if (errorcode != SQLITE_DONE) {\
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)\
+ *error = DP_ERROR_INVALID_PARAMETER;\
+ return -1;\
+ }\
+} while(0)
+
+int dp_db_get_ids(void *handle, const char *table, char *idcolumn, int *ids, const char *where, const int limit, char *ordercolumn, char *ordering, int *error)
{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
int errorcode = SQLITE_OK;
- int buffer_length = 0;
+ int rows_count = 0;
sqlite3_stmt *stmt = NULL;
- char *buffer = NULL;
- dp_request *request = NULL;
- if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return NULL;
- }
+ char *order_query = NULL;
+ if (ordercolumn != NULL)
+ order_query = sqlite3_mprintf("ORDER BY %s %s", ordercolumn, ( ordering == NULL ? "ASC" : ordering ));
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("db_util_open is failed [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- return NULL;
- }
+ if (idcolumn == NULL)
+ idcolumn = DP_DB_COL_ID;
- errorcode =
- sqlite3_prepare_v2(g_dp_db_handle,
- "SELECT state, errorcode, startcount, packagename \
- FROM logging WHERE id = ?",
- -1, &stmt, NULL);
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("sqlite3_prepare_v2 is failed. [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return NULL;
- }
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int is failed. [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return NULL;
- }
+ char *query = sqlite3_mprintf("SELECT %s FROM %s %s %s LIMIT ?", idcolumn, table, ( where == NULL ? "" : where ), ( order_query == NULL ? "" : order_query ));
+ DP_DB_BUFFER_NULL_CHECK(query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ //TRACE_DEBUG("debug query:%s", query);
+ sqlite3_free(query);
+ if (order_query != NULL)
+ sqlite3_free(order_query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if ((errorcode = sqlite3_step(stmt)) == SQLITE_ROW) {
- request = dp_request_new();
- if (request == NULL) {
- TRACE_ERROR("dp_request_new failed");
- __dp_finalize(stmt);
- return NULL;
- }
- request->id = id;
- request->state = sqlite3_column_int(stmt, 0);
- request->error = sqlite3_column_int(stmt, 1);
- request->startcount = sqlite3_column_int(stmt, 2);
-
- buffer = (char *)(sqlite3_column_text(stmt, 3));
- if (buffer) {
- buffer_length = strlen(buffer);
- if (buffer_length > 1) {
- request->packagename
- = (char *)calloc(buffer_length + 1, sizeof(char));
- memcpy(request->packagename, buffer,
- buffer_length * sizeof(char));
- request->packagename[buffer_length] = '\0';
- }
+ errorcode = sqlite3_bind_int(stmt, 1, limit);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+
+ *error = DP_ERROR_NONE;
+ while ((errorcode = sqlite3_step(stmt)) == SQLITE_ROW) {
+ if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER) {
+ int columnvalue = sqlite3_column_int(stmt, 0);
+ //TRACE_DEBUG("id(%d):%d", rows_count, columnvalue);
+ ids[rows_count++] = columnvalue;
}
- } else {
- TRACE_ERROR("sqlite3_step is failed. [%s] errorcode[%d]",
- sqlite3_errmsg(g_dp_db_handle), errorcode);
- __dp_finalize(stmt);
- return NULL;
}
__dp_finalize(stmt);
- return request;
+ return rows_count;
}
-int dp_db_remove_all(int id)
+int dp_db_get_crashed_ids(void *handle, const char *table, int *ids, const int limit, int *error)
{
- #if 0
- dp_db_remove(id, DP_DB_TABLE_REQUEST_INFO);
- dp_db_remove(id, DP_DB_TABLE_DOWNLOAD_INFO);
- dp_db_remove(id, DP_DB_TABLE_HTTP_HEADERS);
- dp_db_remove(id, DP_DB_TABLE_NOTIFICATION);
- #endif
- // apply "ON DELETE CASCADE"
- dp_db_remove(id, DP_DB_TABLE_LOG);
+ // make where.
+ //get ids if state is QUEUED, CONNECTING or DOWNLOADING with auto_download
+ char *where = sqlite3_mprintf("WHERE %s IS 1 AND (%s IS %d OR %s IS %d OR %s IS %d)",
+ DP_DB_COL_AUTO_DOWNLOAD,
+ DP_DB_COL_STATE, DP_STATE_DOWNLOADING,
+ DP_DB_COL_STATE, DP_STATE_CONNECTING,
+ DP_DB_COL_STATE, DP_STATE_QUEUED);
+ if (where != NULL) {
+ int rows_count = dp_db_get_ids(handle, table, DP_DB_COL_ID, ids, where, limit, NULL, NULL, error);
+ sqlite3_free(where);
+ return rows_count;
+ }
+ *error = DP_ERROR_OUT_OF_MEMORY;
return -1;
}
-int dp_db_remove(int id, char *table)
+
+int dp_db_check_duplicated_int(void *handle, const char *table, const char *column, const int value, int *error)
{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
int errorcode = SQLITE_OK;
- int query_len = 0;
- int ret = -1;
+ int count = 0;
sqlite3_stmt *stmt = NULL;
- char *query_format = NULL;
- char *query = NULL;
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("__dp_sql_open[%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- query_format = "DELETE FROM %s WHERE id = ? ";
- // 2 means the length of one %s
- query_len = strlen(query_format) - 2 + strlen(table);
- if (query_len < strlen(query_format)) {
- TRACE_ERROR("[CHECK QUERY FORMAT] [%s][%s]",
- query_format, table);
- return -1;
- }
-
- query = (char *)calloc((query_len + 1), sizeof(char));
- if (query == NULL) {
- TRACE_STRERROR("[CALLOC]");
- return -1;
- }
- query[query_len] = '\0';
-
- ret = snprintf(query, query_len + 1, query_format, table);
-
- if (ret < 0) {
- TRACE_STRERROR("[CHECK COMBINE] [%s]", query);
- free(query);
- return -1;
- }
+ char *query = sqlite3_mprintf("SELECT count(*) FROM %s WHERE %s IS ?", table, column);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // check error of sqlite3_prepare_v2
- if (sqlite3_prepare_v2
- (g_dp_db_handle, query, -1, &stmt, NULL) != SQLITE_OK) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- free(query);
- return -1;
- }
- free(query);
+ errorcode = sqlite3_bind_int(stmt, 1, value);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (sqlite3_bind_int(stmt, 1, id)
- != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int[%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ *error = DP_ERROR_NONE;
errorcode = sqlite3_step(stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- __dp_finalize(stmt);
- return 0;
+ if (errorcode == SQLITE_ROW) {
+ count = sqlite3_column_int(stmt, 0);
+ } else {
+ count = 0;
}
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
__dp_finalize(stmt);
- return -1;
+ return count;
}
-static sqlite3_stmt *__prepare_query(sqlite3 *handle,
- db_query_type type, char *table, char *column)
+int dp_db_check_duplicated_string(void *handle, const int id, const char *table, const char *column, int is_like, const char *value, int *error)
{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ int errorcode = SQLITE_OK;
+ int count = 0;
sqlite3_stmt *stmt = NULL;
- char *query_format = NULL;
- char *query = NULL;
- int ret = -1;
-
- if (type == DP_DB_QUERY_TYPE_GET) {
- query_format = DP_DB_BASIC_GET_QUERY_FORMAT;
- } else if (type == DP_DB_QUERY_TYPE_SET) {
- query_format = DP_DB_BASIC_SET_QUERY_FORMAT;
- } else if (type == DP_DB_QUERY_TYPE_INSERT) {
- query_format = DP_DB_BASIC_INSERT_QUERY_FORMAT;
- } else if (type == DP_DB_QUERY_TYPE_NOW_DATE) {
- query_format = DP_DB_BASIC_NOW_DATE_QUERY_FORMAT;
- } else {
- TRACE_ERROR("[CHECK QUERY TYPE] [%d]", type);
- return NULL;
- }
- if (type == DP_DB_QUERY_TYPE_GET)
- query = sqlite3_mprintf(query_format, column, table);
- else
- query = sqlite3_mprintf(query_format, table, column);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE] [%s]", query_format);
- return NULL;
+ char *id_check = NULL;
+ if (id >= 0) {
+ id_check = sqlite3_mprintf("AND %s IS ?", DP_DB_COL_ID);
}
-
- ret = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ char *query = NULL;
+ if (is_like > 0)
+ query = sqlite3_mprintf("SELECT count(*) FROM %s WHERE %s LIKE ? %s", table, column, (id_check == NULL ? "" : id_check));
+ else
+ query = sqlite3_mprintf("SELECT count(*) FROM %s WHERE %s %s ? %s", table, column, (is_like == 0 ? "IS" : "IS NOT"), (id_check == NULL ? "" : id_check));
+ if (id_check != NULL)
+ sqlite3_free(id_check);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
sqlite3_free(query);
- if ( ret != SQLITE_OK) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(handle));
- __dp_finalize(stmt);
- return NULL;
- }
- return stmt;
-}
-
-int dp_db_insert_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value)
-{
- sqlite3_stmt *stmt = NULL;
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return -1;
- }
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_INSERT, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- int errorcode = SQLITE_OK;
- if (datatype == DP_DB_COL_TYPE_INT) {
- int *cast_value = value;
- errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
- } else if (datatype == DP_DB_COL_TYPE_INT64) {
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = value;
- errorcode = sqlite3_bind_int64(stmt, 2, *cast_value);
-#else
- int *cast_value = value;
- errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
-#endif
- } else if (datatype == DP_DB_COL_TYPE_TEXT) {
- errorcode = sqlite3_bind_text(stmt, 2, (char*)value, -1, NULL);
- } else {
- TRACE_ERROR("[CHECK TYPE] Not Support [%d]", datatype);
- __dp_finalize(stmt);
- return -1;
- }
-
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%d] [%s]",
- datatype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
-
- // VALUES ( id )
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
+ errorcode = sqlite3_bind_text(stmt, 1, value, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ if (id >= 0) {
+ errorcode = sqlite3_bind_int(stmt, 2, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
}
+ *error = DP_ERROR_NONE;
errorcode = sqlite3_step(stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- __dp_finalize(stmt);
- return 0;
+ if (errorcode == SQLITE_ROW) {
+ count = sqlite3_column_int(stmt, 0);
+ } else {
+ count = 0;
}
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
__dp_finalize(stmt);
- return -1;
+ return count;
}
-int dp_db_insert_blob_column(int id, char *table, char *column,
- void *value, unsigned length)
+int dp_db_update_client_info(void *handle, const char *pkgname, const char *smack, const int uid, const int gid, int *error)
{
- sqlite3_stmt *stmt = NULL;
-
- if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ if (pkgname == NULL) {
+ TRACE_ERROR("check pkgname");
return -1;
}
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_INSERT, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
+ int is_update = dp_db_check_duplicated_string(handle, -1, DP_TABLE_CLIENTS, DP_DB_COL_PACKAGE, 0, pkgname, error);
+ if (is_update < 0) {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_DISK_BUSY;
return -1;
}
int errorcode = SQLITE_OK;
- errorcode = sqlite3_bind_blob(stmt, 2, value, (int)length, NULL);
+ sqlite3_stmt *stmt = NULL;
+ char *query = NULL;
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ if (is_update == 0)
+ query = sqlite3_mprintf(
+ "INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s) VALUES (?, ?, %d, %d, 0, DATETIME('NOW'), DATETIME('NOW'))",
+ DP_TABLE_CLIENTS, DP_DB_COL_SMACK_LABEL, DP_DB_COL_PACKAGE, DP_DB_COL_UID,
+ DP_DB_COL_GID, DP_DB_COL_REQUEST_COUNT,
+ DP_DB_COL_CREATE_TIME, DP_DB_COL_ACCESS_TIME, uid, gid);
+ else
+ query = sqlite3_mprintf("UPDATE %s SET %s = ?, %s = %d, %s = %d, %s = DATETIME('NOW') WHERE %s IS ?",
+ DP_TABLE_CLIENTS, DP_DB_COL_SMACK_LABEL, DP_DB_COL_UID,
+ uid, DP_DB_COL_GID, gid, DP_DB_COL_ACCESS_TIME, DP_DB_COL_PACKAGE);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // VALUES ( id )
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
+ if (smack != NULL) {
+ errorcode = sqlite3_bind_text(stmt, 1, smack, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
}
+ errorcode = sqlite3_bind_text(stmt, 2, pkgname, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- errorcode = sqlite3_step(stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- __dp_finalize(stmt);
- return 0;
- }
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-int dp_db_set_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value)
+int dp_db_get_client_property_string(void *handle, const char *pkgname, const char *column, unsigned char **value, unsigned *length, int *error)
{
- sqlite3_stmt *stmt = NULL;
-
- if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return -1;
- }
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_SET, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ if (pkgname == NULL || column == NULL || value == NULL || length == NULL) {
+ TRACE_ERROR("check materials for query");
return -1;
}
int errorcode = SQLITE_OK;
- if (datatype == DP_DB_COL_TYPE_INT) {
- int *cast_value = value;
- errorcode = sqlite3_bind_int(stmt, 1, *cast_value);
- } else if (datatype == DP_DB_COL_TYPE_INT64) {
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = value;
- errorcode = sqlite3_bind_int64(stmt, 1, *cast_value);
-#else
- int *cast_value = value;
- errorcode = sqlite3_bind_int(stmt, 1, *cast_value);
-#endif
- } else if (datatype == DP_DB_COL_TYPE_TEXT) {
- errorcode = sqlite3_bind_text(stmt, 1, (char*)value, -1, NULL);
- } else {
- TRACE_ERROR("[CHECK TYPE] Not Support [%d]", datatype);
- __dp_finalize(stmt);
- return -1;
- }
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s IS ? LIMIT 1", column, DP_TABLE_CLIENTS, DP_DB_COL_PACKAGE);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%d] [%s]",
- datatype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
-
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 2, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ errorcode = sqlite3_bind_text(stmt, 1, pkgname, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ *error = DP_ERROR_NONE;
errorcode = sqlite3_step(stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- __dp_finalize(stmt);
- return 0;
+ *length = 0;
+ if (errorcode == SQLITE_ROW) {
+ int data_type = sqlite3_column_type(stmt, 0);
+ if (data_type == SQLITE_TEXT) {
+ int getbytes = sqlite3_column_bytes(stmt, 0);
+ if (getbytes > 0) {
+ unsigned char *getstr = (unsigned char *)calloc(getbytes + 1, sizeof(unsigned char));
+ if (getstr != NULL) {
+ memcpy(getstr, sqlite3_column_text(stmt, 0), getbytes * sizeof(unsigned char));
+ getstr[getbytes] = '\0';
+ *value = getstr;
+ *length = getbytes;
+ } else {
+ TRACE_ERROR("check available system memory");
+ *error = DP_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else {
+ TRACE_ERROR("check column type:%d", data_type);
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else if (errorcode == SQLITE_ROW) {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ } else {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_ID_NOT_FOUND;
}
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
__dp_finalize(stmt);
- return -1;
+ if (*error != DP_ERROR_NO_DATA && *error != DP_ERROR_NONE)
+ return -1;
+ return 0;
}
-int dp_db_set_blob_column(int id, char *table, char *column,
- void *value, unsigned length)
+int dp_db_new_logging(void *handle, const int id, const int state, const int errorvalue, int *error)
{
- sqlite3_stmt *stmt = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_SET, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
int errorcode = SQLITE_OK;
- errorcode = sqlite3_bind_blob(stmt, 1, value, (int)length, NULL);
+ sqlite3_stmt *stmt = NULL;
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ char *query = sqlite3_mprintf("INSERT INTO %s (%s, %s, %s, %s, %s) VALUES (?, ?, ?, DATETIME('now'), DATETIME('now'))",
+ DP_TABLE_LOGGING, DP_DB_COL_ID, DP_DB_COL_STATE,
+ DP_DB_COL_ERRORCODE, DP_DB_COL_CREATE_TIME, DP_DB_COL_ACCESS_TIME);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 2, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 2, state);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 3, errorvalue);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- errorcode = sqlite3_step(stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- __dp_finalize(stmt);
- return 0;
- }
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-int dp_db_replace_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value)
+int dp_db_update_logging(void *handle, const int id, const int state, const int errorvalue, int *error)
{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return -1;
- }
+ char *query = sqlite3_mprintf("UPDATE %s SET %s = ?, %s = ?, %s = DATETIME('now') WHERE %s = ?",
+ DP_TABLE_LOGGING, DP_DB_COL_STATE, DP_DB_COL_ERRORCODE,
+ DP_DB_COL_ACCESS_TIME, DP_DB_COL_ID);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
+ errorcode = sqlite3_bind_int(stmt, 1, state);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 2, errorvalue);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 3, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- int check_id = dp_db_get_int_column(id, table, DP_DB_COL_ID);
- if (check_id != id) // INSERT
- return dp_db_insert_column(id, table, column, datatype, value);
- // UPDATE
- return dp_db_set_column(id, table, column, datatype, value);
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-int dp_db_replace_blob_column(int id, char *table, char *column1,
- void *value, unsigned length)
+// 0:integer, 1:bigint, 2:string, 3:blob
+int dp_db_replace_property(void *handle, const int id, const char *table, const char *column, const void *value, const unsigned length, const unsigned valuetype, int *error)
{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ if (table == NULL || column == NULL || value == NULL) {
+ TRACE_ERROR("check materials for query id:%d", id);
return -1;
}
- if (!column1) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
+
+ int is_update = dp_db_check_duplicated_int(handle, table, DP_DB_COL_ID, id, error);
+ if (is_update < 0) {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_DISK_BUSY;
return -1;
}
- int check_id = dp_db_get_int_column(id, table, DP_DB_COL_ID);
- if (check_id != id) // INSERT
- {
- return dp_db_insert_blob_column(id, table, column1, value, length);
- }
- // UPDATE
- return dp_db_set_blob_column(id, table, column1, value, length);
-}
-// success : 0
-// error : -1
-char *dp_db_get_text_column(int id, char *table, char *column)
-{
+ int errorcode = SQLITE_OK;
sqlite3_stmt *stmt = NULL;
+ char *query = NULL;
- if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return NULL;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return NULL;
- }
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return NULL;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return NULL;
- }
-
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_GET, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return NULL;
- }
+ if (is_update == 0)
+ query = sqlite3_mprintf("INSERT INTO %s (%s, %s) VALUES (?, ?)", table, column, DP_DB_COL_ID);
+ else
+ query = sqlite3_mprintf("UPDATE %s SET %s = ? WHERE %s IS ?", table, column, DP_DB_COL_ID);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
+ if (valuetype == 0) {
+ int *cast_value = (int *)value;
+ errorcode = sqlite3_bind_int(stmt, 1, *cast_value);
+ } else if (valuetype == 1) {
+ sqlite_int64 *cast_value = (sqlite_int64 *)value;
+ errorcode = sqlite3_bind_int64(stmt, 1, *cast_value);
+ } else if (valuetype == 2) {
+ errorcode = sqlite3_bind_text(stmt, 1, (char *)value, -1, SQLITE_STATIC);
+ } else if (valuetype == 3) {
+ errorcode = sqlite3_bind_blob(stmt, 1, value, (int)length, NULL);
+ } else {
+ TRACE_ERROR("invalid type:%d", valuetype);
__dp_finalize(stmt);
- return NULL;
+ return -1;
}
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 2, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- int buffer_length = 0;
- char *columntext = NULL;
- char *buffer = (char *)(sqlite3_column_text(stmt, 0));
- if (buffer && (buffer_length = strlen(buffer)) > 1) {
- columntext = (char *)calloc(buffer_length + 1, sizeof(char));
- memcpy(columntext, buffer, buffer_length * sizeof(char));
- columntext[buffer_length] = '\0';
- }
- __dp_finalize(stmt);
- return columntext;
- }
- __dp_finalize(stmt);
- return NULL;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-// success : 0
-// error : -1
-void *dp_db_get_blob_column(int id, char *table, char *column, int *length)
+int dp_db_get_property_string(void *handle, const int id, const char *table, const char *column, unsigned char **value, unsigned *length, int *error)
{
- sqlite3_stmt *stmt = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return NULL;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return NULL;
- }
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return NULL;
+ TRACE_ERROR("check id:%d", id);
+ return -1;
}
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return NULL;
+ if (table == NULL || column == NULL || value == NULL || length == NULL) {
+ TRACE_ERROR("check materials for query id:%d", id);
+ return -1;
}
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_GET, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return NULL;
- }
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s = ? LIMIT 1", column, table, DP_DB_COL_ID);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return NULL;
- }
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- int blob_length = 0;
- void *blob_data = NULL;
- blob_length = sqlite3_column_bytes(stmt, 0);
- if(blob_length > 0){
- blob_data = (void*)calloc(blob_length, sizeof(unsigned char));
- if(blob_data != NULL){
- memcpy(blob_data, sqlite3_column_blob(stmt, 0),
- sizeof(unsigned char)*blob_length);
+ *error = DP_ERROR_NONE;
+ errorcode = sqlite3_step(stmt);
+ *length = 0;
+ if (errorcode == SQLITE_ROW) {
+ int data_type = sqlite3_column_type(stmt, 0);
+ if (data_type == SQLITE_TEXT) {
+ int getbytes = sqlite3_column_bytes(stmt, 0);
+ if (getbytes > 0) {
+ unsigned char *getstr = (unsigned char *)calloc(getbytes + 1, sizeof(unsigned char));
+ if (getstr != NULL) {
+ memcpy(getstr, sqlite3_column_text(stmt, 0), getbytes * sizeof(unsigned char));
+ getstr[getbytes] = '\0';
+ *value = getstr;
+ *length = getbytes;
+ } else {
+ TRACE_ERROR("check available system memory");
+ *error = DP_ERROR_OUT_OF_MEMORY;
+ }
} else {
- TRACE_ERROR("[MEM] allocating");
- blob_length = -1;
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else if (data_type == SQLITE_BLOB) {
+ int getbytes = sqlite3_column_bytes(stmt, 0);
+ if (getbytes > 0) {
+ unsigned char *getstr = (unsigned char *)calloc(getbytes, sizeof(unsigned char));
+ if (getstr != NULL) {
+ memcpy(getstr, sqlite3_column_blob(stmt, 0), getbytes * sizeof(unsigned char));
+ *value = getstr;
+ *length = getbytes;
+ } else {
+ TRACE_ERROR("check available system memory");
+ *error = DP_ERROR_OUT_OF_MEMORY;
+ }
+ }else {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
}
} else {
- TRACE_ERROR("NO DATA");
- blob_length = -1;
+ //TRACE_ERROR("check column type:%d", data_type);
+ *error = DP_ERROR_NO_DATA;
}
- __dp_finalize(stmt);
- *length = blob_length;
- return blob_data;
+ } else if (errorcode == SQLITE_ROW) {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ } else {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_ID_NOT_FOUND;
}
__dp_finalize(stmt);
- return NULL;
+ if (*error != DP_ERROR_NO_DATA && *error != DP_ERROR_NONE)
+ return -1;
+ return 0;
}
-
-int dp_db_get_int_column(int id, char *table, char *column)
+int dp_db_get_property_int(void *handle, const int id, const char *table, const char *column, void *value, int *error)
{
- sqlite3_stmt *stmt = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
+ if (table == NULL || column == NULL || value == NULL) {
+ TRACE_ERROR("check materials for query id:%d", id);
return -1;
}
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_GET, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s = ? LIMIT 1", column, table, DP_DB_COL_ID);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- int columnvalue = sqlite3_column_int(stmt, 0);
- __dp_finalize(stmt);
- return columnvalue;
+ *error = DP_ERROR_NONE;
+ errorcode = sqlite3_step(stmt);
+ if (errorcode == SQLITE_ROW) {
+ int data_type = sqlite3_column_type(stmt, 0);
+ if (data_type == SQLITE_INTEGER) {
+ int recv_int = sqlite3_column_int(stmt, 0);
+ int *pvalue = value;
+ *pvalue = recv_int;
+ } else if (data_type == SQLITE_FLOAT) {
+ unsigned long long recv_int = sqlite3_column_int64(stmt, 0);
+ unsigned long long *pvalue = value;
+ *pvalue = recv_int;
+ } else {
+ TRACE_ERROR("check column type:%d", data_type);
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else if (errorcode == SQLITE_DONE) {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ } else {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_ID_NOT_FOUND;
}
__dp_finalize(stmt);
- return -1;
+ if (*error != DP_ERROR_NO_DATA && *error != DP_ERROR_NONE)
+ return -1;
+ return 0;
}
-long long dp_db_get_int64_column(int id, char *table, char *column)
+int dp_db_unset_property_string(void *handle, const int id, const char *table, const char *column, int *error)
{
- sqlite3_stmt *stmt = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ if (table == NULL || column == NULL) {
+ TRACE_ERROR("check materials for query id:%d", id);
return -1;
}
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
+ int is_update = dp_db_check_duplicated_int(handle, table, DP_DB_COL_ID, id, error);
+ if (is_update < 0) {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_DISK_BUSY;
return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
+ } else if (is_update == 0) {
+ *error = DP_ERROR_ID_NOT_FOUND;
return -1;
}
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_GET, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("UPDATE %s SET %s = NULL WHERE %s IS ?", table, column, DP_DB_COL_ID);
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- long long columnvalue = sqlite3_column_int64(stmt, 0);
- __dp_finalize(stmt);
- return columnvalue;
- }
- __dp_finalize(stmt);
- return -1;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-int dp_db_update_date(int id, char *table, char *column)
+// "DELETE FROM %s WHERE %s NOT IN (SELECT %s FROM %s ORDER BY %s %s LIMIT %d)"
+int dp_db_delete(void *handle, const int id, const char *table, int *error)
{
- int errorcode = SQLITE_OK;
- sqlite3_stmt *stmt = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("__dp_sql_open [%s]", sqlite3_errmsg(g_dp_db_handle));
+ if (table == NULL) {
+ TRACE_ERROR("check materials for query id:%d", id);
return -1;
}
- stmt = __prepare_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_NOW_DATE, table, column);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
+ int is_update = dp_db_check_duplicated_int(handle, table, DP_DB_COL_ID, id, error);
+ if (is_update < 0) {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_DISK_BUSY;
return -1;
- }
-
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
+ } else if (is_update == 0) {
+ *error = DP_ERROR_ID_NOT_FOUND;
return -1;
}
- errorcode = sqlite3_step(stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- __dp_finalize(stmt);
- return 0;
- }
- TRACE_ERROR("Failed : [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
-}
-
-static sqlite3_stmt *__prepare_cond_query(sqlite3 *handle,
- db_query_type type, char *table,
- char *column, char *cond_column)
-{
+ int errorcode = SQLITE_OK;
sqlite3_stmt *stmt = NULL;
- char *query_format = NULL;
- char *query = NULL;
- int ret = -1;
-
- if (type == DP_DB_QUERY_TYPE_GET) {
- query_format = DP_DB_COND_GET_QUERY_FORMAT;
- } else if (type == DP_DB_QUERY_TYPE_SET) {
- query_format = DP_DB_COND_SET_QUERY_FORMAT;
- } else {
- TRACE_ERROR("[CHECK QUERY TYPE] [%d]", type);
- return NULL;
- }
-
- if (type == DP_DB_QUERY_TYPE_GET)
- query = sqlite3_mprintf(query_format, column, table, cond_column);
- else
- query = sqlite3_mprintf(query_format, table, column, cond_column);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE] [%s]", query_format);
- return NULL;
- }
+ char *query = sqlite3_mprintf("DELETE FROM %s WHERE %s IS ?", table, DP_DB_COL_ID);
- ret = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
sqlite3_free(query);
- if ( ret != SQLITE_OK) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(handle));
- __dp_finalize(stmt);
- return NULL;
- }
- return stmt;
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-int dp_db_cond_set_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value,
- char *condcolumn, db_column_data_type condtype, void *condvalue)
+int dp_db_new_header(void *handle, const int id, const char *field, const char *value, int *error)
{
- int errorcode = SQLITE_OK;
- sqlite3_stmt *stmt = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return -1;
- }
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
-
- if (!condcolumn) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
+ if (field == NULL) {
+ TRACE_ERROR("check field:%s", field);
return -1;
}
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
+ char *query = sqlite3_mprintf("INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)",
+ DP_TABLE_HEADERS, DP_DB_COL_ID, DP_DB_COL_HEADER_FIELD,
+ DP_DB_COL_HEADER_DATA);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- stmt = __prepare_cond_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_SET, table, column, condcolumn);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_text(stmt, 2, (char *)field, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_text(stmt, 3, (char *)value, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (datatype == DP_DB_COL_TYPE_INT) {
- int *cast_value = value;
- errorcode = sqlite3_bind_int(stmt, 1, *cast_value);
- } else if (datatype == DP_DB_COL_TYPE_INT64) {
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = value;
- errorcode = sqlite3_bind_int64(stmt, 1, *cast_value);
-#else
- int *cast_value = value;
- errorcode = sqlite3_bind_int(stmt, 1, *cast_value);
-#endif
- } else if (datatype == DP_DB_COL_TYPE_TEXT) {
- errorcode = sqlite3_bind_text(stmt, 1, (char*)value, -1, NULL);
- } else {
- TRACE_ERROR("[CHECK TYPE] Not Support [%d]", datatype);
- __dp_finalize(stmt);
- return -1;
- }
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%d] [%s]",
- datatype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
+}
- if (condtype == DP_DB_COL_TYPE_INT) {
- int *cast_value = condvalue;
- errorcode = sqlite3_bind_int(stmt, 3, *cast_value);
- } else if (condtype == DP_DB_COL_TYPE_INT64) {
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = condvalue;
- errorcode = sqlite3_bind_int64(stmt, 3, *cast_value);
-#else
- int *cast_value = condvalue;
- errorcode = sqlite3_bind_int(stmt, 3, *cast_value);
-#endif
- } else if (condtype == DP_DB_COL_TYPE_TEXT) {
- errorcode = sqlite3_bind_text(stmt, 3, (char*)condvalue, -1, NULL);
- } else {
- TRACE_ERROR("[CHECK TYPE] Not Support [%d]", condtype);
- __dp_finalize(stmt);
+int dp_db_update_header(void *handle, const int id, const char *field, const char *value, int *error)
+{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ if (id <= 0) {
+ TRACE_ERROR("check id:%d", id);
return -1;
}
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%d] [%s]",
- datatype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ char *query = sqlite3_mprintf("UPDATE %s SET %s = ? WHERE %s IS ? AND %s IS ?",
+ DP_TABLE_HEADERS, DP_DB_COL_HEADER_DATA,
+ DP_DB_COL_ID, DP_DB_COL_HEADER_FIELD);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 2, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+ errorcode = sqlite3_bind_text(stmt, 1, (char *)value, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 2, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_text(stmt, 2, (char *)field, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- errorcode = sqlite3_step(stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- __dp_finalize(stmt);
- return 0;
- }
- __dp_finalize(stmt);
- return -1;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-char *dp_db_cond_get_text_column(int id, char *table, char *column,
- char *condcolumn, db_column_data_type condtype,
- void *condvalue)
+int dp_db_get_header_value(void *handle, const int id, const char *field, unsigned char **value, unsigned *length, int *error)
{
- sqlite3_stmt *stmt = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return NULL;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return NULL;
- }
-
- if (!column) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return NULL;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return NULL;
+ TRACE_ERROR("check id:%d", id);
+ return -1;
}
-
- stmt = __prepare_cond_query
- (g_dp_db_handle, DP_DB_QUERY_TYPE_GET, table, column, condcolumn);
- if (stmt == NULL) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return NULL;
+ if (field == NULL || value == NULL || length == NULL) {
+ TRACE_ERROR("check materials for query id:%d", id);
+ return -1;
}
int errorcode = SQLITE_OK;
- if (condtype == DP_DB_COL_TYPE_INT) {
- int *cast_value = condvalue;
- errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
- } else if (condtype == DP_DB_COL_TYPE_INT64) {
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = condvalue;
- errorcode = sqlite3_bind_int64(stmt, 2, *cast_value);
-#else
- int *cast_value = condvalue;
- errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
-#endif
- } else if (condtype == DP_DB_COL_TYPE_TEXT) {
- errorcode = sqlite3_bind_text(stmt, 2, (char*)condvalue, -1, NULL);
- } else {
- TRACE_ERROR("[CHECK TYPE] Not Support [%d]", condtype);
- __dp_finalize(stmt);
- return NULL;
- }
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%d] [%s]",
- condtype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return NULL;
- }
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s IS ? AND %s IS ? LIMIT 1", DP_DB_COL_HEADER_DATA, DP_TABLE_HEADERS, DP_DB_COL_ID, DP_DB_COL_HEADER_FIELD);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- // WHERE id = ?
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return NULL;
- }
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_text(stmt, 2, (char *)field, -1, SQLITE_STATIC);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (sqlite3_step(stmt) == SQLITE_ROW) {
- int buffer_length = 0;
- char *columntext = NULL;
- char *buffer = (char *)(sqlite3_column_text(stmt, 0));
- if (buffer && (buffer_length = strlen(buffer)) > 1) {
- columntext = (char *)calloc(buffer_length + 1, sizeof(char));
- memcpy(columntext, buffer, buffer_length * sizeof(char));
- columntext[buffer_length] = '\0';
+ *error = DP_ERROR_NONE;
+ errorcode = sqlite3_step(stmt);
+ *length = 0;
+ if (errorcode == SQLITE_ROW) {
+ int data_type = sqlite3_column_type(stmt, 0);
+ if (data_type == SQLITE_TEXT) {
+ int getbytes = sqlite3_column_bytes(stmt, 0);
+ if (getbytes > 0) {
+ unsigned char *getstr = (unsigned char *)calloc(getbytes + 1, sizeof(unsigned char));
+ if (getstr != NULL) {
+ memcpy(getstr, sqlite3_column_text(stmt, 0), getbytes * sizeof(unsigned char));
+ getstr[getbytes] = '\0';
+ *value = getstr;
+ *length = getbytes;
+ } else {
+ TRACE_ERROR("check available system memory");
+ *error = DP_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else {
+ TRACE_ERROR("check column type:%d", data_type);
+ *error = DP_ERROR_NO_DATA;
}
- __dp_finalize(stmt);
- return columntext;
+ } else if (errorcode == SQLITE_ROW) {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ } else {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_ID_NOT_FOUND;
}
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
__dp_finalize(stmt);
- return NULL;
+ if (*error != DP_ERROR_NO_DATA && *error != DP_ERROR_NONE)
+ return -1;
+ return 0;
}
-int dp_db_cond_remove(int id, char *table,
- char *condcolumn, db_column_data_type condtype,
- void *condvalue)
+// not supprot blob as column & value for additional condition
+int dp_db_cond_delete(void *handle, const int id, const char *table, const char *column, const void *value, const unsigned valuetype, int *error)
{
- int errorcode = SQLITE_OK;
- int ret = -1;
- sqlite3_stmt *stmt = NULL;
- char *query_format = NULL;
- char *query = NULL;
-
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ TRACE_ERROR("check id:%d", id);
return -1;
}
-
- if (!condcolumn) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("__dp_sql_open[%s]", sqlite3_errmsg(g_dp_db_handle));
+ if (table == NULL || column == NULL || value == NULL) {
+ TRACE_ERROR("check materials for query id:%d", id);
return -1;
}
- query_format = "DELETE FROM %s WHERE id = ? AND %s = ?";
-
- query = sqlite3_mprintf(query_format, table, condcolumn);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE] [%s]", query_format);
- return -1;
- }
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("DELETE FROM %s WHERE %s IS ? AND %s IS ?", table, DP_DB_COL_ID, column);
- ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &stmt, NULL);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(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;
- }
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (condtype == DP_DB_COL_TYPE_INT) {
- int *cast_value = condvalue;
+ if (valuetype == 0) {
+ int *cast_value = (int *)value;
errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
- } else if (condtype == DP_DB_COL_TYPE_INT64) {
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = condvalue;
+ } else if (valuetype == 1) {
+ sqlite_int64 *cast_value = (sqlite_int64 *)value;
errorcode = sqlite3_bind_int64(stmt, 2, *cast_value);
-#else
- int *cast_value = condvalue;
- errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
-#endif
- } else if (condtype == DP_DB_COL_TYPE_TEXT) {
- errorcode = sqlite3_bind_text(stmt, 2, (char*)condvalue, -1, NULL);
- } else {
- TRACE_ERROR("[CHECK TYPE] Not Support [%d]", condtype);
- __dp_finalize(stmt);
- return -1;
- }
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%d] [%s]",
- condtype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
+ } else if (valuetype == 2) {
+ errorcode = sqlite3_bind_text(stmt, 2, (char *)value, -1, SQLITE_STATIC);
}
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (sqlite3_bind_int(stmt, 1, id)
- != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int[%s]",
- 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;
- }
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
-}
-
-static int __dp_sql_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);
- break;
- case DP_DB_COL_TYPE_INT64:
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = value;
- errorcode = sqlite3_bind_int64(stmt, index, *cast_value);
-#else
- cast_value = value;
- errorcode = sqlite3_bind_int(stmt, index, *cast_value);
-#endif
- break;
- case DP_DB_COL_TYPE_TEXT:
- errorcode =
- sqlite3_bind_text(stmt, index, (char *)value, -1, SQLITE_STATIC);
- break;
- default:
- errorcode = SQLITE_ERROR;
- break;
- }
- return errorcode;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
}
-char *dp_db_cond_get_text(char *table, char *column, char *condcolumn,
- db_column_data_type condtype, void *condvalue)
+int dp_db_get_cond_ids(void *handle, const char *table, const char *getcolumn, const char *column, const int value, int *ids, const int limit, int *error)
{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ int errorcode = SQLITE_OK;
+ int rows_count = 0;
sqlite3_stmt *stmt = NULL;
- char *query = NULL;
- int ret = -1;
-
- if (table == NULL) {
- TRACE_ERROR("[CHECK TABLE NAME]");
- return NULL;
- }
-
- if (column == NULL) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return NULL;
- }
- if (condcolumn == NULL) {
- TRACE_ERROR("[CHECK Condition]");
- return NULL;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("__dp_sql_open[%s]", sqlite3_errmsg(g_dp_db_handle));
- return NULL;
- }
-
- query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s IS ?",
- column, table, condcolumn);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
- return NULL;
- }
- ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &stmt, NULL);
+ char *query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s IS ?", getcolumn, table, column);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(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 NULL;
- }
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (__dp_sql_bind_value(stmt, condtype, condvalue, 1) != SQLITE_OK) {
- TRACE_ERROR
- ("[BIND][%d][%s]", condtype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return NULL;
- }
- if (sqlite3_step(stmt) == SQLITE_ROW &&
- sqlite3_column_type(stmt, 0) == SQLITE_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';
- }
- __dp_finalize(stmt);
- return getstr;
+ errorcode = sqlite3_bind_int(stmt, 1, value);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+
+ *error = DP_ERROR_NONE;
+ while ((errorcode = sqlite3_step(stmt)) == SQLITE_ROW) {
+ if (sqlite3_column_type(stmt, 0) == SQLITE_INTEGER) {
+ int columnvalue = sqlite3_column_int(stmt, 0);
+ //TRACE_DEBUG("id(%d):%d", rows_count, columnvalue);
+ ids[rows_count++] = columnvalue;
}
}
__dp_finalize(stmt);
- return NULL;
+ return rows_count;
}
-int dp_db_cond_get_int(char *table, char *column, char *condcolumn,
- db_column_data_type condtype, void *condvalue)
+int dp_db_get_cond_string(void *handle, const char *table, char *wherecolumn, const int wherevalue, const char *getcolumn, unsigned char **value, unsigned *length, int *error)
{
- sqlite3_stmt *stmt = NULL;
- char *query = NULL;
- int ret = -1;
-
- if (table == NULL) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ if (table == NULL || getcolumn == NULL || value == NULL || length == NULL) {
+ TRACE_ERROR("check materials for query");
return -1;
}
- if (column == NULL) {
- TRACE_ERROR("[CHECK COLUMN NAME]");
- return -1;
- }
- if (condcolumn == NULL) {
- TRACE_ERROR("[CHECK Condition]");
- return -1;
- }
+ if (wherecolumn == NULL)
+ wherecolumn = DP_DB_COL_ID;
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("__dp_sql_open[%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s IS ?",
- column, table, condcolumn);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
- return -1;
- }
- ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &stmt, NULL);
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s = ? LIMIT 1", getcolumn, table, wherecolumn);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(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;
- }
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (__dp_sql_bind_value(stmt, condtype, condvalue, 1) != SQLITE_OK) {
- TRACE_ERROR
- ("[BIND][%d][%s]", condtype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
- if (sqlite3_step(stmt) == SQLITE_ROW &&
- sqlite3_column_type(stmt, 0) == SQLITE_INTEGER) {
- int columnvalue = sqlite3_column_int(stmt, 0);
- __dp_finalize(stmt);
- return columnvalue;
+ errorcode = sqlite3_bind_int(stmt, 1, wherevalue);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+
+ *error = DP_ERROR_NONE;
+ errorcode = sqlite3_step(stmt);
+ *length = 0;
+ if (errorcode == SQLITE_ROW) {
+ int data_type = sqlite3_column_type(stmt, 0);
+ if (data_type == SQLITE_TEXT) {
+ int getbytes = sqlite3_column_bytes(stmt, 0);
+ if (getbytes > 0) {
+ unsigned char *getstr = (unsigned char *)calloc(getbytes + 1, sizeof(unsigned char));
+ if (getstr != NULL) {
+ memcpy(getstr, sqlite3_column_text(stmt, 0), getbytes * sizeof(unsigned char));
+ getstr[getbytes] = '\0';
+ *value = getstr;
+ *length = getbytes;
+ } else {
+ TRACE_ERROR("check available system memory");
+ *error = DP_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else if (data_type == SQLITE_BLOB) {
+ int getbytes = sqlite3_column_bytes(stmt, 0);
+ if (getbytes > 0) {
+ unsigned char *getstr = (unsigned char *)calloc(getbytes, sizeof(unsigned char));
+ if (getstr != NULL) {
+ memcpy(getstr, sqlite3_column_blob(stmt, 0), getbytes * sizeof(unsigned char));
+ *value = getstr;
+ *length = getbytes;
+ } else {
+ TRACE_ERROR("check available system memory");
+ *error = DP_ERROR_OUT_OF_MEMORY;
+ }
+ }else {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else {
+ TRACE_ERROR("check column type:%d", data_type);
+ *error = DP_ERROR_NO_DATA;
+ }
+ } else if (errorcode == SQLITE_ROW) {
+ TRACE_DEBUG("no data");
+ *error = DP_ERROR_NO_DATA;
+ } else {
+ if ((*error = dp_db_get_errorcode(handle)) == DP_ERROR_NONE)
+ *error = DP_ERROR_ID_NOT_FOUND;
}
__dp_finalize(stmt);
- return -1;
+ if (*error != DP_ERROR_NO_DATA && *error != DP_ERROR_NONE)
+ return -1;
+ return 0;
}
-int dp_db_get_cond_rows_count(int id, char *table,
- char *condcolumn, db_column_data_type condtype,
- void *condvalue)
+int dp_db_limit_rows(void *handle, const char *table, int limit, int *error)
{
- int errorcode = SQLITE_OK;
- int ret = -1;
- sqlite3_stmt *stmt = NULL;
- char *query = NULL;
-
- if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ if (table == NULL) {
+ TRACE_ERROR("check materials for query");
return -1;
}
-
- if (!table) {
- TRACE_ERROR("[CHECK TABLE NAME]");
+ if (limit < 0) {
+ TRACE_ERROR("check limitation:%d", limit);
return -1;
}
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("db_util_open is failed [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("DELETE FROM %s WHERE %s NOT IN (SELECT %s FROM %s ORDER BY %s ASC LIMIT ?)", table, DP_DB_COL_ID, DP_DB_COL_ID, table, DP_DB_COL_CREATE_TIME);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (condcolumn)
- query =
- sqlite3_mprintf
- ("SELECT count(id) FROM %s WHERE id = ? AND %s = ?",
- table, condcolumn);
- else
- query =
- sqlite3_mprintf
- ("SELECT count(id) FROM %s WHERE id = ?", table);
+ errorcode = sqlite3_bind_int(stmt, 1, limit);
+ DP_DB_BASIC_EXCEPTION_CHECK;
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
- return -1;
- }
+ // apply "ON DELETE CASCADE"
- 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;
- }
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
+ return 0;
+}
- if (condcolumn) {
- if (condtype == DP_DB_COL_TYPE_INT) {
- int *cast_value = condvalue;
- errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
- } else if (condtype == DP_DB_COL_TYPE_INT64) {
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = condvalue;
- errorcode = sqlite3_bind_int64(stmt, 2, *cast_value);
-#else
- int *cast_value = condvalue;
- errorcode = sqlite3_bind_int(stmt, 2, *cast_value);
-#endif
- } else if (condtype == DP_DB_COL_TYPE_TEXT) {
- errorcode = sqlite3_bind_text(stmt, 2, (char*)condvalue, -1, NULL);
- } else {
- TRACE_ERROR("[CHECK TYPE] Not Support [%d]", condtype);
- __dp_finalize(stmt);
- return -1;
- }
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%d] [%s]",
- condtype, sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+int dp_db_limit_time(void *handle, const char *table, int hours, int *error)
+{
+ *error = DP_ERROR_INVALID_PARAMETER;
+ DP_DB_PARAM_NULL_CHECK;
+ if (table == NULL) {
+ TRACE_ERROR("check materials for query");
+ return -1;
}
-
- if (sqlite3_bind_int(stmt, 1, id)
- != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int[%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
+ if (hours <= 0) {
+ TRACE_ERROR("check limit time:%d", hours);
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);
+ int errorcode = SQLITE_OK;
+ sqlite3_stmt *stmt = NULL;
+ char *query = sqlite3_mprintf("DELETE FROM %s WHERE %s < DATETIME('now','-%d hours')", table, DP_DB_COL_CREATE_TIME, hours);
+ DP_DB_BUFFER_NULL_CHECK(query);
+ //TRACE_DEBUG("debug query:%s", query);
+ errorcode = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ sqlite3_free(query);
+ DP_DB_BASIC_EXCEPTION_CHECK;
+ *error = DP_ERROR_NONE;
+ DP_DB_WRITE_STEP_EXCEPTION_CHECK;
return 0;
}
-int dp_db_get_http_headers_list(int id, char **headers)
+int dp_db_get_http_headers_list(void *handle, int id, char **headers, int *error)
{
int errorcode = SQLITE_OK;
- int i = 0;
int headers_index = 0;
sqlite3_stmt *stmt = NULL;
+ *error = DP_ERROR_NONE;
+ DP_DB_PARAM_NULL_CHECK;
if (id <= 0) {
TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("db_util_open is failed [%s]",
- sqlite3_errmsg(g_dp_db_handle));
+ *error = DP_ERROR_INVALID_PARAMETER;
return -1;
}
errorcode =
- sqlite3_prepare_v2(g_dp_db_handle,
- "SELECT header_field, header_data FROM httpheaders WHERE id = ?",
+ sqlite3_prepare_v2(handle,
+ "SELECT header_field, header_data FROM header WHERE id = ?",
-1, &stmt, NULL);
- if (errorcode != SQLITE_OK) {
- TRACE_ERROR("sqlite3_prepare_v2 is failed. [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
- if (sqlite3_bind_int(stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("sqlite3_bind_int [%s]",
- sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
- }
+
+ DP_DB_BASIC_EXCEPTION_CHECK;
+
+ errorcode = sqlite3_bind_int(stmt, 1, id);
+
+ DP_DB_BASIC_EXCEPTION_CHECK;
while ((errorcode = sqlite3_step(stmt)) == SQLITE_ROW) {
int buffer_length = 0;
char *header_field = (char *)(sqlite3_column_text(stmt, 0));
char *header_data = (char *)(sqlite3_column_text(stmt, 1));
- i++;
+
// REF : http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
buffer_length = strlen(header_field) + strlen(header_data) + 1;
char *headers_buffer = calloc(buffer_length + 1, sizeof(char));
@@ -1750,600 +1316,7 @@ 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;
- char *temp_dest = NULL;
-
- if (dest == NULL || src == NULL)
- return NULL;
-
- dest_length = strlen(dest);
- src_length = strlen(src);
-
- temp_dest = sqlite3_realloc(dest, dest_length + src_length + 1);
- if (temp_dest == NULL) {
- free(dest);
- return NULL;
- }
- temp_dest = strncat(temp_dest, &sep, 1);
- temp_dest = strncat(temp_dest, src, src_length);
- return temp_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);
- break;
- case DP_DB_COL_TYPE_INT64:
-#ifdef SQLITE_INT64_TYPE
- sqlite3_int64 *cast_value = value;
- errorcode = sqlite3_bind_int64(stmt, index, *cast_value);
-#else
- cast_value = value;
- errorcode = sqlite3_bind_int(stmt, index, *cast_value);
-#endif
- break;
- case DP_DB_COL_TYPE_TEXT:
- errorcode =
- sqlite3_bind_text(stmt, index, (char *)value, -1, SQLITE_STATIC);
- 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_DEBUG("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;
- }
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_finalize(stmt);
- return -1;
-}
-
-int dp_db_update_columns(int id, 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 (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
- 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("UPDATE %s SET %s = ?", table, 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, "WHERE id = ?", ' ');
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
- return -1;
- }
- TRACE_DEBUG("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;
- }
- }
- if (sqlite3_bind_int(stmt, column_count + 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] ID [%s]", 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;
- }
- TRACE_ERROR("[SQL] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __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;
- }
-
- 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;
- }
-
- 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;
-}
-
-static void __dp_db_reset(sqlite3_stmt *stmt)
-{
- if (stmt != 0) {
- sqlite3_clear_bindings(stmt);
- if (sqlite3_reset(stmt) != SQLITE_OK) {
- sqlite3 *handle = sqlite3_db_handle(stmt);
- TRACE_ERROR("failed sqlite3_reset [%s]",
- sqlite3_errmsg(handle));
- }
- }
-}
-
-int dp_db_request_new_logging(const int id, const int state, const char *pkgname)
-{
- int errorcode = SQLITE_OK;
- int ret = -1;
- char *query = NULL;
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[SQL HANDLE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- if (g_dp_db_logging_new_stmt == NULL) {
- query =
- sqlite3_mprintf("INSERT INTO %s (%s, %s, %s, %s) VALUES (?, ?, ?, DATETIME('now'))",
- DP_DB_TABLE_LOG, DP_DB_COL_ID, DP_DB_COL_STATE,
- DP_DB_COL_PACKAGENAME, DP_DB_COL_CREATE_TIME);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
- return -1;
- }
-
- TRACE_DEBUG("query:%s", query);
-
- ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &g_dp_db_logging_new_stmt, NULL);
- sqlite3_free(query);
- if (ret != SQLITE_OK) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
- }
- if (sqlite3_bind_int(g_dp_db_logging_new_stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_db_reset(g_dp_db_logging_new_stmt);
- return -1;
- }
- if (sqlite3_bind_int(g_dp_db_logging_new_stmt, 2, state) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_db_reset(g_dp_db_logging_new_stmt);
- return -1;
- }
- if (sqlite3_bind_text(g_dp_db_logging_new_stmt, 3, pkgname, -1, SQLITE_STATIC) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_db_reset(g_dp_db_logging_new_stmt);
- return -1;
- }
-
- errorcode = sqlite3_step(g_dp_db_logging_new_stmt);
- __dp_db_reset(g_dp_db_logging_new_stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- return 0;
- }
- return -1;
-}
-
-int dp_db_request_update_status(const int id, const int state, const int download_error)
-{
- int errorcode = SQLITE_OK;
- int ret = -1;
- char *query = NULL;
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[SQL HANDLE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- if (g_dp_db_logging_status_stmt == NULL) {
- query =
- sqlite3_mprintf("UPDATE %s SET %s = ?, %s = ?, %s = DATETIME('now') WHERE %s = ?",
- DP_DB_TABLE_LOG, DP_DB_COL_STATE, DP_DB_COL_ERRORCODE,
- DP_DB_COL_ACCESS_TIME, DP_DB_COL_ID);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
- return -1;
- }
-
- TRACE_DEBUG("query:%s", query);
-
- ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &g_dp_db_logging_status_stmt, NULL);
- sqlite3_free(query);
- if (ret != SQLITE_OK) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
- }
- if (sqlite3_bind_int(g_dp_db_logging_status_stmt, 1, state) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_db_reset(g_dp_db_logging_status_stmt);
- return -1;
- }
- if (sqlite3_bind_int(g_dp_db_logging_status_stmt, 2, download_error) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_db_reset(g_dp_db_logging_status_stmt);
- return -1;
- }
- if (sqlite3_bind_int(g_dp_db_logging_status_stmt, 3, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_db_reset(g_dp_db_logging_status_stmt);
- return -1;
- }
-
- errorcode = sqlite3_step(g_dp_db_logging_status_stmt);
- __dp_db_reset(g_dp_db_logging_status_stmt);
- if (errorcode == SQLITE_OK || errorcode == SQLITE_DONE) {
- return 0;
- }
- return -1;
+ return headers_index;
}
-int dp_db_get_state(int id)
-{
- if (id <= 0) {
- TRACE_ERROR("[CHECK ID]");
- return -1;
- }
-
- if (__dp_sql_open() < 0) {
- TRACE_ERROR("[OPEN] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
-
- if (g_dp_db_logging_get_state_stmt == NULL) {
- char *query = sqlite3_mprintf("SELECT %s FROM %s WHERE %s = ?",
- DP_DB_COL_STATE, DP_DB_TABLE_LOG, DP_DB_COL_ID);
- if (query == NULL) {
- TRACE_ERROR("[CHECK COMBINE]");
- return -1;
- }
-
- TRACE_DEBUG("query:%s", query);
-
- int ret = sqlite3_prepare_v2(g_dp_db_handle, query, -1, &g_dp_db_logging_get_state_stmt, NULL);
- sqlite3_free(query);
- if (ret != SQLITE_OK) {
- TRACE_ERROR("[PREPARE] [%s]", sqlite3_errmsg(g_dp_db_handle));
- return -1;
- }
- }
-
- if (sqlite3_bind_int(g_dp_db_logging_get_state_stmt, 1, id) != SQLITE_OK) {
- TRACE_ERROR("[BIND] [%s]", sqlite3_errmsg(g_dp_db_handle));
- __dp_db_reset(g_dp_db_logging_get_state_stmt);
- return -1;
- }
-
- int state = DP_STATE_NONE;
- if (sqlite3_step(g_dp_db_logging_get_state_stmt) == SQLITE_ROW) {
- state = sqlite3_column_int(g_dp_db_logging_get_state_stmt, 0);
- }
- __dp_db_reset(g_dp_db_logging_get_state_stmt);
- return state;
-}
diff --git a/provider/download-provider-ipc.c b/provider/download-provider-ipc.c
new file mode 100644
index 0000000..e79a6f7
--- /dev/null
+++ b/provider/download-provider-ipc.c
@@ -0,0 +1,132 @@
+/*
+ * 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 <time.h>
+
+#include <sys/socket.h> // shutdown
+
+#include "download-provider-log.h"
+#include "download-provider-ipc.h"
+
+int dp_ipc_check_stderr(int basecode)
+{
+ int errorcode = basecode;
+ if (errno == EPIPE) {
+ TRACE_STRERROR("[EPIPE:%d] Broken Pipe", errno);
+ errorcode = DP_ERROR_IO_ERROR;
+ } else if (errno == EAGAIN) {
+ TRACE_STRERROR("[EAGAIN:%d]", errno);
+ errorcode = DP_ERROR_IO_EAGAIN;
+ } else if (errno == EINTR) {
+ TRACE_STRERROR("[EINTR:%d]", errno);
+ errorcode = DP_ERROR_IO_EINTR;
+ } else if (errno == ENOENT) {
+ TRACE_STRERROR("[ENOENT:%d]", errno);
+ errorcode = DP_ERROR_IO_ERROR;
+ } else {
+ TRACE_STRERROR("[errno:%d]", errno);
+ }
+ return errorcode;
+}
+
+int dp_ipc_write(int sock, void *value, size_t type_size)
+{
+ if (sock < 0) {
+ TRACE_ERROR("[ERROR] check sock:%d", sock);
+ return -1;
+ } else if (value == NULL) {
+ TRACE_ERROR("[ERROR] check buffer sock:%d", sock);
+ return -1;
+ } else if (write(sock, value, type_size) <= 0) {
+ TRACE_STRERROR("[IPC.Write] exception sock:%d", sock);
+ return -1;
+ }
+ return 0;
+}
+
+ssize_t dp_ipc_read(int sock, void *value, size_t type_size,
+ const char *func)
+{
+ int errorcode = DP_ERROR_NONE;
+ ssize_t recv_bytes = 0;
+
+ if (sock < 0) {
+ TRACE_ERROR("[ERROR] %s check sock:%d", func, sock);
+ return -1;
+ }
+ if (value == NULL) {
+ TRACE_ERROR("[ERROR] %s check buffer sock:%d", func, sock);
+ return -1;
+ }
+
+ int tryagain = 3;
+ do {
+ errorcode = DP_ERROR_NONE;
+ recv_bytes = read(sock, value, type_size);
+ if (recv_bytes < 0) {
+ TRACE_ERROR("[IPC.Read] %s exception sock:%d", func, sock);
+ errorcode = dp_ipc_check_stderr(DP_ERROR_IO_ERROR);
+ } else if (recv_bytes == 0) {
+ TRACE_ERROR("[ERROR] %s closed peer sock:%d", func, sock);
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ } while (sock >= 0 && (errorcode == DP_ERROR_IO_EAGAIN ||
+ errorcode == DP_ERROR_IO_EINTR) && (--tryagain > 0));
+ return recv_bytes;
+}
+
+dp_ipc_fmt *dp_ipc_get_fmt(int sock)
+{
+ dp_ipc_fmt *ipc_info = malloc(sizeof(dp_ipc_fmt));
+ if (ipc_info == NULL) {
+ TRACE_ERROR("[ERROR] Fail to malloc");
+ return NULL;
+ }
+ memset(ipc_info, 0x00, sizeof(dp_ipc_fmt));
+ ssize_t recv_size = read(sock, ipc_info, sizeof(dp_ipc_fmt));
+ if (recv_size <= 0 || recv_size != sizeof(dp_ipc_fmt)) {
+ TRACE_STRERROR("socket read ipcinfo read size:%d", recv_size);
+ free(ipc_info);
+ return NULL;
+ }
+ return ipc_info;
+}
+
+int dp_ipc_query(int sock, int download_id, short section,
+ unsigned property, int error, size_t size)
+{
+ dp_ipc_fmt ipc_info;
+ memset(&ipc_info, 0x00, sizeof(dp_ipc_fmt));
+ ipc_info.section = section;
+ ipc_info.property = property;
+ ipc_info.id = download_id;
+ ipc_info.errorcode = error;
+ ipc_info.size = size;
+ if (dp_ipc_write(sock, &ipc_info, sizeof(dp_ipc_fmt)) < 0)
+ return -1;
+ return 0;
+}
+
+int dp_ipc_socket_free(int sockfd)
+{
+ if (sockfd < 0)
+ return -1;
+ close(sockfd);
+ return 0;
+}
diff --git a/provider/download-provider-main.c b/provider/download-provider-main.c
index 6e71cb5..ded45db 100755
--- a/provider/download-provider-main.c
+++ b/provider/download-provider-main.c
@@ -17,295 +17,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <glib.h>
-#include <glib-object.h>
#include <pthread.h>
-#include <locale.h>
-#include <libintl.h>
-#include <systemd/sd-daemon.h>
-#include "vconf.h"
+#include <systemd/sd-daemon.h>
+#include <glib-object.h>
#include "download-provider-config.h"
#include "download-provider-log.h"
-#include "download-provider-socket.h"
-#include "download-provider-pthread.h"
-#include "download-provider-slots.h"
-#include "download-provider-db.h"
+#include "download-provider-client-manager.h"
#include "download-provider-network.h"
-#include "download-provider-queue.h"
-#include "download-provider-notification.h"
-#include "download-provider-da-interface.h"
-
-// declare functions
-int dp_lock_pid(char *path);
-void *dp_thread_requests_manager(void *arg);
-static pthread_t g_dp_thread_queue_manager_pid = 0;
-
-// declare global variables
-// need for libsoup, decided the life-time by mainloop.
-GMainLoop *g_main_loop_handle = 0;
-
-void dp_terminate(int signo)
-{
- TRACE_DEBUG("Received SIGTERM:%d", signo);
- if (g_main_loop_is_running(g_main_loop_handle))
- g_main_loop_quit(g_main_loop_handle);
-}
-
-static gboolean __dp_idle_start_service(void *data)
-{
- // declare all resources
- pthread_t thread_pid;
- pthread_attr_t thread_attr;
-
- // initialize
- if (pthread_attr_init(&thread_attr) != 0) {
- TRACE_STRERROR("failed to init pthread attr");
- dp_terminate(SIGTERM);
- return FALSE;
- }
- if (pthread_attr_setdetachstate(&thread_attr,
- PTHREAD_CREATE_DETACHED) != 0) {
- TRACE_STRERROR("failed to set detach option");
- dp_terminate(SIGTERM);
- return FALSE;
- }
-
- // create thread for managing QUEUEs
- if (pthread_create
- (&g_dp_thread_queue_manager_pid, NULL, dp_thread_queue_manager,
- data) != 0) {
- TRACE_STRERROR
- ("failed to create pthread for run_manage_download_server");
- dp_terminate(SIGTERM);
- }
- // start service, accept url-download ( client package )
- if (pthread_create
- (&thread_pid, &thread_attr, dp_thread_requests_manager,
- data) != 0) {
- TRACE_STRERROR
- ("failed to create pthread for run_manage_download_server");
- dp_terminate(SIGTERM);
- }
- return FALSE;
-}
-
-void __set_locale()
-{
- char *str = NULL;
- str = vconf_get_str(VCONFKEY_LANGSET);
- if (str != NULL) {
- setlocale(LC_ALL, str);
- bindtextdomain(PKG_NAME, LOCALE_DIR);
- textdomain(PKG_NAME);
- }
- free(str);
-}
-void __lang_changed_cb(keynode_t *key, void* data)
-{
- __set_locale();
-}
+void *dp_client_manager(void *arg);
int main(int argc, char **argv)
{
- dp_privates *privates = NULL;
- int lock_fd = -1;
-
- if (chdir("/") < 0) {
- TRACE_STRERROR("failed to call setsid or chdir");
- exit(EXIT_FAILURE);
- }
-
-#if 0
- // close all console I/O
- close(STDIN_FILENO);
- close(STDOUT_FILENO);
- close(STDERR_FILENO);
-#endif
-
- if (signal(SIGTERM, dp_terminate) == SIG_ERR) {
- 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);
- }
- if (signal(SIGINT, dp_terminate) == 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
- ("It need to check download-provider is already alive");
- TRACE_ERROR("Or fail to create pid file in (%s)",
- DP_LOCK_PID);
- exit(EXIT_FAILURE);
- }
+ GMainLoop *event_loop;
+ pthread_t tid;
+ TRACE_INFO("download-provider's working is started");
g_type_init();
- // locale
- __set_locale();
- if (vconf_notify_key_changed(VCONFKEY_LANGSET, __lang_changed_cb, NULL) != 0)
- TRACE_ERROR("Fail to set language changed vconf callback");
-
- privates = (dp_privates *) calloc(1, sizeof(dp_privates));
- if (!privates) {
- TRACE_ERROR("[CRITICAL] failed to alloc for private info");
- goto DOWNLOAD_EXIT;
- }
- privates->groups = dp_client_group_slots_new(DP_MAX_GROUP);
- if (privates->groups == NULL) {
- TRACE_ERROR("[CRITICAL] failed to alloc for groups");
- goto DOWNLOAD_EXIT;
+ event_loop = g_main_loop_new(NULL, FALSE);
+ if (!event_loop) {
+ TRACE_ERROR("Failed to create g main loop handle");
+ return 0;
}
- privates->requests = dp_request_slots_new(DP_MAX_REQUEST);
- if (privates->requests == NULL) {
- TRACE_ERROR("[CRITICAL] failed to alloc for requests");
- goto DOWNLOAD_EXIT;
+ // check network status
+ if (dp_network_connection_init() < 0) {
+ TRACE_ERROR("failed to init network-manager");
+ return 0;
}
-
- // ready socket ( listen )
- privates->listen_fd = dp_accept_socket_new();
- if (privates->listen_fd < 0) {
- TRACE_ERROR("[CRITICAL] failed to bind SOCKET");
- goto DOWNLOAD_EXIT;
+ // create a thread for main thread
+ if (pthread_create(&tid, NULL, dp_client_manager, (void *)event_loop) != 0) {
+ TRACE_ERROR("failed to create main thread");
+ return 0;
+ } else {
+ pthread_detach(tid);
+ TRACE_INFO("download main thread is created[%lu]", tid);
}
- dp_db_open();
-
- // convert to request type, insert all to privates->requests
- // timeout of request thread will start these jobs by queue thread
- // load all list from (queue table)
- if (dp_db_crashed_list(privates->requests, DP_MAX_REQUEST) > 0) {
- int i = 0;
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- if (!privates->requests[i].request)
- continue;
- dp_request *request = privates->requests[i].request;
- TRACE_DEBUG
- ("ID [%d] state[%d]", request->id, request->state);
-
- // load to memory, Can be started automatically.
- if (request->state == DP_STATE_DOWNLOADING ||
- request->state == DP_STATE_CONNECTING) {
- request->state = DP_STATE_QUEUED;
- 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("[CHECK SQL]");
- }
- }
-
- if (request->state == DP_STATE_QUEUED) {
- int auto_download = dp_db_get_int_column(request->id,
- DP_DB_TABLE_REQUEST_INFO,
- DP_DB_COL_AUTO_DOWNLOAD);
- if (auto_download == 1) {
- // auto retry... defaultly, show notification
- request->auto_notification = 1;
- request->start_time = (int)time(NULL);
- continue;
- }
- // do not retry this request
- request->state = DP_STATE_FAILED;
- request->error = DP_ERROR_SYSTEM_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("[CHECK SQL]");
- }
- 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("[CHECK SQL]");
- }
- }
+ TRACE_INFO("g main loop is started");
+ g_main_loop_run(event_loop);
+ dp_network_connection_destroy();
+ g_main_loop_unref(event_loop);
- // if wanna restart, call continue before this line.
- // default. update state/error. move to history. unload memory
- // remove from memory
- dp_request_free(request);
- privates->requests[i].request = NULL;
- }
- } // query crashed_list
-
-#if 0
- if (argc != 2 || memcmp(argv[1], "service", 7) != 0) {
- // in first launch in booting time, not request. terminate by self
- if (dp_get_request_count(privates->requests) <= 0) {
- TRACE_DEBUG("First Boot, No Request");
- goto DOWNLOAD_EXIT;
- }
- }
-#endif
-
- dp_clear_downloadinginfo_notification();
-
- if (dp_init_agent() != DP_ERROR_NONE) {
- TRACE_ERROR("[CRITICAL] failed to init agent");
- goto DOWNLOAD_EXIT;
- }
-
- privates->connection = 0;
- privates->network_status = DP_NETWORK_TYPE_OFF;
- if (dp_network_connection_init(privates) < 0) {
- TRACE_DEBUG("use instant network check");
- privates->connection = 0;
- }
-
- // libsoup need mainloop.
- g_main_loop_handle = g_main_loop_new(NULL, 0);
-
- g_idle_add(__dp_idle_start_service, privates);
-
- sd_notify(0, "READY=1");
-
- g_main_loop_run(g_main_loop_handle);
-
-DOWNLOAD_EXIT :
-
- TRACE_DEBUG("Download-Provider will be terminated.");
- if (vconf_ignore_key_changed(VCONFKEY_LANGSET, __lang_changed_cb) != 0)
- TRACE_ERROR("Fail to unset language changed vconf callback");
-
- dp_deinit_agent();
-
- if (privates != NULL) {
-
- if (privates->connection)
- dp_network_connection_destroy(privates->connection);
-
- if (privates->listen_fd >= 0)
- privates->listen_fd = -1;
-
- if (g_dp_thread_queue_manager_pid > 0 &&
- pthread_kill(g_dp_thread_queue_manager_pid, 0) != ESRCH) {
- //pthread_cancel(g_dp_thread_queue_manager_pid);
- //send signal to queue thread
- dp_thread_queue_manager_wake_up();
- int status;
- pthread_join(g_dp_thread_queue_manager_pid, (void **)&status);
- g_dp_thread_queue_manager_pid = 0;
- }
- dp_request_slots_free(privates->requests, DP_MAX_REQUEST);
- privates->requests = NULL;
- dp_client_group_slots_free(privates->groups, DP_MAX_GROUP);
- privates->groups = NULL;
- free(privates);
- privates = NULL;
- }
- dp_db_close();
-
- // delete pid file
- if (access(DP_LOCK_PID, F_OK) == 0) {
- close(lock_fd);
- unlink(DP_LOCK_PID);
- }
- exit(EXIT_SUCCESS);
+ TRACE_INFO("download-provider's working is done");
+ return 0;
}
diff --git a/provider/download-provider-network.c b/provider/download-provider-network.c
index ac3fc5b..5fafe2c 100755
--- a/provider/download-provider-network.c
+++ b/provider/download-provider-network.c
@@ -14,224 +14,130 @@
* limitations under the License.
*/
+#include "download-provider.h"
#include "download-provider-log.h"
-#include "download-provider-config.h"
#include "download-provider-pthread.h"
#include "download-provider-network.h"
+#include "download-provider-client-manager.h"
+
+#include <net_connection.h>
#ifdef SUPPORT_WIFI_DIRECT
#include <wifi-direct.h>
#endif
-extern pthread_mutex_t g_dp_queue_mutex;
-extern pthread_cond_t g_dp_queue_cond;
-
-#if 0
-typedef enum
-{
- CONNECTION_TYPE_DISCONNECTED = 0, /**< Disconnected */
- CONNECTION_TYPE_WIFI = 1, /**< Wi-Fi type */
- CONNECTION_TYPE_CELLULAR = 2, /**< Cellular type */
- CONNECTION_TYPE_ETHERNET = 3, /**< Ethernet type */
- CONNECTION_TYPE_BT = 4, /**< Bluetooth type */
-} connection_type_e;
-typedef enum
-{
- CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE = 0, /**< Out of service */
- CONNECTION_CELLULAR_STATE_FLIGHT_MODE = 1, /**< Flight mode */
- CONNECTION_CELLULAR_STATE_ROAMING_OFF = 2, /**< Roaming is turned off */
- CONNECTION_CELLULAR_STATE_CALL_ONLY_AVAILABLE = 3, /**< Call is only available */
- CONNECTION_CELLULAR_STATE_AVAILABLE = 4, /**< Available but not connected yet */
- CONNECTION_CELLULAR_STATE_CONNECTED = 5, /**< Connected */
-} connection_cellular_state_e
-typedef enum
-{
- CONNECTION_WIFI_STATE_DEACTIVATED = 0, /**< Deactivated state */
- CONNECTION_WIFI_STATE_DISCONNECTED = 1, /**< disconnected state */
- CONNECTION_WIFI_STATE_CONNECTED = 2, /**< Connected state */
-} connection_wifi_state_e;
-typedef enum
-{
- CONNECTION_ETHERNET_STATE_DEACTIVATED = 0, /**< Deactivated state */
- CONNECTION_ETHERNET_STATE_DISCONNECTED = 1, /**< disconnected state */
- CONNECTION_ETHERNET_STATE_CONNECTED = 2, /**< Connected state */
-} connection_ethernet_state_e;
-typedef enum
-{
- CONNECTION_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
- CONNECTION_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- CONNECTION_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory error */
- CONNECTION_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid Operation */
- CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED = TIZEN_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED, /**< Address family not supported */
- CONNECTION_ERROR_OPERATION_FAILED = TIZEN_ERROR_NETWORK_CLASS|0x0401, /**< Operation failed */
- CONNECTION_ERROR_ITERATOR_END = TIZEN_ERROR_NETWORK_CLASS|0x0402, /**< End of iteration */
- CONNECTION_ERROR_NO_CONNECTION = TIZEN_ERROR_NETWORK_CLASS|0x0403, /**< There is no connection */
- CONNECTION_ERROR_NOW_IN_PROGRESS = TIZEN_ERROR_NOW_IN_PROGRESS, /** Now in progress */
- CONNECTION_ERROR_ALREADY_EXISTS = TIZEN_ERROR_NETWORK_CLASS|0x0404, /**< Already exists */
- CONNECTION_ERROR_OPERATION_ABORTED = TIZEN_ERROR_NETWORK_CLASS|0x0405, /**< Operation is aborted */
- CONNECTION_ERROR_DHCP_FAILED = TIZEN_ERROR_NETWORK_CLASS|0x0406, /**< DHCP failed */
- CONNECTION_ERROR_INVALID_KEY = TIZEN_ERROR_NETWORK_CLASS|0x0407, /**< Invalid key */
- CONNECTION_ERROR_NO_REPLY = TIZEN_ERROR_NETWORK_CLASS|0x0408, /**< No reply */
-} connection_error_e;
-
+pthread_mutex_t g_dp_network_mutex = PTHREAD_MUTEX_INITIALIZER;
+int g_network_status = DP_NETWORK_OFF;
+connection_h g_network_connection = 0;
+int g_network_is_wifi_direct = 0;
-static void __print_connection_errorcode_to_string(connection_error_e errorcode)
-{
- switch(errorcode)
- {
- case CONNECTION_ERROR_INVALID_PARAMETER :
- TRACE_DEBUG("CONNECTION_ERROR_INVALID_PARAMETER");
- break;
- case CONNECTION_ERROR_OUT_OF_MEMORY :
- TRACE_DEBUG("CONNECTION_ERROR_OUT_OF_MEMORY");
- break;
- case CONNECTION_ERROR_INVALID_OPERATION :
- TRACE_DEBUG("CONNECTION_ERROR_INVALID_OPERATION");
- break;
- case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED :
- TRACE_DEBUG("CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED");
- break;
- case CONNECTION_ERROR_OPERATION_FAILED :
- TRACE_DEBUG("CONNECTION_ERROR_OPERATION_FAILED");
- break;
- case CONNECTION_ERROR_ITERATOR_END :
- TRACE_DEBUG("CONNECTION_ERROR_ITERATOR_END");
- break;
- case CONNECTION_ERROR_NO_CONNECTION :
- TRACE_DEBUG("CONNECTION_ERROR_NO_CONNECTION");
- break;
- case CONNECTION_ERROR_NOW_IN_PROGRESS :
- TRACE_DEBUG("CONNECTION_ERROR_NOW_IN_PROGRESS");
- break;
- case CONNECTION_ERROR_ALREADY_EXISTS :
- TRACE_DEBUG("CONNECTION_ERROR_ALREADY_EXISTS");
- break;
- case CONNECTION_ERROR_OPERATION_ABORTED :
- TRACE_DEBUG("CONNECTION_ERROR_OPERATION_ABORTED");
- break;
- case CONNECTION_ERROR_DHCP_FAILED :
- TRACE_DEBUG("CONNECTION_ERROR_DHCP_FAILED");
- break;
- case CONNECTION_ERROR_INVALID_KEY :
- TRACE_DEBUG("CONNECTION_ERROR_INVALID_KEY");
- break;
- case CONNECTION_ERROR_NO_REPLY :
- TRACE_DEBUG("CONNECTION_ERROR_NO_REPLY");
- break;
- default :
- TRACE_DEBUG("CONNECTION_ERROR_NONE");
- break;
- }
-}
+#ifdef SUPPORT_COMPANION_MODE
+// support B3 companion mode
+#include "vconf.h"
+#include "vconf-keys.h"
+#include "SAPInterface.h"
+#define VCONFKEY_SAP_CONNECTION_NOTIFICATION VCONFKEY_WMS_WMANAGER_CONNECTED
+#define VCONFKEY_SAP_CONNECTION_TYPE "memory/private/sap/conn_type"
#endif
-
-#ifdef SUPPORT_WIFI_DIRECT
-// support WIFI-Direct
-static void __dp_network_wifi_direct_connection_state_changed_cb(wifi_direct_error_e error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *data)
+static int __dp_network_is_companion_mode()
{
- dp_privates *privates = (dp_privates*)data;
- if (privates == NULL) {
- TRACE_ERROR("[CRITICAL] Invalid data");
- return ;
- }
+#ifdef SUPPORT_COMPANION_MODE
+ int wms_connected = 0;
+ int companion_mode = 0;
+ vconf_get_int(VCONFKEY_SAP_CONNECTION_NOTIFICATION, &wms_connected);
+ vconf_get_int(VCONFKEY_SAP_CONNECTION_TYPE, &companion_mode);
+ TRACE_INFO("wms_connected:%d, companion_mode:%d", wms_connected, companion_mode);
+ if (wms_connected == 1 && (companion_mode & SAP_BT))
+ return 1;
- if (connection_state == WIFI_DIRECT_CONNECTION_RSP) {
- TRACE_DEBUG("WIFI_DIRECT_CONNECTION_RSP");
- privates->is_connected_wifi_direct = 1;
- return ;
- }
- privates->is_connected_wifi_direct = 0;
+#endif
+ return 0;
}
-//return 0 : connected
-int dp_network_wifi_direct_is_connected()
+#ifdef SUPPORT_WIFI_DIRECT
+
+static int __dp_network_wifi_direct_status()
{
- int is_connected = -1;
+ int is_connected = 0;
wifi_direct_state_e wifi_state = WIFI_DIRECT_STATE_DEACTIVATED;
if (wifi_direct_get_state(&wifi_state) == 0) {
- switch (wifi_state)
- {
- case WIFI_DIRECT_STATE_DEACTIVATED :
- TRACE_DEBUG("WIFI_DIRECT_STATE_DEACTIVATED");
- break;
- case WIFI_DIRECT_STATE_DEACTIVATING :
- TRACE_DEBUG("WIFI_DIRECT_STATE_DEACTIVATING");
- break;
- case WIFI_DIRECT_STATE_ACTIVATING :
- TRACE_DEBUG("WIFI_DIRECT_STATE_ACTIVATING");
- break;
- case WIFI_DIRECT_STATE_ACTIVATED :
- TRACE_DEBUG("WIFI_DIRECT_STATE_ACTIVATED");
- break;
- case WIFI_DIRECT_STATE_DISCOVERING :
- TRACE_DEBUG("WIFI_DIRECT_STATE_DISCOVERING");
- break;
- case WIFI_DIRECT_STATE_CONNECTING :
- TRACE_DEBUG("WIFI_DIRECT_STATE_CONNECTING");
- break;
- case WIFI_DIRECT_STATE_DISCONNECTING :
- TRACE_DEBUG("WIFI_DIRECT_STATE_DISCONNECTING");
- break;
- case WIFI_DIRECT_STATE_CONNECTED :
- is_connected = 0;
- TRACE_DEBUG("WIFI_DIRECT_STATE_CONNECTED");
- break;
- default :
- break;
+ if (wifi_state == WIFI_DIRECT_STATE_CONNECTED) {
+ TRACE_INFO("WIFI_DIRECT_STATE_CONNECTED");
+ is_connected = 1;
}
}
return is_connected;
}
-#endif
+// support WIFI-Direct
+static void __dp_network_wifi_direct_changed_cb
+ (wifi_direct_error_e error_code,
+ wifi_direct_connection_state_e connection_state,
+ const char *mac_address, void *data)
+{
+ pthread_mutex_lock(&g_dp_network_mutex);
+ if (connection_state == WIFI_DIRECT_CONNECTION_RSP) {
+ TRACE_INFO("WIFI_DIRECT_CONNECTION_RSP");
+ g_network_is_wifi_direct = __dp_network_wifi_direct_status();
+ } else {
+ TRACE_INFO("WIFI_DIRECT_DISCONNECTION");
+ g_network_is_wifi_direct = 0;
+ }
+ pthread_mutex_unlock(&g_dp_network_mutex);
+}
+#endif
//////////////////////////////////////////////////////////////////////////
/// @brief check the status in more detail by connection type
/// @return dp_network_type
-static dp_network_type __dp_get_network_connection_status(connection_h connection, connection_type_e type)
+static int __dp_get_network_connection_status(connection_h connection, connection_type_e type)
{
- dp_network_type network_type = DP_NETWORK_TYPE_OFF;
- if (type == CONNECTION_TYPE_WIFI) {
+ int network_type = DP_NETWORK_OFF;
+ if (__dp_network_is_companion_mode() == 1) {
+ network_type = DP_NETWORK_ALL;
+ TRACE_INFO("COMPANION MODE");
+ } else if (type == CONNECTION_TYPE_WIFI) {
connection_wifi_state_e wifi_state;
wifi_state = CONNECTION_WIFI_STATE_DEACTIVATED;
- if (connection_get_wifi_state
- (connection, &wifi_state) != CONNECTION_ERROR_NONE)
+ if (connection_get_wifi_state(connection, &wifi_state) !=
+ CONNECTION_ERROR_NONE) {
TRACE_ERROR("Failed connection_get_wifi_state");
- if (wifi_state == CONNECTION_WIFI_STATE_CONNECTED) {
- TRACE_DEBUG("[CONNECTION_WIFI] CONNECTED");
- network_type = DP_NETWORK_TYPE_WIFI;
} else {
- TRACE_DEBUG("[CONNECTION_WIFI] [%d]", wifi_state);
+ if (wifi_state == CONNECTION_WIFI_STATE_CONNECTED) {
+ TRACE_INFO("WIFI CONNECTED");
+ network_type = DP_NETWORK_WIFI;
+ }
}
} else if (type == CONNECTION_TYPE_CELLULAR) {
connection_cellular_state_e cellular_state;
cellular_state = CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE;
- if (connection_get_cellular_state
- (connection, &cellular_state) != CONNECTION_ERROR_NONE)
+ if (connection_get_cellular_state(connection,
+ &cellular_state) != CONNECTION_ERROR_NONE) {
TRACE_ERROR("Failed connection_get_cellular_state");
- if (cellular_state == CONNECTION_CELLULAR_STATE_CONNECTED) {
- TRACE_DEBUG("[CONNECTION_CELLULAR] DATA NETWORK CONNECTED");
- network_type = DP_NETWORK_TYPE_DATA_NETWORK;
} else {
- TRACE_DEBUG("[CONNECTION_CELLULAR] [%d]", cellular_state);
+ if (cellular_state == CONNECTION_CELLULAR_STATE_CONNECTED) {
+ TRACE_INFO("DATA NETWORK CONNECTED");
+ network_type = DP_NETWORK_DATA_NETWORK;
+ }
}
} else if (type == CONNECTION_TYPE_ETHERNET) {
connection_ethernet_state_e ethernet_state;
ethernet_state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
- if (connection_get_ethernet_state
- (connection, &ethernet_state) != CONNECTION_ERROR_NONE)
+ if (connection_get_ethernet_state(connection,
+ &ethernet_state) != CONNECTION_ERROR_NONE) {
TRACE_ERROR("Failed connection_get_ethernet_state");
- if (ethernet_state == CONNECTION_ETHERNET_STATE_CONNECTED) {
- TRACE_DEBUG("[CONNECTION_ETHERNET] ETHERNET CONNECTED");
- network_type = DP_NETWORK_TYPE_ETHERNET;
} else {
- TRACE_DEBUG("[CONNECTION_ETHERNET] [%d]", ethernet_state);
+ if (ethernet_state == CONNECTION_ETHERNET_STATE_CONNECTED) {
+ TRACE_INFO("ETHERNET CONNECTED");
+ network_type = DP_NETWORK_WIFI;
+ }
}
} else {
- TRACE_DEBUG("[DISCONNECTED]");
- network_type = DP_NETWORK_TYPE_OFF;
+ TRACE_INFO("DISCONNECTED");
+ network_type = DP_NETWORK_OFF;
}
+ g_network_status = network_type;
return network_type;
}
@@ -240,33 +146,25 @@ static dp_network_type __dp_get_network_connection_status(connection_h connectio
/// @todo care requests by network status
static void __dp_network_connection_type_changed_cb(connection_type_e type, void *data)
{
- dp_privates *privates = (dp_privates*)data;
- if (privates == NULL) {
- TRACE_ERROR("[CRITICAL] Invalid data");
- return ;
- }
- CLIENT_MUTEX_LOCK(&(g_dp_queue_mutex));
- #if 1 // this callback guarantee that already connectdd
- if (type == CONNECTION_TYPE_WIFI) {
- TRACE_DEBUG("[CONNECTION_WIFI] CONNECTED");
- privates->network_status = DP_NETWORK_TYPE_WIFI;
+ pthread_mutex_lock(&g_dp_network_mutex);
+ // this callback guarantee that already connected
+ if (__dp_network_is_companion_mode() == 1) {
+ TRACE_INFO("COMPANION MODE");
+ g_network_status = DP_NETWORK_ALL;
+ } else if (type == CONNECTION_TYPE_WIFI) {
+ TRACE_INFO("WIFI CONNECTED");
+ g_network_status = DP_NETWORK_WIFI;
} else if (type == CONNECTION_TYPE_CELLULAR) {
- TRACE_DEBUG("[CONNECTION_CELLULAR] DATA NETWORK CONNECTED");
- privates->network_status = DP_NETWORK_TYPE_DATA_NETWORK;
+ TRACE_INFO("DATA NETWORK CONNECTED");
+ g_network_status = DP_NETWORK_DATA_NETWORK;
} else if (type == CONNECTION_TYPE_ETHERNET) {
- TRACE_DEBUG("[CONNECTION_ETHERNET] ETHERNET CONNECTED");
- privates->network_status = DP_NETWORK_TYPE_ETHERNET;
+ TRACE_INFO("ETHERNET CONNECTED");
+ g_network_status = DP_NETWORK_WIFI;
} else {
- TRACE_DEBUG("[DISCONNECTED]");
- privates->network_status = DP_NETWORK_TYPE_OFF;
+ TRACE_INFO("DISCONNECTED");
+ g_network_status = DP_NETWORK_OFF;
}
- if (privates->network_status != DP_NETWORK_TYPE_OFF)
- pthread_cond_signal(&g_dp_queue_cond);
- #else
- privates->network_status =
- __dp_get_network_connection_status(privates->connection, type);
- #endif
- CLIENT_MUTEX_UNLOCK(&(g_dp_queue_mutex));
+ pthread_mutex_unlock(&g_dp_network_mutex);
}
//////////////////////////////////////////////////////////////////////////
@@ -274,124 +172,96 @@ static void __dp_network_connection_type_changed_cb(connection_type_e type, void
/// @todo auto resume feature
static void __dp_network_connection_ip_changed_cb(const char *ip, const char *ipv6, void *data)
{
- dp_privates *privates = (dp_privates*)data;
- if (privates == NULL) {
- TRACE_ERROR("[CRITICAL] Invalid data");
- return ;
- }
- if (privates->network_status != DP_NETWORK_TYPE_OFF) {
- dp_request_slots *requests = privates->requests;
- int i = 0;
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- int locked = pthread_mutex_trylock(&requests[i].mutex);
- // locking failure means it used by other thread.
- if (locked == 0) {
- if (requests[i].request != NULL) {
- if (requests[i].request->state == DP_STATE_DOWNLOADING ||
- (requests[i].request->state == DP_STATE_FAILED &&
- requests[i].request->error == DP_ERROR_CONNECTION_FAILED)) {
- requests[i].request->ip_changed = 1;
- }
- }
- CLIENT_MUTEX_UNLOCK(&requests[i].mutex);
- }
- }
+ if (dp_network_get_status() != DP_NETWORK_OFF) {
+ TRACE_DEBUG("[CONNECTION] IP CHANGED");
+ // broadcast to all thread for clients
+ dp_broadcast_signal();
}
}
+int dp_network_get_status()
+{
+ int status = DP_NETWORK_OFF;
+ pthread_mutex_lock(&g_dp_network_mutex);
+ status = g_network_status;
+ pthread_mutex_unlock(&g_dp_network_mutex);
+ return status;
+}
+
+int dp_network_is_wifi_direct()
+{
+ pthread_mutex_lock(&g_dp_network_mutex);
+ int status = g_network_is_wifi_direct;
+ pthread_mutex_unlock(&g_dp_network_mutex);
+ return status;
+}
+
//////////////////////////////////////////////////////////////////////////
/// @brief create connection handle & regist callback
/// @return 0 : success -1 : failed
-int dp_network_connection_init(dp_privates *privates)
+int dp_network_connection_init()
{
int retcode = 0;
- if (!privates) {
- TRACE_ERROR("[CRITICAL] Invalid data");
- return -1;
- }
-
#ifdef SUPPORT_WIFI_DIRECT
if (wifi_direct_initialize() == 0) {
wifi_direct_set_connection_state_changed_cb
- (__dp_network_wifi_direct_connection_state_changed_cb, privates);
- if (dp_network_wifi_direct_is_connected() == 0)
- privates->is_connected_wifi_direct = 1;
+ (__dp_network_wifi_direct_changed_cb, NULL);
+ g_network_is_wifi_direct = __dp_network_wifi_direct_status();
}
#endif
- if ((retcode = connection_create(&privates->connection)) !=
+ if ((retcode = connection_create(&g_network_connection)) !=
CONNECTION_ERROR_NONE) {
TRACE_ERROR("Failed connection_create [%d]", retcode);
return -1;
}
- if ((retcode = connection_set_type_changed_cb
- (privates->connection, __dp_network_connection_type_changed_cb,
- privates)) != CONNECTION_ERROR_NONE) {
+ if ((retcode = connection_set_type_changed_cb(g_network_connection,
+ __dp_network_connection_type_changed_cb, NULL)) !=
+ CONNECTION_ERROR_NONE) {
TRACE_ERROR("Failed connection_set_type_changed_cb [%d]", retcode);
- connection_destroy(privates->connection);
+ connection_destroy(g_network_connection);
+ g_network_connection = 0;
return -1;
}
+
if ((retcode = connection_set_ip_address_changed_cb
- (privates->connection, __dp_network_connection_ip_changed_cb,
- privates)) != CONNECTION_ERROR_NONE) {
+ (g_network_connection, __dp_network_connection_ip_changed_cb,
+ NULL)) != CONNECTION_ERROR_NONE) {
TRACE_ERROR("Failed __dp_network_connection_ip_changed_cb [%d]", retcode);
- connection_destroy(privates->connection);
+ connection_destroy(g_network_connection);
+ g_network_connection = 0;
return -1;
}
+
connection_type_e type = CONNECTION_TYPE_DISCONNECTED;
- if ((retcode = connection_get_type(privates->connection, &type)) !=
+ if ((retcode = connection_get_type(g_network_connection, &type)) !=
CONNECTION_ERROR_NONE) {
TRACE_ERROR("Failed connection_get_type [%d]", retcode);
- connection_destroy(privates->connection);
+ connection_destroy(g_network_connection);
+ g_network_connection = 0;
return -1;
}
- privates->network_status =
- __dp_get_network_connection_status(privates->connection, type);
+ g_network_status =
+ __dp_get_network_connection_status(g_network_connection, type);
return 0;
}
//////////////////////////////////////////////////////////////////////////
/// @brief destroy connection handle
-void dp_network_connection_destroy(connection_h connection)
+void dp_network_connection_destroy()
{
+ pthread_mutex_lock(&g_dp_network_mutex);
#ifdef SUPPORT_WIFI_DIRECT
wifi_direct_unset_connection_state_changed_cb();
wifi_direct_deinitialize();
#endif
- connection_unset_type_changed_cb(connection);
- connection_unset_ip_address_changed_cb(connection);
- connection_destroy(connection);
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief check network status using connection API
-/// @todo the standard of enabled networking can be changed later
-/// @return Network type
-dp_network_type dp_get_network_connection_instant_status()
-{
- int retcode = 0;
- connection_h network_handle = NULL;
- dp_network_type network_type = DP_NETWORK_TYPE_OFF;
- if ((retcode = connection_create(&network_handle)) !=
- CONNECTION_ERROR_NONE) {
- TRACE_ERROR("Failed connection_create [%d]", retcode);
- return DP_NETWORK_TYPE_OFF;
+ if (g_network_connection != 0) {
+ connection_unset_type_changed_cb(g_network_connection);
+ connection_unset_ip_address_changed_cb(g_network_connection);
+ connection_destroy(g_network_connection);
}
-
- connection_type_e type = CONNECTION_TYPE_DISCONNECTED;
- if ((retcode = connection_get_type(network_handle, &type)) !=
- CONNECTION_ERROR_NONE) {
- TRACE_ERROR("Failed connection_get_type [%d]", retcode);
- connection_destroy(network_handle);
- return DP_NETWORK_TYPE_OFF;
- }
- network_type =
- __dp_get_network_connection_status(network_handle, type);
-
- if (connection_destroy(network_handle) != CONNECTION_ERROR_NONE)
- TRACE_ERROR("Failed connection_destroy");
-
- return network_type;
+ g_network_connection = 0;
+ pthread_mutex_unlock(&g_dp_network_mutex);
}
diff --git a/provider/download-provider-notification-manager.c b/provider/download-provider-notification-manager.c
new file mode 100644
index 0000000..ea89c0c
--- /dev/null
+++ b/provider/download-provider-notification-manager.c
@@ -0,0 +1,573 @@
+/*
+ * 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.
+ */
+
+#ifdef SUPPORT_NOTIFICATION
+#include <stdlib.h>
+#include <signal.h> // pthread_kill
+#include <errno.h> // ESRCH
+
+#include "download-provider-log.h"
+#include "download-provider-pthread.h"
+#include "download-provider-client.h"
+#include "download-provider-client-manager.h"
+#include "download-provider-notification.h"
+#include "download-provider-db-defs.h"
+#include "download-provider-db.h"
+#endif
+#include "download-provider-notification-manager.h"
+
+#ifdef SUPPORT_NOTIFICATION
+typedef struct { // manage clients without mutex
+ int id;
+ int state;
+ int noti_priv_id;
+ double received_size;
+ double file_size;
+ dp_noti_type type;
+ void *slot; // client can not be NULL. it will exist in dummy
+ void *request; // this can be NULL after destroy
+ void *next;
+} dp_notification_queue_fmt;
+
+
+pthread_mutex_t g_dp_notification_manager_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t g_dp_notification_manager_cond = PTHREAD_COND_INITIALIZER;
+pthread_t g_dp_notification_manager_tid = 0;
+
+static dp_notification_queue_fmt *g_dp_notification_clear = NULL;
+static dp_notification_queue_fmt *g_dp_notification_ongoing = NULL;
+static dp_notification_queue_fmt *g_dp_notification = NULL;
+
+pthread_mutex_t g_dp_notification_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t g_dp_notification_queue_ongoing_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// normal . push at the tail of queue.
+static int __dp_notification_queue_push(dp_notification_queue_fmt **queue, void *slot, void *request, const int id, const int state, const int noti_priv_id, const double received_size, const double file_size, const dp_noti_type type)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return -1;
+ }
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check client and request memory address");
+ return -1;
+ } else if (id <= 0) {
+ TRACE_ERROR("check slot or download id", id);
+ return -1;
+ }
+
+ int ret = -1;
+ CLIENT_MUTEX_LOCK(&g_dp_notification_queue_mutex);
+ // search the tail of queue
+ int i = 0;
+ dp_notification_queue_fmt *tailp = *queue;
+ dp_notification_queue_fmt *prevp = NULL;
+ for (; tailp != NULL; i++) {
+ prevp = tailp;
+ tailp = tailp->next;
+ }
+ dp_notification_queue_fmt *new_queue = (dp_notification_queue_fmt *)malloc(sizeof(dp_notification_queue_fmt));
+ if (new_queue != NULL) {
+ new_queue->slot = slot;
+ new_queue->id = id;
+ new_queue->state = state;
+ new_queue->noti_priv_id = noti_priv_id;
+ new_queue->received_size = received_size;
+ new_queue->file_size = file_size;
+ new_queue->type = type;
+ new_queue->request = request;
+ new_queue->next = NULL;
+ if (prevp == NULL)
+ *queue = new_queue;
+ else
+ prevp->next = new_queue;
+ ret = 0;
+ }
+ //TRACE_DEBUG("queue push %d id:%d", i, id);
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
+ return ret;
+}
+
+int __dp_notification_queue_pop(dp_notification_queue_fmt **queue, void **slot, void **request, int *id, int *state, int *noti_priv_id, double *received_size, double *file_size, dp_noti_type *type)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return -1;
+ }
+ if (slot == NULL) {
+ TRACE_ERROR("check client memory address");
+ return -1;
+ }
+
+ int lock = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_queue_mutex);
+ if (lock != 0) {
+ TRACE_DEBUG("skip queue is used by other thread");
+ return 0;
+ }
+ if (queue == NULL || *queue == NULL) {
+ //TRACE_DEBUG("queue empty");
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
+ return -1;
+ }
+ // get a head of queue
+ int ret = -1;
+ do {
+ dp_notification_queue_fmt *popp = *queue;
+ *queue = popp->next;
+ if (popp->slot == NULL) {
+ TRACE_DEBUG("queue error slot:%p id:%d", popp->slot, popp->id);
+ } else {
+ *slot = popp->slot;
+ if (request != NULL) {
+ *request = popp->request;
+ }
+ *id = popp->id;
+ *state = popp->state;
+ if (noti_priv_id != NULL)
+ *noti_priv_id = popp->noti_priv_id;
+ if (received_size != NULL)
+ *received_size = popp->received_size;
+ if (file_size != NULL)
+ *file_size = popp->file_size;
+ *type = popp->type;
+ ret = 0;
+ break;
+ }
+ } while (*queue != NULL); // if meet the tail of queue
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
+ return ret;
+}
+
+int __dp_notification_queue_ongoing_pop(dp_notification_queue_fmt **queue, void **slot, void **request, int *id, int *state, double *received_size, double *file_size, dp_noti_type *type)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return -1;
+ }
+ if (slot == NULL) {
+ TRACE_ERROR("check client memory address");
+ return -1;
+ }
+
+ int lock = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_queue_ongoing_mutex);
+ if (lock != 0) {
+ TRACE_DEBUG("skip queue is used by other thread");
+ return 0;
+ }
+ if (queue == NULL || *queue == NULL) {
+ //TRACE_DEBUG("queue empty");
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
+ return -1;
+ }
+ // get a head of queue
+ int ret = -1;
+ do {
+ dp_notification_queue_fmt *popp = *queue;
+ *queue = popp->next;
+ if (popp->slot == NULL) {
+ TRACE_DEBUG("queue error slot:%p id:%d", popp->slot, popp->id);
+ } else {
+ *slot = popp->slot;
+ if (request != NULL) {
+ *request = popp->request;
+ }
+ *id = popp->id;
+ *state = popp->state;
+ if (received_size != NULL)
+ *received_size = popp->received_size;
+ if (file_size != NULL)
+ *file_size = popp->file_size;
+ *type = popp->type;
+ ret = 0;
+ break;
+ }
+ } while (*queue != NULL); // if meet the tail of queue
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
+ return ret;
+}
+
+static int __dp_notification_queue_ongoing_push(dp_notification_queue_fmt **queue, void *slot, void *request, const int id, const int state, const double received_size, const double file_size, const dp_noti_type type)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return -1;
+ }
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check client and request memory address");
+ return -1;
+ } else if (id <= 0) {
+ TRACE_ERROR("check slot or download id", id);
+ return -1;
+ }
+
+ int ret = -1;
+ CLIENT_MUTEX_LOCK(&g_dp_notification_queue_ongoing_mutex);
+ // search the tail of queue
+ int i = 0;
+ dp_notification_queue_fmt *tailp = *queue;
+ dp_notification_queue_fmt *prevp = NULL;
+ for (; tailp != NULL; i++) {
+ if (tailp->slot == slot && tailp->request == request) {
+ if (tailp->id == id && tailp->state == state && tailp->type == type) {
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
+ return 0;
+ }
+ }
+ prevp = tailp;
+ tailp = tailp->next;
+ }
+ dp_notification_queue_fmt *new_queue = (dp_notification_queue_fmt *)malloc(sizeof(dp_notification_queue_fmt));
+ if (new_queue != NULL) {
+ new_queue->slot = slot;
+ new_queue->id = id;
+ new_queue->state = state;
+ new_queue->received_size = received_size;
+ new_queue->file_size = file_size;
+ new_queue->type = type;
+ new_queue->request = request;
+ new_queue->next = NULL;
+ if (prevp == NULL)
+ *queue = new_queue;
+ else
+ prevp->next = new_queue;
+ ret = 0;
+ }
+ //TRACE_DEBUG("queue push %d id:%d", i, id);
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_ongoing_mutex);
+ return ret;
+}
+
+void __dp_notification_queue_clear(dp_notification_queue_fmt **queue, const int id)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return ;
+ }
+ CLIENT_MUTEX_LOCK(&g_dp_notification_queue_mutex);
+ int i = 0;
+ dp_notification_queue_fmt *tailp = *queue;
+ dp_notification_queue_fmt *prevp = NULL;
+ for (; tailp != NULL; i++) {
+ if (tailp->id == id) {
+ // clear.
+ if (prevp == NULL)
+ *queue = tailp->next;
+ else
+ prevp->next = tailp->next;
+ TRACE_DEBUG("queue clear this %d id:%d", i, tailp->id);
+ free(tailp);
+ break;
+ }
+ prevp = tailp;
+ tailp = tailp->next;
+ }
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_queue_mutex);
+}
+
+int dp_notification_manager_clear_notification(void *slot, void *request, const dp_noti_type type)
+{
+ dp_request_fmt *requestp = request;
+ if (request == NULL) {
+ TRACE_DEBUG("check address request:%p id:%d",
+ request, (request == NULL ? 0 : requestp->id));
+ return -1;
+ }
+ __dp_notification_queue_clear(&g_dp_notification, requestp->id);
+ TRACE_DEBUG("push clear id:%d noti_priv_id:%d", requestp->id, requestp->noti_priv_id);
+ if (__dp_notification_queue_push(&g_dp_notification_clear, slot, request, requestp->id, requestp->state, -1, 0, 0, type) < 0) {
+ TRACE_ERROR("failed to push to notification id:%d", requestp->id);
+ return -1;
+ }
+ dp_notification_manager_wake_up();
+ return 0;
+}
+
+int dp_notification_manager_push_notification(void *slot, void *request, const dp_noti_type type)
+{
+ dp_request_fmt *requestp = request;
+ if (slot == NULL || request == NULL) {
+ TRACE_DEBUG("check address client:%p request:%p id:%d", slot,
+ request, (request == NULL ? 0 : requestp->id));
+ return -1;
+ }
+// TRACE_DEBUG("push noti id:%d noti_priv_id:%d type:%d", requestp->id, requestp->noti_priv_id, type);
+ if (type == DP_NOTIFICATION) {
+ __dp_notification_queue_clear(&g_dp_notification_ongoing, requestp->id);
+ if (__dp_notification_queue_push(&g_dp_notification, slot, request, requestp->id, requestp->state, requestp->noti_priv_id, 0, (double)requestp->file_size, type) < 0) {
+ TRACE_ERROR("failed to push to notification id:%d", requestp->id);
+ return -1;
+ }
+ } else {
+ __dp_notification_queue_clear(&g_dp_notification, requestp->id);
+ if (__dp_notification_queue_ongoing_push(&g_dp_notification_ongoing, slot, request, requestp->id, requestp->state, (double)requestp->received_size, (double)requestp->file_size, type) < 0) {
+ TRACE_ERROR("failed to push to notification id:%d", requestp->id);
+ return -1;
+ }
+ }
+ dp_notification_manager_wake_up();
+ return 0;
+}
+
+static void __dp_notification_manager_check_notification()
+{
+ int pop_queue = 0;
+ do {
+ int errorcode = DP_ERROR_NONE;
+ int download_id = -1;
+ int state = -1;
+ dp_noti_type noti_type = -1;
+ dp_client_slots_fmt *slot = NULL;
+ dp_request_fmt *request = NULL;
+ pop_queue = 0;
+ if (__dp_notification_queue_pop(&g_dp_notification_clear, (void *)&slot, (void *)&request, &download_id, &state, NULL, NULL, NULL, &noti_type) == 0) {
+ if (slot != NULL) {
+ int noti_priv_id = -1;
+ if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
+ if (request != NULL && request->id == download_id && request->noti_priv_id >= 0) {
+ noti_priv_id = request->noti_priv_id;
+ request->noti_priv_id = -1;
+ if (dp_db_replace_property(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_PRIV_ID, (void *)&request->noti_priv_id, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ }
+ TRACE_DEBUG("clear ongoing id:%d noti_priv_id:%d type:%d", download_id, noti_priv_id, noti_type);
+ if (noti_priv_id >= 0) {
+ if (noti_type > DP_NOTIFICATION)
+ dp_notification_delete_ongoing(noti_priv_id);
+ else
+ dp_notification_delete(noti_priv_id);
+ }
+ }
+ pop_queue++;
+ continue;
+ }
+ int noti_priv_id = -1;
+ if (__dp_notification_queue_pop(&g_dp_notification, (void *)&slot, (void *)&request, &download_id, &state, &noti_priv_id, NULL, NULL, &noti_type) == 0) {
+ if (slot != NULL) {
+ __dp_notification_queue_clear(&g_dp_notification_ongoing, download_id); // prevent new ongoing
+ if (noti_priv_id >= 0) {
+ TRACE_DEBUG("clear ongoing(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
+ dp_notification_delete_ongoing(noti_priv_id);
+ noti_priv_id = -1;
+ }
+ if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
+ TRACE_DEBUG("notification id:%d type:%d state:%d", download_id, noti_type, state);
+ if (request != NULL && request->id == download_id && request->noti_priv_id >= 0) {
+ dp_notification_delete_ongoing(request->noti_priv_id);
+ request->noti_priv_id = -1;
+ }
+ dp_content_type content_type = DP_CONTENT_UNKNOWN;
+ if (request != NULL)
+ content_type = request->content_type;
+ noti_priv_id = dp_notification_new(slot->client.dbhandle, download_id, state, content_type, slot->pkgname); // lazy API
+ TRACE_DEBUG("new notification(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
+ if (noti_priv_id < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", download_id);
+ } else {
+ if (request != NULL && request->id == download_id) {
+ request->noti_priv_id = noti_priv_id;
+ }
+ if (dp_db_replace_property(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_PRIV_ID, (void *)&noti_priv_id, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ }
+ }
+ pop_queue++;
+ }
+ double received_size = 0;
+ double file_size = 0;
+ if (__dp_notification_queue_ongoing_pop(&g_dp_notification_ongoing, (void *)&slot, (void *)&request, &download_id, &state, &received_size, &file_size, &noti_type) == 0) {
+ if (slot != NULL) {
+ int noti_priv_id = -1;
+ int request_id = -1;
+ if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
+ if (request != NULL && request->id == download_id) {
+ request_id = download_id;
+ if (request->noti_priv_id >= 0) {
+ noti_priv_id = request->noti_priv_id;
+ }
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ } else {
+ TRACE_ERROR("ongoing wrong address id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
+ continue;
+ }
+
+ if (request_id < 0) {
+ TRACE_ERROR("ongoing wrong info id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
+ slot = NULL;
+ request = NULL;
+ continue;
+ }
+ if (noti_priv_id < 0 && noti_type > DP_NOTIFICATION_ONGOING) {
+ TRACE_DEBUG("ongoing precheck id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
+ noti_type = DP_NOTIFICATION_ONGOING;
+ }
+
+ TRACE_DEBUG("ongoing id:%d noti_priv_id:%d type:%d state:%d", download_id, noti_priv_id, noti_type, state);
+
+ char *subject = NULL;
+ if (noti_type == DP_NOTIFICATION || noti_type == DP_NOTIFICATION_ONGOING_UPDATE) {
+ unsigned length = 0;
+ if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
+ if (request != NULL) {
+ if (dp_db_get_property_string(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_SUBJECT, (unsigned char **)&subject, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get subject id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ } else if (subject == NULL && dp_db_get_property_string(slot->client.dbhandle, download_id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_NAME, (unsigned char **)&subject, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get content_name id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ }
+ }
+
+ if (noti_type > DP_NOTIFICATION_ONGOING) { // update
+ if (noti_priv_id >= 0 && dp_notification_ongoing_update(noti_priv_id, received_size, file_size, subject) < 0) {
+ TRACE_ERROR("failed to update ongoing for id:%d", download_id);
+ }
+ } else { // new ongoing
+ if (noti_priv_id >= 0) {
+ TRACE_DEBUG("clear ongoing id:%d noti_priv_id:%d", download_id, noti_priv_id);
+ dp_notification_delete(noti_priv_id);
+ dp_notification_delete_ongoing(noti_priv_id);
+ noti_priv_id = -1;
+ }
+ unsigned char *raws_buffer = NULL;
+ unsigned length = 0;
+ if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
+ if (dp_db_get_property_string(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_RAW_ONGOING, &raws_buffer, &length, &errorcode) < 0) {
+ TRACE_DEBUG("failed to get bundle raws id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ }
+ noti_priv_id = dp_notification_ongoing_new(slot->pkgname, subject, raws_buffer, length);
+ TRACE_DEBUG("new ongoing(%d) id:%d type:%d state:%d", noti_priv_id, download_id, noti_type, state);
+ free(raws_buffer);
+ if (noti_priv_id < 0) {
+ TRACE_ERROR("failed to update ongoing for id:%d", download_id);
+ } else {
+ if (CLIENT_MUTEX_CHECKLOCK(&slot->mutex) == 0) {
+ if (request != NULL)
+ request->noti_priv_id = noti_priv_id;
+ if (dp_db_replace_property(slot->client.dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_PRIV_ID, (void *)&noti_priv_id, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ }
+ }
+ }
+ free(subject);
+ }
+ pop_queue++;
+ }
+ } while (pop_queue > 0);
+}
+
+static void *__dp_notification_manager(void *arg)
+{
+ pthread_cond_init(&g_dp_notification_manager_cond, NULL);
+
+ dp_notification_set_locale();
+
+ while (g_dp_notification_manager_tid > 0) {
+
+ if (g_dp_notification_manager_tid <= 0) {
+ TRACE_DEBUG("notification-manager is closed by other thread");
+ break;
+ }
+
+ // check wifi_direct first
+ __dp_notification_manager_check_notification();
+
+ CLIENT_MUTEX_LOCK(&g_dp_notification_manager_mutex);
+ pthread_cond_wait(&g_dp_notification_manager_cond, &g_dp_notification_manager_mutex);
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
+ }
+
+ TRACE_DEBUG("notification-manager's working is done");
+ dp_notification_clear_locale();
+ pthread_cond_destroy(&g_dp_notification_manager_cond);
+ pthread_exit(NULL);
+ return 0;
+}
+
+static int __dp_notification_manager_start()
+{
+ if (g_dp_notification_manager_tid == 0 ||
+ pthread_kill(g_dp_notification_manager_tid, 0) == ESRCH) {
+ TRACE_DEBUG("try to create notification-manager");
+ if (pthread_create(&g_dp_notification_manager_tid, NULL,
+ __dp_notification_manager, NULL) != 0) {
+ TRACE_STRERROR("failed to create notification-manager");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void dp_notification_manager_wake_up()
+{
+ if (g_dp_notification_manager_tid > 0) {
+ int locked = CLIENT_MUTEX_TRYLOCK(&g_dp_notification_manager_mutex);
+ if (locked == 0) {
+ pthread_cond_signal(&g_dp_notification_manager_cond);
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
+ }
+ } else {
+ __dp_notification_manager_start();
+ }
+}
+
+void dp_notification_manager_kill()
+{
+ if (g_dp_notification_manager_tid > 0 &&
+ pthread_kill(g_dp_notification_manager_tid, 0) != ESRCH) {
+ //send signal to notification thread
+ g_dp_notification_manager_tid = 0;
+ CLIENT_MUTEX_LOCK(&g_dp_notification_manager_mutex);
+ pthread_cond_signal(&g_dp_notification_manager_cond);
+ CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex);
+ pthread_cancel(g_dp_notification_manager_tid);
+ int status;
+ pthread_join(g_dp_notification_manager_tid, (void **)&status);
+ }
+}
+#else
+
+int dp_notification_manager_clear_notification(void *slot, void *request, const dp_noti_type type)
+{
+ return 0;
+}
+
+int dp_notification_manager_push_notification(void *slot, void *request, const dp_noti_type type)
+{
+ return 0;
+}
+
+void dp_notification_manager_wake_up()
+{
+ return;
+}
+
+void dp_notification_manager_kill()
+{
+ return;
+}
+#endif
diff --git a/provider/download-provider-notification.c b/provider/download-provider-notification.c
index f6e2f8b..521cb44 100755
--- a/provider/download-provider-notification.c
+++ b/provider/download-provider-notification.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
@@ -14,39 +14,124 @@
* limitations under the License.
*/
+#ifdef SUPPORT_NOTIFICATION
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
-#include "bundle.h"
-#include "notification.h"
-#include "appsvc.h"
-
-#include "download-provider-defs.h"
-
+#include "download-provider.h"
#include "download-provider-notification.h"
-#include "download-provider-request.h"
+#include "download-provider-db-defs.h"
#include "download-provider-db.h"
#include "download-provider-log.h"
+#include "download-provider-client.h"
+#include "download-provider-utils.h"
+#include <bundle.h>
+#include <notification.h>
+#include <notification_internal.h>
+#include <appsvc.h>
+
+#include <vconf.h>
+#include <locale.h>
#include <libintl.h>
-#define S_(s) dgettext("sys_string", s)
#define __(s) dgettext(PKG_NAME, s)
-#define DP_NOTIFICATION_ICON_PATH IMAGE_DIR"/Q02_Notification_download_complete.png"
-#define DP_NOTIFICATION_ONGOING_ICON_PATH IMAGE_DIR"/Notification_download_animation.gif"
+#define DP_DOMAIN PKG_NAME
+#define DP_LOCALEDIR LOCALE_DIR
+#define DP_NOTIFICATION_NO_SUBJECT "No Name"
+
+#ifdef _TIZEN_2_3_UX
+#define DP_NOTIFICATION_DRM_ICON_PATH IMAGE_DIR"/download_manager_icon_drm.png"
+#define DP_NOTIFICATION_UNKNOWN_ICON_PATH IMAGE_DIR"/download_manager_icon_unknown.png"
+#define DP_NOTIFICATION_EXCEL_ICON_PATH IMAGE_DIR"/download_manager_icon_xls.png"
+#define DP_NOTIFICATION_HTML_ICON_PATH IMAGE_DIR"/download_manager_icon_html.png"
+#define DP_NOTIFICATION_MUSIC_ICON_PATH IMAGE_DIR"/download_manager_icon_music.png"
+#define DP_NOTIFICATION_PDF_ICON_PATH IMAGE_DIR"/download_manager_icon_pdf.png"
+#define DP_NOTIFICATION_PPT_ICON_PATH IMAGE_DIR"/download_manager_icon_ppt.png"
+#define DP_NOTIFICATION_TEXT_ICON_PATH IMAGE_DIR"/download_manager_icon_text.png"
+#define DP_NOTIFICATION_WORD_ICON_PATH IMAGE_DIR"/download_manager_icon_word.png"
+#define DP_NOTIFICATION_VIDEO_ICON_PATH IMAGE_DIR"/download_manager_icon_movie.png"
+#define DP_NOTIFICATION_IMAGE_ICON_PATH IMAGE_DIR"/download_manager_icon_img.png"
+#define DP_NOTIFICATION_FALSH_ICON_PATH IMAGE_DIR"/download_manager_icon_swf.png"
+#define DP_NOTIFICATION_TPK_ICON_PATH IMAGE_DIR"/download_manager_icon_tpk.png"
+#define DP_NOTIFICATION_VCAL_ICON_PATH IMAGE_DIR"/download_manager_icon_date.png"
+
+// base path
+#define QP_PRELOAD_NOTI_ICON_PATH "/usr/apps/com.samsung.quickpanel/shared/res/noti_icons"
+// each application path
+#define QP_PRELOAD_COMMON_PATH QP_PRELOAD_NOTI_ICON_PATH"/Common"
+#define DP_NOTIFICATION_COMPLETED_ICON_PATH QP_PRELOAD_COMMON_PATH"/noti_download_complete.png"
+#define DP_NOTIFICATION_FAILED_ICON_PATH QP_PRELOAD_COMMON_PATH"/noti_download_failed.png"
+
+#define DP_NOTIFICATION_ONGOING_ICON_PATH "reserved://quickpanel/ani/downloading"
#define DP_NOTIFICATION_DOWNLOADING_ICON_PATH "reserved://indicator/ani/downloading"
-#define DP_NOTIFICATION_FAILED_ICON_PATH IMAGE_DIR"/Q02_Notification_download_failed.png"
-
-static const char *__noti_error_str(
- notification_error_e err)
+#define DP_NOTIFICATION_FAILED_INDICATOR_ICON_PATH IMAGE_DIR"/B03_Processing_download_failed.png"
+#define DP_NOTIFICATION_COMPLETED_INDICATOR_ICON_PATH IMAGE_DIR"/B03_Processing_download_complete.png"
+#else
+#define DP_NOTIFICATION_DRM_ICON_PATH IMAGE_DIR"/U01_icon_drm.png"
+#define DP_NOTIFICATION_UNKNOWN_ICON_PATH IMAGE_DIR"/U01_icon_unkown.png"
+#define DP_NOTIFICATION_EXCEL_ICON_PATH IMAGE_DIR"/U01_icon_excel.png"
+#define DP_NOTIFICATION_HTML_ICON_PATH IMAGE_DIR"/U01_icon_html.png"
+#define DP_NOTIFICATION_MUSIC_ICON_PATH IMAGE_DIR"/U01_list_icon_mp3.png"
+#define DP_NOTIFICATION_PDF_ICON_PATH IMAGE_DIR"/U01_icon_pdf.png"
+#define DP_NOTIFICATION_PPT_ICON_PATH IMAGE_DIR"/U01_icon_ppt.png"
+#define DP_NOTIFICATION_TEXT_ICON_PATH IMAGE_DIR"/U01_icon_text.png"
+#define DP_NOTIFICATION_WORD_ICON_PATH IMAGE_DIR"/U01_icon_word.png"
+#define DP_NOTIFICATION_VIDEO_ICON_PATH IMAGE_DIR"/U01_list_icon_mp4.png"
+#define DP_NOTIFICATION_IMAGE_ICON_PATH IMAGE_DIR"/U01_list_icon_image.png"
+#define DP_NOTIFICATION_FALSH_ICON_PATH IMAGE_DIR"/U01_icon_swf.png"
+#define DP_NOTIFICATION_TPK_ICON_PATH IMAGE_DIR"/U01_icon_tpk.png"
+#define DP_NOTIFICATION_VCAL_ICON_PATH IMAGE_DIR"/U01_icon_vcs.png"
+
+#define DP_NOTIFICATION_FAILED_ICON_PATH IMAGE_DIR"/noti_download_failed.png"
+#define DP_NOTIFICATION_COMPLETED_ICON_PATH IMAGE_DIR"/noti_download_complete.png"
+
+#define DP_NOTIFICATION_ONGOING_ICON_PATH "reserved://quickpanel/ani/downloading"
+#define DP_NOTIFICATION_DOWNLOADING_ICON_PATH "reserved://indicator/ani/downloading"
+#define DP_NOTIFICATION_FAILED_INDICATOR_ICON_PATH IMAGE_DIR"/B03_processing_download_fail.png"
+#define DP_NOTIFICATION_COMPLETED_INDICATOR_ICON_PATH IMAGE_DIR"/B03_processing_download_complete.png"
+#endif
+
+#define DP_MAX_ICONS_TABLE_COUNT 15
+
+char *file_icons_table[DP_MAX_ICONS_TABLE_COUNT]={
+ //unknown file type
+ DP_NOTIFICATION_UNKNOWN_ICON_PATH,
+ //image
+ DP_NOTIFICATION_IMAGE_ICON_PATH,
+ //video
+ DP_NOTIFICATION_VIDEO_ICON_PATH,
+ // audio /music
+ DP_NOTIFICATION_MUSIC_ICON_PATH,
+ // PDF
+ DP_NOTIFICATION_PDF_ICON_PATH,
+ // word
+ DP_NOTIFICATION_WORD_ICON_PATH,
+ // ppt
+ DP_NOTIFICATION_PPT_ICON_PATH,
+ // excel
+ DP_NOTIFICATION_EXCEL_ICON_PATH,
+ // html
+ DP_NOTIFICATION_HTML_ICON_PATH,
+ // txt
+ DP_NOTIFICATION_TEXT_ICON_PATH,
+ // DRM
+ DP_NOTIFICATION_DRM_ICON_PATH,
+ DP_NOTIFICATION_DRM_ICON_PATH,
+ DP_NOTIFICATION_FALSH_ICON_PATH,
+ DP_NOTIFICATION_TPK_ICON_PATH,
+ DP_NOTIFICATION_VCAL_ICON_PATH,
+};
+
+static const char *__dp_noti_error_str(int err)
{
switch (err) {
- case NOTIFICATION_ERROR_INVALID_DATA:
- return "NOTIFICATION_ERROR_INVALID_DATA";
- case NOTIFICATION_ERROR_NO_MEMORY:
- return "NOTIFICATION_ERROR_NO_MEMORY";
+ case NOTIFICATION_ERROR_INVALID_PARAMETER:
+ return "NOTIFICATION_ERROR_INVALID_PARAMETER";
+ case NOTIFICATION_ERROR_OUT_OF_MEMORY:
+ return "NOTIFICATION_ERROR_OUT_OF_MEMORY";
case NOTIFICATION_ERROR_FROM_DB:
return "NOTIFICATION_ERROR_FROM_DB";
case NOTIFICATION_ERROR_ALREADY_EXIST_ID:
@@ -61,7 +146,7 @@ static const char *__noti_error_str(
return "Unknown error";
}
-static char *__get_string_sender(char *url)
+char *__dp_noti_get_sender(char *url)
{
char *temp = NULL;
char *found = NULL;
@@ -73,13 +158,13 @@ static char *__get_string_sender(char *url)
return NULL;
found = strstr(url, "://");
- if (found) {
+ if (found != NULL) {
temp = found + 3;
} else {
temp = url;
}
found = strchr(temp, '/');
- if (found) {
+ if (found != NULL) {
int len = 0;
len = found - temp;
sender = calloc(len + 1, sizeof(char));
@@ -93,7 +178,7 @@ static char *__get_string_sender(char *url)
// For credential URL
found = strchr(sender, '@');
found1 = strchr(sender, ':');
- if (found && found1 && found1 < found) {
+ if (found != NULL && found1 != NULL && found1 < found) {
int len = 0;
found = found + 1;
len = strlen(found);
@@ -110,47 +195,16 @@ static char *__get_string_sender(char *url)
}
}
-static char *__get_string_size(long long file_size)
-{
- const char *unitStr[4] = {"B", "KB", "MB", "GB"};
- double doubleTypeBytes = 0.0;
- int unit = 0;
- long long bytes = file_size;
- long long unitBytes = bytes;
- char *temp = NULL;
-
- /* using bit operation to avoid floating point arithmetic */
- for (unit = 0; (unitBytes > 1024 && unit < 4); unit++) {
- unitBytes = unitBytes >> 10;
- }
- unitBytes = 1 << (10 * unit);
-
- if (unit > 3)
- unit = 3;
-
- char str[64] = {0};
- if (unit == 0) {
- snprintf(str, sizeof(str), "%lld %s", bytes, unitStr[unit]);
- } else {
- doubleTypeBytes = ((double)bytes / (double)unitBytes);
- snprintf(str, sizeof(str), "%.2f %s", doubleTypeBytes, unitStr[unit]);
- }
-
- str[63] = '\0';
- temp = dp_strdup(str);
- return temp;
-}
-
-static char *__get_string_status(dp_state_type state)
+static char *__dp_noti_status(dp_state_type state)
{
char *message = NULL;
switch (state) {
case DP_STATE_COMPLETED:
- message = __("IDS_DM_HEADER_DOWNLOAD_COMPLETE");
+ message = "IDS_DM_HEADER_DOWNLOAD_COMPLETE";
break;
case DP_STATE_CANCELED:
case DP_STATE_FAILED:
- message = S_("IDS_COM_POP_DOWNLOAD_FAILED");
+ message = "IDS_DM_BODY_DOWNLOAD_FAILED_M_STATUS_ABB";
break;
default:
break;
@@ -158,459 +212,414 @@ static char *__get_string_status(dp_state_type state)
return message;
}
-int dp_set_downloadinginfo_notification(int id, char *packagename)
+void __lang_changed_cb(keynode_t *key, void* data)
{
- notification_h noti_handle = NULL;
- notification_error_e err = NOTIFICATION_ERROR_NONE;
- int privId = 0;
- bundle *b = NULL;
- void *blob_data = NULL;
- bundle_raw* b_raw = NULL;
- int length;
+ char *str = NULL;
+ str = vconf_get_str(VCONFKEY_LANGSET);
+ if (str != NULL) {
+ setlocale(LC_ALL, str);
+ bindtextdomain(PKG_NAME, LOCALE_DIR);
+ textdomain(PKG_NAME);
+ }
+ free(str);
+}
+
+void dp_notification_set_locale()
+{
+ // move to notification.c
+ // locale
+ __lang_changed_cb(NULL, NULL);
+ if (vconf_notify_key_changed(VCONFKEY_LANGSET, __lang_changed_cb, NULL) != 0)
+ TRACE_ERROR("Fail to set language changed vconf callback");
+}
+
+void dp_notification_clear_locale()
+{
+ // move to notification.c
+ if (vconf_ignore_key_changed(VCONFKEY_LANGSET, __lang_changed_cb) != 0)
+ TRACE_ERROR("Fail to unset language changed vconf callback");
+}
+void dp_notification_clear_ongoings()
+{
+ int err = NOTIFICATION_ERROR_NONE;
+ err = notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_ONGOING);
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("[FAIL] clear noti [%s]", __dp_noti_error_str(err));
+ }
+ return;
+}
+
+int dp_notification_ongoing_new(const char *pkgname, const char *subject, unsigned char *raws_buffer, const int raws_length)
+{
+ int err = NOTIFICATION_ERROR_NONE;
+ notification_h noti_handle = NULL;
noti_handle = notification_create(NOTIFICATION_TYPE_ONGOING);
- if (!noti_handle) {
- TRACE_ERROR("[FAIL] create notification handle");
+ if (noti_handle == NULL) {
+ TRACE_ERROR("failed to create notification handle");
return -1;
}
- char *title = dp_db_get_text_column(id,
- DP_DB_TABLE_NOTIFICATION, DP_DB_COL_TITLE);
- if(title != NULL) {
- err = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE,
- title, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
- free(title);
- if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
- }
+ if (subject != NULL) {
+ err = notification_set_text(noti_handle,
+ NOTIFICATION_TEXT_TYPE_TITLE, subject, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
} else {
- char *content_name =
- dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_CONTENT_NAME);
-
- if (content_name == NULL)
- content_name = strdup("No Name");
-
err = notification_set_text(noti_handle,
- NOTIFICATION_TEXT_TYPE_TITLE, content_name, NULL,
+ NOTIFICATION_TEXT_TYPE_TITLE, DP_NOTIFICATION_NO_SUBJECT, NULL,
NOTIFICATION_VARIABLE_TYPE_NONE);
- if (content_name)
- free(content_name);
}
-
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set subject error:%s", __dp_noti_error_str(err));
}
err = notification_set_image(noti_handle,
- NOTIFICATION_IMAGE_TYPE_ICON, DP_NOTIFICATION_ONGOING_ICON_PATH);
+ NOTIFICATION_IMAGE_TYPE_ICON,
+ DP_NOTIFICATION_ONGOING_ICON_PATH);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set icon [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set icon error:%s", __dp_noti_error_str(err));
}
- blob_data = dp_db_get_blob_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_RAW_BUNDLE_ONGOING, &length);
- if (blob_data != NULL) {
- b_raw = (bundle_raw*)blob_data;
- if (b_raw != NULL) {
- b = bundle_decode_raw(b_raw, length);
- if (b != NULL) {
- 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_encoded_rawdata(&b_raw);
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
+ if (raws_buffer != NULL && raws_length > 0) {
+ bundle *b = NULL;
+ b = bundle_decode_raw((bundle_raw *)raws_buffer, raws_length);
+ if (b != NULL) {
+ err = notification_set_execute_option(noti_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b);
+ } else {
+ b = bundle_create();
+ if (b != NULL && pkgname != NULL) {
+ if (appsvc_set_pkgname(b, pkgname) != APPSVC_RET_OK) {
+ TRACE_ERROR("failed to set set pkgname");
+ } else {
+ err = notification_set_execute_option(noti_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b);
}
- bundle_free_encoded_rawdata(&b_raw);
- bundle_free(b);
+ } else {
+ TRACE_ERROR("failed to create bundle");
}
}
- } else {
- b = bundle_create();
- if (!b) {
- TRACE_ERROR("[FAIL] create bundle");
- notification_free(noti_handle);
- return -1;
- }
-
- if (packagename &&
- appsvc_set_pkgname(b, packagename) != APPSVC_RET_OK) {
- TRACE_ERROR("[FAIL] set pkg name");
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
- }
- 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;
+ TRACE_ERROR("failed to set service error:%s", __dp_noti_error_str(err));
}
- bundle_free(b);
+ if (b != NULL)
+ bundle_free(b);
}
+
err = notification_set_property(noti_handle,
NOTIFICATION_PROP_DISABLE_TICKERNOTI);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set property [%s]", __noti_error_str(err));
+ TRACE_ERROR("failed to set property error:%s", __dp_noti_error_str(err));
notification_free(noti_handle);
return -1;
}
-
err = notification_set_image(noti_handle,
- NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR, DP_NOTIFICATION_DOWNLOADING_ICON_PATH);
+ NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR,
+ DP_NOTIFICATION_DOWNLOADING_ICON_PATH);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set icon indicator [%s]", __noti_error_str(err));
+ TRACE_ERROR("failed to set icon indicator error:%s", __dp_noti_error_str(err));
notification_free(noti_handle);
return -1;
}
-
- err = notification_set_display_applist(noti_handle, NOTIFICATION_DISPLAY_APP_ALL);
+ err = notification_set_display_applist(noti_handle,
+ NOTIFICATION_DISPLAY_APP_ALL);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set disable icon [%s]", __noti_error_str(err));
+ TRACE_ERROR("failed to set display app all error:%s", __dp_noti_error_str(err));
notification_free(noti_handle);
return -1;
}
- err = notification_insert(noti_handle, &privId);
+ int priv_id = 0;
+ err = notification_insert(noti_handle, &priv_id);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set insert [%s]", __noti_error_str(err));
+ TRACE_ERROR("failed to set priv_id error:%s", __dp_noti_error_str(err));
notification_free(noti_handle);
return -1;
}
- TRACE_DEBUG("m_noti_id [%d]", privId);
+ //TRACE_DEBUG("m_noti_id [%d]", priv_id);
notification_free(noti_handle);
- return privId;
+
+ return priv_id; // store on memory for reuse it
}
-int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, dp_state_type state)
-{
- notification_h noti_handle = NULL;
- notification_error_e err = NOTIFICATION_ERROR_NONE;
- int privId = 0;
- bundle *b = NULL;
- void *blob_data = NULL;
- bundle_raw* b_raw = NULL;
- int length = 0;
- if (priv_id >= 0) {
- err = notification_delete_by_priv_id(NULL, NOTIFICATION_TYPE_ONGOING,
- priv_id);
+
+int dp_notification_ongoing_update(const int noti_priv_id, const double received_size, const double file_size, const char *subject)
+{
+ if (noti_priv_id > 0) {
+ int err = NOTIFICATION_ERROR_NONE;
+ if (file_size > 0)
+ err = notification_update_progress(NULL, noti_priv_id, (received_size / file_size));
+ else
+ err = notification_update_size(NULL, noti_priv_id, received_size);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] delete notification handle [%s]",
- __noti_error_str(err));
+ TRACE_ERROR("failed to update error:%s", __dp_noti_error_str(err));
+ // return 0 because progress is called frequently
+ }
+ if (subject != NULL) {
+ notification_h noti_handle = NULL;
+ noti_handle = notification_load(NULL, noti_priv_id);
+ if (noti_handle != NULL) {
+ err = notification_set_text(noti_handle,
+ NOTIFICATION_TEXT_TYPE_TITLE, subject, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+ err = notification_update(noti_handle);
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("failed to update by priv_id:%d", noti_priv_id);
+ }
+ notification_free(noti_handle);
+ } else {
+ TRACE_ERROR("failed to load handle by priv_id:%d", noti_priv_id);
+ return -1;
+ }
}
}
+ return 0;
+}
- noti_handle = notification_create(NOTIFICATION_TYPE_NOTI);
- if (!noti_handle) {
- TRACE_ERROR("[FAIL] create notification handle");
+int dp_notification_delete_ongoing(const int noti_priv_id)
+{
+ int err = NOTIFICATION_ERROR_NONE;
+ err = notification_delete_by_priv_id(NULL, NOTIFICATION_TYPE_ONGOING, noti_priv_id);
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("failed to delete notification by priv_id:%d error:%s", noti_priv_id, __dp_noti_error_str(err));
+ }
+ return 0;
+}
+
+int dp_notification_delete(const int noti_priv_id)
+{
+ int err = NOTIFICATION_ERROR_NONE;
+ err = notification_delete_by_priv_id(NULL, NOTIFICATION_TYPE_NOTI, noti_priv_id);
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("failed to delete notification by priv_id:%d error:%s", noti_priv_id, __dp_noti_error_str(err));
+ }
+ return 0;
+}
+
+
+int dp_notification_new(void *dbhandle, const int download_id, const int state, int content_type, const char *pkgname)
+{
+ int errorcode = DP_ERROR_NONE;
+ int err = NOTIFICATION_ERROR_NONE;
+
+ if (state != DP_STATE_COMPLETED &&
+ state != DP_STATE_CANCELED &&
+ state != DP_STATE_FAILED) {
+ TRACE_ERROR("deny by invalid state:%d id:%d", state, download_id);
+ return -1;
+ }
+
+
+ notification_h noti_handle = NULL;
+ noti_handle = notification_create(NOTIFICATION_TYPE_NOTI);
+ if (noti_handle == NULL) {
+ TRACE_ERROR("failed to create notification handle");
return -1;
}
+ err = notification_set_layout(noti_handle, NOTIFICATION_LY_NOTI_EVENT_SINGLE);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err));
+ TRACE_ERROR("Fail to set notification layout [%d]", err);
notification_free(noti_handle);
return -1;
}
- err = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_TITLE,
- __get_string_status(state), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ err = notification_set_text_domain(noti_handle, DP_DOMAIN, DP_LOCALEDIR);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err));
+ TRACE_ERROR("Fail to set text domain [%d]", err);
notification_free(noti_handle);
return -1;
}
- char *description =
- dp_db_get_text_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_DESCRIPTION);
- if(description != NULL) {
+ char *string = NULL;
+ unsigned length = 0;
+ if (dp_db_get_property_string(dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_DESCRIPTION, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get description id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ if (string != NULL) {
+#ifdef _TIZEN_2_3_UX
+ err = notification_set_text(noti_handle,
+ NOTIFICATION_TEXT_TYPE_CONTENT, string, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+#else
err = notification_set_text(noti_handle,
- NOTIFICATION_TEXT_TYPE_INFO_2, description,
- NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
- free(description);
+ NOTIFICATION_TEXT_TYPE_TITLE, string, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+#endif
+ free(string);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set description [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set state id:%d error:%s", download_id, __dp_noti_error_str(err));
}
} else {
- char *url = NULL;
- url = dp_db_get_text_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_URL);
- if (url) {
- char *sender_str = __get_string_sender(url);
- err = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_INFO_2,
- sender_str, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
- if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err));
- free(sender_str);
- free(url);
- notification_free(noti_handle);
- return -1;
- }
- free(sender_str);
- free(url);
+ string = __dp_noti_status(state);
+#ifdef _TIZEN_2_3_UX
+ err = notification_set_text(noti_handle,
+ NOTIFICATION_TEXT_TYPE_CONTENT, __(string), string,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+#else
+ err = notification_set_text(noti_handle,
+ NOTIFICATION_TEXT_TYPE_TITLE, __(string), string,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+#endif
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("failed to set state id:%d error:%s", download_id, __dp_noti_error_str(err));
}
}
- char *title = dp_db_get_text_column(id,
- DP_DB_TABLE_NOTIFICATION, DP_DB_COL_TITLE);
- if(title != NULL) {
- err = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_CONTENT,
- title, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
- free(title);
+ string = NULL;
+ if (dp_db_get_property_string(dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_SUBJECT, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get subject id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ err = NOTIFICATION_ERROR_NONE;
+ if (string == NULL && dp_db_get_property_string(dbhandle, download_id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_NAME, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get content_name id:%d error:%s", download_id, dp_print_errorcode(errorcode));
+ }
+ if (string == NULL)
+ string = dp_strdup(DP_NOTIFICATION_NO_SUBJECT);
+ if (string != NULL) {
+#ifdef _TIZEN_2_3_UX
+ err = notification_set_text(noti_handle,
+ NOTIFICATION_TEXT_TYPE_TITLE, string, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+#else
+ err = notification_set_text(noti_handle,
+ NOTIFICATION_TEXT_TYPE_CONTENT, string, NULL,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+#endif
+ free(string);
+ string = NULL;
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set state id:%d error:%s", download_id, __dp_noti_error_str(err));
}
- } else {
- char *content_name =
- dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_CONTENT_NAME);
- if (content_name == NULL)
- content_name = strdup("No Name");
-
- err = notification_set_text(noti_handle,
- NOTIFICATION_TEXT_TYPE_CONTENT, content_name,
- NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
- free(content_name);
}
-
- time_t tt = time(NULL);
- err = notification_set_time_to_text(noti_handle,
- NOTIFICATION_TEXT_TYPE_INFO_SUB_1, tt);
+ err = notification_set_time(noti_handle, time(NULL));
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set time [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set time id:%d error:%s", download_id, __dp_noti_error_str(err));
}
+
+ bundle *b = NULL;
+ bundle_raw *raws_buffer = NULL;
if (state == DP_STATE_COMPLETED) {
- blob_data = dp_db_get_blob_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_RAW_BUNDLE_COMPLETE, &length);
- if (blob_data != NULL) {
- b_raw = (bundle_raw*)blob_data;
- if (b_raw != NULL) {
- b = bundle_decode_raw(b_raw, length);
- if (b != NULL) {
- 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_encoded_rawdata(&b_raw);
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
- }
- bundle_free_encoded_rawdata(&b_raw);
- }
- }
+
+ if (dp_db_get_property_string(dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_RAW_COMPLETE, &raws_buffer, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get bundle raws id:%d", download_id);
+ }
+ if (raws_buffer != NULL) {
+ b = bundle_decode_raw(raws_buffer, length);
+ bundle_free_encoded_rawdata(&raws_buffer);
+ }
+ if (b != NULL) {
+ err = notification_set_execute_option(noti_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b);
} else {
- char *file_path = NULL;
b = bundle_create();
- if (!b) {
- TRACE_ERROR("[FAIL] create bundle");
- notification_free(noti_handle);
- return -1;
- }
- if (appsvc_set_operation(b, APPSVC_OPERATION_VIEW) != APPSVC_RET_OK) {
- TRACE_ERROR("[FAIL] appsvc set operation");
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
- }
- file_path = dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_SAVED_PATH);
- if (file_path == NULL) {
- TRACE_ERROR("[FAIL] get file path");
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
-
+ if (dp_db_get_property_string(dbhandle, download_id, DP_TABLE_DOWNLOAD, DP_DB_COL_SAVED_PATH, (unsigned char **)&string, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get saved_path id:%d error:%s", download_id, dp_print_errorcode(errorcode));
}
- if (appsvc_set_uri(b, file_path) != APPSVC_RET_OK) {
- TRACE_ERROR("[FAIL] appsvc set uri");
- bundle_free(b);
- notification_free(noti_handle);
- free(file_path);
- return -1;
- }
- free(file_path);
- 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;
+ if (b != NULL && string != NULL) {
+ if (appsvc_set_operation(b, APPSVC_OPERATION_VIEW) != APPSVC_RET_OK) {
+ TRACE_ERROR("failed to set service operation id:%d", download_id);
+ } else {
+ if (appsvc_set_uri(b, string) != APPSVC_RET_OK) {
+ TRACE_ERROR("failed to set service uri id:%d", download_id);
+ } else {
+ err = notification_set_execute_option(noti_handle,
+ NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b);
+ }
+ }
+ } else {
+ TRACE_SECURE_ERROR("failed to create bundle id:%d path:%s", download_id, string);
}
+ free(string);
+ string = NULL;
+ }
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("failed to set service id:%d error:%s", download_id, __dp_noti_error_str(err));
}
- long long file_size = dp_db_get_int64_column(id,
- DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_CONTENT_SIZE);
- char *size_str = __get_string_size(file_size);
- err = notification_set_text(noti_handle, NOTIFICATION_TEXT_TYPE_INFO_1,
- size_str, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ char *file_type_icon = DP_NOTIFICATION_UNKNOWN_ICON_PATH;
+ if (content_type > 0 && content_type < DP_MAX_ICONS_TABLE_COUNT)
+ file_type_icon = file_icons_table[content_type];
+ err = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON, file_type_icon);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set title [%s]", __noti_error_str(err));
- free(size_str);
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set icon id:%d error:%s", download_id, __dp_noti_error_str(err));
}
- free(size_str);
-
- err = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON,
- DP_NOTIFICATION_ICON_PATH);
+ err = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR,
+ DP_NOTIFICATION_COMPLETED_INDICATOR_ICON_PATH);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set icon [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set icon id:%d error:%s", download_id, __dp_noti_error_str(err));
}
+
} else if (state == DP_STATE_CANCELED || state == DP_STATE_FAILED) {
- blob_data = dp_db_get_blob_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_RAW_BUNDLE_FAIL, &length);
- if (blob_data != NULL) {
- b_raw = (bundle_raw *)blob_data;
- if (b_raw != NULL) {
- b = bundle_decode_raw(b_raw, length);
- if (b != NULL) {
- 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_encoded_rawdata(&b_raw);
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
- }
- bundle_free_encoded_rawdata(&b_raw);
- }
- }
+
+ if (dp_db_get_property_string(dbhandle, download_id, DP_TABLE_NOTIFICATION, DP_DB_COL_NOTI_RAW_FAIL, &raws_buffer, &length, &errorcode) < 0) {
+ TRACE_ERROR("failed to get bundle raws id:%d", download_id);
+ }
+ if (raws_buffer != NULL) {
+ b = bundle_decode_raw(raws_buffer, length);
+ bundle_free_encoded_rawdata(&raws_buffer);
+ }
+ if (b != NULL) {
+ err = notification_set_execute_option(noti_handle, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b);
} else {
b = bundle_create();
- if (!b) {
- TRACE_ERROR("[FAIL] create bundle");
- notification_free(noti_handle);
- return -1;
- }
- if (packagename &&
- appsvc_set_pkgname(b, packagename) !=
- APPSVC_RET_OK) {
- TRACE_ERROR("[FAIL] set pkg name");
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
- }
- 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;
+ if (b != NULL && pkgname != NULL) {
+ if (appsvc_set_pkgname(b, pkgname) != APPSVC_RET_OK) {
+ TRACE_ERROR("failed to set set pkgname id:%d", download_id);
+ } else {
+ err = notification_set_execute_option(noti_handle,
+ NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, "View", NULL, b);
+ }
+ } else {
+ TRACE_ERROR("failed to create bundle id:%d", download_id);
}
}
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("failed to set service id:%d error:%s", download_id, __dp_noti_error_str(err));
+ }
+
err = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON,
DP_NOTIFICATION_FAILED_ICON_PATH);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set icon [%s]", __noti_error_str(err));
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set icon id:%d error:%s", download_id, __dp_noti_error_str(err));
+ }
+ err = notification_set_image(noti_handle, NOTIFICATION_IMAGE_TYPE_ICON_FOR_INDICATOR,
+ DP_NOTIFICATION_FAILED_INDICATOR_ICON_PATH);
+ if (err != NOTIFICATION_ERROR_NONE) {
+ TRACE_ERROR("failed to set icon id:%d error:%s", download_id, __dp_noti_error_str(err));
}
- } else {
- TRACE_ERROR("[CRITICAL] invalid state");
- bundle_free(b);
- notification_free(noti_handle);
- return -1;
- }
- if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set time [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- bundle_free(b);
- return -1;
}
- bundle_free(b);
+ if (b != NULL)
+ bundle_free(b);
err = notification_set_property(noti_handle,
NOTIFICATION_PROP_DISABLE_TICKERNOTI);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set property [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set property id:%d error:%s", download_id, __dp_noti_error_str(err));
}
-
err = notification_set_display_applist(noti_handle,
NOTIFICATION_DISPLAY_APP_ALL ^ NOTIFICATION_DISPLAY_APP_INDICATOR);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set disable icon [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set display app all id:%d error:%s", download_id, __dp_noti_error_str(err));
}
- err = notification_insert(noti_handle, &privId);
+ int priv_id = 0;
+ err = notification_insert(noti_handle, &priv_id);
if (err != NOTIFICATION_ERROR_NONE) {
- TRACE_ERROR("[FAIL] set insert [%s]", __noti_error_str(err));
- notification_free(noti_handle);
- return -1;
+ TRACE_ERROR("failed to set priv_id id:%d error:%s", download_id, __dp_noti_error_str(err));
}
- TRACE_DEBUG("m_noti_id [%d]", privId);
+ //TRACE_DEBUG("m_noti_id [%d]", priv_id);
notification_free(noti_handle);
- return privId;
-}
-void dp_update_downloadinginfo_notification(int priv_id, double received_size, double file_size)
-{
- notification_error_e err = NOTIFICATION_ERROR_NONE;
- if (priv_id < 0) {
- TRACE_ERROR("[FAIL] Invalid priv_id[%d]", priv_id);
- return;
- }
-
- if (file_size > 0) {
- double progress;
- progress = received_size / file_size;
- err = notification_update_progress(NULL, priv_id, progress);
- if (err != NOTIFICATION_ERROR_NONE)
- 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[%s]",
- __noti_error_str(err));
- }
+ return priv_id;
}
-
-void dp_clear_downloadinginfo_notification()
+#else
+void dp_notification_clear_ongoings()
{
- 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 [%s]", __noti_error_str(err));
- }
return;
}
+#endif
diff --git a/provider/download-provider-notify.c b/provider/download-provider-notify.c
new file mode 100644
index 0000000..3288fde
--- /dev/null
+++ b/provider/download-provider-notify.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <fcntl.h>
+
+#include <download-provider-log.h>
+#include <download-provider-client.h>
+#include <download-provider-client-manager.h>
+#include <download-provider-ipc.h>
+
+static char *__dp_notify_get_path(pid_t pid)
+{
+ size_t path_size = sizeof(NOTIFY_DIR) + 21;
+ char *notify_fifo = (char *)calloc(path_size, sizeof(char));
+ if (notify_fifo == NULL) {
+ TRACE_STRERROR("failed to alocalte fifo path pid:%d", (int)pid);
+ return NULL;
+ }
+ if (snprintf(notify_fifo, path_size,"%s/%d", NOTIFY_DIR, pid) < 0) {
+ TRACE_STRERROR("failed to make fifo path pid:%d", (int)pid);
+ free(notify_fifo);
+ return NULL;
+ }
+ return notify_fifo;
+}
+
+int dp_notify_init(pid_t pid)
+{
+ char *notify_fifo = __dp_notify_get_path(pid);
+ if (notify_fifo == NULL)
+ return -1;
+ int notify_fd = -1;
+ struct stat fifo_state;
+ if (stat(notify_fifo, &fifo_state) == 0) // found
+ unlink(notify_fifo);
+ if (mkfifo(notify_fifo, 0644/*-rwrr*/) < 0) {
+ TRACE_STRERROR("failed to make fifo %s", notify_fifo);
+ } else {
+ notify_fd = open(notify_fifo, O_RDWR | O_NONBLOCK, 0644);
+ }
+ free(notify_fifo);
+ return notify_fd;
+}
+
+void dp_notify_deinit(pid_t pid)
+{
+ char *notify_fifo = __dp_notify_get_path(pid);
+ if (notify_fifo == NULL)
+ return ;
+ struct stat fifo_state;
+ if (stat(notify_fifo, &fifo_state) == 0) // found
+ unlink(notify_fifo);
+ free(notify_fifo);
+}
+
+static int __dp_notify_feedback(int sock, int id, int state, int errorcode, unsigned long long received_size)
+{
+ dp_ipc_event_fmt eventinfo;
+ memset(&eventinfo, 0x00, sizeof(dp_ipc_event_fmt));
+ eventinfo.id = id;
+ eventinfo.state = state;
+ eventinfo.errorcode = errorcode;
+ eventinfo.received_size = received_size;
+ if (dp_ipc_write(sock, &eventinfo, sizeof(dp_ipc_event_fmt)) < 0) {
+ // failed to read from socket // ignore this status
+ return -1;
+ }
+ return 0;
+}
+
+int dp_notify_feedback(int sock, void *slot, int id, int state, int errorcode, unsigned long long received_size)
+{
+ if (__dp_notify_feedback(sock, id, state, errorcode, received_size) < 0) {
+ TRACE_ERROR("notify failure by IO_ERROR");
+ if (slot != NULL) {
+ dp_client_slots_fmt *base_slot = slot;
+ if (base_slot->client.notify >= 0)
+ close(base_slot->client.notify);
+ base_slot->client.notify = -1;
+ dp_notify_deinit(base_slot->credential.pid);
+ TRACE_ERROR("disable notify channel by IO_ERROR");
+ }
+ return -1;
+ }
+ return 0;
+}
diff --git a/provider/download-provider-plugin-download-agent.c b/provider/download-provider-plugin-download-agent.c
new file mode 100644
index 0000000..5522510
--- /dev/null
+++ b/provider/download-provider-plugin-download-agent.c
@@ -0,0 +1,989 @@
+/*
+ * 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 <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <string.h>
+#include <dlfcn.h> // dlopen
+#include <fcntl.h>
+
+#include <download-provider.h>
+#include <download-provider-log.h>
+#include <download-provider-pthread.h>
+#include <download-provider-ipc.h>
+#include <download-provider-db-defs.h>
+#include <download-provider-db.h>
+#include <download-provider-utils.h>
+#include <download-provider-notify.h>
+#include <download-provider-smack.h>
+#include <download-provider-client.h>
+#include <download-provider-client-manager.h>
+#include <download-provider-plugin-download-agent.h>
+#include <download-provider-notification-manager.h>
+#include <download-provider-queue-manager.h>
+
+#include <download-agent-defs.h>
+#include <download-agent-interface.h>
+#include "xdgmime.h"
+#include "content/mime_type.h"
+
+#define DP_SDCARD_MNT_POINT "/opt/storage/sdcard"
+#define DP_MAX_FILE_PATH_LEN 256
+#define DP_MAX_MIME_TABLE_NUM 15
+
+typedef struct {
+ const char *mime;
+ int content_type;
+}mime_table_type;
+
+const char *ambiguous_mime_type_list[] = {
+ "text/plain",
+ "application/octet-stream"
+};
+
+mime_table_type mime_table[]={
+ // PDF
+ {"application/pdf",DP_CONTENT_PDF},
+ // word
+ {"application/msword",DP_CONTENT_WORD},
+ {"application/vnd.openxmlformats-officedocument.wordprocessingml.document",DP_CONTENT_WORD},
+ // ppt
+ {"application/vnd.ms-powerpoint",DP_CONTENT_PPT},
+ {"application/vnd.openxmlformats-officedocument.presentationml.presentation",DP_CONTENT_PPT},
+ // excel
+ {"application/vnd.ms-excel",DP_CONTENT_EXCEL},
+ {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",DP_CONTENT_EXCEL},
+ // html
+ {"text/html",DP_CONTENT_HTML},
+ // txt
+ {"text/txt",DP_CONTENT_TEXT},
+ {"text/plain",DP_CONTENT_TEXT},
+ // DRM
+ {"application/vnd.oma.drm.content",DP_CONTENT_SD_DRM},
+ {"application/vnd.oma.drm.message",DP_CONTENT_DRM},
+ {"application/x-shockwave-flash", DP_CONTENT_FLASH},
+ {"application/vnd.tizen.package", DP_CONTENT_TPK},
+ {"text/calendar",DP_CONTENT_VCAL},
+};
+
+static void *g_da_handle = NULL;
+static int (*download_agent_init)(void) = NULL; // int da_init(da_client_cb_t *da_client_callback);
+static int (*download_agent_deinit)(void) = NULL; // int da_deinit();
+static int (*download_agent_is_alive)(int) = NULL; // int da_is_valid_download_id(int download_id);
+static int (*download_agent_suspend)(int) = NULL; // int da_suspend_download(int download_id);
+static int (*download_agent_resume)(int) = NULL; // int da_resume_download(int download_id);
+static int (*download_agent_cancel)(int) = NULL; // int da_cancel_download(int download_id);
+static int (*download_agent_suspend_without_update)(int) = NULL; // int da_suspend_download_without_update(int download_id);
+static int (*download_agent_cancel_without_update)(int) = NULL; // int da_cancel_download_without_update(int download_id);
+static int (*download_agent_start)(const char *url, req_data_t *ext_data, da_cb_t *da_cb_data, int *download_id) = NULL; // int da_start_download_with_extension(const char *url, extension_data_t *ext_data, int *download_id);
+static dp_content_type __dp_get_content_type(const char *mime, const char *file_path);
+
+static int __change_error(int err)
+{
+ int ret = DP_ERROR_NONE;
+ switch (err) {
+ case DA_RESULT_OK:
+ ret = DP_ERROR_NONE;
+ break;
+ case DA_ERR_INVALID_ARGUMENT:
+ ret = DP_ERROR_INVALID_PARAMETER;
+ break;
+ case DA_ERR_FAIL_TO_MEMALLOC:
+ ret = DP_ERROR_OUT_OF_MEMORY;
+ break;
+ case DA_ERR_UNREACHABLE_SERVER:
+ ret = DP_ERROR_NETWORK_UNREACHABLE;
+ break;
+ case DA_ERR_HTTP_TIMEOUT:
+ ret = DP_ERROR_CONNECTION_TIMED_OUT;
+ break;
+ case DA_ERR_DISK_FULL:
+ ret = DP_ERROR_NO_SPACE;
+ break;
+ case DA_ERR_INVALID_STATE:
+ ret = DP_ERROR_INVALID_STATE;
+ break;
+ case DA_ERR_NETWORK_FAIL:
+ ret = DP_ERROR_NETWORK_ERROR;
+ break;
+ case DA_ERR_CONNECTION_FAIL:
+ case DA_ERR_NETWORK_UNAUTHORIZED:
+ ret = DP_ERROR_CONNECTION_FAILED;
+ break;
+ case DA_ERR_INVALID_URL:
+ ret = DP_ERROR_INVALID_URL;
+ break;
+ case DA_ERR_INVALID_INSTALL_PATH:
+ ret = DP_ERROR_INVALID_DESTINATION;
+ break;
+ case DA_ERR_ALREADY_MAX_DOWNLOAD:
+ ret = DP_ERROR_TOO_MANY_DOWNLOADS;
+ break;
+ case DA_ERR_FAIL_TO_CREATE_THREAD:
+ case DA_ERR_FAIL_TO_ACCESS_FILE:
+ default:
+ ret = DP_ERROR_IO_ERROR;
+ break;
+ }
+ return ret;
+}
+
+static int __dp_da_state_feedback(dp_client_slots_fmt *slot, dp_request_fmt *request)
+{
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check address");
+ return -1; // try cancel
+ }
+
+ TRACE_INFO("[INFO][%d] state:%s error:%s", request->id,
+ dp_print_state(request->state), dp_print_errorcode(request->error));
+
+ int errorcode = DP_ERROR_NONE;
+ if (dp_db_update_logging(slot->client.dbhandle, request->id,
+ request->state, request->error, &errorcode) < 0) {
+ TRACE_ERROR("logging failure id:%d error:%d", request->id, errorcode);
+ return -1; // try cancel
+ }
+
+ request->access_time = (int)time(NULL);
+
+ if (request->state_cb == 1) {
+ if (slot->client.notify < 0 ||
+ dp_notify_feedback(slot->client.notify, slot, request->id, request->state, request->error, 0) < 0) {
+ TRACE_ERROR("id:%d disable state callback by IO_ERROR", request->id);
+ request->state_cb = 0;
+ }
+ }
+
+ return 0;
+}
+
+static int __precheck_request(dp_request_fmt *request, int agentid)
+{
+ if (request == NULL) {
+ TRACE_ERROR("null-check request req_id:%d", agentid);
+ return -1;
+ }
+ if (request->id < 0 || (request->agent_id != agentid)) {
+ TRACE_ERROR("id-check request_id:%d agent_id:%d req_id:%d",
+ request->id, request->agent_id, agentid);
+ return -1;
+ }
+ return 0;
+}
+
+static int __set_file_permission_to_client(dp_client_slots_fmt *slot, dp_request_fmt *request, char *saved_path)
+{
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check address slot:%p request:%p id:%d agentid:%d", slot, request, (request == NULL ? 0 : request->id), (request == NULL ? 0 : request->agent_id));
+ return DP_ERROR_INVALID_PARAMETER;
+ } else if (saved_path == NULL) {
+ TRACE_ERROR("check null saved path");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+
+ struct stat lstat_info;
+ struct stat fstat_info;
+ int fd;
+ int errorcode = DP_ERROR_NONE;
+ char *str = NULL;
+ str = strrchr(saved_path, '/');
+ dp_credential cred = slot->credential;
+ if (lstat(saved_path, &lstat_info) != -1) {
+ fd = open (saved_path, O_RDONLY);
+ if (fd != -1) {
+ if (fstat(fd, &fstat_info) != -1) {
+ if (lstat_info.st_mode == fstat_info.st_mode &&
+ lstat_info.st_ino == fstat_info.st_ino &&
+ lstat_info.st_dev == fstat_info.st_dev) {
+ if ((fchown(fd, cred.uid, cred.gid) != 0) ||
+ (fchmod(fd, S_IRUSR | S_IWUSR |
+ S_IRGRP | S_IROTH) != 0)) {
+ TRACE_STRERROR("[ERROR][%d] permission user:%d group:%d",
+ request->id, cred.uid, cred.gid);
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ }
+ } else {
+ TRACE_STRERROR("fstat & lstat info have not matched");
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ }
+ } else {
+ TRACE_STRERROR("fstat call failed");
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ }
+ close(fd);
+ } else {
+ TRACE_SECURE_ERROR("open failed for file : %s", saved_path);
+ errorcode = DP_ERROR_IO_ERROR;
+ }
+ } else {
+ TRACE_STRERROR("lstat call failed");
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ }
+ if (errorcode == DP_ERROR_NONE && dp_smack_is_mounted() == 1) {
+ // get smack_label from sql
+ char *smack_label = dp_db_get_client_smack_label(slot->pkgname);
+ if (smack_label == NULL) {
+ TRACE_SECURE_ERROR("[SMACK][%d] no label", request->id);
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ } else {
+ size_t len = str - (saved_path);
+ char *dir_path = (char *)calloc(len + 1, sizeof(char));
+ if (dir_path != NULL) {
+ strncpy(dir_path, saved_path, len);
+ errorcode = dp_smack_set_label(smack_label, dir_path, saved_path);
+ free(dir_path);
+ } else {
+ TRACE_STRERROR("[ERROR] calloc");
+ errorcode = DP_ERROR_OUT_OF_MEMORY;
+ }
+ free(smack_label);
+ }
+ }
+ return errorcode;
+}
+
+static void __finished_cb(finished_info_t *info, void *user_req_data,
+ void *user_client_data)
+{
+ if (info == NULL) {
+ TRACE_ERROR("check download info address");
+ return ;
+ }
+ dp_client_slots_fmt *slot = user_client_data;
+ dp_request_fmt *request = user_req_data;
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check address slot:%p request:%p id:%d agentid:%d", slot, request, (request == NULL ? 0 : request->id), info->download_id);
+ free(info->etag);
+ free(info->saved_path);
+ free(info);
+ return ;
+ }
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+ if (__precheck_request(request, info->download_id) < 0) {
+ TRACE_ERROR("error request agent_id:%d", info->download_id);
+ if (dp_cancel_agent_download(info->download_id) < 0)
+ TRACE_ERROR("failed to call cancel_download(%d)", info->download_id);
+ free(info->etag);
+ free(info->saved_path);
+ free(info);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ return ;
+ }
+
+ int state = DP_STATE_NONE;
+ int errorcode = DP_ERROR_NONE;
+
+ if (info->http_status > 0) {
+ if (dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_HTTP_STATUS, (void *)&info->http_status, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set http_status(%d)", request->id, info->http_status);
+ }
+ }
+
+ TRACE_SECURE_DEBUG("[FINISH][%d][%s]", request->id, info->saved_path);
+ if (info->err == DA_RESULT_OK) {
+ if (info->saved_path != NULL) {
+ if(strncmp(DP_SDCARD_MNT_POINT, info->saved_path, strlen(DP_SDCARD_MNT_POINT)) != 0) {
+ errorcode = __set_file_permission_to_client(slot, request, info->saved_path);
+ }
+ } else {
+ TRACE_ERROR("[ERROR][%d] No SavedPath", request->id);
+ errorcode = DP_ERROR_INVALID_DESTINATION;
+ }
+ if (errorcode == DP_ERROR_NONE)
+ state = DP_STATE_COMPLETED;
+ else
+ state = DP_STATE_FAILED;
+ } else {
+ if (info->err == DA_RESULT_USER_CANCELED) {
+
+ TRACE_INFO("[CANCELED][%d]", request->id);
+
+ // if state is canceled and error is DP_ERROR_IO_EAGAIN mean ip_changed
+ if (request->error == DP_ERROR_IO_EAGAIN) {
+ request->error = DP_ERROR_NONE;
+ } else {
+ state = DP_STATE_CANCELED;
+ errorcode = request->error;
+ }
+
+ } else {
+ state = DP_STATE_FAILED;
+ errorcode = __change_error(info->err);
+ TRACE_ERROR("[FAILED][%d][%s] agent error:%d", request->id,
+ dp_print_errorcode(errorcode), info->err);
+ }
+
+ }
+
+ if (errorcode == DP_ERROR_NONE && info->saved_path != NULL) {
+
+ char *content_name = NULL;
+ char *str = NULL;
+ str = strrchr(info->saved_path, '/');
+ if (str != NULL) {
+ str++;
+ content_name = dp_strdup(str);
+ }
+ if (request->file_size == 0) {// missed in download_cb
+ request->file_size = request->received_size;
+ if (dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_SIZE, (void *)&request->file_size, 0, 1, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set content_size(%ld)", request->id, request->file_size);
+ }
+ }
+ // update contentname, savedpath
+ if (content_name != NULL) {
+ if (dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_NAME, (void *)content_name, 0, 2, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set content_name", request->id);
+ }
+ }
+ if (dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_SAVED_PATH, (void *)info->saved_path, 0, 2, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set saved_path", request->id);
+ }
+ free(content_name);
+ /* update the received file size.
+ * The last received file size cannot update
+ * because of reducing update algorithm*/
+ if (request->progress_cb == 1) {
+ if (slot->client.notify < 0 ||
+ dp_notify_feedback(slot->client.notify, slot, request->id, DP_STATE_DOWNLOADING, DP_ERROR_NONE, request->received_size) < 0) {
+ TRACE_ERROR("id:%d disable progress callback by IO_ERROR", request->id);
+ request->progress_cb = 0;
+ }
+ }
+ }
+
+ request->state = state;
+ request->error = errorcode;
+
+ if (__dp_da_state_feedback(slot, request) < 0) {
+ TRACE_ERROR("id:%d check notify channel", request->id);
+ if (dp_cancel_agent_download_without_update(request->agent_id) < 0)
+ TRACE_ERROR("[fail][%d]cancel_agent", request->id);
+ }
+ if (request->noti_type == DP_NOTIFICATION_TYPE_COMPLETE_ONLY ||
+ request->noti_type == DP_NOTIFICATION_TYPE_ALL) {
+ if (dp_notification_manager_push_notification(slot, request, DP_NOTIFICATION) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", request->id);
+ }
+ }
+ free(info->etag);
+ free(info->saved_path);
+ free(info);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+}
+
+static void __paused_cb(int download_id, void *user_req_data, void *user_client_data)
+{
+ dp_client_slots_fmt *slot = user_client_data;
+ dp_request_fmt *request = user_req_data;
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check address slot:%p request:%p id:%d agentid:%d", slot, request, (request == NULL ? 0 : request->id), download_id);
+ return ;
+ }
+ dp_queue_manager_wake_up();
+}
+
+static void __download_info_cb(download_info_t *info, void *user_req_data, void *user_client_data)
+{
+ if (info == NULL) {
+ TRACE_ERROR("check download info address");
+ return ;
+ }
+ dp_client_slots_fmt *slot = user_client_data;
+ dp_request_fmt *request = user_req_data;
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check address slot:%p request:%p id:%d agentid:%d", slot, request, (request == NULL ? 0 : request->id), info->download_id);
+ free(info->content_name);
+ free(info->etag);
+ free(info->file_type);
+ free(info->tmp_saved_path);
+ free(info);
+ return ;
+ }
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+ if (__precheck_request(request, info->download_id) < 0) {
+ TRACE_ERROR("error request agent_id:%d", info->download_id);
+ if (dp_cancel_agent_download(info->download_id) < 0)
+ TRACE_ERROR("failed to call cancel_download(%d)", info->download_id);
+ free(info->content_name);
+ free(info->etag);
+ free(info->file_type);
+ free(info->tmp_saved_path);
+ free(info);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ return ;
+ }
+
+ // update info before sending event
+ TRACE_SECURE_DEBUG("[DOWNLOAD][%d][%s]", request->id, info->tmp_saved_path);
+ if (info->tmp_saved_path != NULL) {
+ int errorcode = DP_ERROR_NONE;
+ if (dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_MIMETYPE, (void *)info->file_type, 0, 2, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set mimetype", request->id);
+ }
+ if (dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_NAME, (void *)info->content_name, 0, 2, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set contentname", request->id);
+ }
+ if (dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_TMP_SAVED_PATH, (void *)info->tmp_saved_path, 0, 2, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set tmp_saved_path", request->id);
+ }
+ if (info->file_size > 0 && dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_CONTENT_SIZE, (void *)&(info->file_size), 0, 1, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set file size", request->id);
+ }
+ if (info->etag && dp_db_replace_property(slot->client.dbhandle, request->id, DP_TABLE_DOWNLOAD, DP_DB_COL_ETAG, (void *)info->etag, 0, 2, &errorcode) < 0) {
+ TRACE_ERROR("id:%d failed to set etag", request->id);
+ }
+ if(strncmp(DP_SDCARD_MNT_POINT, info->tmp_saved_path, strlen(DP_SDCARD_MNT_POINT)) != 0) {
+ errorcode = __set_file_permission_to_client(slot, request, info->tmp_saved_path);
+ }
+ request->error = errorcode;
+ } else {
+ request->error = DP_ERROR_IO_ERROR;
+ }
+
+ if (request->error != DP_ERROR_NONE) {
+ request->state = DP_STATE_FAILED;
+ TRACE_ERROR("id:%d try to cancel(%d)", request->id, info->download_id);
+ if (dp_cancel_agent_download(request->agent_id) < 0) {
+ TRACE_ERROR("[fail][%d] cancel_agent:%d", request->id,
+ info->download_id);
+ }
+ } else {
+ request->state = DP_STATE_DOWNLOADING;
+ request->file_size = info->file_size; // unsigned
+ TRACE_DEBUG("[STARTED] id:%d agentid:%d", request->id, info->download_id);
+ }
+
+ if (__dp_da_state_feedback(slot, request) < 0) {
+ TRACE_ERROR("id:%d check notify channel", request->id);
+ if (dp_cancel_agent_download(request->agent_id) < 0)
+ TRACE_ERROR("[fail][%d]cancel_agent", request->id);
+ }
+ // notification
+ if (request->noti_type == DP_NOTIFICATION_TYPE_ALL) {
+ if (dp_notification_manager_push_notification(slot, request, DP_NOTIFICATION_ONGOING_UPDATE) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", request->id);
+ }
+ }
+ //get the mime type for dp notification
+ if (request->noti_type > DP_NOTIFICATION_TYPE_NONE) {
+ request->content_type = __dp_get_content_type(info->file_type, info->tmp_saved_path);
+ }
+ free(info->content_name);
+ free(info->etag);
+ free(info->file_type);
+ free(info->tmp_saved_path);
+ free(info);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+}
+
+static void __progress_cb(int download_id, unsigned long long received_size,
+ void *user_req_data, void *user_client_data)
+{
+ dp_client_slots_fmt *slot = user_client_data;
+ dp_request_fmt *request = user_req_data;
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check address slot:%p request:%p id:%d agentid:%d", slot, request, (request == NULL ? 0 : request->id), download_id);
+ return ;
+ }
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+ /*
+ if (CLIENT_MUTEX_TRYLOCK(&slot->mutex) != 0) {
+ TRACE_ERROR("slot busy agent_id:%d", download_id);
+ return ;
+ }
+ */
+ if (__precheck_request(request, download_id) < 0) {
+ TRACE_ERROR("error request agent_id:%d", download_id);
+ if (dp_cancel_agent_download(download_id) < 0)
+ TRACE_ERROR("failed to call cancel_download(%d)", download_id);
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ return ;
+ }
+
+ // For resume case after pause, it change state from connecting to downloading
+ if (request->state == DP_STATE_CONNECTING) {
+ request->state = DP_STATE_DOWNLOADING;
+ if (__dp_da_state_feedback(slot, request) < 0) {
+ TRACE_ERROR("id:%d check notify channel", request->id);
+ if (dp_cancel_agent_download(request->agent_id) < 0)
+ TRACE_ERROR("[fail][%d]cancel_agent", request->id);
+ }
+ }
+
+ if (request->state == DP_STATE_DOWNLOADING) {
+ request->received_size = received_size;
+ time_t tt = time(NULL);
+ struct tm *localTime = localtime(&tt);
+ // send event every 1 second.
+ if (request->progress_lasttime != localTime->tm_sec) {
+ request->progress_lasttime = localTime->tm_sec;
+
+ if (request->progress_cb == 1) {
+ if (slot->client.notify < 0 ||
+ dp_notify_feedback(slot->client.notify, slot,
+ request->id, DP_STATE_DOWNLOADING, DP_ERROR_NONE, received_size) < 0) {
+ // failed to read from socket // ignore this status
+ TRACE_ERROR("id:%d disable progress callback by IO_ERROR", request->id);
+ request->progress_cb = 0;
+ }
+ }
+
+ if (request->noti_type == DP_NOTIFICATION_TYPE_ALL) {
+ if (dp_notification_manager_push_notification(slot, request, DP_NOTIFICATION_ONGOING_PROGRESS) < 0) {
+ TRACE_ERROR("failed to register notification for id:%d", request->id);
+ }
+ }
+
+ }
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+}
+
+static int __dp_is_ambiguous_mime_type(const char *mime_type)
+{
+ if (mime_type == NULL)
+ return -1;
+
+ int index = 0;
+ int listSize = sizeof(ambiguous_mime_type_list) / sizeof(const char *);
+ for (index = 0; index < listSize; index++) {
+ if (0 == strncmp(mime_type, ambiguous_mime_type_list[index],
+ strlen(ambiguous_mime_type_list[index]))) {
+ TRACE_DEBUG("It is ambiguous");
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static dp_content_type __dp_get_content_type(const char *mime, const char *file_path)
+{
+ int i = 0;
+ int type = DP_CONTENT_UNKNOWN;
+ char *temp_mime = NULL;
+ if (mime == NULL || strlen(mime) < 1)
+ return DP_CONTENT_UNKNOWN;
+
+ if ((file_path != NULL) && (strlen(file_path) > 0) &&
+ (__dp_is_ambiguous_mime_type(mime) == 0)) {
+ const char *ext = strrchr(file_path, '.');
+ if (ext == NULL) {
+ TRACE_ERROR("File Extension is NULL");
+ return type;
+ }
+ mime_type_get_mime_type(ext + 1, &temp_mime);
+ }
+ if (temp_mime == NULL) {
+ temp_mime = (char *)calloc(1, DP_MAX_FILE_PATH_LEN);
+ if (temp_mime == NULL) {
+ TRACE_ERROR("Fail to call calloc");
+ return type;
+ }
+ strncpy(temp_mime, mime, DP_MAX_FILE_PATH_LEN - 1);
+ }
+ TRACE_SECURE_DEBUG("mime type [%s]", temp_mime);
+
+ /* Search a content type from mime table. */
+ for (i = 0; i < DP_MAX_MIME_TABLE_NUM; i++) {
+ if (strncmp(mime_table[i].mime, temp_mime, strlen(temp_mime)) == 0){
+ type = mime_table[i].content_type;
+ break;
+ }
+ }
+ if (type == DP_CONTENT_UNKNOWN) {
+ const char *unaliased_mime = NULL;
+ /* unaliased_mimetype means representative mime among similar types */
+ unaliased_mime = xdg_mime_unalias_mime_type(temp_mime);
+
+ if (unaliased_mime != NULL) {
+ TRACE_SECURE_DEBUG("unaliased mime type[%s]",unaliased_mime);
+ if (strstr(unaliased_mime,"video/") != NULL)
+ type = DP_CONTENT_VIDEO;
+ else if (strstr(unaliased_mime,"audio/") != NULL)
+ type = DP_CONTENT_MUSIC;
+ else if (strstr(unaliased_mime,"image/") != NULL)
+ type = DP_CONTENT_IMAGE;
+ }
+ }
+ free(temp_mime);
+ TRACE_DEBUG("type[%d]", type);
+ return type;
+}
+
+
+int dp_init_agent()
+{
+
+ g_da_handle = dlopen("/usr/lib/libdownloadagent2.so", RTLD_LAZY | RTLD_GLOBAL);
+ if (!g_da_handle) {
+ TRACE_ERROR("[dlopen] %s", dlerror());
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+ dlerror(); /* Clear any existing error */
+
+ *(void **) (&download_agent_init) = dlsym(g_da_handle, "da_init");
+ if (download_agent_init == NULL ) {
+ TRACE_ERROR("[dlsym] da_init:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(void **) (&download_agent_deinit) = dlsym(g_da_handle, "da_deinit");
+ if (download_agent_deinit == NULL ) {
+ TRACE_ERROR("[dlsym] da_deinit:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(void **) (&download_agent_is_alive) =
+ dlsym(g_da_handle, "da_is_valid_download_id");
+ if (download_agent_is_alive == NULL ) {
+ TRACE_ERROR("[dlsym] da_is_valid_download_id:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(void **) (&download_agent_suspend) =
+ dlsym(g_da_handle, "da_suspend_download");
+ if (download_agent_suspend == NULL ) {
+ TRACE_ERROR("[dlsym] da_suspend_download:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(void **) (&download_agent_resume) =
+ dlsym(g_da_handle, "da_resume_download");
+ if (download_agent_resume == NULL) {
+ TRACE_ERROR("[dlsym] da_resume_download:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+// *(void **) (&download_agent_cancel) = dlsym(g_da_handle, "da_cancel_download_without_update");
+ *(void **) (&download_agent_cancel) =
+ dlsym(g_da_handle, "da_cancel_download");
+ if (download_agent_cancel == NULL) {
+ TRACE_ERROR("[dlsym] da_cancel_download:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(void **) (&download_agent_start) =
+ dlsym(g_da_handle, "da_start_download");
+ if (download_agent_start == NULL) {
+ TRACE_ERROR("[dlsym] da_start_download:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(void **) (&download_agent_cancel_without_update) = dlsym(g_da_handle, "da_cancel_download_without_update");
+ if (download_agent_cancel_without_update == NULL) {
+ TRACE_ERROR("[dlsym] da_cancel_download_without_update:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ *(void **) (&download_agent_suspend_without_update) = dlsym(g_da_handle, "da_suspend_download_without_update");
+ if (download_agent_suspend_without_update == NULL) {
+ TRACE_ERROR("[dlsym] da_suspend_download_without_update:%s", dlerror());
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ int da_ret = -1;
+ da_ret = (*download_agent_init)();
+ if (da_ret != DA_RESULT_OK) {
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+ return DP_ERROR_NONE;
+}
+
+void dp_deinit_agent()
+{
+ if (g_da_handle != NULL) {
+ if (download_agent_deinit != NULL)
+ (*download_agent_deinit)();
+
+ dlclose(g_da_handle);
+ g_da_handle = NULL;
+ }
+}
+
+// 1 : alive
+// 0 : not alive
+int dp_is_alive_download(int req_id)
+{
+ int da_ret = 0;
+ if (req_id < 0)
+ return 0;
+ if (download_agent_is_alive != NULL)
+ da_ret = (*download_agent_is_alive)(req_id);
+ return da_ret;
+}
+
+// 0 : success
+// -1 : failed
+int dp_cancel_agent_download(int req_id)
+{
+ if (req_id < 0) {
+ TRACE_ERROR("[NULL-CHECK] req_id");
+ return -1;
+ }
+ if (dp_is_alive_download(req_id) == 0) {
+ TRACE_ERROR("[CHECK agent-id:%d] dead request", req_id);
+ return -1;
+ }
+ if (download_agent_cancel != NULL) {
+ if ((*download_agent_cancel)(req_id) == DA_RESULT_OK)
+ return 0;
+ }
+ return -1;
+}
+
+// 0 : success
+// -1 : failed
+int dp_pause_agent_download(int req_id)
+{
+ if (req_id < 0) {
+ TRACE_ERROR("[NULL-CHECK] req_id");
+ return -1;
+ }
+ if (dp_is_alive_download(req_id) == 0) {
+ TRACE_ERROR("[CHECK agent-id:%d] dead request", req_id);
+ return -1;
+ }
+ if (download_agent_suspend != NULL) {
+ if ((*download_agent_suspend)(req_id) == DA_RESULT_OK)
+ return 0;
+ }
+ return -1;
+}
+
+
+// 0 : success
+// -1 : failed
+int dp_cancel_agent_download_without_update(int req_id)
+{
+ if (req_id < 0) {
+ TRACE_ERROR("[NULL-CHECK] req_id");
+ return -1;
+ }
+ if (dp_is_alive_download(req_id) == 0) {
+ TRACE_ERROR("[CHECK agent-id:%d] dead request", req_id);
+ return -1;
+ }
+ if (download_agent_cancel_without_update != NULL) {
+ if ((*download_agent_cancel_without_update)(req_id) == DA_RESULT_OK)
+ return 0;
+ }
+ return -1;
+}
+
+// 0 : success
+// -1 : failed
+int dp_pause_agent_download_without_update(int req_id)
+{
+ if (req_id < 0) {
+ TRACE_ERROR("[NULL-CHECK] req_id");
+ return -1;
+ }
+ if (dp_is_alive_download(req_id) == 0) {
+ TRACE_ERROR("[CHECK agent-id:%d] dead request", req_id);
+ return -1;
+ }
+ if (download_agent_suspend_without_update != NULL) {
+ if ((*download_agent_suspend_without_update)(req_id) == DA_RESULT_OK)
+ return 0;
+ }
+ return -1;
+}
+
+// 0 : success
+// -1 : failed
+// -2 : pended
+int dp_start_agent_download(void *slot, void *request)
+{
+ int da_ret = -1;
+ int req_dl_id = -1;
+ req_data_t *req_data = NULL;
+
+ dp_client_slots_fmt *base_slot = slot;
+ dp_request_fmt *base_req = request;
+
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check slot or request address");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+
+ da_cb_t da_cb = {
+ __download_info_cb,
+ __progress_cb,
+ __finished_cb,
+ __paused_cb
+ };
+
+ req_data = (req_data_t *)calloc(1, sizeof(req_data_t));
+ if (req_data == NULL) {
+ TRACE_ERROR("[ERROR] calloc");
+ return DP_ERROR_OUT_OF_MEMORY;
+ }
+
+ int errorcode = DP_ERROR_NONE;
+ unsigned length = 0;
+ char *url = NULL;
+ char *destination = NULL;
+ char *tmp_saved_path = NULL;
+ char *user_tmp_file_path = NULL;
+ char *filename = NULL;
+ char *etag = NULL;
+ int user_network_bonding = 0;
+
+ if (dp_db_get_property_string(base_slot->client.dbhandle, base_req->id, DP_TABLE_REQUEST, DP_DB_COL_URL, (unsigned char **)&url, &length, &errorcode) < 0 ||
+ url == NULL) {
+ free(req_data);
+ if (errorcode == DP_ERROR_NO_DATA) {
+ TRACE_ERROR("url id:%d NO_DATA", base_req->id);
+ return DP_ERROR_INVALID_URL;
+ } else {
+ TRACE_ERROR("url id:%d DISK_BUSY", base_req->id);
+ return DP_ERROR_DISK_BUSY;
+ }
+ }
+ if (dp_db_get_property_string(base_slot->client.dbhandle, base_req->id, DP_TABLE_REQUEST, DP_DB_COL_TEMP_FILE_PATH, (unsigned char **)&user_tmp_file_path, &length, &errorcode) < 0 ||
+ user_tmp_file_path == NULL) {
+ TRACE_DEBUG("user_tmp_file_path id:%d NO_DATA", base_req->id);
+ }
+
+ if (user_tmp_file_path != NULL)
+ req_data->temp_file_path = user_tmp_file_path;
+ else {
+ if (dp_db_get_property_string(base_slot->client.dbhandle, base_req->id, DP_TABLE_REQUEST, DP_DB_COL_FILENAME, (unsigned char **)&filename, &length, &errorcode) < 0 ||
+ filename == NULL) {
+ TRACE_DEBUG("filename id:%d NO_DATA", base_req->id);
+ } else
+ req_data->file_name = filename;
+ if (dp_db_get_property_string(base_slot->client.dbhandle, base_req->id, DP_TABLE_REQUEST, DP_DB_COL_DESTINATION, (unsigned char **)&destination, &length, &errorcode) < 0 ||
+ destination == NULL) {
+ TRACE_DEBUG("destination id:%d NO_DATA", base_req->id);
+ } else
+ req_data->install_path = destination;
+ if (dp_db_get_property_string(base_slot->client.dbhandle, base_req->id, DP_TABLE_DOWNLOAD, DP_DB_COL_TMP_SAVED_PATH, (unsigned char **)&tmp_saved_path, &length, &errorcode) < 0 ||
+ tmp_saved_path == NULL) {
+ TRACE_DEBUG("tmp_saved_path id:%d NO_DATA", base_req->id);
+ }
+ }
+
+ if (tmp_saved_path != NULL) {
+ if (dp_db_get_property_string(base_slot->client.dbhandle, base_req->id, DP_TABLE_DOWNLOAD, DP_DB_COL_ETAG, (unsigned char **)&etag, &length, &errorcode) < 0 ||
+ etag == NULL) {
+ TRACE_DEBUG("etag id:%d NO_DATA", base_req->id);
+ }
+ if (etag != NULL) {
+ TRACE_DEBUG("try to resume id:%d", base_req->id);
+ req_data->etag = etag;
+ req_data->temp_file_path = tmp_saved_path;
+ } else {
+ /* FIXME later : It is better to handle the unlink function in download agaent module
+ * or in upload the request data to memory after the download provider process is restarted */
+ TRACE_SECURE_INFO("try to restart id:%d remove tmp file:%s",
+ base_req->id, tmp_saved_path);
+ if (dp_is_file_exist(tmp_saved_path) == 0) {
+ if (unlink(tmp_saved_path) != 0)
+ TRACE_STRERROR("failed to remove file id:%d", base_req->id);
+ }
+ }
+ }
+ if( dp_db_get_property_int(base_slot->client.dbhandle, base_req->id, DP_TABLE_REQUEST, DP_DB_COL_NETWORK_BONDING, (int *)&user_network_bonding, &errorcode) < 0 ||
+ user_network_bonding < 0) {
+ TRACE_DEBUG("unable to get network bonding value for id:%d", base_req->id);
+ } else
+ req_data->network_bonding = user_network_bonding;
+
+ req_data->pkg_name = base_slot->pkgname;
+
+ // get headers list from header table(DB)
+ int headers_count = dp_db_check_duplicated_int(base_slot->client.dbhandle, DP_TABLE_HEADERS, DP_DB_COL_ID, base_req->id, &errorcode);
+ if (headers_count > 0) {
+ req_data->request_header = calloc(headers_count, sizeof(char *));
+ if (req_data->request_header != NULL) {
+ headers_count = dp_db_get_http_headers_list(base_slot->client.dbhandle, base_req->id, (char **)req_data->request_header, &errorcode);
+ if (headers_count > 0)
+ req_data->request_header_count = headers_count;
+ }
+ }
+
+ req_data->user_client_data = (void *)slot;
+ req_data->user_req_data = (void *)request;
+
+ // call start API of agent lib
+ if (download_agent_start != NULL)
+ da_ret = (*download_agent_start)(url, req_data, &da_cb, &req_dl_id);
+ if (req_data->request_header_count > 0) {
+ int len = 0;
+ int i = 0;
+ len = req_data->request_header_count;
+ for (i = 0; i < len; i++)
+ free((void *)(req_data->request_header[i]));
+ free(req_data->request_header);
+ }
+ free(url);
+ free(destination);
+ free(tmp_saved_path);
+ free(user_tmp_file_path);
+ free(filename);
+ free(etag);
+ free(req_data);
+
+ if (da_ret == DA_RESULT_OK) {
+ TRACE_DEBUG("request id :%d SUCCESS agent_id:%d", base_req->id, req_dl_id);
+ base_req->agent_id = req_dl_id;
+ }
+ return __change_error(da_ret);
+}
+
+int dp_resume_agent_download(int req_id)
+{
+ int da_ret = -1;
+ if (req_id < 0) {
+ TRACE_ERROR("[NULL-CHECK] req_id");
+ return DP_ERROR_INVALID_PARAMETER;
+ }
+ if (download_agent_resume != NULL)
+ da_ret = (*download_agent_resume)(req_id);
+ if (da_ret == DA_RESULT_OK)
+ return DP_ERROR_NONE;
+ else if (da_ret == DA_ERR_INVALID_STATE)
+ return DP_ERROR_INVALID_STATE;
+ return __change_error(da_ret);
+}
+
diff --git a/provider/download-provider-pthread.c b/provider/download-provider-pthread.c
new file mode 100644
index 0000000..3ef2816
--- /dev/null
+++ b/provider/download-provider-pthread.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+
+#include "download-provider-log.h"
+#include "download-provider-pthread.h"
+
+static char *__print_pthread_error(int code)
+{
+ switch(code)
+ {
+ case 0:
+ return "NONE";
+ case EINVAL:
+ return "EINVAL";
+ case ENOMEM:
+ return "ENOMEM";
+ case EBUSY:
+ return "EBUSY";
+ case EDEADLK:
+ return "EDEADLK";
+ }
+ return "UNKNOWN";
+}
+
+int dp_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+{
+ int ret = pthread_mutex_init(mutex, attr);
+ if (0 == ret || EBUSY == ret)
+ return 0;
+ else
+ TRACE_STRERROR("error:%d.%s", ret, __print_pthread_error(ret));
+ return -1;
+}
+
+void dp_mutex_lock(pthread_mutex_t *mutex, const char *func, int line)
+{
+ int ret = pthread_mutex_lock(mutex);
+ if (ret != 0)
+ TRACE_STRERROR("%s:%d error:%d.%s", func, line, ret,
+ __print_pthread_error(ret));
+}
+
+int dp_mutex_check_lock(pthread_mutex_t *mutex, const char *func, int line)
+{
+ int ret = pthread_mutex_lock(mutex);
+ if (ret != 0)
+ TRACE_STRERROR("%s:%d error:%d.%s", func, line, ret,
+ __print_pthread_error(ret));
+ return ret;
+}
+
+int dp_mutex_trylock(pthread_mutex_t *mutex, const char *func, int line)
+{
+ int ret = pthread_mutex_trylock(mutex);
+ if (ret != 0 && ret != EINVAL) {
+ TRACE_STRERROR("%s:%d error:%d.%s", func, line, ret,
+ __print_pthread_error(ret));
+ }
+ return ret;
+}
+
+int dp_mutex_timedlock(pthread_mutex_t *mutex, int sec, const char *func, int line)
+{
+ struct timespec deltatime;
+ deltatime.tv_sec = sec;
+ deltatime.tv_nsec = 0;
+ int ret = pthread_mutex_timedlock(mutex, &deltatime);
+ if (ret != 0) {
+ TRACE_STRERROR("%s:%d error:%d.%s", func, line, ret,
+ __print_pthread_error(ret));
+ }
+ return ret;
+}
+
+void dp_mutex_unlock(pthread_mutex_t *mutex, const char *func, int line)
+{
+ int ret = pthread_mutex_unlock(mutex);
+ if (ret != 0)
+ TRACE_STRERROR("%s:%d error:%d.%s", func, line, ret,
+ __print_pthread_error(ret));
+}
+
+void dp_mutex_destroy(pthread_mutex_t *mutex)
+{
+ int ret = pthread_mutex_destroy(mutex);
+ if (ret != 0) {
+ TRACE_STRERROR("error:%d.%s", ret, __print_pthread_error(ret));
+ if(EBUSY == ret) {
+ if (pthread_mutex_unlock(mutex) == 0)
+ pthread_mutex_destroy(mutex);
+ }
+ }
+}
diff --git a/provider/download-provider-queue-manager.c b/provider/download-provider-queue-manager.c
new file mode 100644
index 0000000..41f4a36
--- /dev/null
+++ b/provider/download-provider-queue-manager.c
@@ -0,0 +1,315 @@
+/*
+ * 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 <stdlib.h>
+#include <signal.h> // pthread_kill
+#include <errno.h> // ESRCH
+
+#include <download-provider-log.h>
+#include <download-provider-pthread.h>
+
+#include <download-provider-db-defs.h>
+#include <download-provider-db.h>
+#include <download-provider-queue.h>
+#include <download-provider-network.h>
+#include <download-provider-notify.h>
+#include <download-provider-client.h>
+#include <download-provider-client-manager.h>
+#include <download-provider-plugin-download-agent.h>
+
+pthread_mutex_t g_dp_queue_manager_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t g_dp_queue_manager_cond = PTHREAD_COND_INITIALIZER;
+pthread_t g_dp_queue_manager_tid = 0;
+
+static dp_queue_fmt *g_dp_queue_network_all = NULL;
+static dp_queue_fmt *g_dp_queue_network_wifi = NULL;
+static dp_queue_fmt *g_dp_queue_network_data_network = NULL;
+static dp_queue_fmt *g_dp_queue_network_wifi_direct = NULL;
+
+static dp_queue_fmt **__dp_queue_manager_get_queue(int network)
+{
+ switch(network) {
+ case DP_NETWORK_ALL:
+ //TRACE_DEBUG("network all");
+ return &g_dp_queue_network_all;
+ case DP_NETWORK_WIFI:
+ //TRACE_DEBUG("network wifi only");
+ return &g_dp_queue_network_wifi;
+ case DP_NETWORK_DATA_NETWORK:
+ //TRACE_DEBUG("network data network only");
+ return &g_dp_queue_network_data_network;
+ case DP_NETWORK_WIFI_DIRECT:
+ //TRACE_DEBUG("network wifi-direct");
+ return &g_dp_queue_network_wifi_direct;
+ default:
+ break;
+ }
+ return NULL;
+}
+int dp_queue_manager_push_queue(void *slot, void *request)
+{
+ dp_request_fmt *requestp = request;
+ if (slot == NULL || request == NULL) {
+ TRACE_DEBUG("check address client:%p request:%p id:%d", slot,
+ request, (request == NULL ? 0 : requestp->id));
+ return -1;
+ }
+ dp_queue_fmt **queue = __dp_queue_manager_get_queue(requestp->network_type);
+ if (requestp->state != DP_STATE_QUEUED) {
+ TRACE_ERROR("check id:%d state:%s", requestp->id, dp_print_state(requestp->state));
+ return -1;
+ }
+ if (dp_queue_push(queue, slot, request) < 0) {
+ TRACE_ERROR("failed to push to queue id:%d", requestp->id);
+ return -1;
+ }
+ return 0;
+}
+
+void dp_queue_manager_clear_queue(void *request)
+{
+ dp_request_fmt *requestp = request;
+ if (request == NULL) {
+ TRACE_DEBUG("check address request:%p id:%d",
+ request, (request == NULL ? 0 : requestp->id));
+ return ;
+ }
+ dp_queue_fmt **queue = __dp_queue_manager_get_queue(requestp->network_type);
+ dp_queue_clear(queue, request);
+}
+
+// if return negative, queue-manager try again.
+static int __dp_queue_manager_try_download(dp_client_slots_fmt *slot, dp_request_fmt *request)
+{
+ int errorcode = DP_ERROR_NONE;
+ int result = 0;
+
+ if (slot == NULL || request == NULL) {
+ TRACE_DEBUG("check address client:%p request:%p id:%d", slot,
+ request, (request == NULL ? 0 : request->id));
+ // return 0 to ignore this call.
+ return 0;
+ }
+
+ if (request->state != DP_STATE_QUEUED) {
+ TRACE_ERROR("check id %d state:%d", request->id, request->state);
+ return 0;
+ }
+
+ // check startcount
+
+ request->startcount++;
+ request->access_time = (int)time(NULL);
+
+ if (dp_db_replace_property(slot->client.dbhandle, request->id,
+ DP_TABLE_LOGGING, DP_DB_COL_STARTCOUNT,
+ (void *)&request->startcount, 0, 0, &errorcode) < 0) {
+ TRACE_ERROR("failed to set startcount");
+ return -1;
+ }
+
+ errorcode = DP_ERROR_NONE;
+
+ if (dp_is_alive_download(request->agent_id) > 0)
+ errorcode = dp_resume_agent_download(request->agent_id);
+ else
+ // call agent start function
+ errorcode = dp_start_agent_download(slot, request);
+
+ if (errorcode == DP_ERROR_NONE) {
+ request->state = DP_STATE_CONNECTING;
+ } else if (errorcode == DP_ERROR_TOO_MANY_DOWNLOADS ||
+ errorcode == DP_ERROR_DISK_BUSY ||
+ errorcode == DP_ERROR_OUT_OF_MEMORY) {
+ TRACE_ERROR("push queue id:%d error:%s", request->id, dp_print_errorcode(errorcode));
+ // PENDED
+ request->state = DP_STATE_QUEUED;
+ result = -1; // try again.
+ } else if (errorcode == DP_ERROR_INVALID_STATE) { // by resume
+ // ignore this request
+ result = -1;
+ TRACE_ERROR("failed to resume id:%d", request->id);
+ request->agent_id = -1; // workaround. da_agent will an object for this agent_id later
+ } else if (errorcode != DP_ERROR_NONE) {
+ request->state = DP_STATE_FAILED;
+ }
+
+ request->error = errorcode;
+
+ if (result == 0) { // it's not for retrying
+ int sqlerror = DP_ERROR_NONE;
+ if (dp_db_update_logging(slot->client.dbhandle, request->id,
+ request->state, request->error, &sqlerror) < 0) {
+ TRACE_ERROR("logging failure id:%d error:%d", request->id, sqlerror);
+ }
+ if (errorcode != DP_ERROR_NONE && request->state_cb == 1) { // announce state
+
+ TRACE_ERROR("notify id:%d error:%s", request->id, dp_print_errorcode(errorcode));
+ if (dp_notify_feedback(slot->client.notify, slot,
+ request->id, request->state, request->error, 0) < 0) {
+ TRACE_ERROR("disable state callback by IO_ERROR id:%d", request->id);
+ request->state_cb = 0;
+ }
+ }
+ }
+
+ return result;
+
+}
+
+static int __dp_queue_manager_check_queue(dp_queue_fmt **queue)
+{
+ dp_client_slots_fmt *slot = NULL;
+ dp_request_fmt *request = NULL;
+ while (dp_queue_pop(queue, (void *)&slot, (void *)&request) == 0) { // pop a request from queue.
+ TRACE_DEBUG("queue-manager pop a request");
+ if (slot == NULL || request == NULL) {
+ TRACE_DEBUG("queue error client:%p request:%p id:%d", slot, request, (request == NULL ? 0 : request->id));
+ continue;
+ }
+
+ CLIENT_MUTEX_LOCK(&slot->mutex);
+
+ TRACE_DEBUG("queue info slot:%p request:%p id:%d", slot, request, (request == NULL ? 0 : request->id));
+
+ int errorcode = DP_ERROR_NONE;
+ int download_state = DP_STATE_NONE;
+ if (slot != NULL && request != NULL &&
+ dp_db_get_property_int(slot->client.dbhandle, request->id, DP_TABLE_LOGGING, DP_DB_COL_STATE, &download_state, &errorcode) < 0) {
+ TRACE_ERROR("deny checking id:%d db state:%s memory:%s", request->id, dp_print_state(download_state), dp_print_state(request->state));
+ errorcode = DP_ERROR_ID_NOT_FOUND;
+ }
+
+ if (download_state == DP_STATE_QUEUED && __dp_queue_manager_try_download(slot, request) < 0) {
+ // if failed to start, push at the tail of queue. try again.
+ if (dp_queue_push(queue, slot, request) < 0) {
+ TRACE_ERROR("failed to push to queue id:%d", request->id);
+ int errorcode = DP_ERROR_NONE;
+ if (dp_db_update_logging(slot->client.dbhandle, request->id, DP_STATE_FAILED, DP_ERROR_QUEUE_FULL, &errorcode) < 0) {
+ TRACE_ERROR("failed to update log id:%d", request->id);
+ }
+ request->state = DP_STATE_FAILED;
+ request->error = DP_ERROR_QUEUE_FULL;
+ }
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+ return -1; // return negative for taking a break
+ }
+
+ CLIENT_MUTEX_UNLOCK(&slot->mutex);
+
+ slot = NULL;
+ request = NULL;
+ }
+ return 0;
+}
+
+static void *__dp_queue_manager(void *arg)
+{
+ pthread_cond_init(&g_dp_queue_manager_cond, NULL);
+
+ if (dp_init_agent() != DP_ERROR_NONE) {
+ TRACE_ERROR("failed to init agent");
+ pthread_cond_destroy(&g_dp_queue_manager_cond);
+ pthread_exit(NULL);
+ return 0;
+ }
+
+ do {
+
+ if (g_dp_queue_manager_tid <= 0) {
+ TRACE_INFO("queue-manager is closed by other thread");
+ break;
+ }
+
+ // check wifi_direct first
+ if (dp_network_is_wifi_direct() == 1 && __dp_queue_manager_check_queue(&g_dp_queue_network_wifi_direct) < 0) {
+ TRACE_ERROR("download-agent is busy, try again after 15 seconds");
+ } else { // enter here if disable wifi-direct or download-agent is available
+ int network_status = dp_network_get_status();
+ if (network_status != DP_NETWORK_OFF) {
+ TRACE_INFO("queue-manager try to check queue network:%d", network_status);
+ if (g_dp_queue_network_all != NULL && __dp_queue_manager_check_queue(&g_dp_queue_network_all) < 0) {
+ TRACE_ERROR("download-agent is busy, try again after 15 seconds");
+ } else {
+ dp_queue_fmt **queue = __dp_queue_manager_get_queue(network_status);
+ if (__dp_queue_manager_check_queue(queue) < 0) {
+ TRACE_ERROR("download-agent is busy, try again after 15 seconds");
+ }
+ }
+ }
+ }
+
+ struct timeval now;
+ struct timespec ts;
+ gettimeofday(&now, NULL);
+ ts.tv_sec = now.tv_sec + 5;
+ ts.tv_nsec = now.tv_usec * 1000;
+ CLIENT_MUTEX_LOCK(&g_dp_queue_manager_mutex);
+ pthread_cond_timedwait(&g_dp_queue_manager_cond, &g_dp_queue_manager_mutex, &ts);
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_manager_mutex);
+
+ } while (g_dp_queue_manager_tid > 0);
+
+ TRACE_DEBUG("queue-manager's working is done");
+ dp_deinit_agent();
+ dp_queue_clear_all(&g_dp_queue_network_all);
+ pthread_cond_destroy(&g_dp_queue_manager_cond);
+ pthread_exit(NULL);
+ return 0;
+}
+
+static int __dp_queue_manager_start()
+{
+ if (g_dp_queue_manager_tid == 0 ||
+ pthread_kill(g_dp_queue_manager_tid, 0) == ESRCH) {
+ TRACE_DEBUG("try to create queue-manager");
+ if (pthread_create(&g_dp_queue_manager_tid, NULL,
+ __dp_queue_manager, NULL) != 0) {
+ TRACE_STRERROR("failed to create queue-manager");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void dp_queue_manager_wake_up()
+{
+ if (g_dp_queue_manager_tid > 0 &&
+ pthread_kill(g_dp_queue_manager_tid, 0) != ESRCH) {
+ int locked = CLIENT_MUTEX_TRYLOCK(&g_dp_queue_manager_mutex);
+ if (locked == 0) {
+ pthread_cond_signal(&g_dp_queue_manager_cond);
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_manager_mutex);
+ }
+ } else {
+ __dp_queue_manager_start();
+ }
+}
+
+void dp_queue_manager_kill()
+{
+ if (g_dp_queue_manager_tid > 0 &&
+ pthread_kill(g_dp_queue_manager_tid, 0) != ESRCH) {
+ //send signal to queue thread
+ g_dp_queue_manager_tid = 0;
+ CLIENT_MUTEX_LOCK(&g_dp_queue_manager_mutex);
+ pthread_cond_signal(&g_dp_queue_manager_cond);
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_manager_mutex);
+ pthread_cancel(g_dp_queue_manager_tid);
+ int status;
+ pthread_join(g_dp_queue_manager_tid, (void **)&status);
+ }
+}
diff --git a/provider/download-provider-queue.c b/provider/download-provider-queue.c
new file mode 100644
index 0000000..ad038fd
--- /dev/null
+++ b/provider/download-provider-queue.c
@@ -0,0 +1,194 @@
+/*
+ * 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 <stdlib.h>
+
+#include <download-provider-queue.h>
+#include <download-provider-log.h>
+#include <download-provider-pthread.h>
+#include <download-provider-client.h>
+#include <download-provider-client-manager.h>
+
+/* queue
+ * 1. push : at the tail of linked list
+ * 2. pop : at the head of linked list
+ * 3. priority push : at the head of linked list
+ * 4. in pop, check client of slot, search request by download_id
+ */
+
+//dp_queue_fmt *g_dp_queue = NULL; // head of linked list
+pthread_mutex_t g_dp_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// normal . push at the tail of queue.
+int dp_queue_push(dp_queue_fmt **queue, void *slot, void *request)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return -1;
+ }
+ dp_client_slots_fmt *baseslot = slot;
+ dp_request_fmt *new_request = request;
+ if (slot == NULL || request == NULL || new_request->id <= 0) {
+ TRACE_ERROR("check client and request memory address");
+ return -1;
+ } else if (new_request->id <= 0) {
+ TRACE_ERROR("check slot or download id", new_request->id);
+ return -1;
+ } else if (new_request->state != DP_STATE_QUEUED) {
+ TRACE_ERROR("check id:%d state:%s", new_request->id, dp_print_state(new_request->state));
+ return -1;
+ }
+
+ CLIENT_MUTEX_LOCK(&g_dp_queue_mutex);
+ // search the tail of queue
+ int i = 0;
+ dp_queue_fmt *tailp = *queue;
+ dp_queue_fmt *prevp = NULL;
+ TRACE_DEBUG("queue req slot:%p request:%p id:%d", slot, request, (request == NULL ? 0 : new_request->id));
+ for (; tailp != NULL; i++) {
+ dp_request_fmt *qrequestp = tailp->request;
+ if (tailp->slot == NULL || tailp->request == NULL ||
+ qrequestp->state != DP_STATE_QUEUED) {
+ TRACE_DEBUG("queue error %d slot:%p request:%p id:%d", i, tailp->slot, tailp->request, (tailp->request == NULL ? 0 : ((dp_request_fmt *)tailp->request)->id));
+ } else if (tailp->slot == slot && tailp->request == request && qrequestp->id == new_request->id) {
+ TRACE_INFO("queue duplicte %d slot:%p request:%p id:%d", i, slot, request, new_request->id);
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+ return 0;
+ } else {
+ TRACE_INFO("queue info %d slot:%p request:%p id:%d %s", i, tailp->slot, tailp->request, ((dp_request_fmt *)tailp->request)->id, ((dp_client_slots_fmt *)tailp->slot)->pkgname);
+ }
+ prevp = tailp;
+ tailp = tailp->next;
+ }
+ dp_queue_fmt *new_queue = (dp_queue_fmt *)malloc(sizeof(dp_queue_fmt));
+ if (new_queue != NULL) {
+ new_queue->slot = slot;
+ new_queue->request = request;
+ new_queue->next = NULL;
+ if (prevp == NULL)
+ *queue = new_queue;
+ else
+ prevp->next = new_queue;
+ } else {
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+ return -1;
+ }
+ TRACE_DEBUG("queue push %d info:%s id:%d", i, baseslot->pkgname, new_request->id);
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+ return 0;
+}
+
+int dp_queue_pop(dp_queue_fmt **queue, void **slot, void **request)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return -1;
+ }
+ if (slot == NULL || request == NULL) {
+ TRACE_ERROR("check client and request memory address");
+ return -1;
+ }
+
+ int lock = CLIENT_MUTEX_TRYLOCK(&g_dp_queue_mutex);
+ if (lock != 0) {
+ TRACE_DEBUG("skip queue is used by other thread");
+ return 0;
+ }
+ if (*queue == NULL) {
+ //TRACE_DEBUG("queue empty");
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+ return -1;
+ }
+ // get a head of queue
+ int ret = -1;
+ dp_queue_fmt *popp;
+ do {
+ popp = *queue;
+ *queue = popp->next;
+ dp_client_slots_fmt *slotp = popp->slot;
+ dp_request_fmt *requestp = popp->request;
+ if (slotp == NULL || requestp == NULL ||
+ requestp->state != DP_STATE_QUEUED) {
+ TRACE_DEBUG("queue error slot:%p request:%p id:%d", popp->slot, popp->request, (requestp == NULL ? 0 : requestp->id));
+ free(popp);
+ } else {
+ TRACE_INFO("queue pop slot:%p request:%p id:%d %s", popp->slot, popp->request, requestp->id, slotp->pkgname);
+ *slot = popp->slot;
+ *request = popp->request;
+ ret = 0;
+ free(popp);
+ break;
+ }
+ } while (*queue != NULL); // if meet the tail of queue
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+ return ret;
+}
+
+void dp_queue_clear(dp_queue_fmt **queue, void *request)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return ;
+ }
+ if (request == NULL) {
+ TRACE_ERROR("check client and request memory address");
+ return ;
+ }
+ CLIENT_MUTEX_LOCK(&g_dp_queue_mutex);
+ int i = 0;
+ dp_queue_fmt *tailp = *queue;
+ dp_queue_fmt *prevp = NULL;
+ TRACE_DEBUG("queue clear req request:%p id:%d", request, (request == NULL ? 0 : ((dp_request_fmt *)request)->id));
+ for (; tailp != NULL; i++) {
+ dp_request_fmt *requestp = tailp->request;
+ TRACE_DEBUG("queue info %d request:%p id:%d", i, requestp, (requestp == NULL ? 0 : requestp->id));
+ if (requestp == request) {
+ // clear.
+ if (prevp == NULL)
+ *queue = tailp->next;
+ else
+ prevp->next = tailp->next;
+ TRACE_DEBUG("queue clear this %d request:%p id:%d", i, requestp, (requestp == NULL ? 0 : requestp->id));
+ free(tailp);
+ break;
+ }
+ prevp = tailp;
+ tailp = tailp->next;
+ }
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+}
+
+void dp_queue_clear_all(dp_queue_fmt **queue)
+{
+ if (queue == NULL) {
+ TRACE_ERROR("check memory address of queue");
+ return ;
+ }
+ CLIENT_MUTEX_LOCK(&g_dp_queue_mutex);
+ if (queue == NULL || *queue == NULL) {
+ TRACE_DEBUG("queue empty");
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+ return ;
+ }
+ // get a head of queue
+ do {
+ dp_queue_fmt *popp = *queue;
+ *queue = popp->next;
+ TRACE_DEBUG("queue clear slot:%p request:%p id:%d", popp->slot, popp->request, (popp->request == NULL ? 0 : ((dp_request_fmt *)popp->request)->id));
+ free(popp);
+ } while (*queue != NULL); // if meet the tail of queue
+ CLIENT_MUTEX_UNLOCK(&g_dp_queue_mutex);
+}
diff --git a/provider/download-provider-request.c b/provider/download-provider-request.c
deleted file mode 100755
index 10fea00..0000000
--- a/provider/download-provider-request.c
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <sys/time.h>
-#include <sys/statfs.h>
-#include "download-provider.h"
-#include "download-provider-log.h"
-
-#include "download-provider-slots.h"
-#include "download-provider-socket.h"
-#include "download-provider-db.h"
-#include "download-provider-pthread.h"
-
-#include "download-provider-notification.h"
-
-#define SMACKFS_MAGIC 0x43415d53
-#define SMACKFS_MNT "/smack"
-///////// below functions are called by main thread of thread-request.c
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief create unique id as integer type
-/// @return unique id combined local time and the special calculation
-static int __get_download_request_id(void)
-{
- static int last_uniquetime = 0;
- int uniquetime = 0;
-
- do {
- struct timeval tval;
- int cipher = 1;
- int c = 0;
-
- gettimeofday(&tval, NULL);
-
- int usec = tval.tv_usec;
- for (c = 0; ; c++, cipher++) {
- if ((usec /= 10) <= 0)
- break;
- }
- if (tval.tv_usec == 0)
- tval.tv_usec = (tval.tv_sec & 0x0fff);
- int disit_unit = 10;
- for (c = 0; c < cipher - 3; c++)
- disit_unit = disit_unit * 10;
- uniquetime = tval.tv_sec + ((tval.tv_usec << 2) * 100) +
- ((tval.tv_usec >> (cipher - 1)) * disit_unit) +
- ((tval.tv_usec + (tval.tv_usec % 10)) & 0x0fff);
- } while (last_uniquetime == uniquetime);
- last_uniquetime = uniquetime;
- return uniquetime;
-}
-
-char *dp_print_state(dp_state_type state)
-{
- switch(state)
- {
- case DP_STATE_NONE :
- return "NONE";
- case DP_STATE_READY :
- return "READY";
- case DP_STATE_QUEUED :
- return "QUEUED";
- case DP_STATE_CONNECTING :
- return "CONNECTING";
- case DP_STATE_DOWNLOADING :
- return "DOWNLOADING";
- case DP_STATE_PAUSE_REQUESTED :
- return "PAUSE_REQUESTED";
- case DP_STATE_PAUSED :
- return "PAUSED";
- case DP_STATE_COMPLETED :
- return "COMPLETED";
- case DP_STATE_CANCELED :
- return "CANCELED";
- case DP_STATE_FAILED :
- return "FAILED";
- default :
- break;
- }
- return "UNKNOWN";
-}
-
-char *dp_print_errorcode(dp_error_type errorcode)
-{
- switch(errorcode)
- {
- case DP_ERROR_NONE :
- return "NONE";
- case DP_ERROR_INVALID_PARAMETER :
- return "INVALID_PARAMETER";
- case DP_ERROR_OUT_OF_MEMORY :
- return "OUT_OF_MEMORY";
- case DP_ERROR_IO_ERROR :
- return "IO_ERROR";
- case DP_ERROR_NETWORK_UNREACHABLE :
- return "NETWORK_UNREACHABLE";
- case DP_ERROR_CONNECTION_TIMED_OUT :
- return "CONNECTION_TIMED_OUT";
- case DP_ERROR_NO_SPACE :
- return "NO_SPACE";
- case DP_ERROR_FIELD_NOT_FOUND :
- return "FIELD_NOT_FOUND";
- case DP_ERROR_INVALID_STATE :
- return "INVALID_STATE";
- case DP_ERROR_CONNECTION_FAILED :
- return "CONNECTION_FAILED";
- case DP_ERROR_INVALID_URL :
- return "INVALID_URL";
- case DP_ERROR_INVALID_DESTINATION :
- return "INVALID_DESTINATION";
- case DP_ERROR_QUEUE_FULL :
- return "QUEUE_FULL";
- case DP_ERROR_ALREADY_COMPLETED :
- return "ALREADY_COMPLETED";
- case DP_ERROR_FILE_ALREADY_EXISTS :
- return "FILE_ALREADY_EXISTS";
- case DP_ERROR_TOO_MANY_DOWNLOADS :
- return "TOO_MANY_DOWNLOADS";
- case DP_ERROR_NO_DATA :
- return "NO_DATA";
- case DP_ERROR_UNHANDLED_HTTP_CODE :
- return "UNHANDLED_HTTP_CODE";
- case DP_ERROR_CANNOT_RESUME :
- return "CANNOT_RESUME";
- case DP_ERROR_PERMISSION_DENIED :
- return "PERMISSION_DENIED";
- case DP_ERROR_RESPONSE_TIMEOUT :
- return "RESPONSE_TIMEOUT";
- case DP_ERROR_REQUEST_TIMEOUT :
- return "REQUEST_TIMEOUT";
- case DP_ERROR_SYSTEM_DOWN :
- return "SYSTEM_DOWN";
- case DP_ERROR_CLIENT_DOWN :
- return "CLIENT_DOWN";
- case DP_ERROR_ID_NOT_FOUND :
- return "ID_NOT_FOUND";
- default :
- break;
- }
- return "UNKNOWN";
-}
-
-int dp_is_smackfs_mounted()
-{
- struct statfs sfs;
- int ret;
- do {
- ret = statfs(SMACKFS_MNT, &sfs);
- } while (ret < 0 && errno == EINTR);
- if (ret) {
- TRACE_ERROR("[SMACK ERROR]");
- return -1;
- }
- if (sfs.f_type == SMACKFS_MAGIC) {
- return 1;
- }
- TRACE_ERROR("[SMACK DISABLE]");
- return 0;
-}
-
-char *dp_strdup(char *src)
-{
- char *dest = NULL;
- size_t src_len = 0;
-
- if (src == NULL) {
- TRACE_ERROR("[CHECK PARAM]");
- return NULL;
- }
-
- src_len = strlen(src);
- if (src_len <= 0) {
- TRACE_ERROR("[CHECK PARAM] len[%d]", src_len);
- return NULL;
- }
-
- dest = (char *)calloc(src_len + 1, sizeof(char));
- if (dest == NULL) {
- TRACE_STRERROR("[CHECK] allocation");
- return NULL;
- }
- memcpy(dest, src, src_len * sizeof(char));
- dest[src_len] = '\0';
-
- return dest;
-}
-
-// check param
-// create new slot
-// fill info to new slot
-// make new id
-// save info to QUEUE(DB)
-dp_error_type dp_request_create(int id, dp_client_group *group, dp_request **empty_slot)
-{
- if (id != -1) {
- TRACE_ERROR("[CHECK PROTOCOL] ID not -1");
- return DP_ERROR_INVALID_STATE;
- }
- if (group == NULL || empty_slot == NULL) {
- TRACE_ERROR("[CHECK INTERNAL][%d]", id);
- return DP_ERROR_INVALID_PARAMETER;
- }
- // New allocation Slot
- dp_request *new_request = dp_request_new();
- if (new_request == NULL) {
- TRACE_STRERROR("[CHECK MEMORY][%d]", id);
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- int check_id = -1;
- do {
- new_request->id = __get_download_request_id();
- check_id = dp_db_get_int_column(new_request->id,
- DP_DB_TABLE_LOG, DP_DB_COL_ID);
- } while (check_id == new_request->id); // means duplicated id
-
- new_request->group = group;
- if (group->pkgname != NULL && strlen(group->pkgname) > 1)
- new_request->packagename = dp_strdup(group->pkgname);
- if (new_request->packagename == NULL) {
- dp_request_free(new_request);
- TRACE_ERROR("[ERROR][%d] OUT_OF_MEMORY [PACKAGENAME]", id);
- return DP_ERROR_OUT_OF_MEMORY;
- }
- new_request->state = DP_STATE_READY;
- new_request->error = DP_ERROR_NONE;
- new_request->create_time = (int)time(NULL);
-
- if (dp_db_request_new_logging(new_request->id, new_request->state,
- new_request->packagename) < 0) {
- dp_request_free(new_request);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL]");
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
- *empty_slot = new_request;
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_url(int id, dp_request *request, char *url)
-{
- int length = 0;
- if (url == NULL || (length = strlen(url)) <= 1)
- return DP_ERROR_INVALID_URL;
-
- if (request != NULL) {
- if (request->state == DP_STATE_CONNECTING ||
- request->state == DP_STATE_DOWNLOADING ||
- request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_CONNECTING ||
- state == DP_STATE_DOWNLOADING ||
- state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_URL,
- DP_DB_COL_TYPE_TEXT, url) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_destination(int id, dp_request *request, char *dest)
-{
- int length = 0;
- if (!dest || (length = strlen(dest)) <= 1)
- return DP_ERROR_INVALID_DESTINATION;
-
- if (request != NULL) {
- if (request->state == DP_STATE_CONNECTING ||
- request->state == DP_STATE_DOWNLOADING ||
- request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_CONNECTING ||
- state == DP_STATE_DOWNLOADING ||
- state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_DESTINATION,
- DP_DB_COL_TYPE_TEXT, dest) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_filename(int id, dp_request *request, char *filename)
-{
- int length = 0;
- if (!filename || (length = strlen(filename)) <= 1)
- return DP_ERROR_INVALID_PARAMETER;
-
- if (request != NULL) {
- if (request->state == DP_STATE_CONNECTING ||
- request->state == DP_STATE_DOWNLOADING ||
- request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_CONNECTING ||
- state == DP_STATE_DOWNLOADING ||
- state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_FILENAME,
- DP_DB_COL_TYPE_TEXT, filename) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- TRACE_SECURE_DEBUG("ID [%d] Filename[%s]", id, filename);
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_title(int id, dp_request *request, char *title)
-{
- int length = 0;
- if (!title || (length = strlen(title)) <= 1)
- return DP_ERROR_INVALID_PARAMETER;
-
- if (request != NULL) {
- if (request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- if (dp_db_replace_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_TITLE,
- DP_DB_COL_TYPE_TEXT, title) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- TRACE_SECURE_DEBUG("ID [%d] title[%s]", id, title);
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_bundle(int id, dp_request *request, int type, bundle_raw *b, unsigned length)
-{
- char *column = NULL;
- if (b == NULL || (length < 1))
- return DP_ERROR_INVALID_PARAMETER;
-
- if (request != NULL) {
- if (request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- switch(type) {
- case DP_NOTIFICATION_BUNDLE_TYPE_ONGOING:
- column = DP_DB_COL_RAW_BUNDLE_ONGOING;
- break;
- case DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE:
- column = DP_DB_COL_RAW_BUNDLE_COMPLETE;
- break;
- case DP_NOTIFICATION_BUNDLE_TYPE_FAILED:
- column = DP_DB_COL_RAW_BUNDLE_FAIL;
- break;
- default:
- TRACE_ERROR("[CHECK TYPE][%d]", type);
- return DP_ERROR_INVALID_PARAMETER;
- }
- if (dp_db_replace_blob_column
- (id, DP_DB_TABLE_NOTIFICATION, column, b, length) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- //TRACE_SECURE_DEBUG("ID [%d] title[%s]", id, title);
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_description(int id, dp_request *request, char *description)
-{
- int length = 0;
- if (!description || (length = strlen(description)) <= 1)
- return DP_ERROR_INVALID_PARAMETER;
-
- if (request != NULL) {
- if (request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- if (dp_db_replace_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_DESCRIPTION,
- DP_DB_COL_TYPE_TEXT, description) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
-
- TRACE_SECURE_DEBUG("ID [%d] description[%s]", id, description);
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_noti_type(int id, dp_request *request, unsigned type)
-{
- if (request != NULL) {
- if (request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- if (dp_db_replace_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE,
- DP_DB_COL_TYPE_INT, &type) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- return DP_ERROR_NO_SPACE;
- }
- return DP_ERROR_OUT_OF_MEMORY;
- }
- if (request)
- {
- if(!type)
- request->auto_notification = 0;
- else
- request->auto_notification = 1;
- }
- TRACE_SECURE_DEBUG("ID [%d] enable[%d]", id, type);
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_notification(int id, dp_request *request, unsigned enable)
-{
- if (request != NULL) {
- if (request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- // update queue DB
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO,
- DP_DB_COL_NOTIFICATION_ENABLE, DP_DB_COL_TYPE_INT,
- &enable) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- return DP_ERROR_OUT_OF_MEMORY;
- }
- // update memory
- if (request)
- request->auto_notification = enable;
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_auto_download(int id, dp_request *request, unsigned enable)
-{
- if (request != NULL) {
- if (request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- // update queue DB
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_AUTO_DOWNLOAD,
- DP_DB_COL_TYPE_INT, &enable) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- return DP_ERROR_OUT_OF_MEMORY;
- }
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_state_event(int id, dp_request *request, unsigned enable)
-{
- if (request == NULL) {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
-
- if (state == DP_STATE_DOWNLOADING ||
- state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- // update queue DB
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_STATE_EVENT,
- DP_DB_COL_TYPE_INT, &enable) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- return DP_ERROR_OUT_OF_MEMORY;
- }
- // update memory
- if (request != NULL)
- request->state_cb = enable;
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_progress_event(int id, dp_request *request, unsigned enable)
-{
- if (request == NULL) {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
-
- if (state == DP_STATE_DOWNLOADING ||
- state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- // update queue DB
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_PROGRESS_EVENT,
- DP_DB_COL_TYPE_INT, &enable) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- return DP_ERROR_OUT_OF_MEMORY;
- }
- // update memory
- if (request)
- request->progress_cb = enable;
- return DP_ERROR_NONE;
-}
-
-dp_error_type dp_request_set_network_type(int id, dp_request *request, int type)
-{
- if (request != NULL) {
- if (request->state == DP_STATE_CONNECTING ||
- request->state == DP_STATE_DOWNLOADING ||
- request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- return DP_ERROR_INVALID_STATE;
- }
- } else {
- // check id in logging table.
- dp_state_type state = dp_db_get_state(id);
- // check again from logging table
- if (state == DP_STATE_CONNECTING ||
- state == DP_STATE_DOWNLOADING ||
- state == DP_STATE_COMPLETED) {
- TRACE_ERROR("[ERROR][%d] now[%s]", id, dp_print_state(state));
- return DP_ERROR_INVALID_STATE;
- }
- }
-
- // update queue DB
- if (dp_db_replace_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_NETWORK_TYPE,
- DP_DB_COL_TYPE_INT, &type) < 0) {
- TRACE_ERROR("[CHECK SQL][%d]", id);
- return DP_ERROR_OUT_OF_MEMORY;
- }
- // update memory
- if (request)
- request->network_type = type;
- return DP_ERROR_NONE;
-}
-
-char *dp_request_get_url(int id, dp_error_type *errorcode)
-{
- char *url = NULL;
- url = dp_db_get_text_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_URL);
- if (url == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return url;
-}
-
-char *dp_request_get_destination(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *dest = NULL;
- dest = dp_db_get_text_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_DESTINATION);
- if (dest == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return dest;
-}
-
-char *dp_request_get_filename(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *filename = NULL;
- filename = dp_db_get_text_column
- (id, DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_FILENAME);
- if (filename == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return filename;
-}
-
-char *dp_request_get_title(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *title = NULL;
- title = dp_db_get_text_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_TITLE);
- if (title == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return title;
-}
-
-bundle_raw *dp_request_get_bundle(int id, dp_request *request, dp_error_type *errorcode, char* column, int *length)
-{
- void *blob_data = NULL;
- blob_data = dp_db_get_blob_column
- (id, DP_DB_TABLE_NOTIFICATION, column, length);
- if (blob_data == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return (bundle_raw*)blob_data;
-}
-
-
-char *dp_request_get_description(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *description = NULL;
- description = dp_db_get_text_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_DESCRIPTION);
- if (description == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return description;
-}
-
-int dp_request_get_noti_type(int id, dp_request *request, dp_error_type *errorcode)
-{
- int type = -1;
- type = dp_db_get_int_column
- (id, DP_DB_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE);
- if (type == -1)
- *errorcode = DP_ERROR_NO_DATA;
- return type;
-}
-
-
-
-char *dp_request_get_contentname(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *content = NULL;
- content = dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_CONTENT_NAME);
- if (content == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return content;
-}
-
-char *dp_request_get_etag(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *etag = NULL;
- etag = dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_ETAG);
- if (etag == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return etag;
-}
-
-char *dp_request_get_savedpath(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *savedpath = NULL;
- savedpath = dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_SAVED_PATH);
- if (savedpath == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return savedpath;
-}
-
-char *dp_request_get_tmpsavedpath(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *tmppath = NULL;
- tmppath = dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_TMP_SAVED_PATH);
- if (tmppath == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return tmppath;
-}
-
-char *dp_request_get_mimetype(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *mimetype = NULL;
- mimetype = dp_db_get_text_column
- (id, DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_MIMETYPE);
- if (mimetype == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return mimetype;
-}
-
-char *dp_request_get_pkg_name(int id, dp_request *request, dp_error_type *errorcode)
-{
- char *pkg_name = NULL;
- pkg_name = dp_db_get_text_column
- (id, DP_DB_TABLE_LOG, DP_DB_COL_PACKAGENAME);
- if (pkg_name == NULL) {
- *errorcode = DP_ERROR_NO_DATA;
- return NULL;
- }
- return pkg_name;
-}
-
-dp_request *dp_request_load_from_log(int id, dp_error_type *errorcode)
-{
- dp_request *request = NULL;
-
- request = dp_db_load_logging_request(id);
- if (request == NULL) {
- *errorcode = DP_ERROR_ID_NOT_FOUND;
- return NULL;
- }
- if (request->state == DP_STATE_COMPLETED) {
- TRACE_ERROR
- ("[ERROR][%d] now[%s]", id, dp_print_state(request->state));
- *errorcode = DP_ERROR_INVALID_STATE;
- dp_request_free(request);
- return NULL;
- }
- return request;
-}
-
-
-void dp_request_state_response(dp_request *request)
-{
- if (request == NULL) {
- return ;
- }
-
- TRACE_INFO("[INFO][%d] state:%s error:%s", request->id,
- dp_print_state(request->state),
- dp_print_errorcode(request->error));
-
- if (dp_db_request_update_status(request->id, request->state,
- request->error) < 0)
- TRACE_ERROR("[ERROR][%d][SQL]", request->id);
-
- if (request->group != NULL && request->group->event_socket >= 0 &&
- request->state_cb == 1) {
- dp_ipc_send_event(request->group->event_socket, request->id,
- request->state, request->error, 0);
- }
-
- if (request->state == DP_STATE_DOWNLOADING) {
- if (request->auto_notification == 1 &&
- request->packagename != NULL) {
- if (request->noti_priv_id != -1) {
- dp_update_downloadinginfo_notification
- (request->noti_priv_id,
- (double)request->received_size,
- (double)request->file_size);
- } else {
- request->noti_priv_id = dp_set_downloadinginfo_notification
- (request->id, request->packagename);
- }
- } else {
- int noti_type = dp_db_get_int_column(request->id,
- DP_DB_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE);
- if (noti_type == DP_NOTIFICATION_TYPE_ALL &&
- request->packagename != NULL) {
- if (request->noti_priv_id != -1) {
- dp_update_downloadinginfo_notification
- (request->noti_priv_id,
- (double)request->received_size,
- (double)request->file_size);
- } else {
- request->noti_priv_id = dp_set_downloadinginfo_notification
- (request->id, request->packagename);
- }
- }
- }
- request->start_time = (int)time(NULL);
- request->pause_time = 0;
- request->stop_time = 0;
- } else if (request->state == DP_STATE_PAUSED) {
- if (request->group != NULL)
- request->group->queued_count--;
- request->pause_time = (int)time(NULL);
- } else {
- if (request->group != NULL )
- request->group->queued_count--;
-
- if (request->auto_notification == 1 &&
- request->packagename != NULL) {
- request->noti_priv_id = dp_set_downloadedinfo_notification
- (request->noti_priv_id, request->id,
- request->packagename, request->state);
-
- } else {
- int noti_type = dp_db_get_int_column(request->id,
- DP_DB_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE);
- if (noti_type > DP_NOTIFICATION_TYPE_NONE &&
- request->packagename != NULL)
- request->noti_priv_id = dp_set_downloadedinfo_notification
- (request->noti_priv_id, request->id,
- request->packagename, request->state);
- }
-
- request->stop_time = (int)time(NULL);
- }
-}
diff --git a/provider/download-provider-slots.c b/provider/download-provider-slots.c
deleted file mode 100755
index ad39ee8..0000000
--- a/provider/download-provider-slots.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <time.h>
-#include <sys/time.h>
-
-#include "download-provider.h"
-#include "download-provider-log.h"
-#include "download-provider-pthread.h"
-
-#include "download-provider-slots.h"
-#include "download-provider-socket.h"
-
-dp_group_slots *dp_client_group_slots_new(int size)
-{
- dp_group_slots *slots = NULL;
- if (size <= 0)
- return NULL;
- slots = (dp_group_slots *) calloc(size,
- sizeof(dp_group_slots));
- return slots;
-}
-
-dp_request_slots *dp_request_slots_new(int size)
-{
- int i = 0;
- dp_request_slots *slots = NULL;
- if (size <= 0)
- return NULL;
- slots = (dp_request_slots *) calloc(size,
- sizeof(dp_request_slots));
- for (; i < size; i++)
- CLIENT_MUTEX_INIT(&slots[i].mutex, NULL);
- return slots;
-}
-
-void dp_request_init(dp_request *request)
-{
- if (request == NULL)
- return ;
-
- request->id = -1;
- request->agent_id = -1;
- request->create_time = 0;
- request->start_time = 0;
- request->pause_time = 0;
- request->stop_time = 0;
- request->state = DP_STATE_NONE;
- request->error = DP_ERROR_NONE;
- request->state_cb = 0;
- request->progress_cb = 0;
- request->progress_lasttime = 0;
- request->received_size = 0;
- request->file_size = 0;
- request->network_type = DP_NETWORK_TYPE_ALL;
- request->startcount = 0;
- request->auto_notification = 0;
- request->noti_priv_id = -1;
- request->packagename = NULL;
- request->group = NULL;
-}
-
-dp_request *dp_request_new()
-{
- dp_request *request = NULL;
- request = (dp_request *) calloc(1,
- sizeof(dp_request));
- if (!request)
- return NULL;
- dp_request_init(request);
- return request;
-}
-
-int dp_request_slot_free(dp_request_slots *request_slot)
-{
- if (request_slot == NULL)
- return -1;
- CLIENT_MUTEX_LOCK(&request_slot->mutex);
- dp_request_free(request_slot->request);
- request_slot->request = NULL;
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- return 0;
-}
-
-int dp_request_free(dp_request *request)
-{
- if (request == NULL)
- return -1;
- free(request->packagename);
- dp_request_init(request);
- free(request);
- return 0;
-}
-
-int dp_client_group_free(dp_client_group *group)
-{
- 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->smack_label);
- free(group);
- }
- return 0;
-}
-
-int dp_client_group_slots_free(dp_group_slots *slots, int size)
-{
- int i = 0;
- if (slots) {
- for (; i < size; i++) {
- if (slots->group)
- dp_client_group_free(slots->group);
- slots->group = NULL;
- }
- free(slots);
- }
- slots = NULL;
- return 0;
-}
-
-int dp_request_slots_free(dp_request_slots *slots, int size)
-{
- int i = 0;
- if (slots != NULL) {
- for (; i < size; i++) {
- dp_request_free(slots[i].request);
- slots[i].request = NULL;
- CLIENT_MUTEX_DESTROY(&slots[i].mutex);
- }
- free(slots);
- }
- slots = NULL;
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief return count of requests in slot
-int dp_get_request_count(dp_request_slots *slots)
-{
- int i = 0;
- int count = 0;
-
- if (!slots)
- return -1;
-
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- if (slots[i].request != NULL)
- count++;
- }
- return count;
-}
diff --git a/provider/download-provider-smack.c b/provider/download-provider-smack.c
new file mode 100644
index 0000000..5e89c45
--- /dev/null
+++ b/provider/download-provider-smack.c
@@ -0,0 +1,165 @@
+/*
+ * 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 <stdlib.h>
+#include <errno.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <sys/smack.h>
+
+#include <download-provider.h>
+#include <download-provider-log.h>
+#include <download-provider-utils.h>
+
+#define SMACKFS_MAGIC 0x43415d53
+#define SMACKFS_MNT "/smack"
+
+static int __dp_smack_is_transmute(char *path)
+{
+ char *dir_label = NULL;
+ int ret = -1;
+ if (smack_getlabel(path, &dir_label, SMACK_LABEL_TRANSMUTE) == 0 &&
+ dir_label != NULL) {
+ if (strncmp(dir_label, "TRUE", strlen(dir_label)) == 0)
+ ret = 0;
+ }
+ free(dir_label);
+ return ret;
+}
+
+int dp_smack_is_mounted()
+{
+ struct statfs sfs;
+ int ret;
+ do {
+ ret = statfs(SMACKFS_MNT, &sfs);
+ } while (ret < 0 && errno == EINTR);
+ if (ret) {
+ TRACE_ERROR("[SMACK ERROR]");
+ return -1;
+ }
+ if (sfs.f_type == SMACKFS_MAGIC) {
+ return 1;
+ }
+ TRACE_ERROR("[SMACK DISABLE]");
+ return 0;
+}
+
+int dp_smack_set_label(char *label, char *source, char *target)
+{
+ if (label == NULL || source == NULL || target == NULL)
+ return DP_ERROR_PERMISSION_DENIED;
+
+ int is_setted_dir_label = 0;
+ int errorcode = DP_ERROR_NONE;
+
+ if (__dp_smack_is_transmute(source) < 0) {
+ TRACE_SECURE_ERROR("[SMACK] no transmute:%s", source);
+ } else {
+ char *dir_label = NULL;
+ if (smack_getlabel(source, &dir_label, SMACK_LABEL_ACCESS) == 0) {
+ if (smack_have_access(label, dir_label, "t") > 0) {
+ if (smack_setlabel(target, dir_label, SMACK_LABEL_ACCESS) != 0) {
+ TRACE_SECURE_ERROR("[SMACK ERROR] label:%s", dir_label);
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ } else {
+ is_setted_dir_label = 1;
+ }
+ } else {
+ TRACE_SECURE_ERROR("[SMACK ERROR] access:%s/%s", label, dir_label);
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ }
+ } else {
+ TRACE_SECURE_ERROR("[SMACK ERROR] no label:", source);
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ }
+ free(dir_label);
+ }
+ if (is_setted_dir_label == 0 &&
+ smack_setlabel(target, label, SMACK_LABEL_ACCESS) != 0) {
+ TRACE_SECURE_ERROR("[SMACK ERROR] label:%s", label);
+ errorcode = DP_ERROR_PERMISSION_DENIED;
+ // remove file.
+ if (dp_is_file_exist(target) == 0)
+ unlink(target);
+ }
+ return errorcode;
+}
+
+char *dp_smack_get_label_from_socket(int sock)
+{
+ char *label = NULL;
+ if (smack_new_label_from_socket(sock, &label) != 0) {
+ free(label);
+ return NULL;
+ }
+ return label;
+}
+
+int dp_smack_is_valid_dir(int uid, int gid, char *smack_label, char *dir)
+{
+ if (smack_label == NULL || dir == NULL) {
+ TRACE_ERROR("check parameter %s/%s", smack_label, dir);
+ return -1;
+ }
+ int ret = -1;
+ struct stat dstate;
+ if (stat(dir, &dstate) == 0) {
+ if ((dstate.st_uid == uid && (dstate.st_mode & (S_IRUSR | S_IWUSR)) == (S_IRUSR | S_IWUSR)) ||
+ (dstate.st_gid == gid && (dstate.st_mode & (S_IRGRP | S_IWGRP)) == (S_IRGRP | S_IWGRP)) ||
+ ((dstate.st_mode & (S_IROTH | S_IWOTH)) == (S_IROTH | S_IWOTH))) {
+ char *dir_label = NULL;
+ if (smack_getlabel(dir, &dir_label, SMACK_LABEL_ACCESS) == 0 &&
+ smack_have_access(smack_label, dir_label, "rw") > 0) {
+ ret = 0;
+ }
+ free(dir_label);
+ }
+ }
+ return ret;
+}
+
+int dp_is_valid_dir(const char *dirpath)
+{
+ struct stat dir_state;
+ int stat_ret;
+ if (dirpath == NULL) {
+ TRACE_ERROR("check path");
+ return -1;
+ }
+ stat_ret = stat(dirpath, &dir_state);
+ if (stat_ret == 0 && S_ISDIR(dir_state.st_mode)) {
+ return 0;
+ }
+ return -1;
+}
+
+void dp_rebuild_dir(const char *dirpath, mode_t mode)
+{
+ if (dp_is_valid_dir(dirpath) < 0) {
+ if (mkdir(dirpath, mode) == 0) {
+ TRACE_INFO("check directory:%s", dirpath);
+ if (smack_setlabel(dirpath, "_", SMACK_LABEL_ACCESS) != 0) {
+ TRACE_SECURE_ERROR("failed to set smack label:%s", dirpath);
+ }
+ } else {
+ TRACE_STRERROR("failed to create directory:%s", dirpath);
+ }
+ }
+}
diff --git a/provider/download-provider-socket.c b/provider/download-provider-socket.c
deleted file mode 100755
index 7feabf8..0000000
--- a/provider/download-provider-socket.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <pthread.h>
-
-#include <time.h>
-#include <sys/time.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <systemd/sd-daemon.h>
-#include <signal.h>
-
-#include "download-provider.h"
-#include "download-provider-log.h"
-#include "download-provider-socket.h"
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief write the error to socket
-/// @return if success, return 0
-int dp_ipc_send_errorcode(int fd, dp_error_type errorcode)
-{
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return -1;
- }
-
- if (fd >= 0 && write(fd, &errorcode, sizeof(dp_error_type)) <= 0) {
- TRACE_STRERROR("[ERROR] write FD[%d]", fd);
- return -1;
- }
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief write the progressinfo to socket
-/// @return if success, return 0
-int dp_ipc_send_event(int fd, int id, dp_state_type state,
- dp_error_type errorcode, unsigned long long received_size)
-{
- if (fd < 0) {
- TRACE_ERROR("[ERROR][%d] CHECK FD[%d]", id, fd);
- return -1;
- }
-
- dp_event_info eventinfo;
- eventinfo.id = id;
- eventinfo.state = state;
- eventinfo.err = errorcode;
- eventinfo.received_size = received_size;
-
- // write
- if (fd >= 0 && write(fd, &eventinfo, sizeof(dp_event_info)) <= 0) {
- TRACE_STRERROR("[ERROR][%d] write FD[%d]", id, fd);
- return -1;
- }
- return 0;
-}
-
-// keep the order/ unsigned , str
-char *dp_ipc_read_string(int fd)
-{
- unsigned length = 0;
- size_t recv_size = 0;
- unsigned remain_size = 0;
- size_t buffer_size = 0;
- char *str = NULL;
-
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return NULL;
- }
-
- // read flexible URL from client.
- ssize_t recv_bytes = read(fd, &length, sizeof(unsigned));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
- return NULL;
- }
- if (length < 1 || length > DP_MAX_URL_LEN) {
- TRACE_ERROR("[STRING LEGNTH] [%d]", length);
- return NULL;
- }
- str = (char *)calloc((length + 1), sizeof(char));
- if (str == NULL) {
- TRACE_STRERROR("[ERROR] calloc length:%d FD[%d]", length, fd);
- return NULL;
- }
- remain_size = length;
- do {
- buffer_size = 0;
- if (remain_size > DP_DEFAULT_BUFFER_SIZE)
- buffer_size = DP_DEFAULT_BUFFER_SIZE;
- else
- buffer_size = remain_size;
- recv_size = (size_t)read(fd, str + (int)(length - remain_size),
- buffer_size * sizeof(char));
- if (recv_size > DP_DEFAULT_BUFFER_SIZE) {
- recv_size = -1;
- break;
- }
- if (recv_size > 0)
- remain_size = remain_size - (unsigned)recv_size;
- } while (recv_size > 0 && remain_size > 0);
-
- if (recv_size == 0) {
- TRACE_STRERROR("[ERROR] closed peer:%d", fd);
- free(str);
- return NULL;
- }
- str[length] = '\0';
- return str;
-}
-
-
-// 0 : Socket Error
-// -1 : Invalid type
-unsigned dp_ipc_read_bundle(int fd, int *type, bundle_raw **b)
-{
- unsigned length = 0;
- size_t recv_size = 0;
- unsigned remain_size = 0;
- size_t buffer_size = 0;
- bundle_raw *b_raw = NULL;
-
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return 0;
- }
-
- // read flexible URL from client.
- ssize_t recv_bytes = read(fd, type, sizeof(int));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[ERROR] read FD[%d] type[%d]", fd, type);
- return 0;
- }
- if ((*type) != DP_NOTIFICATION_BUNDLE_TYPE_ONGOING &&
- (*type) != DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE &&
- (*type) != DP_NOTIFICATION_BUNDLE_TYPE_FAILED) {
- TRACE_ERROR("[NOTI TYPE] [%d]", *type);
- return -1;
- }
- // read flexible URL from client.
- recv_bytes = read(fd, &length, sizeof(unsigned));
- if (recv_bytes < 0) {
- TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
- return 0;
- }
- if (length < 1 || length > DP_MAX_URL_LEN) {
- TRACE_ERROR("[STRING LEGNTH] [%d]", length);
- return 0;
- }
- b_raw = (bundle_raw *)calloc(length, 1);
- if (b_raw == NULL) {
- TRACE_STRERROR("[ERROR] calloc length:%d FD[%d]", length, fd);
- return 0;
- }
- remain_size = length;
- do {
- buffer_size = 0;
- if (remain_size > DP_DEFAULT_BUFFER_SIZE)
- buffer_size = DP_DEFAULT_BUFFER_SIZE;
- else
- buffer_size = remain_size;
- recv_size = (size_t)read(fd, b_raw + (int)(length - remain_size),
- buffer_size * sizeof(char));
- if (recv_size > DP_DEFAULT_BUFFER_SIZE) {
- recv_size = -1;
- break;
- }
- if (recv_size > 0)
- remain_size = remain_size - (unsigned)recv_size;
- } while (recv_size > 0 && remain_size > 0);
-
- if (recv_size <= 0) {
- TRACE_STRERROR("[ERROR] closed peer:%d", fd);
- bundle_free_encoded_rawdata(&b_raw);
- return 0;
- }
- *b = b_raw;
- return length;
-}
-
-// keep the order/ unsigned , str
-int dp_ipc_send_string(int fd, const char *str)
-{
- unsigned length = 0;
-
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return -1;
- }
- if (str == NULL) {
- TRACE_ERROR("[ERROR] CHECK STRING FD[%d]", fd);
- return -1;
- }
-
- length = strlen(str);
- if (length < 1) {
- TRACE_ERROR("[ERROR] CHECK LENGTH FD[%d]", fd);
- return -1;
- }
- if (fd >= 0 && write(fd, &length, sizeof(unsigned)) <= 0) {
- TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
- return -1;
- }
- if (fd >= 0 && write(fd, str, length * sizeof(char)) <= 0) {
- TRACE_STRERROR("[ERROR] write FD[%d]", fd);
- return -1;
- }
- return 0;
-}
-
-int dp_ipc_send_bundle(int fd, bundle_raw *b, unsigned length)
-{
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return -1;
- }
- if (b == NULL) {
- TRACE_ERROR("[ERROR] CHECK STRING FD[%d]", fd);
- return -1;
- }
-
- if (length < 1) {
- TRACE_ERROR("[ERROR] CHECK LENGTH FD[%d]", fd);
- return -1;
- }
- if (fd >= 0 && write(fd, &length, sizeof(unsigned)) <= 0) {
- TRACE_STRERROR("[ERROR] read FD[%d] length[%d]", fd, length);
- return -1;
- }
- if (fd >= 0 && write(fd, b, length) <= 0) {
- TRACE_STRERROR("[ERROR] write FD[%d]", fd);
- return -1;
- }
- return 0;
-}
-
-int dp_ipc_send_custom_type(int fd, void *value, size_t type_size)
-{
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return -1;
- }
- if (value == NULL) {
- TRACE_ERROR("[ERROR] CHECK VALUE FD[%d]", fd);
- return -1;
- }
- if (fd >= 0 && write(fd, value, type_size) <= 0) {
- TRACE_STRERROR("[ERROR] write FD[%d]", fd);
- return -1;
- }
- return 0;
-}
-
-int dp_ipc_read_custom_type(int fd, void *value, size_t type_size)
-{
- if (fd < 0) {
- TRACE_ERROR("[ERROR] CHECK FD[%d]", fd);
- return -1;
- }
- if (value == NULL) {
- TRACE_ERROR("[ERROR] CHECK VALUE FD[%d]", fd);
- return -1;
- }
-
- ssize_t recv_bytes = read(fd, value, type_size);
- if (recv_bytes < 0) {
- TRACE_STRERROR("[ERROR] read FD[%d]", fd);
- return -1;
- }
- return 0;
-}
-
-int dp_accept_socket_new()
-{
- int sockfd = -1;
- struct sockaddr_un listenaddr;
-
- int n = sd_listen_fds(1);
- if (n > 1) {
- TRACE_STRERROR("too many file descriptors received");
- return -1;
- } else if (n == 1) {
- int r;
- if ((r = sd_is_socket_unix(SD_LISTEN_FDS_START, SOCK_STREAM, 1, DP_IPC, 0)) <= 0) {
- TRACE_STRERROR("passed systemd file descriptor is of wrong type");
- return -1;
- }
- sockfd = SD_LISTEN_FDS_START + 0;
- } else {
- if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- TRACE_STRERROR("failed to create socket");
- return -1;
- }
-
- bzero(&listenaddr, sizeof(listenaddr));
- listenaddr.sun_family = AF_UNIX;
- strcpy(listenaddr.sun_path, DP_IPC);
-
- if (bind(sockfd, (struct sockaddr *)&listenaddr, sizeof listenaddr) !=
- 0) {
- TRACE_STRERROR("[CRITICAL] bind");
- close(sockfd);
- return -1;
- }
-
- if (chmod(listenaddr.sun_path, 0777) < 0) {
- TRACE_STRERROR("[CRITICAL] chmod");
- close(sockfd);
- return -1;
- }
-
- // need 3 socket per a group
- if (listen(sockfd, DP_MAX_GROUP * 3) != 0) {
- TRACE_STRERROR("[CRITICAL] listen");
- close(sockfd);
- return -1;
- }
- }
- return sockfd;
-}
-
-int dp_socket_free(int sockfd)
-{
- TRACE_DEBUG("[%d]", sockfd);
- if (sockfd < 0)
- return -1;
- shutdown(sockfd, 0);
- close(sockfd);
- return 0;
-}
diff --git a/provider/download-provider-thread-queue.c b/provider/download-provider-thread-queue.c
deleted file mode 100755
index b82618d..0000000
--- a/provider/download-provider-thread-queue.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <time.h>
-#include <sys/time.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <signal.h>
-
-#include <pthread.h>
-
-#include "download-provider.h"
-#include "download-provider-log.h"
-#include "download-provider-config.h"
-#include "download-provider-slots.h"
-#include "download-provider-socket.h"
-#include "download-provider-pthread.h"
-#include "download-provider-db.h"
-#include "download-provider-queue.h"
-#include "download-provider-network.h"
-#include "download-provider-da-interface.h"
-
-void dp_terminate(int signo);
-
-pthread_mutex_t g_dp_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t g_dp_queue_cond = PTHREAD_COND_INITIALIZER;
-
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief check network status is matched with the type setted by user
-/// @return matched : 0 mispatch : -1
-static int __is_matched_network(dp_network_type now_state, dp_network_type setted_state)
-{
- if (now_state == setted_state
- || now_state == DP_NETWORK_TYPE_ETHERNET
- || setted_state == DP_NETWORK_TYPE_ALL)
- return 0;
- #if 0
- if (setted_state == DP_NETWORK_TYPE_ALL
- || setted_state == DP_NETWORK_TYPE_DATA_NETWORK
- || now_state == DP_NETWORK_TYPE_WIFI
- || now_state == DP_NETWORK_TYPE_ETHERNET
- || (setted_state == DP_NETWORK_TYPE_WIFI
- && (now_state == DP_NETWORK_TYPE_WIFI
- || now_state == DP_NETWORK_TYPE_ETHERNET))
- )
- return 0;
- #endif
- return -1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief the count of slot downloading currently
-static unsigned __get_active_count(dp_request_slots *requests)
-{
- unsigned count = 0;
- unsigned i = 0;
-
- if (requests == NULL)
- return 0;
-
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- int locked = pthread_mutex_trylock(&requests[i].mutex);
- // locking failure means it used by other thread.
- if (locked == 0) {
- if (requests[i].request != NULL) {
- if (requests[i].request->state == DP_STATE_CONNECTING ||
- requests[i].request->state == DP_STATE_DOWNLOADING)
- count++;
- }
- CLIENT_MUTEX_UNLOCK(&requests[i].mutex);
- }
- }
- return count;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief index of slot which last time is oldest
-static int __get_oldest_request_with_network(dp_request_slots *requests, dp_state_type state, dp_network_type now_state)
-{
- int i = 0;
- int oldest_time = (int)time(NULL);
- oldest_time++; // most last time
- int oldest_index = -1;
-
- if (requests == NULL)
- return -1;
-
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- int locked = pthread_mutex_trylock(&requests[i].mutex);
- // locking failure means it used by other thread.
- if (locked == 0) {
- if (requests[i].request != NULL) {
- if (requests[i].request->state == state &&
- requests[i].request->start_time > 0 &&
- requests[i].request->start_time < oldest_time &&
- __is_matched_network(now_state,
- requests[i].request->network_type) == 0) {
- oldest_time = requests[i].request->start_time;
- oldest_index = i;
- }
- }
- CLIENT_MUTEX_UNLOCK(&requests[i].mutex);
- }
- }
- return oldest_index;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief THREAD function for calling da_start_download_with_extension.
-/// @warning da_start_download_with_extension can take long time
-/// @param the pointer of memory slot allocated for this request.
-/// @todo simplify da_start_download_with_extension
-static void *__request_download_start_agent(void *args)
-{
- dp_error_type errcode = DP_ERROR_NONE;
-
- dp_request_slots *request_slot = (dp_request_slots *) args;
- if (request_slot == NULL) {
- TRACE_ERROR("[NULL-CHECK] request_slot");
- pthread_exit(NULL);
- return 0;
- }
-
- CLIENT_MUTEX_LOCK(&request_slot->mutex);
-
- if (request_slot->request == NULL) {
- TRACE_ERROR("[NULL-CHECK] request");
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- pthread_exit(NULL);
- return 0;
- }
-
- dp_request *request = request_slot->request;
-
- if (dp_is_alive_download(request->agent_id)) {
- errcode = dp_resume_agent_download(request->agent_id);
- } else {
- // call agent start function
- errcode = dp_start_agent_download(request_slot);
- }
- // send to state callback.
- if (errcode == DP_ERROR_NONE) {
- // CONNECTING
- request->state = DP_STATE_CONNECTING;
- request->error = DP_ERROR_NONE;
- request->startcount++;
- if (dp_db_set_column
- (request->id, DP_DB_TABLE_LOG, DP_DB_COL_STARTCOUNT,
- DP_DB_COL_TYPE_INT, &request->startcount) < 0)
- TRACE_ERROR("[ERROR][%d][SQL]", request->id);
- } else if (errcode == DP_ERROR_TOO_MANY_DOWNLOADS) {
- // PENDED
- request->state = DP_STATE_QUEUED;
- request->error = DP_ERROR_TOO_MANY_DOWNLOADS;
- } else if (errcode == DP_ERROR_CONNECTION_FAILED) {
- // FAILED
- request->state = DP_STATE_FAILED;
- request->error = DP_ERROR_CONNECTION_FAILED;
- if (request->group != NULL &&
- request->group->event_socket >= 0) {
- dp_ipc_send_event(request->group->event_socket,
- request->id, request->state, request->error, 0);
- }
- } else if (errcode == DP_ERROR_INVALID_STATE) {
- // API FAILED
- request->error = DP_ERROR_INVALID_STATE;
- if (request->group != NULL &&
- request->group->event_socket >= 0) {
- dp_ipc_send_event(request->group->event_socket,
- request->id, request->state, request->error, 0);
- }
- } else {
- request->state = DP_STATE_FAILED;
- request->error = errcode;
- if (request->group != NULL &&
- request->group->event_socket >= 0) {
- dp_ipc_send_event(request->group->event_socket,
- request->id, request->state, request->error, 0);
- }
- }
- if (dp_db_request_update_status(request->id, request->state, request->error) < 0) {
- TRACE_ERROR("[ERROR][%d][SQL]", request->id);
- }
-
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
-
- if (errcode == DP_ERROR_NONE) {
- TRACE_DEBUG("try other requests -----------------");
- dp_thread_queue_manager_wake_up();
- }
-
- pthread_exit(NULL);
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief create thread.
-/// @warning if failed to create thread, change to PENED.
-/// @param the pointer of memory slot allocated for this request.
-static int __request_download_start_thread(dp_request_slots *request_slot)
-{
- // declare all resources
- pthread_t thread_pid;
- pthread_attr_t thread_attr;
-
- if (request_slot == NULL || request_slot->request == NULL) {
- TRACE_ERROR("[CRITICAL] Invalid Address");
- return -1;
- }
- dp_request *request = request_slot->request;
-
- // initialize
- if (pthread_attr_init(&thread_attr) != 0) {
- TRACE_STRERROR("[ERROR][%d] pthread_attr_init", request->id);
- return -1;
- }
- if (pthread_attr_setdetachstate(&thread_attr,
- PTHREAD_CREATE_DETACHED) != 0) {
- TRACE_STRERROR
- ("[ERROR][%d] pthread_attr_setdetachstate", request->id);
- return -1;
- }
-
- request->state = DP_STATE_CONNECTING;
- if (pthread_create(&thread_pid, &thread_attr,
- __request_download_start_agent, request_slot) != 0) {
- TRACE_STRERROR("[ERROR][%d] pthread_create", request->id);
- pthread_attr_destroy(&thread_attr);
- request->state = DP_STATE_QUEUED;
- return -1;
- }
- pthread_attr_destroy(&thread_attr);
- return 0;
-}
-
-
-void dp_thread_queue_manager_wake_up()
-{
- CLIENT_MUTEX_LOCK(&(g_dp_queue_mutex));
- pthread_cond_signal(&g_dp_queue_cond);
- CLIENT_MUTEX_UNLOCK(&(g_dp_queue_mutex));
-}
-
-
-// Main role : start download, check status of queue.
-// No timeout. Wake up by Signal be sent from other thread
-void *dp_thread_queue_manager(void *arg)
-{
- int i;
- int active_count;
- dp_client_group *group = NULL;
- dp_request *request = NULL;
-
- dp_privates *privates = (dp_privates*)arg;
- if (!privates) {
- TRACE_ERROR("[CRITICAL] Invalid Address");
- dp_terminate(SIGTERM);
- pthread_exit(NULL);
- return 0;
- }
-
- pthread_cond_init(&g_dp_queue_cond, NULL);
- while (privates != NULL && privates->listen_fd >= 0) {
-
- CLIENT_MUTEX_LOCK(&(g_dp_queue_mutex));
- pthread_cond_wait(&g_dp_queue_cond, &g_dp_queue_mutex);
-
- // request thread response instantly
- CLIENT_MUTEX_UNLOCK(&(g_dp_queue_mutex));
-
- if (privates == NULL || privates->requests == NULL ||
- privates->listen_fd < 0) {
- TRACE_DEBUG("Terminate Thread");
- break;
- }
-
- // if failed to initialize the callback for checking connection
- if (!privates->connection)
- privates->network_status =
- dp_get_network_connection_instant_status();
-
-#ifdef SUPPORT_WIFI_DIRECT
- if (privates->is_connected_wifi_direct == 0) {
- if (dp_network_wifi_direct_is_connected() == 0) {
- // wifi-direct activated. pass.
- privates->is_connected_wifi_direct = 1;
- }
- }
-#endif
-
- if (privates->network_status == DP_NETWORK_TYPE_OFF &&
- privates->is_connected_wifi_direct == 0) {
- TRACE_DEBUG("[CHECK NETWORK STATE]");
- continue;
- }
-
- active_count = __get_active_count(privates->requests);
-
- TRACE_DEBUG("Status Queue: now active[%d] max[%d]",
- active_count, DP_MAX_DOWNLOAD_AT_ONCE);
-
- // Start Conditions
- // 1. state is QUEUED
- // 2. 1 QUEUED per 1 Group : need not to check max limitation.!!
- // if no group, it will be started later.
- // 3. most old last time : below conditions need max limitation.
- // 4. match network connection type
- // 5. wifi-direct on
-
- // search group having 1 queued_count
- // guarantee 1 instant download per 1 group
- if (active_count >= DP_MAX_DOWNLOAD_AT_ONCE) {
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- CLIENT_MUTEX_LOCK(&privates->requests[i].mutex);
- request = privates->requests[i].request;
- if (request != NULL && request->state == DP_STATE_QUEUED) {
- group = privates->requests[i].request->group;
- if (group && group->queued_count == 1) {
- if (__is_matched_network
- (privates->network_status,
- request->network_type) == 0 ||
- (privates->is_connected_wifi_direct == 1 &&
- request->network_type ==
- DP_NETWORK_TYPE_WIFI_DIRECT)) {
- if (__request_download_start_thread(&privates->requests[i]) == 0) {
- TRACE_DEBUG
- ("[Guarantee Intant Download] Group [%s]", group->pkgname);
- active_count++;
- }
- }
- }
- }
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- }
- }
-
- if (active_count >= DP_MAX_DOWNLOAD_AT_ONCE) {
- TRACE_DEBUG("[BUSY] Active[%d] Max[%d]",
- active_count, DP_MAX_DOWNLOAD_AT_ONCE);
- continue;
- }
-
- // can start download more.
- // search oldest request
- while(active_count < DP_MAX_DOWNLOAD_AT_ONCE) {
-
-#ifdef SUPPORT_WIFI_DIRECT
- // WIFI-Direct first
- if (privates->is_connected_wifi_direct == 1) {
- i = __get_oldest_request_with_network(privates->requests,
- DP_STATE_QUEUED, DP_NETWORK_TYPE_WIFI_DIRECT);
- if (i >= 0) {
- TRACE_DEBUG("Found WIFI-Direct request %d", i);
- if (__request_download_start_thread(&privates->requests[i]) == 0)
- active_count++;
- continue;
- }
- }
-#endif
-
- i = __get_oldest_request_with_network(privates->requests,
- DP_STATE_QUEUED, privates->network_status);
- if (i < 0) {
- TRACE_DEBUG
- ("No Request now active[%d] max[%d]",
- active_count, DP_MAX_DOWNLOAD_AT_ONCE);
- break;
- }
- TRACE_DEBUG("QUEUE Status now %d active %d/%d", i,
- active_count, DP_MAX_DOWNLOAD_AT_ONCE);
- __request_download_start_thread(&privates->requests[i]);
- active_count++;
- }
- }
- pthread_cond_destroy(&g_dp_queue_cond);
- pthread_exit(NULL);
- return 0;
-}
diff --git a/provider/download-provider-thread-request.c b/provider/download-provider-thread-request.c
deleted file mode 100755
index 1f1e151..0000000
--- a/provider/download-provider-thread-request.c
+++ /dev/null
@@ -1,2158 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <time.h>
-#include <sys/time.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <signal.h>
-
-#include <app_manager.h>
-#include <sys/smack.h>
-#include <bundle.h>
-
-#include "download-provider.h"
-#include "download-provider-log.h"
-#include "download-provider-config.h"
-#include "download-provider-slots.h"
-#include "download-provider-socket.h"
-#include "download-provider-pthread.h"
-#include "download-provider-db.h"
-#include "download-provider-queue.h"
-#include "download-provider-request.h"
-#include "download-provider-network.h"
-#include "download-provider-da-interface.h"
-#include "download-provider-notification.h"
-
-void dp_terminate(int signo);
-
-static char *__print_command(dp_command_type cmd)
-{
- switch(cmd)
- {
- case DP_CMD_CREATE :
- return "CREATE";
- case DP_CMD_START :
- return "START";
- case DP_CMD_PAUSE :
- return "PAUSE";
- case DP_CMD_CANCEL :
- return "CANCEL";
- case DP_CMD_DESTROY :
- return "DESTROY";
- case DP_CMD_FREE :
- return "FREE";
- case DP_CMD_ECHO :
- return "ECHO";
- case DP_CMD_SET_URL :
- return "SET_URL";
- case DP_CMD_SET_DESTINATION :
- return "SET_DESTINATION";
- case DP_CMD_SET_FILENAME :
- return "SET_FILENAME";
- case DP_CMD_SET_NOTIFICATION :
- return "SET_NOTIFICATION";
- case DP_CMD_SET_STATE_CALLBACK :
- return "SET_STATE_CALLBACK";
- case DP_CMD_SET_PROGRESS_CALLBACK :
- return "SET_PROGRESS_CALLBACK";
- case DP_CMD_SET_AUTO_DOWNLOAD :
- return "SET_AUTO_DOWNLOAD";
- case DP_CMD_SET_NETWORK_TYPE :
- return "SET_NETWORK_TYPE";
- case DP_CMD_SET_HTTP_HEADER :
- return "SET_HTTP_HEADER";
- case DP_CMD_DEL_HTTP_HEADER :
- return "DEL_HTTP_HEADER";
- case DP_CMD_GET_HTTP_HEADER :
- return "GET_HTTP_HEADER";
- case DP_CMD_GET_URL :
- return "GET_URL";
- case DP_CMD_GET_DESTINATION :
- return "GET_DESTINATION";
- case DP_CMD_GET_FILENAME :
- return "GET_FILENAME";
- case DP_CMD_GET_NOTIFICATION :
- return "GET_NOTIFICATION";
- case DP_CMD_GET_STATE_CALLBACK :
- return "GET_STATE_CALLBACK";
- case DP_CMD_GET_PROGRESS_CALLBACK :
- return "GET_PROGRESS_CALLBACK";
- case DP_CMD_GET_HTTP_HEADERS :
- return "GET_HTTP_HEADERS";
- case DP_CMD_GET_HTTP_HEADER_LIST:
- return "GET_HTTP_HEADER_LIST";
- 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 :
- return "GET_NETWORK_TYPE";
- case DP_CMD_GET_SAVED_PATH :
- return "GET_SAVED_PATH";
- case DP_CMD_GET_TEMP_SAVED_PATH :
- return "GET_TEMP_SAVED_PATH";
- case DP_CMD_GET_MIME_TYPE :
- return "GET_MIME_TYPE";
- case DP_CMD_GET_RECEIVED_SIZE :
- return "GET_RECEIVED_SIZE";
- case DP_CMD_GET_TOTAL_FILE_SIZE :
- return "GET_TOTAL_FILE_SIZE";
- case DP_CMD_GET_CONTENT_NAME :
- return "GET_CONTENT_NAME";
- case DP_CMD_GET_HTTP_STATUS :
- return "GET_HTTP_STATUS";
- case DP_CMD_GET_ETAG :
- return "DP_CMD_GET_ETAG";
- case DP_CMD_GET_STATE :
- return "GET_STATE";
- case DP_CMD_GET_ERROR :
- return "ERROR";
- case DP_CMD_SET_COMMAND_SOCKET :
- return "SET_COMMAND_SOCKET";
- case DP_CMD_SET_EVENT_SOCKET :
- return "SET_EVENT_SOCKET";
- case DP_CMD_SET_NOTIFICATION_BUNDLE:
- return "SET_NOTIFICATION_BUNDLE";
- case DP_CMD_SET_NOTIFICATION_TITLE:
- return "SET_NOTIFICATION_TITLE";
- case DP_CMD_SET_NOTIFICATION_DESCRIPTION:
- return "SET_NOTIFICATION_DESCRIPTION";
- case DP_CMD_SET_NOTIFICATION_TYPE:
- return "SET_NOTIFICATION_TYPE";
- case DP_CMD_GET_NOTIFICATION_BUNDLE:
- return "GET_NOTIFICATION_BUNDLE";
- case DP_CMD_GET_NOTIFICATION_TITLE:
- return "GET_NOTIFICATION_TITLE";
- case DP_CMD_GET_NOTIFICATION_DESCRIPTION:
- return "GET_NOTIFICATION_DESCRIPTION";
- case DP_CMD_GET_NOTIFICATION_TYPE:
- return "GET_NOTIFICATION_TYPE";
- default :
- break;
- }
- return "UNKNOWN COMMAND";
-}
-
-/* compare two string */
-static int __cmp_string(char *s1, char *s2)
-{
- size_t s1_len = 0;
- size_t s2_len = 0;
-
- if (s1 == NULL || s2 == NULL) {
- TRACE_ERROR("[CHECK PARAM]");
- return -1;
- }
-
- s1_len = strlen(s1);
- if (s1_len <= 0) {
- TRACE_ERROR("[CHECK PARAM] len[%d]", s1_len);
- return -1;
- }
-
- s2_len = strlen(s2);
- if (s2_len <= 0) {
- TRACE_ERROR("[CHECK PARAM] len[%d]", s2_len);
- return -1;
- }
-
- if (s1_len != s2_len) {
- TRACE_ERROR("[DIFF] len[%d:%d]", s1_len, s2_len);
- return -1;
- }
-
- if (strncmp(s1, s2, s1_len) != 0) {
- TRACE_ERROR("[DIFF] cmp");
- return -1;
- }
-
- return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief return index of empty slot
-static int __get_empty_request_index(dp_request_slots *slots)
-{
- int i = 0;
-
- if (slots == NULL)
- return -1;
-
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- if (slots[i].request == NULL)
- return i;
- }
- return -1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief return index of slot having same ID
-/// @param ID want to search
-static int __get_same_request_index(dp_request_slots *slots, int id)
-{
- int i = 0;
-
- if (!slots || id < 0)
- return -1;
-
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- if (slots[i].request != NULL) {
- if (slots[i].request->id == id)
- return i;
- }
- }
- return -1;
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief return custom value via IPC
-static void __send_return_custom_type(int fd, dp_error_type errcode, void *value, size_t type_size)
-{
- dp_ipc_send_errorcode(fd, errcode);
- dp_ipc_send_custom_type(fd, value, type_size);
-}
-
-static int __is_downloading(dp_state_type state)
-{
- if (state == DP_STATE_CONNECTING || state == DP_STATE_DOWNLOADING)
- return 0;
- return -1;
-}
-
-static int __is_started(dp_state_type state)
-{
- if (state == DP_STATE_QUEUED || __is_downloading(state) == 0)
- return 0;
- return -1;
-}
-
-static int __is_stopped(dp_state_type state)
-{
- if (state == DP_STATE_COMPLETED || state == DP_STATE_FAILED ||
- state == DP_STATE_CANCELED)
- return 0;
- return -1;
-}
-
-// cancel the downloading if no auto-download, then clear group
-static void __clear_group(dp_privates *privates, dp_client_group *group)
-{
- dp_request *request = NULL;
- int i = 0;
-
- for (i = 0; i < DP_MAX_REQUEST; i++) {
-
- CLIENT_MUTEX_LOCK(&privates->requests[i].mutex);
-
- if (privates->requests[i].request == NULL) {
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- continue;
- }
-
- request = privates->requests[i].request;
-
- if (request->group == NULL || request->id <= 0 ||
- request->group != group) {
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- continue;
- }
-
- // if stopped, paused or not started yet, clear request
- if (__is_started(request->state) < 0) {
- TRACE_DEBUG("[FREE][%d] state[%s]", request->id,
- dp_print_state(request->state));
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- dp_request_slot_free(&privates->requests[i]);
- continue;
- }
-
- // disconnect the request from group.
- TRACE_SECURE_DEBUG("[DISCONNECT][%d] state:%s pkg:%s sock:%d",
- request->id, dp_print_state(request->state),
- request->group->pkgname, request->group->cmd_socket);
- request->group = NULL;
- request->state_cb = 0;
- request->progress_cb = 0;
-
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
-
- }
- // clear this group
- dp_client_group_free(group);
-}
-
-static void __dp_remove_tmpfile(int id, dp_request *request)
-{
- dp_error_type errorcode = DP_ERROR_NONE;
- char *path =
- dp_request_get_tmpsavedpath(id, request, &errorcode);
- if (errorcode == DP_ERROR_NONE &&
- (path != NULL && strlen(path) > 0) &&
- dp_is_file_exist(path) == 0) {
- TRACE_SECURE_DEBUG("[REMOVE][%d] TEMP FILE [%s]", id, path);
- if (unlink(path) != 0)
- TRACE_STRERROR("[ERROR][%d] remove file", id);
- }
- free(path);
-}
-
-static int __dp_check_valid_directory(dp_request *request, char *dir)
-{
- int ret = -1;
- int ret_val = 0;
- char *dir_label = NULL;
- struct stat dir_state;
-
- ret_val = stat(dir, &dir_state);
- if (ret_val == 0) {
- dp_credential cred;
- if (request->group == NULL) {
- cred.uid = dp_db_cond_get_int(DP_DB_TABLE_GROUPS,
- DP_DB_GROUPS_COL_UID,
- DP_DB_GROUPS_COL_PKG,
- DP_DB_COL_TYPE_TEXT, request->packagename);
- cred.gid = dp_db_cond_get_int(DP_DB_TABLE_GROUPS,
- DP_DB_GROUPS_COL_GID,
- DP_DB_GROUPS_COL_PKG,
- DP_DB_COL_TYPE_TEXT, request->packagename);
- } else {
- cred = request->group->credential;
- }
- if (dir_state.st_uid == cred.uid
- && (dir_state.st_mode & (S_IRUSR | S_IWUSR))
- == (S_IRUSR | S_IWUSR)) {
- ret = 0;
- } else if (dir_state.st_gid == cred.gid
- && (dir_state.st_mode & (S_IRGRP | S_IWGRP))
- == (S_IRGRP | S_IWGRP)) {
- ret = 0;
- } else if ((dir_state.st_mode & (S_IROTH | S_IWOTH))
- == (S_IROTH | S_IWOTH)) {
- ret = 0;
- }
- }
-
- if (ret != 0)
- return ret;
-
- ret_val = smack_getlabel(dir, &dir_label, SMACK_LABEL_ACCESS);
- if (ret_val != 0) {
- TRACE_SECURE_ERROR("[ERROR][%d][SMACK ERROR]", request->id);
- free(dir_label);
- return -1;
- }
-
- char *smack_label = NULL;
- if (request->group == NULL) {
- // get smack_label from sql
- smack_label = dp_db_cond_get_text(DP_DB_TABLE_GROUPS,
- DP_DB_GROUPS_COL_SMACK_LABEL, DP_DB_GROUPS_COL_PKG,
- DP_DB_COL_TYPE_TEXT, request->packagename);
- if (smack_label != NULL) {
- ret_val = smack_have_access(smack_label, dir_label, "rw");
- free(smack_label);
- }
- } else {
- if (request->group->smack_label != NULL) {
- ret_val = smack_have_access(request->group->smack_label, dir_label, "rw");
- }
- }
- if (ret_val == 0) {
- TRACE_SECURE_ERROR("[ERROR][%d][SMACK NO RULE]", request->id);
- ret = -1;
- } else if (ret_val < 0){
- TRACE_SECURE_ERROR("[ERROR][%d][SMACK ERROR]", request->id);
- ret = -1;
- }
- free(dir_label);
- return ret;
-}
-
-static int __dp_call_cancel_agent(dp_request *request)
-{
- int ret = -1;
- if (request != NULL) {
- if (request->agent_id >= 0) {
- TRACE_INFO("[%d]cancel_agent(%d) state:%s", request->id,
- request->agent_id, dp_print_state(request->state));
- if (dp_cancel_agent_download(request->agent_id) == 0)
- ret = 0;
- } else {
- TRACE_DEBUG("[CHECK] agent-id");
- }
- }
- return ret;
-}
-
-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_DEBUG("[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_SECURE_DEBUG("[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) {
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", id);
- ret = DP_ERROR_NO_SPACE;
- } else {
- 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_DEBUG("[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("[fail][%d][sql]", id);
- TRACE_SECURE_ERROR("[fail]key:%s", key);
- ret = DP_ERROR_OUT_OF_MEMORY;
- }
- }
- TRACE_DEBUG("[ERROR][%d][%s]", id, dp_print_errorcode(ret));
- TRACE_SECURE_DEBUG("key:%s", key);
- free(key);
- return ret;
-}
-
-static int __dp_get_http_header_fields(int fd, int id, char ***values,
- unsigned *count)
-{
- dp_error_type ret = DP_ERROR_NONE;
- 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;
- }
-
- db_conds_list_fmt conds_p;
- conds_p.column = DP_DB_COL_ID;
- conds_p.type = DP_DB_COL_TYPE_INT;
- conds_p.value = &id;
- conds_p.is_like = 0;
- int check_rows = dp_db_get_conds_rows_count
- (DP_DB_TABLE_HTTP_HEADERS, DP_DB_COL_HEADER_FIELD, "AND",
- 1, &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 {
- int rows_count =
- dp_db_get_conds_list(DP_DB_TABLE_HTTP_HEADERS,
- DP_DB_COL_HEADER_FIELD, DP_DB_COL_TYPE_TEXT,
- (void **)rows_array, check_rows, -1, NULL, NULL,
- "AND", 1, &conds_p);
- if (rows_count <= 0) {
- // NO_DATA
- ret = DP_ERROR_NO_DATA;
- free(rows_array);
- } else {
- *count = rows_count;
- *values = rows_array;
- }
- }
- }
- 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;
- char *smack_label = NULL;
- int ret = 0;
-
- 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_SECURE_DEBUG("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_DEBUG("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);
- free(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_SECURE_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;
-
- int conds_count = 4;
- db_conds_list_fmt conds_p[conds_count];
- memset(&conds_p, 0x00, conds_count * sizeof(db_conds_list_fmt));
- conds_p[0].column = DP_DB_GROUPS_COL_UID;
- conds_p[0].type = DP_DB_COL_TYPE_INT;
- conds_p[0].value = &credential.uid;
- conds_p[1].column = DP_DB_GROUPS_COL_GID;
- conds_p[1].type = DP_DB_COL_TYPE_INT;
- conds_p[1].value = &credential.gid;
- conds_p[2].column = DP_DB_GROUPS_COL_PKG;
- conds_p[2].type = DP_DB_COL_TYPE_TEXT;
- conds_p[2].value = pkgname;
-
- if (dp_is_smackfs_mounted() == 1) {
- ret = smack_new_label_from_socket(clientfd, &smack_label);
- if (ret != 0) {
- TRACE_ERROR("[CRITICAL] cannot get smack label");
- free(pkgname);
- free(smack_label);
- return -1;
- }
- TRACE_SECURE_INFO("credential label:[%s]", smack_label);
- groups[i].group->smack_label = smack_label;
-
- conds_p[3].column = DP_DB_GROUPS_COL_SMACK_LABEL;
- conds_p[3].type = DP_DB_COL_TYPE_TEXT;
- conds_p[3].value = smack_label;
- } else {
- conds_count = 3; // ignore smack label
- groups[i].group->smack_label = NULL;
- }
-
- if (dp_db_insert_columns(DP_DB_TABLE_GROUPS, conds_count, conds_p) < 0) {
- free(pkgname);
- free(smack_label);
- if (dp_db_is_full_error() == 0)
- TRACE_ERROR("[SQLITE_FULL]");
- return -1;
- }
-
- TRACE_SECURE_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_DEBUG("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_SECURE_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;
-}
-
-static dp_error_type __dp_do_get_command(int sock, dp_command* cmd, dp_request *request)
-{
- unsigned is_checked = 1;
- dp_error_type errorcode = DP_ERROR_NONE;
-
- char *read_str = NULL;
- // No read(), write a string
- switch(cmd->cmd) {
- case DP_CMD_GET_URL:
- read_str = dp_request_get_url(cmd->id, &errorcode);
- break;
- case DP_CMD_GET_DESTINATION:
- read_str = dp_request_get_destination(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_FILENAME:
- read_str = dp_request_get_filename(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_SAVED_PATH:
- read_str = dp_request_get_savedpath(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_TEMP_SAVED_PATH:
- read_str = dp_request_get_tmpsavedpath(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_MIME_TYPE:
- read_str = dp_request_get_mimetype(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_CONTENT_NAME:
- read_str = dp_request_get_contentname(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_ETAG:
- read_str = dp_request_get_etag(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_NOTIFICATION_TITLE:
- read_str = dp_request_get_title(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_NOTIFICATION_DESCRIPTION:
- read_str = dp_request_get_description(cmd->id, request, &errorcode);
- break;
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- if (read_str == NULL || strlen(read_str) < 1)
- errorcode = DP_ERROR_NO_DATA;
- dp_ipc_send_errorcode(sock, errorcode);
- if (errorcode == DP_ERROR_NONE) {
- dp_ipc_send_string(sock, read_str);
- } else {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- free(read_str);
- return errorcode;
- }
-
- // No read(), write a integer variable
- int read_int = 0;
- errorcode = DP_ERROR_NONE;
- is_checked = 1;
- switch(cmd->cmd) {
- case DP_CMD_GET_NOTIFICATION:
- read_int = dp_db_get_int_column(cmd->id, DP_DB_TABLE_REQUEST_INFO,
- DP_DB_COL_NOTIFICATION_ENABLE);
- break;
- case DP_CMD_GET_AUTO_DOWNLOAD:
- read_int = dp_db_get_int_column(cmd->id, DP_DB_TABLE_REQUEST_INFO,
- DP_DB_COL_AUTO_DOWNLOAD);
- break;
- case DP_CMD_GET_NETWORK_TYPE:
- read_int = dp_db_get_int_column(cmd->id, DP_DB_TABLE_REQUEST_INFO,
- DP_DB_COL_NETWORK_TYPE);
- break;
- case DP_CMD_GET_HTTP_STATUS:
- read_int = dp_db_get_int_column(cmd->id, DP_DB_TABLE_DOWNLOAD_INFO,
- DP_DB_COL_HTTP_STATUS);
- break;
- case DP_CMD_GET_STATE:
- if (request == NULL) {
- read_int = dp_db_get_state(cmd->id);
- } else {
- read_int = request->state;
- }
- break;
- case DP_CMD_GET_NOTIFICATION_TYPE:
- TRACE_DEBUG("DP_CMD_GET_NOTIFICATION_TYPE");
- read_int = dp_request_get_noti_type(cmd->id, request, &errorcode);
- break;
- case DP_CMD_GET_ERROR:
- if (request == NULL) {
- read_int = dp_db_get_int_column(cmd->id,
- DP_DB_TABLE_LOG, DP_DB_COL_ERRORCODE);
- } else {
- read_int = request->error;
- }
- break;
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- if (read_int < 0)
- errorcode = DP_ERROR_NO_DATA;
- dp_ipc_send_errorcode(sock, errorcode);
- if (errorcode == DP_ERROR_NONE) {
- dp_ipc_send_custom_type(sock, &read_int, sizeof(int));
- } else {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- return errorcode;
- }
-
- // No read(), write a long long variable
- unsigned long long recv_long = 0;
- errorcode = DP_ERROR_NONE;
- is_checked = 1;
- switch(cmd->cmd) {
- case DP_CMD_GET_RECEIVED_SIZE:
- if (request == NULL)
- errorcode = DP_ERROR_NO_DATA;
- else
- recv_long = request->received_size;
- break;
- case DP_CMD_GET_TOTAL_FILE_SIZE:
- if (request != NULL) {
- recv_long = request->file_size;
- } else {
- long long file_size =
- dp_db_get_int64_column(cmd->id,
- DP_DB_TABLE_DOWNLOAD_INFO, DP_DB_COL_CONTENT_SIZE);
- if (file_size < 0)
- errorcode = DP_ERROR_NO_DATA;
- else // casting
- recv_long = file_size;
- }
- break;
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- dp_ipc_send_errorcode(sock, errorcode);
- if (errorcode == DP_ERROR_NONE) {
- dp_ipc_send_custom_type(sock, &recv_long,
- sizeof(unsigned long long));
- } else {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- return errorcode;
- }
-
- // No read(), write a bundle variable
- bundle_raw *b_raw = NULL;
- int length = -1;
- char *column = NULL;
- errorcode = DP_ERROR_NONE;
- is_checked = 1;
- switch(cmd->cmd) {
- case DP_CMD_GET_NOTIFICATION_BUNDLE:
- TRACE_DEBUG("DP_CMD_GET_NOTIFICATION_BUNDLE");
- dp_ipc_send_errorcode(sock, DP_ERROR_NONE);
- if ((dp_ipc_read_custom_type(sock, &read_int, sizeof(int)) < 0)) {
- TRACE_ERROR("DP_CMD_GET_NOTIFICATION_BUNDLE read fail");
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- switch(read_int) {
- case DP_NOTIFICATION_BUNDLE_TYPE_ONGOING:
- column = DP_DB_COL_RAW_BUNDLE_ONGOING;
- break;
- case DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE:
- column = DP_DB_COL_RAW_BUNDLE_COMPLETE;
- break;
- case DP_NOTIFICATION_BUNDLE_TYPE_FAILED:
- column = DP_DB_COL_RAW_BUNDLE_FAIL;
- break;
- default:
- TRACE_ERROR("[CHECK TYPE][%d]", read_int);
- errorcode = DP_ERROR_INVALID_PARAMETER;
- break;
- }
- b_raw = dp_request_get_bundle(cmd->id, request,
- &errorcode, column, &length);
- break;
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- dp_ipc_send_errorcode(sock, errorcode);
- if (errorcode == DP_ERROR_NONE) {
- dp_ipc_send_bundle(sock, b_raw, length);
- } else {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- bundle_free_encoded_rawdata(&b_raw);
- return errorcode;
- }
-
- dp_ipc_send_errorcode(sock, DP_ERROR_NONE);
- // complex read() and write().
- char *read_str2 = NULL;
- errorcode = DP_ERROR_NONE;
- read_str = NULL;
- is_checked = 1;
- switch(cmd->cmd) {
- case DP_CMD_GET_HTTP_HEADER:
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- read_str2 = dp_db_cond_get_text_column(cmd->id,
- DP_DB_TABLE_HTTP_HEADERS, DP_DB_COL_HEADER_DATA,
- DP_DB_COL_HEADER_FIELD, DP_DB_COL_TYPE_TEXT, read_str);
- if (read_str2 == NULL)
- errorcode = DP_ERROR_NO_DATA;
- dp_ipc_send_errorcode(sock, errorcode);
- if (errorcode == DP_ERROR_NONE)
- dp_ipc_send_string(sock, read_str2);
- break;
- case DP_CMD_GET_HTTP_HEADER_LIST:
- {
- char **values = NULL;
- unsigned rows_count = 0;
- errorcode = __dp_get_http_header_fields(sock,
- cmd->id, &values, &rows_count);
- if (errorcode == DP_ERROR_NONE) {
- __send_return_custom_type(sock, DP_ERROR_NONE,
- &rows_count, sizeof(int));
- // sending strings
- int i = 0;
- for (i = 0; i < rows_count; i++) {
- if (dp_ipc_send_string(sock, values[i]) < 0)
- break;
- }
- for (i = 0; i < rows_count; i++)
- free(values[i]);
- } else {
- if (errorcode != DP_ERROR_IO_ERROR)
- dp_ipc_send_errorcode(sock, errorcode);
- }
- free(values);
- break;
- }
- case DP_CMD_GET_EXTRA_PARAM:
- {
- char **values = NULL;
- unsigned rows_count = 0;
- errorcode = __dp_get_extra_param_values(sock,
- cmd->id, &values, &rows_count);
- if (errorcode == DP_ERROR_NONE) {
- __send_return_custom_type(sock, DP_ERROR_NONE,
- &rows_count, sizeof(int));
- // sending strings
- int i = 0;
- for (i = 0; i < rows_count; i++) {
- if (dp_ipc_send_string(sock, values[i]) < 0)
- break;
- }
- for (i = 0; i < rows_count; i++)
- free(values[i]);
- } else {
- if (errorcode != DP_ERROR_IO_ERROR)
- dp_ipc_send_errorcode(sock, errorcode);
- }
- free(values);
- break;
- }
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- if (errorcode != DP_ERROR_NONE) {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- free(read_str);
- free(read_str2);
- return errorcode;
- }
- return DP_ERROR_UNKNOWN;
-}
-
-static dp_error_type __dp_do_set_command(int sock, dp_command *cmd, dp_request *request)
-{
- unsigned is_checked = 1;
- int read_int = 0;
- dp_error_type errorcode = DP_ERROR_NONE;
- char *read_str = NULL;
- bundle_raw *b_raw = NULL;
- unsigned bundle_length = 0;
- int noti_bundle_type = 0;
-
- dp_ipc_send_errorcode(sock, DP_ERROR_NONE);
- // read a interger or a string, return errorcode.
- errorcode = DP_ERROR_NONE;
- switch(cmd->cmd) {
- case DP_CMD_SET_STATE_CALLBACK:
- if (dp_ipc_read_custom_type(sock, &read_int, sizeof(int)) < 0) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_state_event(cmd->id, request, read_int);
- break;
- case DP_CMD_SET_PROGRESS_CALLBACK:
- if (dp_ipc_read_custom_type(sock, &read_int, sizeof(int)) < 0) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_progress_event(cmd->id, request, read_int);
- break;
- case DP_CMD_SET_NETWORK_TYPE:
- if (dp_ipc_read_custom_type(sock, &read_int, sizeof(int)) < 0) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- if (read_int == DP_NETWORK_TYPE_ALL ||
- read_int == DP_NETWORK_TYPE_WIFI ||
- read_int == DP_NETWORK_TYPE_DATA_NETWORK ||
- read_int == DP_NETWORK_TYPE_ETHERNET ||
- read_int == DP_NETWORK_TYPE_WIFI_DIRECT)
- errorcode = dp_request_set_network_type(cmd->id, request, read_int);
- else
- errorcode = DP_ERROR_INVALID_PARAMETER;
- break;
- case DP_CMD_SET_AUTO_DOWNLOAD:
- if (dp_ipc_read_custom_type(sock, &read_int, sizeof(int)) < 0) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_auto_download(cmd->id, request, read_int);
- break;
- case DP_CMD_SET_NOTIFICATION:
- if (dp_ipc_read_custom_type(sock, &read_int, sizeof(int)) < 0) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_notification(cmd->id, request, read_int);
- break;
- case DP_CMD_SET_URL:
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_url(cmd->id, request, read_str);
- break;
- case DP_CMD_SET_DESTINATION:
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- if (dp_is_smackfs_mounted() == 1 &&
- __dp_check_valid_directory(request, read_str) != 0){
- errorcode = DP_ERROR_PERMISSION_DENIED;
- break;
- }
- errorcode = dp_request_set_destination(cmd->id, request, read_str);
- break;
- case DP_CMD_SET_FILENAME:
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_filename(cmd->id, request, read_str);
- break;
- case DP_CMD_SET_NOTIFICATION_BUNDLE:
- bundle_length = dp_ipc_read_bundle(sock, &noti_bundle_type, &b_raw);
- if (bundle_length == 0) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- } else if (bundle_length == -1) {
- errorcode = DP_ERROR_INVALID_PARAMETER;
- break;
- }
- errorcode = dp_request_set_bundle(cmd->id, request,
- noti_bundle_type, b_raw, bundle_length);
- break;
- case DP_CMD_SET_NOTIFICATION_TITLE:
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_title(cmd->id, request, read_str);
- break;
- case DP_CMD_SET_NOTIFICATION_DESCRIPTION:
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- errorcode = dp_request_set_description(cmd->id, request, read_str);
- break;
- case DP_CMD_SET_NOTIFICATION_TYPE:
- if ((dp_ipc_read_custom_type(sock, &read_int, sizeof(int)) < 0)) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- if (read_int == DP_NOTIFICATION_TYPE_NONE ||
- read_int == DP_NOTIFICATION_TYPE_COMPLETE_ONLY ||
- read_int == DP_NOTIFICATION_TYPE_ALL)
- errorcode = dp_request_set_noti_type(cmd->id, request, read_int);
- else
- errorcode = DP_ERROR_INVALID_PARAMETER;
- break;
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- free(read_str);
- bundle_free_encoded_rawdata(&b_raw);
- if (errorcode != DP_ERROR_NONE) {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- if (errorcode == DP_ERROR_IO_ERROR)
- return errorcode;
- dp_ipc_send_errorcode(sock, errorcode);
- return errorcode;
- }
-
- // complex read() and write().
- char *read_str2 = NULL;
- errorcode = DP_ERROR_NONE;
- read_str = NULL;
- is_checked = 1;
- switch(cmd->cmd) {
- case DP_CMD_SET_HTTP_HEADER:
- {
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- if ((read_str2 = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- int conds_count = 3; // id + field + data
- db_conds_list_fmt conds_p[conds_count];
- 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 = &cmd->id;
- conds_p[1].column = DP_DB_COL_HEADER_FIELD;
- conds_p[1].type = DP_DB_COL_TYPE_TEXT;
- conds_p[1].value = read_str;
- conds_p[2].column = DP_DB_COL_HEADER_DATA;
- conds_p[2].type = DP_DB_COL_TYPE_TEXT;
- conds_p[2].value = read_str2;
- if (dp_db_get_conds_rows_count(DP_DB_TABLE_HTTP_HEADERS,
- DP_DB_COL_ID, "AND", 2, conds_p) <= 0) { // insert
- if (dp_db_insert_columns(DP_DB_TABLE_HTTP_HEADERS,
- conds_count, conds_p) < 0) {
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", cmd->id);
- errorcode = DP_ERROR_NO_SPACE;
- } else {
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- }
- }
- } else { // update data by field
- if (dp_db_cond_set_column(cmd->id, DP_DB_TABLE_HTTP_HEADERS,
- DP_DB_COL_HEADER_DATA, DP_DB_COL_TYPE_TEXT, read_str2,
- DP_DB_COL_HEADER_FIELD, DP_DB_COL_TYPE_TEXT, read_str) < 0) {
- if (dp_db_is_full_error() == 0) {
- TRACE_ERROR("[SQLITE_FULL][%d]", cmd->id);
- errorcode = DP_ERROR_NO_SPACE;
- } else {
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- }
- }
- }
- dp_ipc_send_errorcode(sock, errorcode);
- break;
- }
- case DP_CMD_DEL_HTTP_HEADER:
- if ((read_str = dp_ipc_read_string(sock)) == NULL) {
- errorcode = DP_ERROR_IO_ERROR;
- break;
- }
- if (dp_db_get_cond_rows_count(cmd->id, DP_DB_TABLE_HTTP_HEADERS,
- DP_DB_COL_HEADER_FIELD, DP_DB_COL_TYPE_TEXT,
- read_str) <= 0) {
- errorcode = DP_ERROR_NO_DATA;
- } else {
- if (dp_db_cond_remove(cmd->id, DP_DB_TABLE_HTTP_HEADERS,
- DP_DB_COL_HEADER_FIELD, DP_DB_COL_TYPE_TEXT, read_str) < 0)
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- }
- dp_ipc_send_errorcode(sock, errorcode);
- break;
- case DP_CMD_ADD_EXTRA_PARAM:
- errorcode = __dp_add_extra_param(sock, cmd->id);
- if (errorcode != DP_ERROR_IO_ERROR)
- dp_ipc_send_errorcode(sock, errorcode);
- break;
- case DP_CMD_REMOVE_EXTRA_PARAM:
- errorcode = __dp_remove_extra_param(sock, cmd->id);
- if (errorcode != DP_ERROR_IO_ERROR)
- dp_ipc_send_errorcode(sock, errorcode);
- break;
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- if (errorcode != DP_ERROR_NONE) {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- free(read_str);
- free(read_str2);
- return errorcode;
- }
- return DP_ERROR_UNKNOWN;
-}
-
-static dp_error_type __dp_do_action_command(int sock, dp_command* cmd, dp_request *request)
-{
- unsigned is_checked = 1;
- int read_int = 0;
- dp_error_type errorcode = DP_ERROR_NONE;
-
- read_int = 0;
- errorcode = DP_ERROR_NONE;
- is_checked = 1;
- switch(cmd->cmd) {
- case DP_CMD_DESTROY:
- if (request != NULL) {// just update the state
- if (__is_started(request->state) == 0) {
- read_int = DP_STATE_CANCELED;
- if (dp_db_set_column(cmd->id, DP_DB_TABLE_LOG, DP_DB_COL_STATE,
- DP_DB_COL_TYPE_INT, &read_int) < 0) {
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- } else {
- if (__dp_call_cancel_agent(request) < 0)
- TRACE_ERROR("[fail][%d]cancel_agent", cmd->id);
- request->state = DP_STATE_CANCELED;
- if (request->auto_notification == 1 &&
- request->packagename != NULL) {
- request->noti_priv_id = dp_set_downloadedinfo_notification
- (request->noti_priv_id, request->id,
- request->packagename, request->state);
- } else {
- int noti_type = dp_db_get_int_column(request->id,
- DP_DB_TABLE_NOTIFICATION, DP_DB_COL_NOTI_TYPE);
- if (noti_type > DP_NOTIFICATION_TYPE_NONE &&
- request->packagename != NULL)
- request->noti_priv_id = dp_set_downloadedinfo_notification
- (request->noti_priv_id, request->id,
- request->packagename, request->state);
- }
- }
- }
- }
- break;
- case DP_CMD_PAUSE:
- {
- // to check fastly, divide the case by request value
- if (request == NULL) {
- dp_state_type state = dp_db_get_state(cmd->id);
- // already paused or stopped
- if (state > DP_STATE_DOWNLOADING) {
- errorcode = DP_ERROR_INVALID_STATE;
- } else {
- // change state to paused.
- state = DP_STATE_PAUSED;
- if (dp_db_set_column(cmd->id, DP_DB_TABLE_LOG,
- DP_DB_COL_STATE, DP_DB_COL_TYPE_INT, &state) < 0)
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- }
- break;
- }
-
- if (request->state > DP_STATE_DOWNLOADING) {
- errorcode = DP_ERROR_INVALID_STATE;
- break;
- }
-
- // before downloading including QUEUED
- if (__is_downloading(request->state) < 0) {
- dp_state_type state = DP_STATE_PAUSED;
- if (dp_db_set_column(cmd->id, DP_DB_TABLE_LOG, DP_DB_COL_STATE,
- DP_DB_COL_TYPE_INT, &state) < 0) {
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- } else {
- request->state = state;
- }
- break;
- }
- // only downloading.
- dp_state_type state = DP_STATE_PAUSE_REQUESTED;
- if (dp_db_set_column(cmd->id, DP_DB_TABLE_LOG,
- DP_DB_COL_STATE, DP_DB_COL_TYPE_INT, &state) < 0) {
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- } else {
- TRACE_INFO("[%s][%d]pause_agent(%d) state:%s",
- __print_command(cmd->cmd), cmd->id,
- request->agent_id,
- dp_print_state(request->state));
- if (dp_pause_agent_download
- (request->agent_id) < 0) {
- TRACE_ERROR("[fail][%d]pause_agent(%d)",
- cmd->id, request->agent_id);
- }
- request->state = state;
- request->error = DP_ERROR_NONE;
- request->pause_time = (int)time(NULL);
- dp_db_update_date(cmd->id, DP_DB_TABLE_LOG,
- DP_DB_COL_ACCESS_TIME);
- }
- break;
- }
- case DP_CMD_CANCEL:
- {
- // to check fastly, divide the case by request value
- if (request == NULL) {
- dp_state_type state = dp_db_get_state(cmd->id);
- // already paused or stopped
- if (__is_stopped(state) == 0) {
- errorcode = DP_ERROR_INVALID_STATE;
- } else {
- // change state to canceled.
- state = DP_STATE_CANCELED;
- if (dp_db_set_column(cmd->id, DP_DB_TABLE_LOG,
- DP_DB_COL_STATE, DP_DB_COL_TYPE_INT, &state) < 0)
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- }
- break;
- }
-
- if (__is_stopped(request->state) == 0) {
- TRACE_ERROR("[%s][%d]__is_stopped agentid:%d state:%s",
- __print_command(cmd->cmd), cmd->id,
- request->agent_id, dp_print_state(request->state));
- errorcode = DP_ERROR_INVALID_STATE;
- } else {
- // change state to canceled.
- dp_state_type state = DP_STATE_CANCELED;
- if (dp_db_set_column(cmd->id, DP_DB_TABLE_LOG, DP_DB_COL_STATE,
- DP_DB_COL_TYPE_INT, &state) < 0)
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- }
- if (errorcode == DP_ERROR_NONE) {
- if (__dp_call_cancel_agent(request) < 0)
- TRACE_ERROR("[fail][%d]cancel_agent", cmd->id);
- request->state = DP_STATE_CANCELED;
- }
- dp_db_update_date(cmd->id, DP_DB_TABLE_LOG, DP_DB_COL_ACCESS_TIME);
- break;
- }
- default:
- is_checked = 0;
- break;
- }
- if (is_checked == 1) {
- if (errorcode != DP_ERROR_NONE) {
- TRACE_ERROR("[ERROR][%d][%s][%s]", cmd->id,
- __print_command(cmd->cmd), dp_print_errorcode(errorcode));
- }
- dp_ipc_send_errorcode(sock, errorcode);
- return errorcode;
- }
- return DP_ERROR_UNKNOWN;
-}
-
-static dp_error_type __do_dp_start_command(int sock, int id, dp_privates *privates,
- dp_client_group *group, dp_request *request)
-{
- dp_error_type errorcode = DP_ERROR_NONE;
-
- // need URL at least
- char *url = dp_request_get_url(id, &errorcode);
- free(url);
- if (errorcode == DP_ERROR_NO_DATA) {
- errorcode = DP_ERROR_INVALID_URL;
- dp_ipc_send_errorcode(sock, errorcode);
- return errorcode;
- }
-
- if (request == NULL) { // Support Re-download
- // Support Re-download
- int index = __get_empty_request_index(privates->requests);
- if (index < 0) { // Busy, No Space in slot
- errorcode = DP_ERROR_QUEUE_FULL;
- TRACE_SECURE_ERROR("[ERROR][%d][RESTORE][%s]", id,
- dp_print_errorcode(errorcode));
- } else {
- CLIENT_MUTEX_LOCK(&privates->requests[index].mutex);
- dp_request *tmp_request =
- dp_request_load_from_log (id, &errorcode);
- if (tmp_request != NULL) {
- // restore callback info
- tmp_request->state_cb = dp_db_get_int_column(id,
- DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_STATE_EVENT);
- tmp_request->progress_cb = dp_db_get_int_column(id,
- DP_DB_TABLE_REQUEST_INFO, DP_DB_COL_PROGRESS_EVENT);
- tmp_request->auto_notification =
- dp_db_get_int_column(id, DP_DB_TABLE_REQUEST_INFO,
- DP_DB_COL_NOTIFICATION_ENABLE);
- if (group != NULL) // for send event to client
- tmp_request->group = group;
- privates->requests[index].request = tmp_request;
- request = privates->requests[index].request;
- } else {
- TRACE_SECURE_ERROR("[ERROR][%d][RESTORE][%s]", id,
- dp_print_errorcode(errorcode));
- dp_ipc_send_errorcode(sock, errorcode);
- CLIENT_MUTEX_UNLOCK(&privates->requests[index].mutex);
- return errorcode;
- }
- CLIENT_MUTEX_UNLOCK(&privates->requests[index].mutex);
- }
- }
-
- // check status
- if (errorcode == DP_ERROR_NONE &&
- (__is_started(request->state) == 0 ||
- request->state == DP_STATE_COMPLETED))
- errorcode = DP_ERROR_INVALID_STATE;
-
- if (errorcode == DP_ERROR_NONE) {
-
- dp_state_type state = DP_STATE_QUEUED;
- if (dp_db_set_column(id, DP_DB_TABLE_LOG,
- DP_DB_COL_STATE, DP_DB_COL_TYPE_INT, &state) < 0) {
- errorcode = DP_ERROR_OUT_OF_MEMORY;
- } else {
- if (group != NULL)
- group->queued_count++;
- request->start_time = (int)time(NULL);
- request->pause_time = 0;
- request->stop_time = 0;
- request->state = state;
- request->error = DP_ERROR_NONE;
- dp_db_update_date(id, DP_DB_TABLE_LOG, DP_DB_COL_ACCESS_TIME);
- }
-
- }
-
- dp_ipc_send_errorcode(sock, errorcode);
- if (errorcode != DP_ERROR_NONE) {
- TRACE_SECURE_ERROR("[ERROR][%d][START][%s]", id,
- dp_print_errorcode(errorcode));
- }
- return errorcode;
-}
-
-// in url-download, make 3 connection before send CREATE command.
-// after accepting, fill info to pacakgelist.
-// 3 socket per 1 package ( info/request/progress )
-void *dp_thread_requests_manager(void *arg)
-{
- fd_set rset, eset, listen_fdset, except_fdset;
- struct timeval timeout; // for timeout of select
- long flexible_timeout = DP_CARE_CLIENT_MAX_INTERVAL;
- int listenfd, clientfd, maxfd;
- socklen_t clientlen;
- struct sockaddr_un clientaddr;
- dp_credential credential;
- unsigned i, is_timeout;
- int prev_timeout = 0;
- dp_error_type errorcode = DP_ERROR_NONE;
-
- dp_privates *privates = (dp_privates*)arg;
- if (privates == NULL || privates->groups == NULL) {
- TRACE_ERROR("[CRITICAL] Invalid Address");
- dp_terminate(SIGTERM);
- pthread_exit(NULL);
- return 0;
- }
-
- listenfd = privates->listen_fd;
- maxfd = listenfd;
-
- TRACE_DEBUG("Ready to listen [%d][%s]", listenfd, DP_IPC);
-
- FD_ZERO(&listen_fdset);
- FD_ZERO(&except_fdset);
- FD_SET(listenfd, &listen_fdset);
- FD_SET(listenfd, &except_fdset);
-
- while (privates != NULL && privates->listen_fd >= 0) {
-
- // select with timeout
- // initialize timeout structure for calling timeout exactly
- memset(&timeout, 0x00, sizeof(struct timeval));
- timeout.tv_sec = flexible_timeout;
- clientfd = -1;
- credential.pid = -1;
- credential.uid = -1;
- credential.gid = -1;
- is_timeout = 1;
-
- rset = listen_fdset;
- eset = except_fdset;
-
- if (select((maxfd + 1), &rset, 0, &eset, &timeout) < 0) {
- TRACE_STRERROR("[CRITICAL] select");
- break;
- }
-
- if (privates == NULL || privates->listen_fd < 0) {
- TRACE_DEBUG("Terminate Thread");
- break;
- }
-
- if (FD_ISSET(listenfd, &eset) > 0) {
- TRACE_ERROR("[CRITICAL] listenfd Exception of socket");
- break;
- } else if (FD_ISSET(listenfd, &rset) > 0) {
- // new client(package) called url_download_create API.
- // update g_dp_request_max_fd & g_dp_info_max_fd
- // add to socket to g_dp_request_rset & g_dp_info_rset
-
- is_timeout = 0;
-
- // Anyway accept client.
- clientlen = sizeof(clientaddr);
- clientfd = accept(listenfd,
- (struct sockaddr*)&clientaddr,
- &clientlen);
- if (clientfd < 0) {
- TRACE_ERROR("[CRITICAL] accept provider was crashed ?");
- // provider need the time of refresh.
- break;
- }
-
- dp_command_type connect_cmd = DP_CMD_NONE;
- if (dp_ipc_read_custom_type(clientfd,
- &connect_cmd, sizeof(dp_command_type)) < 0) {
- TRACE_ERROR("[CRITICAL] CAPI not support CONNECT CMD");
- close(clientfd);
- continue;
- }
- if (connect_cmd <= 0) {
- TRACE_ERROR("[CRITICAL] peer terminate ?");
- close(clientfd);
- continue;
- }
-
-#ifdef SO_PEERCRED
- // getting the info of client
- socklen_t cr_len = sizeof(credential);
- if (getsockopt(clientfd, SOL_SOCKET, SO_PEERCRED,
- &credential, &cr_len) == 0) {
- TRACE_DEBUG
- ("credential : pid=%d, uid=%d, gid=%d",
- credential.pid, credential.uid, credential.gid);
- }
-#else // In case of not supported SO_PEERCRED
- int client_pid = 0;
- if (dp_ipc_read_custom_type(clientfd,
- &client_pid, sizeof(int)) < 0) {
- TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
- close(clientfd);
- continue;
- }
- if (client_pid <= 0) {
- TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
- close(clientfd);
- continue;
- }
- credential.pid = client_pid;
- if (dp_ipc_read_custom_type(clientfd,
- &credential.uid, sizeof(int)) < 0) {
- TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
- close(clientfd);
- continue;
- }
- if (dp_ipc_read_custom_type(clientfd,
- &credential.gid, sizeof(int)) < 0) {
- TRACE_ERROR("[CRITICAL] not support SO_PEERCRED");
- close(clientfd);
- continue;
- }
-#endif
-
- 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);
- }
- 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++) {
- dp_client_group *group = privates->groups[i].group;
- if (group == NULL || group->cmd_socket < 0)
- continue;
- const int sock = group->cmd_socket;
- int time_of_job = (int)time(NULL);
- if (FD_ISSET(sock, &rset) > 0) {
- int index = -1;
- dp_command command;
-
- is_timeout = 0;
- command.cmd = DP_CMD_NONE;
- command.id = -1;
-
- if (dp_ipc_read_custom_type(sock, &command,
- sizeof(dp_command)) < 0) {
- TRACE_STRERROR("failed to read cmd");
- //Resource temporarily unavailable
- continue;
- }
-
- if (command.cmd == 0 || command.cmd >= DP_CMD_LAST_SECT) { // Client meet some Error.
- TRACE_SECURE_INFO("[Closed Peer] pkg:%s sock:%d slot:%d",
- group->pkgname, sock, i);
- // check all request included to this group
- FD_CLR(sock, &listen_fdset);
- __clear_group(privates, group);
- privates->groups[i].group = NULL;
- continue;
- }
-
- // Echo .client can check whether provider is busy
- if (command.cmd == DP_CMD_ECHO) {
- // provider can clear read buffer here
- TRACE_DEBUG("[ECHO] sock:%d", sock);
- if (dp_ipc_send_errorcode(sock,
- DP_ERROR_NONE) < 0) {
- // disconnect this group, bad client
- TRACE_ERROR("[ECHO] IO ERROR CLEAN sock:%d", sock);
- FD_CLR(sock, &listen_fdset);
- __clear_group(privates, group);
- privates->groups[i].group = NULL;
- }
- continue;
- }
-
- if (command.cmd == DP_CMD_CREATE) {
- TRACE_SECURE_INFO("[CREATE] id:%d sock:%d pid:%d gindex:%d pkg:%s",
- command.id, sock,
- group->credential.pid, i, group->pkgname);
- // search empty slot in privates->requests
- index =
- __get_empty_request_index(privates->requests);
- if (index < 0) {
- TRACE_ERROR("[CHECK] [DP_ERROR_QUEUE_FULL]");
- // Busy, No Space in slot
- dp_ipc_send_errorcode(sock, DP_ERROR_QUEUE_FULL);
- } else {
- errorcode = DP_ERROR_NONE;
- CLIENT_MUTEX_LOCK(&privates->requests[index].mutex);
- errorcode = dp_request_create(command.id, group,
- &privates->requests[index].request);
- dp_ipc_send_errorcode(sock, errorcode);
- if (errorcode == DP_ERROR_NONE) {
- dp_ipc_send_custom_type(sock,
- &privates->requests[index].request->id,
- sizeof(int));
- TRACE_DEBUG("[CREATE] GOOD id:%d slot:%d time:%d",
- privates->requests[index].request->id,
- index, ((int)time(NULL) - time_of_job));
- } else {
- TRACE_ERROR("[ERROR][%s]",
- dp_print_errorcode(errorcode));
- }
- CLIENT_MUTEX_UNLOCK(&privates->requests[index].mutex);
- }
- continue;
- }
-
- // below commands must need ID
- // check exception before searching slots.
- if (command.id < 0) {
- TRACE_ERROR("[CHECK PROTOCOL] ID should not be -1");
- dp_ipc_send_errorcode(sock,
- DP_ERROR_INVALID_PARAMETER);
- // disconnect this group, bad client
- FD_CLR(sock, &listen_fdset);
- __clear_group(privates, group);
- privates->groups[i].group = NULL;
- continue;
- }
-
- // search id in requests slot
- index = __get_same_request_index(privates->requests,
- command.id);
-
- dp_request_slots *request_slot = NULL;
- unsigned is_loaded = 0;
- errorcode = DP_ERROR_NONE;
-
- if (index >= 0) {
- CLIENT_MUTEX_LOCK(&privates->requests[index].mutex);
- if (privates->requests[index].request != NULL)
- is_loaded = 1;
- else
- CLIENT_MUTEX_UNLOCK(&privates->requests[index].mutex);
- }
-
- errorcode = DP_ERROR_UNKNOWN; // check matched command
-
- // divide on memory or from DB
- if (is_loaded == 1 && index >= 0) { // already locked
-
- TRACE_SECURE_INFO("[%s] id:%d sock:%d pid:%d gindex:%d slot:%d pkg:%s",
- __print_command(command.cmd), command.id, sock,
- group->credential.pid, i, index, group->pkgname);
-
- request_slot = &privates->requests[index];
-
- // auth by pkgname
- if (__cmp_string(group->pkgname, request_slot->request->packagename) < 0) {
- TRACE_SECURE_ERROR("[ERROR][%d] Auth [%s]/[%s]",
- command.id, group->pkgname, request_slot->request->packagename);
- TRACE_ERROR("[ERROR][%d][INVALID_PARAMETER]", command.id);
- dp_ipc_send_errorcode(sock, DP_ERROR_INVALID_PARAMETER);
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
- continue;
- }
-
- // if no group, update group.
- if (request_slot->request->group == NULL)
- request_slot->request->group = group;
-
- if (command.cmd == DP_CMD_START)
- errorcode = __do_dp_start_command(sock, command.id, privates, group, request_slot->request);
- else if (command.cmd > DP_CMD_SET_SECT && command.cmd < DP_CMD_LAST_SECT)
- errorcode = __dp_do_set_command(sock, &command, request_slot->request);
- else if (command.cmd > DP_CMD_GET_SECT && command.cmd < DP_CMD_SET_SECT)
- errorcode = __dp_do_get_command(sock, &command, request_slot->request);
- else if (command.cmd > DP_CMD_ACTION_SECT && command.cmd < DP_CMD_GET_SECT)
- errorcode = __dp_do_action_command(sock, &command, request_slot->request);
-
- CLIENT_MUTEX_UNLOCK(&request_slot->mutex);
-
- if (command.cmd == DP_CMD_START && errorcode == DP_ERROR_NONE) {
- //send signal to queue thread
- dp_thread_queue_manager_wake_up();
- }
- if (command.cmd == DP_CMD_FREE) {// enter after unlock
- dp_request_slot_free(request_slot);
- errorcode = DP_ERROR_NONE;
- }
-
- } else { // not found on the slots
-
- TRACE_SECURE_INFO("[%s] id:%d sock:%d pid:%d gindex:%d slot:no pkg:%s",
- __print_command(command.cmd), command.id, sock,
- group->credential.pid, i, group->pkgname);
-
- int check_id = dp_db_get_int_column(command.id,
- DP_DB_TABLE_LOG, DP_DB_COL_ID);
- if (check_id < 0 || check_id != command.id) {
- errorcode = DP_ERROR_ID_NOT_FOUND;
- TRACE_ERROR("[ERROR][%d][ID_NOT_FOUND]", command.id);
- dp_ipc_send_errorcode(sock, DP_ERROR_ID_NOT_FOUND);
- continue;
- }
- // auth by pkgname
- char *auth_pkgname = dp_db_get_text_column(command.id,
- DP_DB_TABLE_LOG, DP_DB_COL_PACKAGENAME);
- if (auth_pkgname == NULL) {
- TRACE_ERROR("[ERROR][%d][ID_NOT_FOUND]", command.id);
- dp_ipc_send_errorcode(sock, DP_ERROR_ID_NOT_FOUND);
- continue;
- }
- // auth by pkgname
- if (__cmp_string(group->pkgname, auth_pkgname) < 0) {
- TRACE_SECURE_ERROR("[ERROR][%d] Auth [%s]/[%s]",
- command.id, group->pkgname, auth_pkgname);
- TRACE_ERROR("[ERROR][%d][INVALID_PARAMETER]", command.id);
- dp_ipc_send_errorcode(sock, DP_ERROR_INVALID_PARAMETER);
- free(auth_pkgname);
- continue;
- }
- free(auth_pkgname);
-
- if (command.cmd == DP_CMD_START)
- errorcode = __do_dp_start_command(sock, command.id, privates, group, NULL);
- else if (command.cmd == DP_CMD_FREE)
- errorcode = DP_ERROR_NONE;
- else if (command.cmd > DP_CMD_SET_SECT && command.cmd < DP_CMD_LAST_SECT)
- errorcode = __dp_do_set_command(sock, &command, NULL);
- else if (command.cmd > DP_CMD_GET_SECT && command.cmd < DP_CMD_SET_SECT)
- errorcode = __dp_do_get_command(sock, &command, NULL);
- else if (command.cmd > DP_CMD_ACTION_SECT && command.cmd < DP_CMD_GET_SECT)
- errorcode = __dp_do_action_command(sock, &command, NULL);
-
- if (command.cmd == DP_CMD_START && errorcode == DP_ERROR_NONE) {
- //send signal to queue thread
- dp_thread_queue_manager_wake_up();
- }
- }
-
- if (errorcode == DP_ERROR_IO_ERROR) {
- TRACE_ERROR("[IO_ERROR][%d] slot:%d pid:%d",
- command.id, i,
- privates->groups[i].group->credential.pid);
- FD_CLR(sock, &listen_fdset);
- __clear_group(privates, group);
- privates->groups[i].group = NULL;
- continue;
- }
- if (errorcode == DP_ERROR_UNKNOWN) { // UnKnown Command
- TRACE_INFO("[UNKNOWN][%d] slot:%d pid:%d",
- command.id, i,
- privates->groups[i].group->credential.pid);
- dp_ipc_send_errorcode(sock, DP_ERROR_IO_ERROR);
- // disconnect this group, bad client
- FD_CLR(sock, &listen_fdset);
- __clear_group(privates, group);
- privates->groups[i].group = NULL;
- }
-
- } // FD_ISSET
- } // DP_MAX_GROUP
-
- // timeout
- if (is_timeout == 1) {
- int now_timeout = (int)time(NULL);
- TRACE_DEBUG("[TIMEOUT] prev %ld, now %ld, setted %ld sec",
- prev_timeout, now_timeout, flexible_timeout);
- if (prev_timeout == 0) {
- prev_timeout = now_timeout;
- } else if (now_timeout < prev_timeout ||
- (now_timeout - prev_timeout) > flexible_timeout) {
- TRACE_ERROR("[WARN] check system date prev[%ld]now[%ld]",
- prev_timeout, now_timeout);
- } else {
- if ((now_timeout - prev_timeout) <
- DP_CARE_CLIENT_MIN_INTERVAL) {
- // this is error.
- // terminate Process
- TRACE_STRERROR
- ("[CRITICAL] Sock exception prev[%ld]now[%ld][%ld]",
- prev_timeout, now_timeout, flexible_timeout);
- break;
- }
- }
-
- // get 48hour old request from log DB
- // clear old request
- dp_db_limit_rows(DP_LOG_DB_LIMIT_ROWS);
- int old_request_count = dp_db_get_count_by_limit_time();
- if (old_request_count > 0) {
- if (old_request_count > DP_LOG_DB_CLEAR_LIMIT_ONE_TIME)
- old_request_count = DP_LOG_DB_CLEAR_LIMIT_ONE_TIME;
-
- TRACE_DEBUG
- ("[CLEAR] [%d] old reqeusts", old_request_count);
-
- dp_request_slots *old_requests =
- dp_request_slots_new(old_request_count);
- if (old_requests != NULL) {
- int list_count = dp_db_get_list_by_limit_time
- (old_requests, old_request_count);
- for (i = 0; i < list_count; i++) {
- // search on slots by ID.
- int index = __get_same_request_index
- (privates->requests,
- old_requests[i].request->id);
- if (index >= 0) {
- CLIENT_MUTEX_LOCK(&privates->requests[index].mutex);
- dp_request *request =
- privates->requests[index].request;
- // if downloading..remain it.
- if (request == NULL || __is_downloading(request->state) == 0) {
- CLIENT_MUTEX_UNLOCK(&privates->requests[index].mutex);
- continue;
- }
- CLIENT_MUTEX_UNLOCK(&privates->requests[index].mutex);
- TRACE_DEBUG("[CLEAR][%d] 48 hour state:%s",
- request->id,
- dp_print_state(request->state));
- // unload from slots ( memory )
- dp_request_slot_free(&privates->requests[index]);
- }
- // remove tmp file regardless
- __dp_remove_tmpfile
- (old_requests[i].request->id,
- old_requests[i].request);
- // remove from DB
- dp_db_remove_all(old_requests[i].request->id);
- }
- dp_request_slots_free(old_requests, old_request_count);
- }
- }
-
- // clean slots
- int ready_requests = 0;
- for (i = 0; i < DP_MAX_REQUEST; i++) {
- CLIENT_MUTEX_LOCK(&privates->requests[i].mutex);
- if (privates->requests[i].request == NULL) {
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- continue;
- }
- dp_request *request = privates->requests[i].request;
-
- // If downloading is too slow ? how to deal this request?
- // can limit too slot download using starttime.(48 hours)
- if (__is_downloading(request->state) == 0) {
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- continue;
- }
-
- // paused & agent_id not exist.... unload from memory.
- if (request->state == DP_STATE_PAUSED &&
- dp_is_alive_download(request->agent_id) == 0) {
- TRACE_DEBUG("[FREE][%d] dead agent-id(%d) state:%s",
- request->id, request->agent_id,
- dp_print_state(request->state));
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- dp_request_slot_free(&privates->requests[i]);
- continue;
- }
-
- // client should call START command in 60 sec
- // unload from memory
- if (request->start_time <= 0 &&
- (now_timeout - request->create_time) >
- DP_CARE_CLIENT_MAX_INTERVAL) {
- int download_id = request->id;
- dp_state_type state = DP_STATE_FAILED;
- errorcode = DP_ERROR_RESPONSE_TIMEOUT;
- TRACE_DEBUG
- ("[FREE][%d] start in %d sec state:%s last:%ld",
- download_id, DP_CARE_CLIENT_MAX_INTERVAL,
- dp_print_state(request->state),
- request->start_time);
- if (request->group != NULL &&
- request->state_cb == 1 &&
- request->group->event_socket >= 0)
- dp_ipc_send_event(request->group->event_socket,
- download_id, state, errorcode, 0);
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- dp_request_slot_free(&privates->requests[i]);
- // no problem although updating is failed.
- if (dp_db_request_update_status(download_id, state, errorcode) < 0) {
- TRACE_ERROR("[fail][%d][sql] set state:%s error:%s",
- download_id, dp_print_state(state), dp_print_errorcode(errorcode));
- }
- continue;
- }
-
- // stopped by ipchanged. decide auto resume
- if (request->stop_time <= 0 &&
- request->state == DP_STATE_FAILED &&
- request->error == DP_ERROR_CONNECTION_FAILED) {
- if (dp_get_network_connection_instant_status() !=
- DP_NETWORK_TYPE_OFF &&
- request->ip_changed == 1) {
- TRACE_DEBUG("[RESUME][%d] will be queued",
- request->id);
- request->state = DP_STATE_QUEUED;
- request->error = DP_ERROR_NONE;
- ready_requests++;
- } else {
- dp_request_state_response(request);
- }
- }
-
- // client should call DESTROY command in MAX_INTERVAL sec after finished
- if (request->stop_time > 0 &&
- (now_timeout - request->stop_time) >
- DP_CARE_CLIENT_MAX_INTERVAL) {
- // check state again. stop_time means it's stopped
- if (__is_stopped(request->state) == 0) {
- TRACE_DEBUG
- ("[FREE][%d] by timeout state:%s stop:%ld",
- request->id,
- dp_print_state(request->state),
- request->stop_time);
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- dp_request_slot_free(&privates->requests[i]);
- continue;
- }
- }
-
- // check after clear
- if (request->state == DP_STATE_QUEUED)
- ready_requests++;
-
- CLIENT_MUTEX_UNLOCK(&privates->requests[i].mutex);
- }
-
- if (ready_requests > 0) {
- //send signal to queue thread will check queue.
- dp_thread_queue_manager_wake_up();
- } else {
- // if no request & timeout is bigger than 60 sec
- // terminate by self.
- if ((now_timeout - prev_timeout) >= flexible_timeout &&
- dp_get_request_count(privates->requests) <= 0) {
- TRACE_DEBUG("No Request. Terminate Daemon");
- break;
- }
- }
- prev_timeout = now_timeout;
- } else {
- prev_timeout = 0;
- }
- }
- TRACE_DEBUG("terminate main thread ...");
- dp_terminate(SIGTERM);
- pthread_exit(NULL);
- return 0;
-}
diff --git a/provider/download-provider-utils.c b/provider/download-provider-utils.c
new file mode 100644
index 0000000..a1fb736
--- /dev/null
+++ b/provider/download-provider-utils.c
@@ -0,0 +1,103 @@
+/*
+ * 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 <string.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <sys/time.h>
+#include <sys/statfs.h>
+#include <unistd.h>
+
+#include "download-provider-log.h"
+
+char *dp_strdup(char *src)
+{
+ char *dest = NULL;
+ size_t src_len = 0;
+
+ if (src == NULL) {
+ TRACE_ERROR("[CHECK PARAM]");
+ return NULL;
+ }
+
+ src_len = strlen(src);
+ if (src_len <= 0) {
+ TRACE_ERROR("[CHECK PARAM] len[%d]", src_len);
+ return NULL;
+ }
+
+ dest = (char *)calloc(src_len + 1, sizeof(char));
+ if (dest == NULL) {
+ TRACE_STRERROR("[CHECK] allocation");
+ return NULL;
+ }
+ memcpy(dest, src, src_len * sizeof(char));
+ dest[src_len] = '\0';
+
+ return dest;
+}
+
+int dp_is_file_exist(const char *file_path)
+{
+ struct stat file_state;
+ int stat_ret;
+
+ if (file_path == NULL) {
+ TRACE_ERROR("[NULL-CHECK] file path is NULL");
+ return -1;
+ }
+
+ stat_ret = stat(file_path, &file_state);
+
+ if (stat_ret == 0)
+ if (file_state.st_mode & S_IFREG)
+ return 0;
+
+ return -1;
+}
+
+long dp_get_file_modified_time(const char *file_path)
+{
+ struct stat file_state;
+ int stat_ret;
+
+ if (file_path == NULL) {
+ TRACE_ERROR("[NULL-CHECK] file path is NULL");
+ return -1;
+ }
+
+ stat_ret = stat(file_path, &file_state);
+ if (stat_ret == 0)
+ return file_state.st_mtime;
+ return -1;
+}
+
+int dp_remove_file(const char *file_path)
+{
+ if ((file_path != NULL && strlen(file_path) > 0) &&
+ dp_is_file_exist(file_path) == 0) {
+ if (unlink(file_path) != 0) {
+ TRACE_STRERROR("failed to remove file");
+ return -1;
+ }
+ return 0;
+ }
+ return -1;
+}
diff --git a/provider/include/download-provider-client-manager.h b/provider/include/download-provider-client-manager.h
new file mode 100644
index 0000000..0bb02ec
--- /dev/null
+++ b/provider/include/download-provider-client-manager.h
@@ -0,0 +1,35 @@
+/*
+ * 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_CLIENT_MANAGER_H
+#define DOWNLOAD_PROVIDER_CLIENT_MANAGER_H
+
+#include <download-provider.h>
+#include <download-provider-client.h>
+
+typedef struct {
+ dp_credential credential;
+ pthread_mutex_t mutex; // lock whenever access client variable
+ pthread_t thread;
+ char *pkgname;
+ dp_client_fmt client;
+} dp_client_slots_fmt;
+
+int dp_client_slot_free(dp_client_slots_fmt *slot);
+void dp_broadcast_signal();
+char *dp_db_get_client_smack_label(const char *pkgname);
+
+#endif
diff --git a/provider/include/download-provider-client.h b/provider/include/download-provider-client.h
new file mode 100644
index 0000000..6ce8d14
--- /dev/null
+++ b/provider/include/download-provider-client.h
@@ -0,0 +1,60 @@
+/*
+ * 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_CLIENT_H
+#define DOWNLOAD_PROVIDER_CLIENT_H
+
+#include <pthread.h>
+#include <download-provider.h>
+
+typedef struct {
+ int state; // downloading state, to prevent the crash, placed at the head of structure.
+ int id; // ID created in create request in requests thread.
+ int agent_id;
+ int error;
+ int network_type;
+ int access_time;
+ unsigned state_cb; // set : 1 unset : 0
+ unsigned progress_cb; // set : 1 unset : 0
+ unsigned startcount;
+ size_t progress_lasttime;
+ unsigned long long received_size; // progress
+ unsigned long long file_size;
+ dp_content_type content_type;
+ int noti_type;
+ int noti_priv_id;
+ void *next;
+} dp_request_fmt;
+
+typedef struct {
+ int channel; // ipc , if negative means dummy client
+ int notify; // event
+ int access_time;
+ void *dbhandle;
+ dp_request_fmt *requests;
+} dp_client_fmt;
+
+void *dp_client_request_thread(void *arg);
+char *dp_print_state(int state);
+char *dp_print_errorcode(int errorcode);
+char *dp_print_section(short section);
+char *dp_print_property(unsigned property);
+void dp_request_create(dp_client_fmt *client, dp_request_fmt *request);
+void dp_request_free(dp_request_fmt *request);
+int dp_request_destroy(dp_client_fmt *client, dp_ipc_fmt *ipc_info, dp_request_fmt *requestp);
+void dp_client_clear_requests(void *slotp);
+
+#endif
diff --git a/provider/include/download-provider-config.h b/provider/include/download-provider-config.h
index 96862ec..5ab6bce 100755
--- a/provider/include/download-provider-config.h
+++ b/provider/include/download-provider-config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
@@ -14,33 +14,26 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_CONFIG_H
-#define DOWNLOAD_PROVIDER2_CONFIG_H
+#ifndef DOWNLOAD_PROVIDER_CONFIG_H
+#define DOWNLOAD_PROVIDER_CONFIG_H
#include <download-provider.h>
-#include <download-provider-slots.h>
-#include <net_connection.h>
+// client-manager
+#define DP_MAX_CLIENTS 32 // the maximun number of slots
+#define DP_CARE_CLIENT_MANAGER_INTERVAL 120
+#define DP_CARE_CLIENT_REQUEST_INTERVAL 120
+#define DP_CARE_CLIENT_CLEAR_INTERVAL 200
-#define DP_LOCK_PID "/tmp/download-provider.lock"
-
-#define DP_CARE_CLIENT_MIN_INTERVAL 5
-#define DP_CARE_CLIENT_MAX_INTERVAL 120
-
-// check this value should be lower than DP_MAX_REQUEST
-#define DP_MAX_DOWNLOAD_AT_ONCE 50
+// database
+#define DP_CARE_CLIENT_INFO_PERIOD 48 // hour
+// each client thread
+#define DP_MAX_REQUEST MAX_DOWNLOAD_HANDLE
#define DP_LOG_DB_LIMIT_ROWS 1000
#define DP_LOG_DB_CLEAR_LIMIT_ONE_TIME 100
-// Share the structure for all threads
-typedef struct {
- int listen_fd;
- int is_connected_wifi_direct;
- connection_h connection;
- dp_network_type network_status;
- dp_group_slots *groups;
- dp_request_slots *requests;
-} dp_privates;
+// queue-manager
+#define DP_MAX_DOWNLOAD_AT_ONCE 50
#endif
diff --git a/provider/include/download-provider-db-defs.h b/provider/include/download-provider-db-defs.h
new file mode 100644
index 0000000..6fd1a46
--- /dev/null
+++ b/provider/include/download-provider-db-defs.h
@@ -0,0 +1,157 @@
+/*
+ * 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_PROVIDER_DB_DEFS_H
+#define DOWNLOAD_PROVIDER_DB_DEFS_H
+
+#define DP_DBFILE_CLIENTS ".download-provider-clients"
+
+// provider have a groups database file.
+#define DP_TABLE_CLIENTS "clients"
+// each client has a database file with below tables. file is named as pkgname.
+#define DP_TABLE_LOGGING "logging"
+#define DP_TABLE_REQUEST "request"
+#define DP_TABLE_DOWNLOAD "download"
+#define DP_TABLE_HEADERS "header"
+#define DP_TABLE_NOTIFICATION "notification"
+
+// common
+#define DP_DB_COL_ROW_ID "ROWID"
+#define DP_DB_COL_ID "id"
+#define DP_DB_COL_CREATE_TIME "createtime"
+#define DP_DB_COL_ACCESS_TIME "accesstime"
+
+// clients table
+#define DP_DB_COL_SMACK_LABEL "smack_label"
+#define DP_DB_COL_PACKAGE "package"
+#define DP_DB_COL_UID "uid"
+#define DP_DB_COL_GID "gid"
+#define DP_DB_COL_REQUEST_COUNT "requests"
+
+// logging table
+#define DP_DB_COL_STATE "state"
+#define DP_DB_COL_ERRORCODE "errorcode"
+#define DP_DB_COL_AUTO_DOWNLOAD "auto_download"
+#define DP_DB_COL_STARTCOUNT "startcount"
+
+// request table
+#define DP_DB_COL_URL "url"
+#define DP_DB_COL_DESTINATION "destination"
+#define DP_DB_COL_FILENAME "filename"
+#define DP_DB_COL_STATE_EVENT "state_event"
+#define DP_DB_COL_PROGRESS_EVENT "progress_event"
+#define DP_DB_COL_NETWORK_TYPE "network_type"
+#define DP_DB_COL_NETWORK_BONDING "network_bonding"
+#define DP_DB_COL_TEMP_FILE_PATH "temp_file_path"
+
+// download table
+#define DP_DB_COL_SAVED_PATH "saved_path"
+#define DP_DB_COL_TMP_SAVED_PATH "tmp_saved_path"
+#define DP_DB_COL_MIMETYPE "mimetype"
+#define DP_DB_COL_CONTENT_NAME "content_name"
+#define DP_DB_COL_ETAG "etag"
+#define DP_DB_COL_CONTENT_SIZE "content_size"
+#define DP_DB_COL_HTTP_STATUS "http_status"
+
+// notification table
+#define DP_DB_COL_NOTI_TYPE "type"
+#define DP_DB_COL_NOTI_SUBJECT "subject"
+#define DP_DB_COL_NOTI_DESCRIPTION "description"
+#define DP_DB_COL_NOTI_PRIV_ID "priv_id"
+#define DP_DB_COL_NOTI_RAW_ONGOING "raw_ongoing"
+#define DP_DB_COL_NOTI_RAW_COMPLETE "raw_completed"
+#define DP_DB_COL_NOTI_RAW_FAIL "raw_failed"
+
+// http headers table
+#define DP_DB_COL_HEADER_FIELD "header_field"
+#define DP_DB_COL_HEADER_DATA "header_data"
+
+
+
+// when a client is accepted, add
+// when disconnected with no request, clear
+// if exist, it's possible to be remain some requests
+#define DP_SCHEMA_CLIENTS "CREATE TABLE IF NOT EXISTS clients(\
+id INTEGER UNIQUE PRIMARY KEY,\
+package TEXT UNIQUE NOT NULL,\
+smack_label TEXT DEFAULT NULL,\
+uid INTEGER DEFAULT 0,\
+gid INTEGER DEFAULT 0,\
+requests INTEGER DEFAULT 0,\
+createtime DATE,\
+accesstime DATE\
+)"
+
+// limitation : 1000 rows, 48 hours standard by createtime
+#define DP_SCHEMA_LOGGING "CREATE TABLE IF NOT EXISTS logging(\
+id INTEGER UNIQUE PRIMARY KEY DESC NOT NULL,\
+state INTEGER DEFAULT 0,\
+errorcode INTEGER DEFAULT 0,\
+auto_download BOOLEAN DEFAULT 0,\
+startcount INTEGER DEFAULT 0,\
+createtime DATE,\
+accesstime DATE\
+)"
+
+#define DP_SCHEMA_REQUEST "CREATE TABLE IF NOT EXISTS request(\
+id INTEGER UNIQUE PRIMARY KEY,\
+state_event BOOLEAN DEFAULT 0,\
+progress_event BOOLEAN DEFAULT 0,\
+network_type TINYINT DEFAULT 3,\
+filename TEXT DEFAULT NULL,\
+destination TEXT DEFAULT NULL,\
+url TEXT DEFAULT NULL,\
+temp_file_path TEXT DEFAULT NULL,\
+network_bonding BOOLEAN DEFAULT 0,\
+FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE\
+)"
+
+#define DP_SCHEMA_DOWNLOAD "CREATE TABLE IF NOT EXISTS download(\
+id INTEGER UNIQUE PRIMARY KEY,\
+http_status INTEGER DEFAULT 0,\
+content_size UNSIGNED BIG INT DEFAULT 0,\
+mimetype VARCHAR(64) DEFAULT NULL,\
+content_name TEXT DEFAULT NULL,\
+saved_path TEXT DEFAULT NULL,\
+tmp_saved_path TEXT DEFAULT NULL,\
+etag TEXT DEFAULT NULL,\
+FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE\
+)"
+
+#define DP_SCHEMA_NOTIFICATION "CREATE TABLE IF NOT EXISTS notification(\
+id INTEGER UNIQUE PRIMARY KEY,\
+subject TEXT DEFAULT NULL,\
+description TEXT DEFAULT NULL,\
+type INTEGER DEFAULT 0,\
+priv_id INTEGER DEFAULT -1,\
+raw_completed BLOB DEFAULT NULL,\
+raw_failed BLOB DEFAULT NULL,\
+raw_ongoing BLOB DEFAULT NULL,\
+FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE\
+)"
+
+#define DP_SCHEMA_HEADER "CREATE TABLE IF NOT EXISTS header(\
+id INTEGER NOT NULL,\
+header_field TEXT DEFAULT NULL,\
+header_data TEXT DEFAULT NULL,\
+FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE\
+)"
+
+#define DP_SCHEMA_LOGGING_INDEX "CREATE UNIQUE INDEX IF NOT EXISTS requests_index ON logging (id, state, errorcode, createtime, accesstime)"
+
+
+
+#endif
diff --git a/provider/include/download-provider-db.h b/provider/include/download-provider-db.h
index 24a7d27..6f3a938 100755
--- a/provider/include/download-provider-db.h
+++ b/provider/include/download-provider-db.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
@@ -14,230 +14,42 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_DB_H
-#define DOWNLOAD_PROVIDER2_DB_H
+#ifndef DOWNLOAD_PROVIDER_DB_H
+#define DOWNLOAD_PROVIDER_DB_H
+
+int dp_db_check_connection(void *handle);
+int dp_db_open_client_manager(void **handle);
+int dp_db_open_client(void **handle, char *pkgname);
+int dp_db_open_client_v2(void **handle, char *pkgname);
+int dp_db_remove_database(char *pkgname, long now_time, long diff_time);
+int dp_db_get_ids(void *handle, const char *table, char *idcolumn, int *ids, const char *where, const int limit, char *ordercolumn, char *ordering, int *error);
+int dp_db_get_crashed_ids(void *handle, const char *table, int *ids, const int limit, int *error);
+void dp_db_close(void *handle);
+void dp_db_reset(void *stmt);
+void dp_db_finalize(void *stmt);
+int dp_db_get_errorcode(void *handle);
+
+int dp_db_check_duplicated_int(void *handle, const char *table, const char *column, const int value, int *error);
+int dp_db_check_duplicated_string(void *handle, const int id, const char *table, const char *column, const int is_like, const char *value, int *error);
+int dp_db_update_client_info(void *handle, const char *pkgname, const char *smack, const int uid, const int gid, int *error);
+int dp_db_get_client_property_string(void *handle, const char *pkgname, const char *column, unsigned char **value, unsigned *length, int *error);
+int dp_db_new_logging(void *handle, const int id, const int state, const int errorvalue, int *error);
+int dp_db_update_logging(void *handle, const int id, const int state, const int errorvalue, int *error);
+int dp_db_replace_property(void *handle, const int id, const char *table, const char *column, const void *value, const unsigned length, const unsigned valuetype, int *error);
+int dp_db_get_property_string(void *handle, const int id, const char *table, const char *column, unsigned char **value, unsigned *length, int *error);
+int dp_db_get_property_int(void *handle, const int id, const char *table, const char *column, void *value, int *error);
+int dp_db_unset_property_string(void *handle, const int id, const char *table, const char *column, int *error);
+int dp_db_delete(void *handle, const int id, const char *table, int *error);
+
+
+int dp_db_new_header(void *handle, const int id, const char *field, const char *value, int *error);
+int dp_db_update_header(void *handle, const int id, const char *field, const char *value, int *error);
+int dp_db_get_header_value(void *handle, const int id, const char *field, unsigned char **value, unsigned *length, int *error);
+int dp_db_cond_delete(void *handle, const int id, const char *table, const char *column, const void *value, const unsigned valuetype, int *error);
+int dp_db_get_cond_ids(void *handle, const char *table, const char *getcolumn, const char *column, const int value, int *ids, const int limit, int *error);
+int dp_db_get_cond_string(void *handle, const char *table, char *wherecolumn, const int wherevalue, const char *getcolumn, unsigned char **value, unsigned *length, int *error);
+int dp_db_limit_rows(void *handle, const char *table, int limit, int *error);
+int dp_db_limit_time(void *handle, const char *table, int hours, int *error);
+int dp_db_get_http_headers_list(void *handle, int id, char **headers, int *error);
-#include "download-provider-config.h"
-#include "download-provider-slots.h"
-
-/*
- * Memory ( sync with logging ) : id, state, errorcode, startcount, packagename
- * DB TABLES
- * logging : id, state, errorcode, startcount, createtime, accesstime, packagename
- * requestinfo : id, auto_download, network_type, filename, destination, url
- * downloadinfo : id, http_status, content_size, mimetype, contentname, saved_path, tmp_saved_path, etag
- * httpheaders : id, header_field, header_data
- * notification : id, noti_enable, extra_key, extra_data
- */
-/*
-CREATE TABLE IF NOT EXISTS groups
-(
- id INTEGER UNIQUE PRIMARY KEY,
- uid INTEGER DEFAULT 0,
- gid INTEGER DEFAULT 0,
- extra_int INTEGER DEFAULT 0,
- packagename TEXT DEFAULT NULL,
- smack_label TEXT DEFAULT NULL,
- extra TEXT DEFAULT NULL,
- date_first_connected DATE,
- date_last_connected DATE
-);
-
-CREATE TABLE logging
-(
- id INTEGER UNIQUE PRIMARY KEY,
- state INTEGER DEFAULT 0,
- errorcode INTEGER DEFAULT 0,
- startcount INTEGER DEFAULT 0,
- packagename TEXT DEFAULT NULL,
- createtime DATE,
- accesstime DATE
-);
-
-CREATE TABLE requestinfo
-(
- id INTEGER UNIQUE PRIMARY KEY,
- auto_download BOOLEAN DEFAULT 0,
- state_event BOOLEAN DEFAULT 0,
- progress_event BOOLEAN DEFAULT 0,
- network_type TINYINT DEFAULT 0,
- filename TEXT DEFAULT NULL,
- destination TEXT DEFAULT NULL,
- url TEXT DEFAULT NULL,
- FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE TABLE downloadinfo
-(
- id INTEGER UNIQUE PRIMARY KEY,
- http_status INTEGER DEFAULT 0,
- content_size UNSIGNED BIG INT DEFAULT 0,
- mimetype VARCHAR(64) DEFAULT NULL,
- content_name TEXT DEFAULT NULL,
- saved_path TEXT DEFAULT NULL,
- tmp_saved_path TEXT DEFAULT NULL,
- etag TEXT DEFAULT NULL,
- FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE TABLE httpheaders
-(
- id INTEGER NOT NULL,
- header_field TEXT DEFAULT NULL,
- header_data TEXT DEFAULT NULL,
- FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE TABLE notification
-(
- id INTEGER UNIQUE PRIMARY KEY,
- noti_enable BOOLEAN DEFAULT 0,
- extra_key TEXT DEFAULT NULL,
- extra_data TEXT DEFAULT NULL,
- FOREIGN KEY(id) REFERENCES logging(id) ON DELETE CASCADE
-);
-
-CREATE UNIQUE INDEX requests_index ON logging (id, state, errorcode, packagename, createtime, accesstime);
-*/
-
-#define DP_DB_TABLE_GROUPS "groups"
-#define DP_DB_TABLE_LOG "logging"
-#define DP_DB_TABLE_REQUEST_INFO "requestinfo"
-#define DP_DB_TABLE_DOWNLOAD_INFO "downloadinfo"
-#define DP_DB_TABLE_HTTP_HEADERS "httpheaders"
-#define DP_DB_TABLE_NOTIFICATION "notification"
-
-#define DP_DB_COL_ID "id"
-#define DP_DB_COL_STATE "state"
-#define DP_DB_COL_ERRORCODE "errorcode"
-#define DP_DB_COL_NETWORK_TYPE "network_type"
-#define DP_DB_COL_HTTP_STATUS "http_status"
-#define DP_DB_COL_AUTO_DOWNLOAD "auto_download"
-#define DP_DB_COL_STATE_EVENT "state_event"
-#define DP_DB_COL_PROGRESS_EVENT "progress_event"
-#define DP_DB_COL_CONTENT_SIZE "content_size"
-#define DP_DB_COL_CREATE_TIME "createtime"
-#define DP_DB_COL_ACCESS_TIME "accesstime"
-#define DP_DB_COL_STARTCOUNT "startcount"
-#define DP_DB_COL_PACKAGENAME "packagename"
-#define DP_DB_COL_DESTINATION "destination"
-#define DP_DB_COL_FILENAME "filename"
-#define DP_DB_COL_CONTENT_NAME "content_name"
-#define DP_DB_COL_MIMETYPE "mimetype"
-#define DP_DB_COL_ETAG "etag"
-#define DP_DB_COL_SAVED_PATH "saved_path"
-#define DP_DB_COL_TMP_SAVED_PATH "tmp_saved_path"
-#define DP_DB_COL_URL "url"
-#define DP_DB_COL_HEADER_FIELD "header_field"
-#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"
-#define DP_DB_COL_RAW_BUNDLE_ONGOING "raw_bundle_data_ongoing_state"
-#define DP_DB_COL_RAW_BUNDLE_COMPLETE "raw_bundle_data_complete_state"
-#define DP_DB_COL_RAW_BUNDLE_FAIL "raw_bundle_data_fail_state"
-#define DP_DB_COL_TITLE "title"
-#define DP_DB_COL_DESCRIPTION "description"
-#define DP_DB_COL_NOTI_TYPE "noti_type"
-
-#define DP_DB_GROUPS_COL_UID "uid"
-#define DP_DB_GROUPS_COL_GID "gid"
-#define DP_DB_GROUPS_COL_PKG "packagename"
-#define DP_DB_GROUPS_COL_SMACK_LABEL "smack_label"
-
-
-typedef enum {
- DP_DB_COL_TYPE_NONE = 0,
- DP_DB_COL_TYPE_INT = 10,
- DP_DB_COL_TYPE_INT64 = 20,
- 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();
-
-int dp_db_is_full_error();
-
-int dp_db_remove_all(int id);
-int dp_db_remove(int id, char *table);
-int dp_db_insert_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value);
-int dp_db_insert_blob_column(int id, char *table, char *column,
- void *value, unsigned length);
-int dp_db_set_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value);
-int dp_db_set_blob_column(int id, char *table, char *column,
- void *value, unsigned length);
-int dp_db_replace_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value);
-int dp_db_replace_blob_column(int id, char *table, char *column,
- void *value, unsigned length);
-char *dp_db_get_text_column(int id, char *table, char *column);
-void *dp_db_get_blob_column(int id, char *table, char *column, int *length);
-int dp_db_get_int_column(int id, char *table, char *column);
-long long dp_db_get_int64_column(int id, char *table, char *column);
-int dp_db_update_date(int id, char *table, char *column);
-
-// cond : id & cond
-int dp_db_cond_set_column(int id, char *table, char *column,
- db_column_data_type datatype, void *value,
- char *condcolumn, db_column_data_type condtype,
- void *condvalue);
-char *dp_db_cond_get_text_column(int id, char *table, char *column,
- char *condcolumn, db_column_data_type condtype,
- void *condvalue);
-int dp_db_cond_remove(int id, char *table,
- char *condcolumn, db_column_data_type condtype,
- void *condvalue);
-int dp_db_get_cond_rows_count(int id, char *table,
- char *condcolumn, db_column_data_type condtype,
- void *condvalue);
-
-char *dp_db_cond_get_text(char *table, char *column, char *condcolumn,
- db_column_data_type condtype, void *condvalue);
-int dp_db_cond_get_int(char *table, char *column, char *condcolumn,
- db_column_data_type condtype, void *condvalue);
-
-// Special API for http headers
-int dp_db_get_http_headers_list(int id, char **headers);
-
-// For auto-download in booting time
-int dp_db_crashed_list(dp_request_slots *requests, int limit);
-
-// For loading to memory when no in memory
-dp_request *dp_db_load_logging_request(int id);
-
-// For limitation by 48 hours & 1000 rows
-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_update_columns(int id, 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);
-
-int dp_db_request_new_logging(const int id, const int state, const char *pkgname);
-int dp_db_request_update_status(const int id, const int state, const int download_error);
-int dp_db_get_state(int id);
-int dp_db_request_new_logging(const int id,
- const int state, const char *pkgname);
#endif
diff --git a/provider/include/download-provider-defs.h b/provider/include/download-provider-defs.h
deleted file mode 100755
index af166fd..0000000
--- a/provider/include/download-provider-defs.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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
-
-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 = 10,
- 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_PERMISSION_DENIED = DP_ERROR_NONE + 20,
- 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;
-
-typedef enum {
- DP_NOTIFICATION_BUNDLE_TYPE_ONGOING = 0, // Ongoing, Failed
- DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE, // Completed
- DP_NOTIFICATION_BUNDLE_TYPE_FAILED // Failed
-} dp_notification_bundle_type;
-
-typedef enum {
- DP_NOTIFICATION_TYPE_NONE = 0, // Not register Noti.
- DP_NOTIFICATION_TYPE_COMPLETE_ONLY, // Success, Failed
- DP_NOTIFICATION_TYPE_ALL // Ongoing, Success, Failed
-} dp_notification_type;
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/provider/download-provider-pid.c b/provider/include/download-provider-ipc.h
index bd1a223..afddbe6 100755..100644
--- a/provider/download-provider-pid.c
+++ b/provider/include/download-provider-ipc.h
@@ -1,3 +1,4 @@
+
/*
* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
*
@@ -14,21 +15,22 @@
* limitations under the License.
*/
-#include <unistd.h>
-#include <fcntl.h>
-
-//////////////////////////////////////////////////////////////////////////
-/// @brief check whether daemon is alive
-/// @warning lockfd should be managed without close()
-/// @param the patch for locking the file
-int dp_lock_pid(char *path)
-{
- int lockfd = -1;
- if ((lockfd = open(path, O_WRONLY | O_CREAT, (0666 & (~000)))) < 0) {
- return -1;
- } else if (lockf(lockfd, F_TLOCK, 0) < 0) {
- close(lockfd);
- return -1;
- }
- return lockfd;
-}
+#ifndef DOWNLOAD_PROVIDER_IPC_H
+#define DOWNLOAD_PROVIDER_IPC_H
+
+#include "download-provider.h"
+
+int dp_ipc_check_stderr(int basecode);
+int dp_ipc_write(int sock, void *value, size_t type_size);
+ssize_t dp_ipc_read(int sock, void *value, size_t type_size,
+ const char *func);
+
+
+dp_ipc_fmt *dp_ipc_get_fmt(int sock);
+int dp_ipc_query(int sock, int download_id, short section,
+ unsigned property, int error, size_t size);
+
+int dp_ipc_socket_free(int sockfd);
+
+#endif
+
diff --git a/provider/include/download-provider-log.h b/provider/include/download-provider-log.h
index e828905..5b1b0cd 100755
--- a/provider/include/download-provider-log.h
+++ b/provider/include/download-provider-log.h
@@ -23,23 +23,28 @@
#ifdef LOG_TAG
#undef LOG_TAG
#endif
-#define LOG_TAG "DOWNLOAD_PROVIDER"
+#define LOG_TAG DOWNLOAD_PROVIDER_LOG_TAG
+#if defined(LOGD) && defined(TIZEN_DEBUG_ENABLE)
#define TRACE_DEBUG(format, ARG...) LOGD(format, ##ARG)
+#else
+#define TRACE_DEBUG(...) do { } while(0)
+#endif
#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)
+#define TRACE_WARN(format, ARG...) LOGW(format, ##ARG)
-#ifdef SECURE_LOGD
+#if defined(SECURE_LOGD) && defined(TIZEN_DEBUG_ENABLE)
#define TRACE_SECURE_DEBUG(format, ARG...) SECURE_LOGD(format, ##ARG)
#else
#define TRACE_SECURE_DEBUG(...) do { } while(0)
#endif
-#ifdef SECURE_LOGI
+#if defined(SECURE_LOGI) && defined(TIZEN_DEBUG_ENABLE)
#define TRACE_SECURE_INFO(format, ARG...) SECURE_LOGI(format, ##ARG)
#else
#define TRACE_SECURE_INFO(...) do { } while(0)
#endif
-#ifdef SECURE_LOGE
+#if defined(SECURE_LOGE) && defined(TIZEN_DEBUG_ENABLE)
#define TRACE_SECURE_ERROR(format, ARG...) SECURE_LOGE(format, ##ARG)
#else
#define TRACE_SECURE_ERROR(...) do { } while(0)
@@ -50,6 +55,7 @@
#define TRACE_ERROR(...) do { } while(0)
#define TRACE_STRERROR(...) do { } while(0)
#define TRACE_INFO(...) do { } while(0)
+#define TRACE_WARN(...) do { } while(0)
#define TRACE_SECURE_DEBUG(...) do { } while(0)
#define TRACE_SECURE_INFO(...) do { } while(0)
#define TRACE_SECURE_ERROR(...) do { } while(0)
diff --git a/provider/include/download-provider-network.h b/provider/include/download-provider-network.h
index 98a9b43..73fc12d 100755
--- a/provider/include/download-provider-network.h
+++ b/provider/include/download-provider-network.h
@@ -14,21 +14,21 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_NETWORK_H
-#define DOWNLOAD_PROVIDER2_NETWORK_H
+#ifndef DOWNLOAD_PROVIDER_NETWORK_H
+#define DOWNLOAD_PROVIDER_NETWORK_H
-#include <net_connection.h>
+#define DP_NETWORK_OFF -1
-#include "download-provider.h"
+typedef enum {
+ DP_NETWORK_DATA_NETWORK = 0,
+ DP_NETWORK_WIFI = 1,
+ DP_NETWORK_WIFI_DIRECT = 2,
+ DP_NETWORK_ALL = 3
+} dp_network_defs;
-dp_network_type dp_get_network_connection_status(connection_h connection, connection_type_e type);
-void dp_network_connection_type_changed_cb(connection_type_e type, void *data);
-int dp_network_connection_init(dp_privates *privates);
-void dp_network_connection_destroy(connection_h connection);
-dp_network_type dp_get_network_connection_instant_status();
-
-#ifdef SUPPORT_WIFI_DIRECT
-int dp_network_wifi_direct_is_connected();
-#endif
+int dp_network_connection_init();
+void dp_network_connection_destroy();
+int dp_network_get_status();
+int dp_network_is_wifi_direct();
#endif
diff --git a/provider/include/download-provider-notification-manager.h b/provider/include/download-provider-notification-manager.h
new file mode 100644
index 0000000..0ffa740
--- /dev/null
+++ b/provider/include/download-provider-notification-manager.h
@@ -0,0 +1,33 @@
+/*
+ * 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_NOTIFICATION_MANAGER_H
+#define DOWNLOAD_PROVIDER_NOTIFICATION_MANAGER_H
+
+typedef enum {
+ DP_NOTIFICATION = 0,
+ DP_NOTIFICATION_ONGOING,
+ DP_NOTIFICATION_ONGOING_PROGRESS,
+ DP_NOTIFICATION_ONGOING_UPDATE,
+} dp_noti_type;
+
+void dp_notification_manager_kill();
+void dp_notification_manager_wake_up();
+int dp_notification_manager_clear_notification(void *slot, void *request, const dp_noti_type type);
+//int dp_notification_manager_push_notification_ongoing(void *slot, void *request, const dp_noti_type type);
+int dp_notification_manager_push_notification(void *slot, void *request, const dp_noti_type type);
+
+#endif
diff --git a/provider/include/download-provider-notification.h b/provider/include/download-provider-notification.h
index 5a9f5b9..eb3f56e 100755
--- a/provider/include/download-provider-notification.h
+++ b/provider/include/download-provider-notification.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
@@ -14,14 +14,20 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_NOTIFICATION_H
-#define DOWNLOAD_PROVIDER2_NOTIFICATION_H
+#ifndef DOWNLOAD_PROVIDER_NOTIFICATION_H
+#define DOWNLOAD_PROVIDER_NOTIFICATION_H
-#include "download-provider-config.h"
-
-int dp_set_downloadinginfo_notification(int id, char *packagename);
-int dp_set_downloadedinfo_notification(int priv_id, int id, char *packagename, dp_state_type state);
-void dp_update_downloadinginfo_notification(int priv_id, double received_size, double file_size);
-void dp_clear_downloadinginfo_notification(void);
+#ifdef SUPPORT_NOTIFICATION
+void dp_notification_set_locale(void);
+void dp_notification_clear_locale(void);
+void dp_notification_clear_ongoings(void);
+int dp_notification_delete_ongoing(const int noti_priv_id);
+int dp_notification_delete(const int noti_priv_id);
+int dp_notification_ongoing_new(const char *pkgname, const char *subject, unsigned char *raws_buffer, const int raws_length);
+int dp_notification_ongoing_update(const int noti_priv_id, const double received_size, const double file_size, const char *subject);
+int dp_notification_new(void *dbhandle, const int download_id, const int state, int content_type, const char *pkgname);
+#else
+void dp_notification_clear_ongoings(void);
+#endif
#endif
diff --git a/provider/include/download-provider-notify.h b/provider/include/download-provider-notify.h
new file mode 100644
index 0000000..80c21d9
--- /dev/null
+++ b/provider/include/download-provider-notify.h
@@ -0,0 +1,24 @@
+/*
+ * 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_NOTIFY_H
+#define DOWNLOAD_PROVIDER_NOTIFY_H
+
+int dp_notify_init(pid_t pid);
+void dp_notify_deinit(pid_t pid);
+int dp_notify_feedback(int sock, void *slot, int id, int state, int errorcode, unsigned long long received_size);
+
+#endif
diff --git a/provider/include/download-provider-da-interface.h b/provider/include/download-provider-plugin-download-agent.h
index ab6e716..e3fb9c7 100755..100644
--- a/provider/include/download-provider-da-interface.h
+++ b/provider/include/download-provider-plugin-download-agent.h
@@ -14,16 +14,18 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_DA_INTERFACE_H
-#define DOWNLOAD_PROVIDER2_DA_INTERFACE_H
+#ifndef DOWNLOAD_PROVIDER_PLUGIN_DOWNLOAD_AGENT_H
+#define DOWNLOAD_PROVIDER_PLUGIN_DOWNLOAD_AGENT_H
int dp_is_file_exist(const char *file_path);
int dp_init_agent();
void dp_deinit_agent();
-dp_error_type dp_start_agent_download(dp_request_slots *request);
-dp_error_type dp_resume_agent_download(int req_id);
-dp_error_type dp_pause_agent_download(int req_id);
-dp_error_type dp_cancel_agent_download(int req_id);
+int dp_start_agent_download(void *slot, void *request);
+int dp_resume_agent_download(int req_id);
+int dp_pause_agent_download(int req_id);
+int dp_cancel_agent_download(int req_id);
int dp_is_alive_download(int req_id);
+int dp_cancel_agent_download_without_update(int req_id);
+int dp_pause_agent_download_without_update(int req_id);
#endif
diff --git a/provider/include/download-provider-pthread.h b/provider/include/download-provider-pthread.h
index 8c02c59..74e6036 100755
--- a/provider/include/download-provider-pthread.h
+++ b/provider/include/download-provider-pthread.h
@@ -14,81 +14,29 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_PTHREAD_H
-#define DOWNLOAD_PROVIDER2_PTHREAD_H
+#ifndef DOWNLOAD_PROVIDER_PTHREAD_H
+#define DOWNLOAD_PROVIDER_PTHREAD_H
#ifdef __cplusplus
extern "C" {
#endif
-#include <unistd.h>
#include <pthread.h>
-#include <errno.h>
// download-provider use default style mutex.
-
-#define CLIENT_MUTEX_LOCK(mutex_add) {\
- int ret = 0;\
- ret = pthread_mutex_lock(mutex_add);\
- if (EINVAL == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_lock FAIL with EINVAL.");\
- } else if (EDEADLK == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_lock FAIL with EDEADLK.");\
- } else if (ret != 0) {\
- TRACE_STRERROR("ERR:pthread_mutex_lock FAIL with %d.", ret);\
- } \
-}
-
-#define CLIENT_MUTEX_UNLOCK(mutex_add) {\
- int ret = 0;\
- ret = pthread_mutex_unlock(mutex_add);\
- if (EINVAL == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_unlock FAIL with EINVAL.");\
- } else if (EDEADLK == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_unlock FAIL with EDEADLK.");\
- } else if (ret != 0) {\
- TRACE_STRERROR("ERR:pthread_mutex_unlock FAIL with %d.", ret);\
- } \
-}
-
-#define CLIENT_MUTEX_DESTROY(mutex_add) { \
- int ret = 0; \
- ret = pthread_mutex_destroy(mutex_add); \
- if(EINVAL == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_destroy FAIL with EINVAL."); \
- } else if(ENOMEM == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_destroy FAIL with ENOMEM."); \
- } else if(EBUSY == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_destroy FAIL with EBUSY."); \
- if (pthread_mutex_unlock(mutex_add) == 0) \
- pthread_mutex_destroy(mutex_add); \
- } else if (ret != 0) {\
- TRACE_STRERROR("ERR:pthread_mutex_destroy FAIL with %d.", ret); \
- } \
-}
-
-#define CLIENT_MUTEX_INIT(mutex_add, attr) { \
- int ret = 0; \
- unsigned retry = 3; \
- while (retry > 0) { \
- ret = pthread_mutex_init(mutex_add, attr); \
- if (0 == ret) { \
- break; \
- } else if(EINVAL == ret) { \
- TRACE_STRERROR("ERR:pthread_mutex_init FAIL with EINVAL."); \
- } else if(ENOMEM == ret) { \
- TRACE_STRERROR("ERR:pthread_mutex_init FAIL with ENOMEM."); \
- usleep(1000); \
- } else if(EBUSY == ret) {\
- TRACE_STRERROR("ERR:pthread_mutex_destroy FAIL with EBUSY."); \
- if (pthread_mutex_unlock(mutex_add) == 0) \
- pthread_mutex_destroy(mutex_add); \
- } else if (ret != 0) { \
- TRACE_STRERROR("ERR:pthread_mutex_init FAIL with %d.", ret); \
- } \
- retry--; \
- } \
-}
+int dp_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
+void dp_mutex_lock(pthread_mutex_t *mutex, const char *func, int line);
+int dp_mutex_check_lock(pthread_mutex_t *mutex, const char *func, int line);
+int dp_mutex_trylock(pthread_mutex_t *mutex, const char *func, int line);
+int dp_mutex_timedlock(pthread_mutex_t *mutex, int sec, const char *func, int line);
+void dp_mutex_unlock(pthread_mutex_t *mutex, const char *func, int line);
+void dp_mutex_destroy(pthread_mutex_t *mutex);
+
+#define CLIENT_MUTEX_LOCK(mutex) dp_mutex_lock(mutex, __FUNCTION__, __LINE__)
+#define CLIENT_MUTEX_CHECKLOCK(mutex) dp_mutex_check_lock(mutex, __FUNCTION__, __LINE__)
+#define CLIENT_MUTEX_TRYLOCK(mutex) dp_mutex_trylock(mutex, __FUNCTION__, __LINE__)
+#define CLIENT_MUTEX_TIMEDLOCK(mutex, sec) dp_mutex_timedlock(mutex, sec, __FUNCTION__, __LINE__)
+#define CLIENT_MUTEX_UNLOCK(mutex) dp_mutex_unlock(mutex, __FUNCTION__, __LINE__)
#ifdef __cplusplus
}
diff --git a/provider/include/download-provider-queue-manager.h b/provider/include/download-provider-queue-manager.h
new file mode 100644
index 0000000..ba7e641
--- /dev/null
+++ b/provider/include/download-provider-queue-manager.h
@@ -0,0 +1,25 @@
+/*
+ * 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_QUEUE_MANAGER_H
+#define DOWNLOAD_PROVIDER_QUEUE_MANAGER_H
+
+void dp_queue_manager_kill();
+void dp_queue_manager_wake_up();
+int dp_queue_manager_push_queue(void *slot, void *request);
+void dp_queue_manager_clear_queue(void *request);
+
+#endif
diff --git a/provider/include/download-provider-queue.h b/provider/include/download-provider-queue.h
index 71bb62b..a8efcfa 100755
--- a/provider/include/download-provider-queue.h
+++ b/provider/include/download-provider-queue.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
@@ -14,10 +14,18 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_QUEUE_H
-#define DOWNLOAD_PROVIDER2_QUEUE_H
+#ifndef DOWNLOAD_PROVIDER_QUEUE_H
+#define DOWNLOAD_PROVIDER_QUEUE_H
-void dp_thread_queue_manager_wake_up();
-void *dp_thread_queue_manager(void *arg);
+typedef struct { // manage clients without mutex
+ void *slot; // client can not be NULL. it will exist in dummy
+ void *request;
+ void *next;
+} dp_queue_fmt;
+
+int dp_queue_push(dp_queue_fmt **queue, void *slot, void *request);
+int dp_queue_pop(dp_queue_fmt **queue, void **slot, void **request);
+void dp_queue_clear(dp_queue_fmt **queue, void *request);
+void dp_queue_clear_all(dp_queue_fmt **queue);
#endif
diff --git a/provider/include/download-provider-request.h b/provider/include/download-provider-request.h
deleted file mode 100755
index bc26953..0000000
--- a/provider/include/download-provider-request.h
+++ /dev/null
@@ -1,58 +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_REQUEST_H
-#define DOWNLOAD_PROVIDER2_REQUEST_H
-
-#include "download-provider.h"
-#include <bundle.h>
-
-// for Debugging
-char *dp_print_state(dp_state_type state);
-char *dp_print_errorcode(dp_error_type errorcode);
-
-int dp_is_smackfs_mounted(void);
-char *dp_strdup(char *src);
-
-dp_error_type dp_request_create(int id, dp_client_group *group, dp_request** empty_slot);
-dp_error_type dp_request_set_url(int id, dp_request *request, char *url);
-dp_error_type dp_request_set_destination(int id, dp_request *request, char *dest);
-dp_error_type dp_request_set_filename(int id, dp_request *request, char *filename);
-dp_error_type dp_request_set_title(int id, dp_request *request, char *filename);
-dp_error_type dp_request_set_bundle(int id, dp_request *request, int type, bundle_raw *b, unsigned length);
-dp_error_type dp_request_set_description(int id, dp_request *request, char *description);
-dp_error_type dp_request_set_noti_type(int id, dp_request *request, unsigned type);
-dp_error_type dp_request_set_notification(int id, dp_request *request, unsigned enable);
-dp_error_type dp_request_set_auto_download(int id, dp_request *request, unsigned enable);
-dp_error_type dp_request_set_state_event(int id, dp_request *request, unsigned enable);
-dp_error_type dp_request_set_progress_event(int id, dp_request *request, unsigned enable);
-dp_error_type dp_request_set_network_type(int id, dp_request *request, int type);
-char *dp_request_get_url(int id, dp_error_type *errorcode);
-char *dp_request_get_destination(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_filename(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_title(int id, dp_request *request, dp_error_type *errorcode);
-bundle_raw *dp_request_get_bundle(int id, dp_request *request, dp_error_type *errorcode, char* column, int* length);
-char *dp_request_get_description(int id, dp_request *request, dp_error_type *errorcode);
-int dp_request_get_noti_type(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_contentname(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_etag(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_savedpath(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_tmpsavedpath(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_mimetype(int id, dp_request *request, dp_error_type *errorcode);
-char *dp_request_get_pkg_name(int id, dp_request *request, dp_error_type *errorcode);
-dp_request *dp_request_load_from_log(int id, dp_error_type *errorcode);
-void dp_request_state_response(dp_request *request);
-#endif
diff --git a/provider/include/download-provider-slots.h b/provider/include/download-provider-slots.h
deleted file mode 100755
index 53859f8..0000000
--- a/provider/include/download-provider-slots.h
+++ /dev/null
@@ -1,90 +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_SLOTS_H
-#define DOWNLOAD_PROVIDER2_SLOTS_H
-
-#include "download-provider.h"
-#include "download-provider-pthread.h"
-
-// Backgound Daemon should has the limitation of resource.
-#define DP_MAX_GROUP 15
-#define DP_MAX_REQUEST 64
-
-typedef struct {
- pid_t pid;
- uid_t uid;
- gid_t gid;
-} dp_credential;
-
-typedef struct {
- // send command * get return value.
- int cmd_socket;
- // send event to client
- int event_socket;
- unsigned queued_count; // start ++, finish or failed -- ( queue & active )
- // fill by app-manager
- char *pkgname;
- dp_credential credential;
- char *smack_label;
-} dp_client_group;
-
-typedef struct {
- int id; // ID created in create request in requests thread.
- int agent_id;
- int create_time;
- int start_time; // setted by START command
- int pause_time; // setted by PAUSE command
- int stop_time; // time setted by finished_cb
- int noti_priv_id;
- unsigned state_cb; // set : 1 unset : 0
- unsigned progress_cb; // set : 1 unset : 0
- unsigned startcount;
- unsigned auto_notification;
- unsigned ip_changed;
- dp_state_type state; // downloading state
- dp_error_type error;
- dp_network_type network_type;
- size_t progress_lasttime;
- unsigned long long received_size; // progress
- unsigned long long file_size;
- char *packagename;
- dp_client_group *group; // indicate dp_client_group included this request
-} dp_request;
-
-typedef struct {
- dp_client_group *group;
-} dp_group_slots;
-
-typedef struct {
- pthread_mutex_t mutex;
- dp_request *request;
-} dp_request_slots;
-
-
-// functions
-dp_group_slots *dp_client_group_slots_new(int size);
-dp_request_slots *dp_request_slots_new(int size);
-int dp_client_group_free(dp_client_group *group);
-int dp_client_group_slots_free(dp_group_slots *slots, int size);
-dp_request *dp_request_new();
-void dp_request_init(dp_request *request);
-int dp_request_free(dp_request *request);
-int dp_request_slot_free(dp_request_slots *request_slot);
-int dp_request_slots_free(dp_request_slots *slots, int size);
-int dp_get_request_count(dp_request_slots *slots);
-
-#endif
diff --git a/provider/include/download-provider-smack.h b/provider/include/download-provider-smack.h
new file mode 100644
index 0000000..aa78d01
--- /dev/null
+++ b/provider/include/download-provider-smack.h
@@ -0,0 +1,33 @@
+/*
+ * 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_SMACK_H
+#define DOWNLOAD_PROVIDER_SMACK_H
+
+#ifdef SUPPORT_SECURITY_PRIVILEGE
+#include <security-server.h>
+#define SECURITY_PRIVILEGE_INTERNET "system::use_internet"
+#endif
+
+int dp_smack_is_mounted();
+int dp_smack_set_label(char *label, char *source, char *target);
+char *dp_smack_get_label_from_socket(int sock);
+int dp_smack_is_valid_dir(int uid, int gid, char *smack_label, char *dir);
+void dp_rebuild_dir(const char *dirpath, mode_t mode);
+int dp_is_valid_dir(const char *dirpath);
+
+
+#endif
diff --git a/provider/include/download-provider-socket.h b/provider/include/download-provider-socket.h
deleted file mode 100755
index b5a37cb..0000000
--- a/provider/include/download-provider-socket.h
+++ /dev/null
@@ -1,43 +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_SOCKET_H
-#define DOWNLOAD_PROVIDER2_SOCKET_H
-
-#include <bundle.h>
-#include "download-provider.h"
-#include "download-provider-slots.h"
-
-int dp_ipc_send_errorcode(int fd, dp_error_type errorcode);
-int dp_ipc_send_event(int fd, int id, dp_state_type state,
- dp_error_type errorcode, unsigned long long received_size);
-#if 0
-int dp_ipc_send_progressinfo(int fd, int id,
- unsigned long long received_size, unsigned long long file_size,
- unsigned int chunk_size);
-int dp_ipc_send_stateinfo(int fd, int id, dp_state_type state,
- dp_error_type errorcode);
-#endif
-char *dp_ipc_read_string(int fd);
-unsigned dp_ipc_read_bundle(int fd, int *type, bundle_raw **b);
-int dp_ipc_send_string(int fd, const char *str);
-int dp_ipc_send_bundle(int fd, bundle_raw *b, unsigned length);
-int dp_ipc_send_custom_type(int fd, void *value, size_t type_size);
-int dp_ipc_read_custom_type(int fd, void *value, size_t type_size);
-int dp_accept_socket_new();
-int dp_socket_free(int sockfd);
-
-#endif
diff --git a/agent/include/download-agent-utils-dl-id-history.h b/provider/include/download-provider-utils.h
index 3e32048..d965db4 100755..100644
--- a/agent/include/download-agent-utils-dl-id-history.h
+++ b/provider/include/download-provider-utils.h
@@ -14,22 +14,12 @@
* limitations under the License.
*/
-#ifndef _Download_Agent_Utils_Hash_Table_H
-#define _Download_Agent_Utils_Hash_Table_H
+#ifndef DOWNLOAD_PROVIDER_UTILS_H
+#define DOWNLOAD_PROVIDER_UTILS_H
-#include "download-agent-pthread.h"
+char *dp_strdup(char *src);
+int dp_is_file_exist(const char *file_path);
+long dp_get_file_modified_time(const char *file_path);
+int dp_remove_file(const char *file_path);
-typedef struct _dl_id_history_t dl_id_history_t;
-struct _dl_id_history_t {
- int starting_num;
- int cur_dl_id;
- pthread_mutex_t mutex;
-};
-
-da_result_t init_dl_id_history(dl_id_history_t *dl_id_history);
-da_result_t deinit_dl_id_history(dl_id_history_t *dl_id_history);
-
-int get_available_dl_id(dl_id_history_t *dl_id_history);
-
-
-#endif /* _Download_Agent_Utils_Hash_Table_H */
+#endif
diff --git a/provider/include/download-provider.h b/provider/include/download-provider.h
index a1f22f3..92e1fde 100755
--- a/provider/include/download-provider.h
+++ b/provider/include/download-provider.h
@@ -14,105 +14,176 @@
* limitations under the License.
*/
-#ifndef DOWNLOAD_PROVIDER2_H
-#define DOWNLOAD_PROVIDER2_H
-
-#include "download-provider-defs.h"
+#ifndef DOWNLOAD_PROVIDER_H
+#define DOWNLOAD_PROVIDER_H
#ifdef __cplusplus
extern "C" {
#endif
-#define DP_IPC "/tmp/download-provider"
+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_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 = 10,
+ 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_NETWORK_ERROR = DP_ERROR_NONE + 16,
+ 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_PERMISSION_DENIED = DP_ERROR_NONE + 20,
+ DP_ERROR_INVALID_NETWORK_TYPE = DP_ERROR_NONE + 21,
+ 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_DISK_BUSY = DP_ERROR_NONE + 70,
+ 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_NOTIFICATION_BUNDLE_TYPE_ONGOING = 0, // Ongoing, Failed
+ DP_NOTIFICATION_BUNDLE_TYPE_COMPLETE, // Completed
+ DP_NOTIFICATION_BUNDLE_TYPE_FAILED // Failed
+} dp_notification_bundle_type;
+
+typedef enum {
+ DP_NOTIFICATION_SERVICE_TYPE_ONGOING = 0, // Ongoing, Failed
+ DP_NOTIFICATION_SERVICE_TYPE_COMPLETE, // Completed
+ DP_NOTIFICATION_SERVICE_TYPE_FAILED // Failed
+} dp_notification_service_type;
-#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
-#define DP_DEFAULT_BUFFER_SIZE 1024
typedef enum {
- DP_CMD_NONE = 0,
- DP_CMD_ECHO,
- DP_CMD_CREATE,
- DP_CMD_START,
- DP_CMD_SET_COMMAND_SOCKET,
- DP_CMD_SET_EVENT_SOCKET,
- DP_CMD_FREE,
-
- DP_CMD_ACTION_SECT = 100,
- DP_CMD_PAUSE,
- DP_CMD_CANCEL,
- DP_CMD_DESTROY,
-
- DP_CMD_GET_SECT = 200,
- DP_CMD_GET_URL,
- DP_CMD_GET_DESTINATION,
- DP_CMD_GET_FILENAME,
- DP_CMD_GET_NOTIFICATION,
- DP_CMD_GET_STATE_CALLBACK,
- DP_CMD_GET_PROGRESS_CALLBACK,
- DP_CMD_GET_HTTP_HEADERS,
- DP_CMD_GET_AUTO_DOWNLOAD,
- DP_CMD_GET_NETWORK_TYPE,
- DP_CMD_GET_SAVED_PATH,
- DP_CMD_GET_TEMP_SAVED_PATH,
- DP_CMD_GET_MIME_TYPE,
- DP_CMD_GET_HTTP_HEADER,
- DP_CMD_GET_HTTP_HEADER_LIST,
- DP_CMD_GET_EXTRA_PARAM,
- DP_CMD_GET_RECEIVED_SIZE,
- DP_CMD_GET_TOTAL_FILE_SIZE,
- DP_CMD_GET_CONTENT_NAME,
- DP_CMD_GET_HTTP_STATUS,
- DP_CMD_GET_ETAG,
- DP_CMD_GET_STATE,
- DP_CMD_GET_ERROR,
- DP_CMD_GET_NOTIFICATION_BUNDLE,
- DP_CMD_GET_NOTIFICATION_TITLE,
- DP_CMD_GET_NOTIFICATION_DESCRIPTION,
- DP_CMD_GET_NOTIFICATION_TYPE,
-
- DP_CMD_SET_SECT = 300,
- DP_CMD_SET_URL,
- DP_CMD_SET_DESTINATION,
- DP_CMD_SET_FILENAME,
- DP_CMD_SET_NOTIFICATION,
- DP_CMD_SET_STATE_CALLBACK,
- DP_CMD_SET_PROGRESS_CALLBACK,
- DP_CMD_SET_AUTO_DOWNLOAD,
- DP_CMD_SET_NETWORK_TYPE,
- DP_CMD_SET_HTTP_HEADER,
- DP_CMD_SET_EXTRA_PARAM, // prevent build error
- DP_CMD_DEL_HTTP_HEADER,
- DP_CMD_ADD_EXTRA_PARAM,
- DP_CMD_REMOVE_EXTRA_PARAM,
- DP_CMD_SET_NOTIFICATION_BUNDLE,
- DP_CMD_SET_NOTIFICATION_TITLE,
- DP_CMD_SET_NOTIFICATION_DESCRIPTION,
- DP_CMD_SET_NOTIFICATION_TYPE,
-
- DP_CMD_LAST_SECT = 400
-} dp_command_type;
+ DP_NOTIFICATION_TYPE_NONE = 0, // Not register Noti.
+ DP_NOTIFICATION_TYPE_COMPLETE_ONLY, // Success, Failed
+ DP_NOTIFICATION_TYPE_ALL // Ongoing, Success, Failed
+} dp_notification_type;
+
+
+#ifndef IPC_SOCKET
+#define IPC_SOCKET "/opt/data/download-provider/download-provider.sock"
+#endif
+
+#define MAX_DOWNLOAD_HANDLE 32
+#define DP_MAX_STR_LEN 2048
+#define DP_DEFAULT_BUFFER_SIZE 1024
+
+// string to check invalid characters in path before using open() and fopen() API's
+#define DP_INVALID_PATH_STRING ";\\\":*?<>|()"
+
+
+#include <unistd.h>
typedef struct {
- unsigned int length;
- char *str;
-} dp_string;
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+} dp_credential;
+
+typedef enum {
+ DP_SEC_NONE = 0,
+ DP_SEC_INIT,
+ DP_SEC_DEINIT,
+ DP_SEC_CONTROL,
+ DP_SEC_GET,
+ DP_SEC_SET,
+ DP_SEC_UNSET
+} dp_ipc_section_defs;
+
+typedef enum {
+ DP_PROP_NONE = 0,
+ DP_PROP_CREATE,
+ DP_PROP_START,
+ DP_PROP_PAUSE,
+ DP_PROP_CANCEL,
+ DP_PROP_DESTROY,
+ DP_PROP_URL,
+ DP_PROP_DESTINATION,
+ DP_PROP_FILENAME,
+ DP_PROP_STATE_CALLBACK,
+ DP_PROP_PROGRESS_CALLBACK,
+ DP_PROP_AUTO_DOWNLOAD,
+ DP_PROP_NETWORK_TYPE,
+ DP_PROP_NETWORK_BONDING,
+ DP_PROP_SAVED_PATH,
+ DP_PROP_TEMP_SAVED_PATH,
+ DP_PROP_MIME_TYPE,
+ DP_PROP_RECEIVED_SIZE,
+ DP_PROP_TOTAL_FILE_SIZE,
+ DP_PROP_CONTENT_NAME,
+ DP_PROP_HTTP_STATUS,
+ DP_PROP_ETAG,
+ DP_PROP_STATE,
+ DP_PROP_ERROR,
+ DP_PROP_HTTP_HEADERS,
+ DP_PROP_HTTP_HEADER,
+ DP_PROP_NOTIFICATION_RAW,
+ DP_PROP_NOTIFICATION_SUBJECT,
+ DP_PROP_NOTIFICATION_DESCRIPTION,
+ DP_PROP_NOTIFICATION_TYPE
+} dp_ipc_property_defs;
+
+typedef enum {
+ DP_CONTENT_UNKNOWN = 0,
+ DP_CONTENT_IMAGE,
+ DP_CONTENT_VIDEO,
+ DP_CONTENT_MUSIC,
+ DP_CONTENT_PDF,
+ DP_CONTENT_WORD,
+ DP_CONTENT_PPT, // 5
+ DP_CONTENT_EXCEL,
+ DP_CONTENT_HTML,
+ DP_CONTENT_TEXT,
+ DP_CONTENT_DRM,
+ DP_CONTENT_SD_DRM, //10
+ DP_CONTENT_FLASH,
+ DP_CONTENT_TPK,
+ DP_CONTENT_VCAL, //13
+} dp_content_type;
+
typedef struct {
+ short section;
+ unsigned property;
int id;
- dp_state_type state;
- dp_error_type err;
- unsigned long long received_size;
-} dp_event_info;
+ int errorcode;
+ size_t size; // followed extra packet size
+} dp_ipc_fmt;
typedef struct {
- dp_command_type cmd;
int id;
-} dp_command;
-
- // Usage IPC : send(dp_command);send(dp_string);
+ int state;
+ int errorcode;
+ unsigned long long received_size;
+} dp_ipc_event_fmt;
#ifdef __cplusplus
}
diff --git a/res/images/Notification_download_animation.gif b/res/images/Notification_download_animation.gif
deleted file mode 100644
index 17dd2bb..0000000
--- a/res/images/Notification_download_animation.gif
+++ /dev/null
Binary files differ
diff --git a/res/images/Q02_Notification_download_complete.png b/res/images/Q02_Notification_download_complete.png
deleted file mode 100644
index 7a11f3e..0000000
--- a/res/images/Q02_Notification_download_complete.png
+++ /dev/null
Binary files differ
diff --git a/res/images/Q02_Notification_download_failed.png b/res/images/Q02_Notification_download_failed.png
deleted file mode 100644
index d59dd6f..0000000
--- a/res/images/Q02_Notification_download_failed.png
+++ /dev/null
Binary files differ
diff --git a/res/images/redwood/B03_processing_download_complete.png b/res/images/redwood/B03_processing_download_complete.png
new file mode 100644
index 0000000..109512e
--- /dev/null
+++ b/res/images/redwood/B03_processing_download_complete.png
Binary files differ
diff --git a/res/images/redwood/B03_processing_download_fail.png b/res/images/redwood/B03_processing_download_fail.png
new file mode 100644
index 0000000..be67ffe
--- /dev/null
+++ b/res/images/redwood/B03_processing_download_fail.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_broken.png b/res/images/redwood/U01_icon_broken.png
new file mode 100644
index 0000000..9020234
--- /dev/null
+++ b/res/images/redwood/U01_icon_broken.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_drm.png b/res/images/redwood/U01_icon_drm.png
new file mode 100644
index 0000000..06e682b
--- /dev/null
+++ b/res/images/redwood/U01_icon_drm.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_excel.png b/res/images/redwood/U01_icon_excel.png
new file mode 100644
index 0000000..6efd14a
--- /dev/null
+++ b/res/images/redwood/U01_icon_excel.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_html.png b/res/images/redwood/U01_icon_html.png
new file mode 100644
index 0000000..01260ba
--- /dev/null
+++ b/res/images/redwood/U01_icon_html.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_pdf.png b/res/images/redwood/U01_icon_pdf.png
new file mode 100644
index 0000000..3f8cda6
--- /dev/null
+++ b/res/images/redwood/U01_icon_pdf.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_ppt.png b/res/images/redwood/U01_icon_ppt.png
new file mode 100644
index 0000000..79302eb
--- /dev/null
+++ b/res/images/redwood/U01_icon_ppt.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_swf.png b/res/images/redwood/U01_icon_swf.png
new file mode 100644
index 0000000..39a49da
--- /dev/null
+++ b/res/images/redwood/U01_icon_swf.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_text.png b/res/images/redwood/U01_icon_text.png
new file mode 100644
index 0000000..5f8b3bd
--- /dev/null
+++ b/res/images/redwood/U01_icon_text.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_tpk.png b/res/images/redwood/U01_icon_tpk.png
new file mode 100644
index 0000000..796c788
--- /dev/null
+++ b/res/images/redwood/U01_icon_tpk.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_unkown.png b/res/images/redwood/U01_icon_unkown.png
new file mode 100644
index 0000000..25a2801
--- /dev/null
+++ b/res/images/redwood/U01_icon_unkown.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_vcs.png b/res/images/redwood/U01_icon_vcs.png
new file mode 100644
index 0000000..72dbf76
--- /dev/null
+++ b/res/images/redwood/U01_icon_vcs.png
Binary files differ
diff --git a/res/images/redwood/U01_icon_word.png b/res/images/redwood/U01_icon_word.png
new file mode 100644
index 0000000..a45acd7
--- /dev/null
+++ b/res/images/redwood/U01_icon_word.png
Binary files differ
diff --git a/res/images/redwood/U01_list_icon_image.png b/res/images/redwood/U01_list_icon_image.png
new file mode 100644
index 0000000..ebb2a3c
--- /dev/null
+++ b/res/images/redwood/U01_list_icon_image.png
Binary files differ
diff --git a/res/images/redwood/U01_list_icon_mp3.png b/res/images/redwood/U01_list_icon_mp3.png
new file mode 100644
index 0000000..c5176be
--- /dev/null
+++ b/res/images/redwood/U01_list_icon_mp3.png
Binary files differ
diff --git a/res/images/redwood/U01_list_icon_mp4.png b/res/images/redwood/U01_list_icon_mp4.png
new file mode 100644
index 0000000..2e3c87b
--- /dev/null
+++ b/res/images/redwood/U01_list_icon_mp4.png
Binary files differ
diff --git a/res/images/redwood/noti_download_complete.png b/res/images/redwood/noti_download_complete.png
new file mode 100644
index 0000000..6171bd8
--- /dev/null
+++ b/res/images/redwood/noti_download_complete.png
Binary files differ
diff --git a/res/images/redwood/noti_download_failed.png b/res/images/redwood/noti_download_failed.png
new file mode 100644
index 0000000..5eb122b
--- /dev/null
+++ b/res/images/redwood/noti_download_failed.png
Binary files differ
diff --git a/res/images/tizen2.3/B03_Processing_download_complete.png b/res/images/tizen2.3/B03_Processing_download_complete.png
new file mode 100644
index 0000000..8dfb542
--- /dev/null
+++ b/res/images/tizen2.3/B03_Processing_download_complete.png
Binary files differ
diff --git a/res/images/tizen2.3/B03_Processing_download_failed.png b/res/images/tizen2.3/B03_Processing_download_failed.png
new file mode 100644
index 0000000..11d34ab
--- /dev/null
+++ b/res/images/tizen2.3/B03_Processing_download_failed.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_date.png b/res/images/tizen2.3/download_manager_icon_date.png
new file mode 100644
index 0000000..f1ff0f8
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_date.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_drm.png b/res/images/tizen2.3/download_manager_icon_drm.png
new file mode 100644
index 0000000..7965232
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_drm.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_html.png b/res/images/tizen2.3/download_manager_icon_html.png
new file mode 100644
index 0000000..f4a2bfc
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_html.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_img.png b/res/images/tizen2.3/download_manager_icon_img.png
new file mode 100644
index 0000000..1c2f137
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_img.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_movie.png b/res/images/tizen2.3/download_manager_icon_movie.png
new file mode 100644
index 0000000..5902a67
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_movie.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_music.png b/res/images/tizen2.3/download_manager_icon_music.png
new file mode 100644
index 0000000..39f4c06
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_music.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_pdf.png b/res/images/tizen2.3/download_manager_icon_pdf.png
new file mode 100644
index 0000000..96b1a9a
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_pdf.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_ppt.png b/res/images/tizen2.3/download_manager_icon_ppt.png
new file mode 100644
index 0000000..29159cf
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_ppt.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_swf.png b/res/images/tizen2.3/download_manager_icon_swf.png
new file mode 100644
index 0000000..b6335d7
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_swf.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_text.png b/res/images/tizen2.3/download_manager_icon_text.png
new file mode 100644
index 0000000..4961fb5
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_text.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_tpk.png b/res/images/tizen2.3/download_manager_icon_tpk.png
new file mode 100644
index 0000000..58953be
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_tpk.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_unknown.png b/res/images/tizen2.3/download_manager_icon_unknown.png
new file mode 100644
index 0000000..9a367ec
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_unknown.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_word.png b/res/images/tizen2.3/download_manager_icon_word.png
new file mode 100644
index 0000000..3218b53
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_word.png
Binary files differ
diff --git a/res/images/tizen2.3/download_manager_icon_xls.png b/res/images/tizen2.3/download_manager_icon_xls.png
new file mode 100644
index 0000000..aeddf20
--- /dev/null
+++ b/res/images/tizen2.3/download_manager_icon_xls.png
Binary files differ
diff --git a/systemd/download-provider.service b/systemd/download-provider.service
index 30b14d7..4286283 100644
--- a/systemd/download-provider.service
+++ b/systemd/download-provider.service
@@ -5,6 +5,7 @@ After=check-mount.service
[Service]
Type=simple
ExecStart=/usr/bin/download-provider
+MemoryLimit=100M
[Install]
WantedBy=graphical.target
diff --git a/systemd/download-provider.socket b/systemd/download-provider.socket
index 944b28d..3130e34 100644
--- a/systemd/download-provider.socket
+++ b/systemd/download-provider.socket
@@ -1,6 +1,10 @@
[Socket]
-ListenStream=/tmp/download-provider
+ListenStream=/opt/data/download-provider/download-provider.sock
SocketMode=0777
+PassCredentials=yes
+Accept=false
+SmackLabelIPIn=download-provider
+SmackLabelIPOut=download-provider
[Install]
WantedBy=sockets.target