tizen 2.3 release tizen_2.3 submit/tizen_2.3/20150202.063733 tizen_2.3_release
authorjk7744.park <jk7744.park@samsung.com>
Sun, 1 Feb 2015 04:51:52 +0000 (13:51 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sun, 1 Feb 2015 04:51:52 +0000 (13:51 +0900)
315 files changed:
CMakeLists.txt
CREDITS [moved from AUTHORS with 51% similarity]
NOTICE [new file with mode: 0755]
packaging/README.api
packaging/crash-daemon.service [deleted file]
packaging/deviced.efl [new file with mode: 0644]
packaging/deviced.manifest
packaging/deviced.rule [deleted file]
packaging/deviced.service
packaging/deviced.spec
packaging/liblogd-db.manifest [deleted file]
packaging/liblogd.manifest [deleted file]
src/apps/apps.c
src/apps/apps.h
src/apps/cool-down.c [new file with mode: 0644]
src/apps/lowbat.c
src/apps/lowmem.c
src/auto-test/CMakeLists.txt
src/auto-test/activation/CMakeLists.txt [new file with mode: 0644]
src/auto-test/activation/dbus/CMakeLists.txt [new file with mode: 0644]
src/auto-test/activation/dbus/org.tizen.system.deviced-auto-test.service [new file with mode: 0644]
src/auto-test/activation/systemd/CMakeLists.txt [new file with mode: 0644]
src/auto-test/activation/systemd/deviced-auto-test.service [new file with mode: 0644]
src/auto-test/archive.c [new file with mode: 0644]
src/auto-test/board-info.c
src/auto-test/boot.c
src/auto-test/cool-down.c [new file with mode: 0644]
src/auto-test/cpu-info.c
src/auto-test/cradle.c
src/auto-test/earjack.c
src/auto-test/hdmi.c
src/auto-test/keyboard.c
src/auto-test/power-supply.c
src/auto-test/result.c [new file with mode: 0644]
src/auto-test/storage.c
src/auto-test/test.h
src/auto-test/time.c
src/auto-test/tvout.c
src/auto-test/udev.c
src/auto-test/usb.c
src/battery/battery.c [deleted file]
src/battery/config.h
src/battery/lowbat-handler.c
src/board/board-info.c
src/control/control.c
src/cool-down/cool-down-micro.c [new file with mode: 0644]
src/cool-down/cool-down.c [new file with mode: 0644]
src/core/buxton-helper.c [new file with mode: 0644]
src/core/buxton-helper.h [new file with mode: 0644]
src/core/common.c
src/core/common.h
src/core/core.c [deleted file]
src/core/device-change-handler.c
src/core/device-handler.h
src/core/device-notifier.c
src/core/device-notifier.h
src/core/device-plugin.c [deleted file]
src/core/devices.c
src/core/devices.h
src/core/edbus-handler.c
src/core/execute.c
src/core/list.h
src/core/log.c [moved from src/core/device-plugin.h with 60% similarity]
src/core/log.h
src/core/main.c
src/core/noti.c [deleted file]
src/core/power-supply.c
src/core/power-supply.h
src/core/predefine.c [deleted file]
src/core/queue.c [deleted file]
src/core/queue.h [deleted file]
src/core/sig-handler.c
src/core/sysnoti.c [deleted file]
src/cpu/cpu-handler.c
src/devicectl/CMakeLists.txt
src/devicectl/devicectl.c
src/devicectl/usb.c [new file with mode: 0644]
src/devicectl/usb.h [new file with mode: 0644]
src/deviced/dd-deviced.h
src/deviced/dd-haptic.h
src/deviced/dd-led.h
src/deviced/dd-mmc.h
src/deviced/haptic-module.h
src/display/alpm.c
src/display/auto-brightness.c
src/display/core.c
src/display/core.h
src/display/device-interface.c
src/display/device-interface.h
src/display/display-actor.c [new file with mode: 0644]
src/display/display-actor.h [new file with mode: 0644]
src/display/display-dbus.c
src/display/display-emul-mobile.conf [moved from src/display/display-exynos.conf with 89% similarity]
src/display/display-emul-wearable.conf [moved from src/display/display-emul.conf with 100% similarity]
src/display/display-mobile.conf [moved from src/display/display-msm.conf with 92% similarity]
src/display/display-ops.c
src/display/display-ops.h
src/display/display-wearable.conf [new file with mode: 0644]
src/display/enhance.c
src/display/hbm.c
src/display/hbm.h [new file with mode: 0644]
src/display/key-filter-micro.c
src/display/key-filter.c
src/display/poll.c
src/display/poll.h
src/display/setting.c
src/display/setting.h
src/display/smartstay.c
src/display/weaks.h
src/earjack/earjack.c [new file with mode: 0644]
src/fsck-msdos/CMakeLists.txt [new file with mode: 0644]
src/fsck-msdos/LICENSE [new file with mode: 0644]
src/fsck-msdos/boot.c [new file with mode: 0644]
src/fsck-msdos/check.c [new file with mode: 0644]
src/fsck-msdos/dir.c [new file with mode: 0644]
src/fsck-msdos/dosfs.h [new file with mode: 0644]
src/fsck-msdos/ext.h [new file with mode: 0644]
src/fsck-msdos/fat.c [new file with mode: 0644]
src/fsck-msdos/fsutil.h [new file with mode: 0644]
src/fsck-msdos/main.c [new file with mode: 0644]
src/gpio/buzzer.c [new file with mode: 0644]
src/gpio/gpio.c [new file with mode: 0644]
src/gpio/gpio.h [new file with mode: 0644]
src/gpio/hall.c [new file with mode: 0644]
src/gpio/sim.c [new file with mode: 0644]
src/hall/hall-handler.c
src/hall/hall-handler.h
src/haptic/HW_touch_30ms_sharp.ivt [deleted file]
src/haptic/README.standard [new file with mode: 0644]
src/haptic/external.c
src/haptic/haptic-micro.conf [new file with mode: 0644]
src/haptic/haptic-mobile.conf [new file with mode: 0644]
src/haptic/haptic.c
src/haptic/haptic.h
src/haptic/standard.c
src/hdmi-cec/cec.c [new file with mode: 0644]
src/hdmi-cec/cec.h [new file with mode: 0644]
src/hdmi-cec/libcec.c [new file with mode: 0644]
src/hdmi-cec/libcec.h [new file with mode: 0644]
src/icd/icd-integrity.c [new file with mode: 0644]
src/icd/icd-integrity.h [new file with mode: 0644]
src/icd/icd.c [new file with mode: 0644]
src/icd/sha2.c [new file with mode: 0644]
src/icd/sha2.h [new file with mode: 0644]
src/led/conf.c [new file with mode: 0644]
src/led/conf.h [moved from src/led/xml.h with 80% similarity]
src/led/led.conf [new file with mode: 0644]
src/led/rgb.c
src/led/xml.c [deleted file]
src/libdeviced/CMakeLists.txt
src/libdeviced/dbus.c [new file with mode: 0644]
src/libdeviced/deviced-noti.c
src/libdeviced/deviced-util.c
src/libdeviced/display.c
src/libdeviced/led.c
src/libdeviced/mmc.c
src/logd/CMakeLists.txt [new file with mode: 0644]
src/logd/src/CMakeLists.txt [new file with mode: 0644]
src/logd/src/battery/CMakeLists.txt [new file with mode: 0644]
src/logd/src/battery/calibration.c [new file with mode: 0644]
src/logd/src/battery/power-monitor.cpp [new file with mode: 0644]
src/logd/src/liblogd-db/CMakeLists.txt [new file with mode: 0644]
src/logd/src/liblogd-db/db.c [new file with mode: 0644]
src/logd/src/liblogd-db/db.h [new file with mode: 0644]
src/logd/src/liblogd-db/devices.c [new file with mode: 0644]
src/logd/src/liblogd-db/devices.h [new file with mode: 0644]
src/logd/src/liblogd-db/events.c [new file with mode: 0644]
src/logd/src/liblogd-db/events.h [new file with mode: 0644]
src/logd/src/liblogd-db/liblogd-db.pc.in [new file with mode: 0644]
src/logd/src/liblogd-db/logd-db.h [new file with mode: 0644]
src/logd/src/liblogd-db/padvisor.c [new file with mode: 0644]
src/logd/src/liblogd-db/padvisor.h [new file with mode: 0644]
src/logd/src/liblogd-db/proc-stat.c [new file with mode: 0644]
src/logd/src/liblogd-db/proc-stat.h [new file with mode: 0644]
src/logd/src/liblogd-db/tests/CMakeLists.txt [new file with mode: 0644]
src/logd/src/liblogd-db/tests/foreach-test.c [new file with mode: 0644]
src/logd/src/liblogd-db/tests/padvisor-test.c [new file with mode: 0644]
src/logd/src/liblogd/CMakeLists.txt [new file with mode: 0644]
src/logd/src/liblogd/liblogd.pc.in [new file with mode: 0644]
src/logd/src/liblogd/logd.c [new file with mode: 0644]
src/logd/src/liblogd/logd.h [new file with mode: 0644]
src/logd/src/liblogd/tests/CMakeLists.txt [new file with mode: 0644]
src/logd/src/liblogd/tests/store-event-test.c [new file with mode: 0644]
src/logd/src/shared/CMakeLists.txt [new file with mode: 0644]
src/logd/src/shared/logd-taskstats.h [new file with mode: 0644]
src/logd/src/shared/macro.h [new file with mode: 0644]
src/logd/src/shared/netlink.c [new file with mode: 0644]
src/logd/src/shared/netlink.h [new file with mode: 0644]
src/logd/src/shared/proc-events.c [new file with mode: 0644]
src/logd/src/shared/proc-events.h [new file with mode: 0644]
src/logd/src/shared/socket-helper.c [new file with mode: 0644]
src/logd/src/shared/socket-helper.h [new file with mode: 0644]
src/logd/src/shared/task-stats.c [new file with mode: 0644]
src/logd/src/shared/task-stats.h [new file with mode: 0644]
src/logd_grabber/battery.c [new file with mode: 0644]
src/logd_grabber/battery.h [new file with mode: 0644]
src/logd_grabber/config.c [new file with mode: 0644]
src/logd_grabber/config.h [new file with mode: 0644]
src/logd_grabber/data/logd-grabber-micro.conf.in [new file with mode: 0644]
src/logd_grabber/data/logd-grabber.conf.in [new file with mode: 0644]
src/logd_grabber/data/logd.sql [new file with mode: 0644]
src/logd_grabber/display.c [new file with mode: 0644]
src/logd_grabber/display.h [new file with mode: 0644]
src/logd_grabber/event.c [new file with mode: 0644]
src/logd_grabber/event.h [new file with mode: 0644]
src/logd_grabber/journal-reader.c [new file with mode: 0644]
src/logd_grabber/journal-reader.h [new file with mode: 0644]
src/logd_grabber/logd-grabber.c [new file with mode: 0644]
src/logd_grabber/logd-grabber.h [new file with mode: 0644]
src/logd_grabber/mmc.c [new file with mode: 0644]
src/logd_grabber/mmc.h [new file with mode: 0644]
src/logd_grabber/nlproc-stat.c [new file with mode: 0644]
src/logd_grabber/nlproc-stat.h [new file with mode: 0644]
src/logd_grabber/timer.c [new file with mode: 0644]
src/logd_grabber/timer.h [new file with mode: 0644]
src/mmc/exfat.c [new file with mode: 0644]
src/mmc/ext4.c
src/mmc/mmc-handler.c
src/mmc/mmc-handler.h
src/mmc/vfat.c
src/newfs-msdos/CMakeLists.txt [new file with mode: 0644]
src/newfs-msdos/LICENSE [new file with mode: 0644]
src/newfs-msdos/newfs-msdos.c [new file with mode: 0644]
src/ode/noti.c [new file with mode: 0644]
src/ode/noti.h [moved from src/core/emulator.h with 64% similarity]
src/ode/ode.c [new file with mode: 0755]
src/ode/ode.h [moved from src/core/core.h with 81% similarity]
src/pass/pass-core.c [new file with mode: 0644]
src/pass/pass-core.h [new file with mode: 0644]
src/pass/pass-gov-radiation.c [new file with mode: 0644]
src/pass/pass-gov-step.c [new file with mode: 0644]
src/pass/pass-gov.h [moved from src/core/sysnoti.h with 71% similarity]
src/pass/pass-hotplug.h [moved from src/core/data.h with 77% similarity]
src/pass/pass-micro.conf [new file with mode: 0644]
src/pass/pass-plugin.c [new file with mode: 0644]
src/pass/pass-plugin.h [new file with mode: 0644]
src/pass/pass-table.h [new file with mode: 0644]
src/pass/pass-target.h [new file with mode: 0644]
src/pass/pass-util.h [moved from src/core/noti.h with 76% similarity]
src/pass/pass.c [new file with mode: 0644]
src/pass/pass.conf [new file with mode: 0644]
src/pass/pass.h [new file with mode: 0644]
src/pmqos/pmqos.c
src/power/power-handler.c
src/power/power-handler.h
src/power/systemd-power.c
src/powersaver/powersaver-micro.c [new file with mode: 0644]
src/powersaver/powersaver.c
src/powersaver/powersaver.h [new file with mode: 0644]
src/proc/pmon-handler.c
src/proc/proc-handler.c
src/proc/proc-handler.h
src/shared/dbus.c
src/shared/dbus.h
src/sleep/sleep.c [new file with mode: 0644]
src/sleep/sleep.h [new file with mode: 0644]
src/storage/storage.c [moved from src/core/lowstorage.c with 72% similarity]
src/storage/storage.conf [new file with mode: 0644]
src/ta/ta-handler.c
src/telephony/telephony.c
src/testmode/testmode.c
src/ticker/ticker.h
src/tima/noti.c [new file with mode: 0644]
src/tima/noti.h [moved from src/core/predefine.h with 63% similarity]
src/tima/tima-lkm.c [new file with mode: 0644]
src/tima/tima-lkm.h [new file with mode: 0644]
src/tima/tima-pkm.c [new file with mode: 0644]
src/tima/tima-pkm.h [new file with mode: 0644]
src/tima/tima.c [new file with mode: 0644]
src/time/time-handler.c
src/touch/touch.c
src/touch/touchkey.c [new file with mode: 0644]
src/touch/touchscreen.c [new file with mode: 0644]
src/usb/configurations/conf-supported.xml [deleted file]
src/usb/configurations/usb-configurations.xml [deleted file]
src/usb/usb-client-config.c [new file with mode: 0755]
src/usb/usb-client-configuration-micro.conf [new file with mode: 0644]
src/usb/usb-client-configuration.conf [new file with mode: 0644]
src/usb/usb-client-control.c
src/usb/usb-client-dbus.c
src/usb/usb-client-event-sdk.c [new file with mode: 0755]
src/usb/usb-client-mode-micro.c [new file with mode: 0755]
src/usb/usb-client-mode.c [new file with mode: 0755]
src/usb/usb-client-operation.conf [new file with mode: 0644]
src/usb/usb-client-set.c
src/usb/usb-client-xml.c [deleted file]
src/usb/usb-client.c
src/usb/usb-client.h
src/usb/usb-handler.c [deleted file]
src/usb/usb-host-naming.c
src/usb/usb-host-storage-exfat.c [new file with mode: 0644]
src/usb/usb-host-storage-vfat.c
src/usb/usb-host.c
test/_export_env.sh [deleted file]
test/_export_target_env.sh [deleted file]
test/build.sh [deleted file]
test/clean.sh [deleted file]
test/config [deleted file]
test/execute.sh [deleted file]
test/push.sh [deleted file]
test/testcase/Makefile [deleted file]
test/testcase/tslist [deleted file]
test/testcase/utc_system_deviced_battery.c [deleted file]
test/testcase/utc_system_deviced_control.c [deleted file]
test/testcase/utc_system_deviced_deviced.c [deleted file]
test/testcase/utc_system_deviced_deviced_managed.c [deleted file]
test/testcase/utc_system_deviced_display.c [deleted file]
test/testcase/utc_system_deviced_haptic.c [deleted file]
test/testcase/utc_system_deviced_led.c [deleted file]
test/testcase/utc_system_deviced_mmc.c [deleted file]
test/testcase/utc_system_deviced_storage.c [deleted file]
test/tet_scen [deleted file]
test/tetbuild.cfg [deleted file]
test/tetclean.cfg [deleted file]
test/tetexec.cfg [deleted file]

index 3ce4663..0589042 100755 (executable)
@@ -76,37 +76,57 @@ SET(EXEC_PREFIX "${PREFIX}/bin")
 SET(LIBDIR "${PREFIX}/lib")
 SET(INCLUDEDIR "${PREFIX}/include/${PROJECT_NAME}")
 SET(DATADIR "${PREFIX}/share/${PROJECT_NAME}")
+SET(CONFDIR "/etc/${PROJECT_NAME}")
 SET(VERSION 0.1.0)
 
 SET(SRCS
        src/battery/config.c
        src/battery/lowbat-handler.c
-       src/battery/battery.c
+       src/core/buxton-helper.c
        src/core/device-notifier.c
        src/core/main.c
-       src/core/sysnoti.c
        src/core/launch.c
-       src/core/queue.c
-       src/core/core.c
        src/core/devices.c
        src/core/sig-handler.c
+       src/core/log.c
        src/core/device-change-handler.c
-       src/core/predefine.c
        src/core/common.c
        src/core/config-parser.c
        src/core/execute.c
        src/core/edbus-handler.c
        src/core/power-supply.c
-       src/core/lowstorage.c
+       src/earjack/earjack.c
        src/proc/cpu-info.c
        src/board/board-info.c
        src/proc/proc-handler.c
+       src/storage/storage.c
        src/ta/ta-handler.c
        src/time/time-handler.c
        src/ticker/ticker.c
        src/testmode/testmode.c
 )
 
+IF(USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       src/cool-down/cool-down-micro.c
+)
+ELSE()
+SET(SRCS ${SRCS}
+       src/cool-down/cool-down.c
+)
+ENDIF()
+
+SET(SRCS ${SRCS}
+       src/hdmi-cec/libcec.c
+       src/hdmi-cec/cec.c
+)
+SET(SRCS ${SRCS}
+       src/gpio/gpio.c
+       src/gpio/buzzer.c
+       src/gpio/hall.c
+       src/gpio/sim.c
+)
+
 IF(USE_SYSTEMD_SHUTDOWN)
 SET(SRCS ${SRCS}
        src/power/systemd-power.c
@@ -117,44 +137,34 @@ SET(SRCS ${SRCS}
 )
 ENDIF()
 
-IF(NOT USE_MICRO_DD)
-    IF(USE_EMULATOR)
-        ADD_DEFINITIONS("-DMOBILE_EMULATOR")
-        SET(SRCS ${SRCS}
-            src/core/noti.c
-        )
-    ENDIF(USE_EMULATOR)
-ENDIF(NOT USE_MICRO_DD)
+#device sleep
+SET(SRCS ${SRCS}
+       src/sleep/sleep.c
+)
 
 SET(SRCS ${SRCS}
        src/apps/apps.c
+       src/apps/cool-down.c
        src/apps/lowbat.c
        src/apps/poweroff.c
+       src/apps/lowmem.c
        src/pmqos/pmqos.c
        src/pmqos/pmqos-plugin.c
+       src/telephony/telephony.c
 )
 
 IF(NOT USE_MICRO_DD)
 SET(SRCS ${SRCS}
        src/battery/battery-time.c
        src/extcon/extcon.c
-       src/cpu/cpu-handler.c
        src/hall/hall-handler.c
-       src/proc/pmon-handler.c
        src/apps/launch.c
-       src/apps/lowmem.c
        src/apps/mmc.c
        src/apps/usb.c
        src/apps/usbotg.c
        src/apps/system.c
 )
 
-IF(NOT USE_SYSTEMD_SHUTDOWN)
-SET(SRCS ${SRCS}
-       src/telephony/telephony.c
-)
-ENDIF()
-
 SET(SRCS ${SRCS}
        src/mmc/mmc-handler.c
        src/mmc/uevent.c
@@ -172,8 +182,14 @@ SET(SRCS ${SRCS}
 ENDIF(USE_EMULATOR)
 
 SET(SRCS ${SRCS}
+       src/mmc/exfat.c
        src/mmc/vfat.c
 )
+
+SET(SRCS ${SRCS}
+       src/ode/ode.c
+       src/ode/noti.c
+)
 ENDIF(NOT USE_MICRO_DD)
 
 # display(pm)
@@ -186,6 +202,8 @@ SET(SRCS ${SRCS}
        src/display/poll.c
        src/display/setting.c
        src/display/display-ops.c
+       src/display/display-actor.c
+       src/display/auto-brightness.c
 )
 
 IF(USE_MICRO_DD)
@@ -198,7 +216,6 @@ SET(SRCS ${SRCS}
        src/display/brightness.c
        src/display/key-filter.c
        src/display/enhance.c
-       src/display/auto-brightness.c
        src/display/smartstay.c
 )
 ENDIF(USE_MICRO_DD)
@@ -208,18 +225,30 @@ SET(SRCS ${SRCS}
        src/led/torch.c
        src/led/pattern.c
        src/led/noti.c
-       src/led/xml.c
 )
 
+SET(SRCS ${SRCS}
+       src/pass/pass.c
+       src/pass/pass-core.c
+       src/pass/pass-gov-step.c
+       src/pass/pass-gov-radiation.c
+       src/pass/pass-plugin.c
+)
+
+SET(SRCS ${SRCS}
+       src/touch/touchscreen.c)
+
 IF(NOT USE_MICRO_DD)
 SET(SRCS ${SRCS}
        src/touch/touch.c
+       src/touch/touchkey.c
        src/touch/touch-controller.c
        src/touch/touch-plugin.c)
 
 
 SET(SRCS ${SRCS}
        src/led/rgb.c
+       src/led/conf.c
 )
 ENDIF(NOT USE_MICRO_DD)
 
@@ -229,19 +258,25 @@ SET(SRCS ${SRCS}
 
 SET(SRCS ${SRCS}
        src/haptic/haptic.c
-       src/haptic/standard.c
        src/haptic/external.c
+       src/haptic/standard.c
        src/haptic/emulator.c)
 
 # usb client
 SET(SRCS ${SRCS}
        src/usb/usb-common.c
        src/usb/usb-client.c
-       src/usb/usb-client-xml.c
+       src/usb/usb-client-event-sdk.c
+       src/usb/usb-client-config.c
        src/usb/usb-client-set.c
        src/usb/usb-client-control.c
        src/usb/usb-client-dbus.c
 )
+IF(USE_MICRO_DD)
+SET(SRCS ${SRCS} src/usb/usb-client-mode-micro.c)
+ELSE(USE_MICRO_DD)
+SET(SRCS ${SRCS} src/usb/usb-client-mode.c)
+ENDIF(USE_MICRO_DD)
 
 # usb host
 IF(NOT USE_MICRO_DD)
@@ -251,6 +286,7 @@ SET(SRCS ${SRCS}
        src/usb/usb-host-dbus.c
        src/usb/usb-host-storage.c
        src/usb/usb-host-storage-vfat.c
+       src/usb/usb-host-storage-exfat.c
        src/usb/usb-host-hid.c
        src/usb/usb-host-camera.c
        src/usb/usb-host-printer.c
@@ -259,51 +295,34 @@ SET(SRCS ${SRCS}
 ENDIF(NOT USE_MICRO_DD)
 
 # powersaver mode
-IF(USE_MICRO_DD)
 SET(SRCS ${SRCS}
        src/powersaver/powersaver.c
 )
+IF(USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       src/powersaver/powersaver-micro.c
+)
 ENDIF(USE_MICRO_DD)
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/deviced)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/logd/src/shared)
 
 SET(PKG_MODULES
+       libbuxton
        ecore
-       ecore-file
-       ecore-x
        edbus
        eina
        vconf
        dlog
        device-node
-       libxml-2.0
        capi-base-common
-)
-
-IF(NOT USE_MICRO_DD)
-SET(PKG_MODULES ${PKG_MODULES}
-       tapi
-       modem
+       journal
+       storage
        sensor
+       tapi
 )
-ENDIF()
-
-IF(USE_TRUSTZONE_QUALCOMM)
-SET(PKG_MODULES ${PKG_MODULES}
-       tee-qsee
-)
-ENDIF()
 
-IF(NOT USE_MICRO_DD)
-    IF(USE_EMULATOR)
-        SET(PKG_MODULES ${PKG_MODULES}
-            heynoti
-        )
-    ENDIF(USE_EMULATOR)
-ENDIF(NOT USE_MICRO_DD)
 INCLUDE(FindPkgConfig)
 pkg_check_modules(pkgs REQUIRED ${PKG_MODULES})
 
@@ -336,7 +355,7 @@ ENDIF()
 ADD_DEFINITIONS("-DDEBUG")
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-lm" "-ludev" "-ledbus" shared)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-lm" "-ludev" "-ledbus" "-lstorage" shared)
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
 
 INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/deviced/ DESTINATION include/${PROJECT_NAME}
@@ -347,40 +366,48 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/deviced/ DESTINATION include/$
 CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
 
-IF(USE_ARM AND NOT USE_MICRO_DD)
-       INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/haptic/HW_touch_30ms_sharp.ivt DESTINATION ${DATADIR})
-       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/led/led.xml DESTINATION ${DATADIR})
-ENDIF(USE_ARM AND NOT USE_MICRO_DD)
+IF(NOT USE_MICRO_DD)
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/led/led.conf DESTINATION /etc/deviced)
+ENDIF(NOT USE_MICRO_DD)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/dump_pm.sh DESTINATION /opt/etc/dump.d/module.d)
 
-IF(USE_TRUSTZONE_QUALCOMM)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-msm.conf DESTINATION /etc/deviced RENAME display.conf)
+IF(USE_EMULATOR AND USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-emul-wearable.conf DESTINATION /etc/deviced RENAME display.conf)
 ELSEIF(USE_EMULATOR)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-emul.conf DESTINATION /etc/deviced RENAME display.conf)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-emul-mobile.conf DESTINATION /etc/deviced RENAME display.conf)
+ELSEIF(USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-wearable.conf DESTINATION /etc/deviced RENAME display.conf)
 ELSE()
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-exynos.conf DESTINATION /etc/deviced RENAME display.conf)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-mobile.conf DESTINATION /etc/deviced RENAME display.conf)
 ENDIF()
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/mmc/mmc.conf DESTINATION /etc/deviced RENAME mmc.conf)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/pmqos/pmqos.conf DESTINATION /etc/deviced RENAME pmqos.conf)
 
-IF(USE_MICRO_DD)
-    IF(USE_EMULATOR)
-        INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/battery/battery-micro-emul.conf DESTINATION /etc/deviced RENAME battery.conf)
-    ELSE(USR_EMULATOR)
-        INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/battery/battery-micro.conf DESTINATION /etc/deviced RENAME battery.conf)
-    ENDIF(USE_EMULATOR)
-ELSE(USE_MICRO_DD)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/battery/battery.conf DESTINATION /etc/deviced RENAME battery.conf)
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/storage/storage.conf DESTINATION /etc/deviced RENAME storage.conf)
+
+IF(USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/pass/pass-micro.conf DESTINATION /etc/deviced RENAME pass.conf)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/haptic-micro.conf DESTINATION /etc/deviced RENAME haptic.conf)
+ELSE()
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/pass/pass.conf DESTINATION /etc/deviced RENAME pass.conf)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/haptic-mobile.conf DESTINATION /etc/deviced RENAME haptic.conf)
 ENDIF(USE_MICRO_DD)
 
 INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/scripts/deviced-pre.sh DESTINATION bin)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/${PROJECT_NAME}.rule DESTINATION /etc/smack/accesses2.d)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/configurations/conf-supported.xml      DESTINATION ${DATADIR}/usb-configurations)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/configurations/usb-configurations.xml  DESTINATION ${DATADIR}/usb-configurations)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/${PROJECT_NAME}.efl DESTINATION /etc/smack/accesses.d)
+IF(USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/usb-client-configuration-micro.conf  DESTINATION ${CONFDIR} RENAME usb-client-configuration.conf)
+ELSE(USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/usb-client-configuration.conf  DESTINATION ${CONFDIR})
+ENDIF(USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/usb-client-operation.conf  DESTINATION ${CONFDIR})
 
 IF(NOT USE_MICRO_DD)
        INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/movi_format.sh DESTINATION bin)
        INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mmc-smack-label DESTINATION bin)
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/fsck-msdos/LICENSE DESTINATION share/license RENAME fsck_msdosfs)
 ENDIF(NOT USE_MICRO_DD)
 
 # USB (data-router)
@@ -394,6 +421,10 @@ ENDIF()
 
 ADD_SUBDIRECTORY(src)
 ADD_SUBDIRECTORY(src/libdeviced)
+IF(NOT USE_MICRO_DD)
+       ADD_SUBDIRECTORY(src/fsck-msdos)
+       ADD_SUBDIRECTORY(src/newfs-msdos)
+ENDIF(NOT USE_MICRO_DD)
 ADD_SUBDIRECTORY(src/devicectl)
 ADD_SUBDIRECTORY(src/auto-test)
 
diff --git a/AUTHORS b/CREDITS
similarity index 51%
rename from AUTHORS
rename to CREDITS
index 63a6fc5..07a78ec 100644 (file)
--- a/AUTHORS
+++ b/CREDITS
@@ -1,3 +1,10 @@
+Thanks to the follow people for contributing to deviced by reporting
+bugs, providing fixes, providing information, providing resources or
+porting to new systems:
+
+The names are sorted alphabetically by last name.
+Names taken from sources and from version control system.
+
 ChanWoo Choi <cw00.choi@samsung.com>
 Byung-Soo Kim <bs1770.kim@samsung.com>
 Taeyoung Kim <ty317.kim@samsung.com>
@@ -6,3 +13,4 @@ Kyungmin Park <kyungmin.park@samsung.com>
 SeungHun Pi <sh.pi@samsung.com>
 Juho Son <juho80.son@samsung.com>
 Jiyoung Yun <jy910.yun@samsung.com>
+
diff --git a/NOTICE b/NOTICE
new file mode 100755 (executable)
index 0000000..dc3f273
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,4 @@
+Copyright (c) The Android Open Source Project
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.Apache-2.0 file for Apache License terms and conditions.
index 1f8c8ad..6174ae7 100644 (file)
@@ -5,6 +5,9 @@ DBus method_call smack authority
 
 * : all user can access the methods.
 
+Battery
+       org.tizen.system.deviced.Battery.GetPercent                 *
+       org.tizen.system.deviced.Battery.GetPercentRaw              *
 Display
        org.tizen.system.deviced.display.start                      root only
        org.tizen.system.deviced.display.stop                       root only
@@ -23,10 +26,10 @@ Display
        org.tizen.system.deviced.display.setautobrightnessmin       *
        org.tizen.system.deviced.display.setlcdtimeout              *
        org.tizen.system.deviced.display.LockScreenBgOn             *
-       org.tizen.system.deviced.display.GetDisplayCount            *
-       org.tizen.system.deviced.display.GetMaxBrightness           *
-       org.tizen.system.deviced.display.GetBrightness              *
-       org.tizen.system.deviced.display.SetBrightness              *
+       org.tizen.system.deviced.display.GetDisplayCount            deviced::display
+       org.tizen.system.deviced.display.GetMaxBrightness           deviced::display
+       org.tizen.system.deviced.display.GetBrightness              deviced::display
+       org.tizen.system.deviced.display.SetBrightness              deviced::display
        org.tizen.system.deviced.display.HoldBrightness             deviced::display
        org.tizen.system.deviced.display.ReleaseBrightness          *
        org.tizen.system.deviced.display.GetAclStatus               *
@@ -39,45 +42,46 @@ Display
        org.tizen.system.deviced.display.SetFrameRate               *
        org.tizen.system.deviced.display.GetColorBlind              *
        org.tizen.system.deviced.display.SetColorBlind              *
+Hall
+       org.tizen.system.deviced.hall.getstatus                     *
 Hapic
-       org.tizen.system.deviced.haptic.GetCount                    *
-       org.tizen.system.deviced.haptic.OpenDevice                  *
-       org.tizen.system.deviced.haptic.CloseDevice                 *
-       org.tizen.system.deviced.haptic.StopDevice                  *
-       org.tizen.system.deviced.haptic.VibrateMonotone             *
+       org.tizen.system.deviced.haptic.GetCount                    deviced::haptic
+       org.tizen.system.deviced.haptic.OpenDevice                  deviced::haptic
+       org.tizen.system.deviced.haptic.CloseDevice                 deviced::haptic
+       org.tizen.system.deviced.haptic.StopDevice                  deviced::haptic
+       org.tizen.system.deviced.haptic.VibrateMonotone             deviced::haptic
        org.tizen.system.deviced.haptic.VibrateBuffer               *
        org.tizen.system.deviced.haptic.GetState                    *
        org.tizen.system.deviced.haptic.GetDuration                 *
        org.tizen.system.deviced.haptic.CreateEffect                *
        org.tizen.system.deviced.haptic.SaveBinary                  *
+Led
+       org.tizen.system.deviced.Led.playcustom                     deviced::led
+       org.tizen.system.deviced.Led.stopcustom                     deviced::led
+       org.tizen.system.deviced.Led.GetBrightness                  deviced::led
+       org.tizen.system.deviced.Led.GetMaxBrightness               deviced::led
+       org.tizen.system.deviced.Led.SetBrightness                  deviced::led
+       org.tizen.system.deviced.Led.SetIrCommand                   deviced::led
+       org.tizen.system.deviced.Led.SetMode                        *
+       org.tizen.system.deviced.Led.PrintMode                      *
+Lowmem
+Mmc
+       org.tizen.system.deviced.Mmc.RequestMount                   *
+       org.tizen.system.deviced.Mmc.RequestUnmount                 *
+       org.tizen.system.deviced.Mmc.RequestFormat                  *
+Ode
 Pass
        org.tizen.system.deviced.pass.start                         root only
        org.tizen.system.deviced.pass.stop                          root only
        org.tizen.system.deviced.pass.bypass                        root only
-Hall
-       org.tizen.system.deviced.hall.getstatus                     *
 Power
        org.tizen.system.deviced.power.setresetkeydisable           deviced::power
        org.tizen.system.deviced.power.entersleep                   root only
        org.tizen.system.deviced.power.leavesleep                   root only
-       org.tizen.system.deviced.power.reboot                       root only
+       org.tizen.system.deviced.power.reboot                       deviced::power
        org.tizen.system.deviced.power.reboot-recovery              root only
-       org.tizen.system.deviced.power.pwroff-popup                 *
+       org.tizen.system.deviced.power.pwroff-popup                 deviced::power
        org.tizen.system.deviced.power.flightmode                   root only
-Storage
-       org.tizen.system.deviced.storage.getstorage                 *
-Ode
-Lowmem
-Led
-       org.tizen.system.deviced.Led.playcustom                     *
-       org.tizen.system.deviced.Led.stopcustom                     *
-       org.tizen.system.deviced.Led.GetBrightness                  *
-       org.tizen.system.deviced.Led.GetMaxBrightness               *
-       org.tizen.system.deviced.Led.SetBrightness                  *
-       org.tizen.system.deviced.Led.SetIrCommand                   *
-       org.tizen.system.deviced.Led.SetMode                        *
-       org.tizen.system.deviced.Led.PrintMode                      *
-
 Process
        org.tizen.system.deviced.Process.foregrd                    root only
        org.tizen.system.deviced.Process.backgrd                    root only
@@ -85,7 +89,8 @@ Process
        org.tizen.system.deviced.Process.inactive                   *
        org.tizen.system.deviced.Process.oomadj_set                 root only
        org.tizen.system.deviced.Process.process_group_set          root only
-
+Storage
+       org.tizen.system.deviced.storage.getstorage                 *
 SysNoti
        org.tizen.system.deviced.SysNoti.set_max_frequency          root only
        org.tizen.system.deviced.SysNoti.set_min_frequency          root only
@@ -101,8 +106,8 @@ SysNoti
        org.tizen.system.deviced.SysNoti.udev                       root only
        org.tizen.system.deviced.SysNoti.factorymode                root only
        org.tizen.system.deviced.SysNoti.control                    root only
-Mmc
-       org.tizen.system.deviced.Mmc.RequestMount                   *
-       org.tizen.system.deviced.Mmc.RequestUnmount                 *
-       org.tizen.system.deviced.Mmc.RequestFormat                  *
-
+Usbhost
+       org.tizen.system.deviced.Usbhost.StorageInfoAll             deviced::usbhost
+       org.tizen.system.deviced.Usbhost.StorageMount               deviced::usbhost
+       org.tizen.system.deviced.Usbhost.StorageUnmount             deviced::usbhost
+       org.tizen.system.deviced.Usbhost.StorageFormat              deviced::usbhost
diff --git a/packaging/crash-daemon.service b/packaging/crash-daemon.service
deleted file mode 100644 (file)
index 27e39bb..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-[Unit]
-Description=Start the crash daemon service
-After=dbus.socket
-
-[Service]
-ExecStart=/usr/bin/crash-daemon
-Restart=always
-RestartSec=0
-
-[Install]
-WantedBy=multi-user.target
diff --git a/packaging/deviced.efl b/packaging/deviced.efl
new file mode 100644 (file)
index 0000000..0720b83
--- /dev/null
@@ -0,0 +1,10 @@
+deviced sys-assert::core rwxat- ------
+deviced system::media rwxat- ------
+deviced system::media::root rwxat- ------
+deviced system::vconf rwxat- ------
+deviced system::vconf_setting rw---- ------
+deviced com.samsung.setting::private r----- ------
+deviced system::vconf_system rw---- ------
+deviced testmode::vconf r----- ------
+deviced starter::vconf r----- ------
+pulseaudio deviced rw---- ------
index 97710e4..d708947 100644 (file)
@@ -3,13 +3,24 @@
         <domain name="deviced"/>
         <provide>
             <label name="deviced::display" />
+            <label name="deviced::haptic" />
+            <label name="deviced::led" />
             <label name="deviced::power" />
+            <label name="deviced::usbhost" />
         </provide>
+        <request>
+            <smack request="deviced::display" type="rwx" />
+            <smack request="deviced::haptic" type="rwx" />
+            <smack request="deviced::led" type="rwx" />
+            <smack request="deviced::power" type="rwx" />
+            <smack request="deviced::usbhost" type="rwx" />
+        </request>
     </define>
     <assign>
         <filesystem path="/etc/init.d/device-daemon" label="_" exec_label="none" />
         <filesystem path="/etc/rc.d/init.d/device-daemon" label="_" exec_label="none" />
         <filesystem path="/opt/etc/dump.d/module.d/dump_pm.sh" label="_" exec_label="none" />
+        <filesystem path="/usr/share/dbus-1/services/org.tizen.system.deviced-auto-test.service" label="_" exec_label="none" />
         <dbus name="org.tizen.system.deviced" own="deviced" bus="system">
             <node name="/Org/Tizen/System/DeviceD/Display">
                 <interface name="org.tizen.system.deviced.display">
                     <method name="HoldBrightness">
                         <annotation name="com.tizen.smack" value="deviced::display" />
                     </method>
+                    <method name="GetDisplayCount">
+                        <annotation name="com.tizen.smack" value="deviced::display" />
+                    </method>
+                    <method name="GetMaxBrightness">
+                        <annotation name="com.tizen.smack" value="deviced::display" />
+                    </method>
+                    <method name="GetBrightness">
+                        <annotation name="com.tizen.smack" value="deviced::display" />
+                    </method>
+                    <method name="SetBrightness">
+                        <annotation name="com.tizen.smack" value="deviced::display" />
+                    </method>
+                </interface>
+            </node>
+            <node name="/Org/Tizen/System/DeviceD/Haptic">
+                <interface name="org.tizen.system.deviced.haptic">
+                    <method name="GetCount">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="OpenDevice">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="CloseDevice">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="StopDevice">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="VibrateMonotone">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="VibrateBuffer">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="GetState">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="CreateEffect">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                    <method name="GetDuration">
+                        <annotation name="com.tizen.smack" value="deviced::haptic" />
+                    </method>
+                </interface>
+            </node>
+            <node name="/Org/Tizen/System/DeviceD/Led">
+                <interface name="org.tizen.system.deviced.Led">
+                    <method name="GetMaxBrightness">
+                        <annotation name="com.tizen.smack" value="deviced::led" />
+                    </method>
+                    <method name="GetBrightness">
+                        <annotation name="com.tizen.smack" value="deviced::led" />
+                    </method>
+                    <method name="SetBrightness">
+                        <annotation name="com.tizen.smack" value="deviced::led" />
+                    </method>
+                    <method name="playcustom">
+                        <annotation name="com.tizen.smack" value="deviced::led" />
+                    </method>
+                    <method name="stopcustom">
+                        <annotation name="com.tizen.smack" value="deviced::led" />
+                    </method>
+                    <method name="SetIrCommand">
+                        <annotation name="com.tizen.smack" value="deviced::led" />
+                    </method>
                 </interface>
             </node>
             <node name="/Org/Tizen/System/DeviceD/Power">
                     <method name="setresetkeydisable">
                         <annotation name="com.tizen.smack" value="deviced::power" />
                     </method>
+                    <method name="pwroff-popup">
+                        <annotation name="com.tizen.smack" value="deviced::power" />
+                    </method>
+                    <method name="reboot">
+                        <annotation name="com.tizen.smack" value="deviced::power" />
+                    </method>
+                </interface>
+            </node>
+            <node name="/Org/Tizen/System/DeviceD/Usbhost">
+                <interface name="org.tizen.system.deviced.Usbhost">
+                    <method name="StorageInfoAll">
+                        <annotation name="com.tizen.smack" value="deviced::usbhost" />
+                    </method>
+                    <method name="StorageMount">
+                        <annotation name="com.tizen.smack" value="deviced::usbhost" />
+                    </method>
+                    <method name="StorageUnmount">
+                        <annotation name="com.tizen.smack" value="deviced::usbhost" />
+                    </method>
+                    <method name="StorageFormat">
+                        <annotation name="com.tizen.smack" value="deviced::usbhost" />
+                    </method>
                 </interface>
             </node>
         </dbus>
     </assign>
-    <request>
-        <domain name="deviced"/>
-    </request>
 </manifest>
diff --git a/packaging/deviced.rule b/packaging/deviced.rule
deleted file mode 100644 (file)
index bce8fd6..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# subject rule
-deviced sys-assert::core rwxat
-deviced system::media rwxat
-deviced system::vconf rwxat
-deviced system::vconf_setting rw
-deviced com.samsung.setting::private r
-deviced system::vconf_system rw
-deviced testmode::vconf r
-deviced starter::vconf r
-# object rule
-pulseaudio deviced rw
index 9f0661a..ba9cad9 100644 (file)
@@ -1,6 +1,6 @@
 [Unit]
 Description=System device daemon
-After=deviced-pre.service pulseaudio.service sound-init.service
+After=deviced-pre.service immvibed.service
 Requires=deviced-pre.service
 
 [Service]
index 0739bbc..71f816c 100644 (file)
@@ -13,30 +13,35 @@ Source5:    devicectl-start@.service
 Source6:    devicectl-stop@.service
 Source1001: deviced.manifest
 Source1002: libdeviced.manifest
-Source1003: liblogd-db.manifest
-Source1004: liblogd.manifest
 
 BuildRequires:  cmake
 BuildRequires:  libattr-devel
 BuildRequires:  gettext-devel
 BuildRequires:  pkgconfig(ecore)
 BuildRequires:  pkgconfig(vconf)
-%ifnarch %{arm}
-BuildRequires:  pkgconfig(heynoti)
-%endif
 BuildRequires:  pkgconfig(dlog)
-BuildRequires:  pkgconfig(usbutils)
 BuildRequires:  pkgconfig(device-node)
 BuildRequires:  pkgconfig(edbus)
-BuildRequires:  pkgconfig(libxml-2.0)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  systemd-devel
 BuildRequires: pkgconfig(systemd)
 BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(libbuxton)
+BuildRequires: pkgconfig(storage)
+BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(journal)
+BuildRequires: pkgconfig(libarchive)
+BuildRequires: pkgconfig(sensor)
+BuildRequires: pkgconfig(tapi)
+
 Requires(preun): /usr/bin/systemctl
 Requires(post): sys-assert
 Requires(post): /usr/bin/systemctl
 Requires(post): /usr/bin/vconftool
+Requires(post): pulseaudio
+Requires(post): buxton
+Requires(post): pkgconfig(journal)
+Requires(post): pkgconfig(libarchive)
 Requires(postun): /usr/bin/systemctl
 
 %description
@@ -65,56 +70,15 @@ Requires:   libdeviced = %{version}-%{release}
 %description -n libdeviced-devel
 Deviced library for device control (devel)
 
-%package -n logd
-Summary: logd utils
-Group: Framework/system
-
-%description -n logd
-Utils for for logd
-
-%package -n liblogd
-Summary:       Activity logging API(Development)
-Group:         Development/Libraries
-
-%description -n liblogd
-logd library.
-
-%package -n liblogd-devel
-Summary:       Activity logging (Development)
-Summary:    SLP power manager client (devel)
-Group:         Development/Libraries
-
-%description -n liblogd-devel
-logd API library.
-
-%package -n liblogd-db
-Summary:       API to get activity data (Development)
-Group:         Development/Libraries
-
-%description -n liblogd-db
-logd-db library.
-
-%package -n liblogd-db-devel
-Summary:       API to get activity data (Development)
-Group:         Development/Libraries
-
-%description -n liblogd-db-devel
-logd-db API library.
-
 %prep
 %setup -q
+%if "%{?tizen_profile_name}" == "wearable"
 export CFLAGS+=" -DMICRO_DD"
-
-%if 0%{?sec_build_binary_debug_enable}
-export CFLAGS+=" -DTIZEN_DEBUG_ENABLE"
 %endif
 
-%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS+=" -DTIZEN_DEBUG_ENABLE"
 export CFLAGS+=" -DTIZEN_ENGINEER_MODE"
 %define ENGINEER_MODE 1
-%else
-%define ENGINEER_MODE 0
-%endif
 
 %ifarch %{arm}
 %define ARCH arm
@@ -126,8 +90,6 @@ cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCH=%{ARCH}
 %build
 cp %{SOURCE1001} .
 cp %{SOURCE1002} .
-cp %{SOURCE1003} .
-cp %{SOURCE1004} .
 
 make
 
@@ -158,6 +120,36 @@ cp LICENSE.Apache-2.0 %{buildroot}/usr/share/license/%{name}
 cp LICENSE.Apache-2.0 %{buildroot}/usr/share/license/libdeviced
 
 %post
+%if "%{?tizen_profile_name}" == "wearable"
+%else
+#memory type vconf key init
+vconftool set -t int memory/sysman/mmc 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/earjack_key 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/cradle_status 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/added_usb_storage 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/removed_usb_storage 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/earjack -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/sliding_keyboard -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/mmc_mount -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/mmc_unmount -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/mmc_format -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/mmc_format_progress 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/hdmi 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/mmc_err_status 0 -i -s system::vconf_system
+vconftool set -t int memory/private/sysman/enhance_pid 0 -i -s system::vconf_system
+vconftool set -t int memory/private/sysman/siop_disable 0 -i -s system::vconf_system
+vconftool set -t string memory/private/sysman/added_storage_uevent "" -i -s system::vconf_system
+vconftool set -t string memory/private/sysman/removed_storage_uevent "" -u 5000 -i -s system::vconf_system
+vconftool set -t string memory/private/sysman/siop_level_uevent "" -i -s system::vconf_system
+#db type vconf key init
+vconftool set -t int db/sysman/mmc_dev_changed 0 -i -s system::vconf_system
+vconftool set -t int db/private/sysman/enhance_mode 0 -i -s system::vconf_system
+vconftool set -t int db/private/sysman/enhance_scenario 0 -i -s system::vconf_system
+vconftool set -t int db/private/sysman/enhance_tone 0 -i -s system::vconf_system
+vconftool set -t int db/private/sysman/enhance_outdoor 0 -i -s system::vconf_system
+vconftool set -t string db/private/sysman/mmc_device_id "" -i -s system::vconf_system
+%endif
+
 #memory type vconf key init
 vconftool set -t int memory/sysman/usbhost_status -1 -i -s system::vconf_system
 vconftool set -t int memory/sysman/charger_status 0 -i -s system::vconf_system
@@ -170,8 +162,10 @@ vconftool set -t int memory/sysman/stime_changed 0 -i -s system::vconf_system
 vconftool set -t int memory/sysman/power_off 0 -u 5000 -i -f -s system::vconf_system
 vconftool set -t int memory/deviced/boot_power_on 0 -u 5000 -i -f -s system::vconf_system
 vconftool set -t int memory/sysman/battery_level_status -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/low_memory 1 -i -s system::vconf_system
 
 #db type vconf key init
+vconftool set -t int db/private/sysman/cool_down_mode 0 -i -s system::vconf_system
 vconftool set -t bool db/private/deviced/lcd_brightness_init 0 -i -s system::vconf_system
 
 vconftool set -t int memory/pm/state 0 -i -g 5000 -s system::vconf_system
@@ -197,6 +191,19 @@ if [ $1 == 1 ]; then
     systemctl restart zbooting-done.service
 fi
 
+if [ $1 == 2 ]; then # upgrade begins, it's rpm -Uvh
+    #buxton could be started by socket activation
+   systemctl start buxton.service
+fi
+
+%pre
+#without updating services "daemon-reload" following systemctl stop is wait a
+# lot of time
+systemctl daemon-reload
+if [ $1 == 2 ]; then # it's upgrade, for rpm -Uvh
+    systemctl stop buxton.service
+fi
+
 %preun
 if [ $1 == 0 ]; then
     systemctl stop deviced.service
@@ -211,6 +218,8 @@ systemctl daemon-reload
 %{_bindir}/deviced
 %{_bindir}/devicectl
 %{_bindir}/deviced-auto-test
+%{_datadir}/dbus-1/services/org.tizen.system.deviced-auto-test.service
+%{_libdir}/systemd/system/deviced-auto-test.service
 %{_libdir}/systemd/system/deviced.service
 %{_libdir}/systemd/system/multi-user.target.wants/deviced.service
 %{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/deviced.service
@@ -225,8 +234,20 @@ systemctl daemon-reload
 %{_libdir}/systemd/system/devicectl-start@.service
 %{_libdir}/systemd/system/shutdown.target.wants/devicectl-stop@display.service
 %{_datadir}/license/%{name}
-%{_datadir}/deviced/usb-configurations/*
-%{_sysconfdir}/smack/accesses2.d/deviced.rule
+%{_sysconfdir}/smack/accesses.d/deviced.efl
+/etc/deviced/pass.conf
+/etc/deviced/usb-client-configuration.conf
+/etc/deviced/usb-client-operation.conf
+%if "%{?tizen_profile_name}" == "wearable"
+%else
+/etc/deviced/led.conf
+%{_bindir}/movi_format.sh
+%{_bindir}/mmc-smack-label
+%{_bindir}/fsck_msdosfs
+%{_bindir}/newfs_msdos
+%{_datadir}/license/fsck_msdosfs
+%{_datadir}/license/newfs_msdos
+%endif
 
 %manifest deviced.manifest
 %attr(110,root,root) /opt/etc/dump.d/module.d/dump_pm.sh
@@ -234,6 +255,8 @@ systemctl daemon-reload
 %{_sysconfdir}/deviced/mmc.conf
 %{_sysconfdir}/deviced/battery.conf
 %{_sysconfdir}/deviced/pmqos.conf
+%{_sysconfdir}/deviced/storage.conf
+%{_sysconfdir}/deviced/haptic.conf
 
 %attr(750,root,root)%{_bindir}/start_dr.sh
 %if %ENGINEER_MODE
@@ -252,15 +275,3 @@ systemctl daemon-reload
 %{_includedir}/deviced/*.h
 %{_libdir}/libdeviced.so
 %{_libdir}/pkgconfig/deviced.pc
-
-%files -n logd
-
-%files -n liblogd
-%manifest liblogd.manifest
-
-%files -n liblogd-devel
-
-%files -n liblogd-db
-%manifest liblogd-db.manifest
-
-%files -n liblogd-db-devel
diff --git a/packaging/liblogd-db.manifest b/packaging/liblogd-db.manifest
deleted file mode 100644 (file)
index 0a38a69..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest>
-       <define>
-               <domain name="liblogd-db"/>
-       </define>
-       <request>
-               <domain name="liblogd-db"/>
-       </request>
-       <assign>
-               <filesystem path="/usr/lib/liblogd-db.so" label="_" exec_label="none"/>
-       </assign>
-</manifest>
diff --git a/packaging/liblogd.manifest b/packaging/liblogd.manifest
deleted file mode 100644 (file)
index 194afaf..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest>
-       <define>
-               <domain name="liblogd"/>
-       </define>
-       <request>
-               <domain name="liblogd"/>
-       </request>
-       <assign>
-               <filesystem path="/usr/lib/liblogd.so" label="_" exec_label="none"/>
-       </assign>
-</manifest>
index 1560d1e..a4d1530 100755 (executable)
@@ -43,6 +43,11 @@ static void apps_init(void *data)
        static int initialized =0;
 
        if (!initialized) {
+               DD_LIST_FOREACH(apps_head, elem, dev) {
+                       _D("[%s] initialize", dev->name);
+                       if (dev->init)
+                               dev->init();
+               }
                initialized = 1;
                return;
        }
index 8dd93d9..eb01510 100755 (executable)
 
 #include "core/edbus-handler.h"
 #include "core/common.h"
-#include "core/data.h"
+
+enum apps_enable_type{
+       APPS_DISABLE = 0,
+       APPS_ENABLE = 1,
+};
 
 #define APPS_OPS_REGISTER(dev) \
 static void __CONSTRUCTOR__ module_init(void)  \
diff --git a/src/apps/cool-down.c b/src/apps/cool-down.c
new file mode 100644 (file)
index 0000000..b5c0f28
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+#include "core/launch.h"
+
+#define COOL_DOWN_POPUP_BUS_NAME       POPUP_BUS_NAME
+#define COOL_DOWN_POPUP_METHOD_LAUNCH  "CooldownPopupLaunch"
+
+#define COOL_DOWN_POWER_OFF            "cooldown_poweroff"
+#define COOL_DOWN_POWER_WARNING                "cooldown_warning"
+#define COOL_DOWN_POWER_ON             "cooldown_poweron"
+
+#define SIGNAL_COOL_DOWN_SHUT_DOWN     "ShutDown"
+#define SIGNAL_COOL_DOWN_SHUT_DOWN_LEN 8
+#define SIGNAL_COOL_DOWN_LIMIT_ACTION  "LimitAction"
+#define SIGNAL_COOL_DOWN_LIMIT_ACTION_LEN      11
+#define SIGNAL_COOL_DOWN_RELEASE       "Release"
+#define SIGNAL_COOL_DOWN_RELEASE_LEN   7
+
+struct popup_data {
+       char *name;
+       char *key;
+};
+
+static int cool_down_launch(void *data)
+{
+       char *param[2];
+       struct popup_data * key_data = (struct popup_data *)data;
+       int ret;
+
+       if (!key_data || !key_data->key)
+               goto out;
+
+       _I("%s", key_data->key);
+
+       if (strncmp(key_data->key, SIGNAL_COOL_DOWN_SHUT_DOWN,
+           SIGNAL_COOL_DOWN_SHUT_DOWN_LEN) == 0)
+           param[1] = COOL_DOWN_POWER_OFF;
+       else if (strncmp(key_data->key, SIGNAL_COOL_DOWN_LIMIT_ACTION,
+           SIGNAL_COOL_DOWN_LIMIT_ACTION_LEN) == 0)
+            param[1] = COOL_DOWN_POWER_WARNING;
+       else if (strncmp(key_data->key, SIGNAL_COOL_DOWN_RELEASE,
+           SIGNAL_COOL_DOWN_RELEASE_LEN) == 0)
+            param[1] = COOL_DOWN_POWER_ON;
+       else
+               goto out;
+
+       param[0] = POPUP_KEY_CONTENT;
+
+       return dbus_method_async(COOL_DOWN_POPUP_BUS_NAME,
+               POPUP_PATH_SYSTEM, POPUP_INTERFACE_SYSTEM,
+               COOL_DOWN_POPUP_METHOD_LAUNCH, "ss", param);
+out:
+       return 0;
+}
+
+
+static const struct apps_ops cooldown_ops = {
+       .name   = "cooldown-syspopup",
+       .launch = cool_down_launch,
+};
+
+APPS_OPS_REGISTER(&cooldown_ops)
index b90a7ff..abe3278 100644 (file)
 #define LOWBAT_CRITICAL  "critical"
 #define LOWBAT_POWEROFF "poweroff"
 
+#define DBUS_POPUP_PATH_LOWBAT         POPUP_OBJECT_PATH"/Battery"
+#define DBUS_POPUP_INTERFACE_LOWBAT    POPUP_INTERFACE_NAME".Battery"
+
+#define METHOD_LOWBAT_POPUP            "BatteryLow"
+#define METHOD_LOWBAT_POPUP_DISABLE    "LowBatteryDisable"
+#define METHOD_LOWBAT_POPUP_ENABLE     "LowBatteryEnable"
+
 struct popup_data {
        char *name;
        char *key;
@@ -33,6 +40,7 @@ struct popup_data {
 };
 
 static int lowbat_pid = 0;
+static int lowbat_popup = APPS_ENABLE;
 
 static void lowbat_cb(void *data, DBusMessage *msg, DBusError *unused)
 {
@@ -57,16 +65,30 @@ static void lowbat_cb(void *data, DBusMessage *msg, DBusError *unused)
 static int lowbat_launch(void *data)
 {
        char *param[2];
+       char *dest, *path, *iface, *method;
        struct popup_data * key_data = (struct popup_data *)data;
        int ret;
 
+       if (lowbat_popup == APPS_DISABLE) {
+               _D("skip lowbat popup control");
+               return 0;
+       }
+
        param[0] = key_data->key;
        param[1] = key_data->value;
-
-       ret = dbus_method_async_with_reply(POPUP_BUS_NAME,
-                       POPUP_PATH_LOWBAT,
-                       POPUP_INTERFACE_LOWBAT,
-                       POPUP_METHOD_LAUNCH,
+       if (strncmp(key_data->value, "lowbattery_warning", 18) == 0 ||
+           strncmp(key_data->value, "lowbattery_critical", 19) == 0) {
+               dest = POPUP_BUS_NAME;
+               path = DBUS_POPUP_PATH_LOWBAT;
+               iface = DBUS_POPUP_INTERFACE_LOWBAT;
+               method = METHOD_LOWBAT_POPUP;
+       } else {
+               dest = POPUP_BUS_NAME;
+               path = POPUP_PATH_LOWBAT;
+               iface = POPUP_INTERFACE_LOWBAT;
+               method = POPUP_METHOD_LAUNCH;
+       }
+       ret = dbus_method_async_with_reply(dest, path, iface, method,
                        "ss", param, lowbat_cb, -1, NULL);
 
        if (strncmp(key_data->value, LOWBAT_WARNING, strlen(LOWBAT_WARNING)) &&
@@ -102,10 +124,48 @@ static int lowbat_terminate(void *data)
        return 0;
 }
 
+static DBusMessage *dbus_disable_popup(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+
+       lowbat_popup = APPS_DISABLE;
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &lowbat_popup);
+       return reply;
+}
+
+static DBusMessage *dbus_enable_popup(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+
+       lowbat_popup = APPS_ENABLE;
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &lowbat_popup);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { METHOD_LOWBAT_POPUP_DISABLE,  NULL, "i", dbus_disable_popup },
+       { METHOD_LOWBAT_POPUP_ENABLE,   NULL, "i", dbus_enable_popup },
+};
+
+static void lowbat_init(void)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_APPS, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
 
 static const struct apps_ops lowbat_ops = {
-       .name   = "lowbat-syspopup",
-       .launch = lowbat_launch,
+       .name      = "lowbat-syspopup",
+       .init      = lowbat_init,
+       .launch    = lowbat_launch,
        .terminate = lowbat_terminate,
 };
 
index 50755f0..96c16b7 100644 (file)
@@ -36,7 +36,7 @@ static int lowmem_launch(void *data)
        param[0] = params->key;
        param[1] = params->value;
 
-       return dbus_method_sync(POPUP_BUS_NAME,
+       return dbus_method_async(POPUP_BUS_NAME,
                        POPUP_PATH_LOWMEM,
                        POPUP_INTERFACE_LOWMEM,
                        POPUP_METHOD_LAUNCH, "ss", param);
index 303482d..01f072f 100755 (executable)
@@ -15,10 +15,13 @@ SET(SRCS
        test.c
        main.c
        udev.c
+       archive.c
        boot.c
        cpu-info.c
        board-info.c
        time.c
+       result.c
+       cool-down.c
 )
 
 # extcon test
@@ -26,19 +29,20 @@ SET(SRCS ${SRCS}
        power-supply.c
        storage.c
        usb.c
+       hdmi.c
 )
 
 IF(NOT USE_MICRO_DD)
 SET(SRCS ${SRCS}
        cradle.c
        earjack.c
-       hdmi.c
        keyboard.c
+       tvout.c
 )
 ENDIF(NOT USE_MICRO_DD)
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED edbus)
+pkg_check_modules(pkgs REQUIRED edbus libarchive)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -61,6 +65,8 @@ ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
 ADD_DEFINITIONS("-DENABLE_TEST_DLOG")
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} shared)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-larchive" shared)
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+
+ADD_SUBDIRECTORY(activation)
diff --git a/src/auto-test/activation/CMakeLists.txt b/src/auto-test/activation/CMakeLists.txt
new file mode 100644 (file)
index 0000000..af86355
--- /dev/null
@@ -0,0 +1,2 @@
+ADD_SUBDIRECTORY(systemd)
+ADD_SUBDIRECTORY(dbus)
diff --git a/src/auto-test/activation/dbus/CMakeLists.txt b/src/auto-test/activation/dbus/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f970318
--- /dev/null
@@ -0,0 +1,7 @@
+SET(SYSTEM_DBUS_SERVICE_DIR "${PREFIX}/share/dbus-1/services")
+
+INSTALL(FILES
+        ${CMAKE_CURRENT_BINARY_DIR}/org.tizen.system.deviced-auto-test.service
+        DESTINATION
+        ${SYSTEM_DBUS_SERVICE_DIR}
+)
diff --git a/src/auto-test/activation/dbus/org.tizen.system.deviced-auto-test.service b/src/auto-test/activation/dbus/org.tizen.system.deviced-auto-test.service
new file mode 100644 (file)
index 0000000..63efeb5
--- /dev/null
@@ -0,0 +1,5 @@
+[D-BUS Service]
+Name=org.tizen.system.DevicedAutoTest
+Exec=/bin/false
+SystemdService=deviced-auto-test.service
+User=root
diff --git a/src/auto-test/activation/systemd/CMakeLists.txt b/src/auto-test/activation/systemd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cd39303
--- /dev/null
@@ -0,0 +1,11 @@
+SET(SD_SYS_UNIT_DIR "${LIBDIR}/systemd/system")
+
+SET(SD_SYS_UNITS
+        deviced-auto-test.service
+)
+
+INSTALL(FILES
+       ${CMAKE_CURRENT_BINARY_DIR}/${SD_SYS_UNITS}
+        DESTINATION
+        ${SD_SYS_UNIT_DIR}
+)
diff --git a/src/auto-test/activation/systemd/deviced-auto-test.service b/src/auto-test/activation/systemd/deviced-auto-test.service
new file mode 100644 (file)
index 0000000..7e8d820
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=Start the auto test service
+Requires=dbus.socket
+After=dbus.socket
+
+[Service]
+Type=dbus
+BusName=org.tizen.system.DevicedAutoTest
+ExecStart=/usr/bin/deviced-auto-test
+KillSignal=SIGUSR1
diff --git a/src/auto-test/archive.c b/src/auto-test/archive.c
new file mode 100644 (file)
index 0000000..01e834c
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * test
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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/stat.h>
+#include <fcntl.h>
+#include <archive.h>
+#include <archive_entry.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "test.h"
+
+#define DEFAULT_READ_BLOCK_SIZE        10240
+
+struct archive_data {
+       ssize_t len;
+       char *buff;
+};
+
+static mode_t default_mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+
+static int file_is_dir(const char *file)
+{
+       struct stat st;
+
+       if (stat(file, &st) < 0)
+               return 0;
+       if (S_ISDIR(st.st_mode))
+               return 1;
+       return 0;
+}
+
+static struct archive_data* get_data_from_archive(char *path, char *item)
+{
+       struct archive *arch;
+       struct archive_entry *entry;
+       struct archive_data *data = NULL;
+       int fd;
+       int ret;
+
+       if (!path || !item)
+               return NULL;
+
+       _R("%s comp path %s, file name %s", __func__, path, item);
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               _E("open fail");
+               return NULL;
+       }
+       arch = archive_read_new();
+       if (arch == NULL) {
+               _E("Couldn't create archive reader.");
+               goto out;
+       }
+       if (archive_read_support_compression_all(arch) != ARCHIVE_OK) {
+               _E("%s(%d)", archive_error_string( arch ), archive_errno( arch ));
+               goto out;
+       }
+       if (archive_read_support_format_all(arch) != ARCHIVE_OK) {
+               _E("%s(%d)", archive_error_string( arch ), archive_errno( arch ));
+               goto out;
+       }
+       if (archive_read_open_fd(arch, fd, DEFAULT_READ_BLOCK_SIZE) != ARCHIVE_OK) {
+               _E("%s(%d)", archive_error_string( arch ), archive_errno( arch ));
+               goto out;
+       }
+
+       while ((ret = archive_read_next_header(arch, &entry)) == ARCHIVE_OK)  {
+               if (!S_ISREG(archive_entry_mode(entry)))
+                       continue;
+               if (strncmp(archive_entry_pathname(entry), item, strlen(item)))
+                       continue;
+               data = (struct archive_data *)malloc(sizeof(struct archive_data));
+               if (!data) {
+                       _E("malloc fail");
+                       goto finish;
+               }
+               data->len = archive_entry_size(entry);
+               data->buff = (char *)malloc(sizeof(char)*data->len);
+               if (!data->buff) {
+                       _E("malloc fail");
+                       goto finish;
+               }
+               _R("%s file %s size %d", __func__, archive_entry_pathname(entry), data->len);
+               ret = archive_read_data(arch, data->buff, data->len);
+               if (ret < 0)
+                       _E("read fail");
+               break;
+       }
+finish:
+       /* Close the archives.  */
+       if (archive_read_finish(arch) != ARCHIVE_OK)
+               _E("Error closing input archive");
+out:
+       close(fd);
+       return data;
+}
+
+static void test_save_data_to_file(char *name, struct archive_data *data)
+{
+       char path[PATH_MAX];
+       char ss[PATH_MAX];
+       struct stat st;
+       int fd;
+       int ret;
+       int i;
+
+       if (!name || !data) {
+               _E("input fail");
+               return;
+       }
+       snprintf(path, sizeof(path), "/tmp/%s", name);
+       if (file_is_dir(path))
+               return;
+       for (i = 0; path[i] != '\0'; ss[i] = path[i], i++)
+       {
+               if (i == sizeof(ss) - 1) {
+                       _E("fail");
+                       return;
+               }
+               if (((path[i] == '/') || (path[i] == '\\')) && (i > 0)) {
+                       ss[i] = '\0';
+                       if (stat(ss, &st) < 0) {
+                               ret = mkdir(ss, default_mode);
+                               if (ret < 0) {
+                                       _E("Make Directory is failed");
+                                       return;
+                               }
+                       } else if (!S_ISDIR(st.st_mode)) {
+                               _E("fail to check dir %s", ss);
+                               return;
+                       }
+               }
+       }
+       ss[i] = '\0';
+       fd = open(ss, O_CREAT | O_TRUNC | O_WRONLY, 0644);
+       if (fd < 0) {
+               _E("open fail(%s)", strerror(errno));
+               return;
+       }
+       ret = write(fd, data->buff, data->len);
+       if (ret < 0)
+               _E("write fail");
+       close(fd);
+       _R("%s %s", __func__, path);
+}
+
+static int archive_unit(int argc, char **argv)
+{
+       struct archive_data *data = NULL;
+       struct timespec start;
+       struct timespec end;
+       long delta;
+
+       if (argc != 4) {
+               _E("arg fail");
+               goto out;
+       }
+       clock_gettime(CLOCK_REALTIME, &start);
+       data = get_data_from_archive(argv[2], argv[3]);
+       clock_gettime(CLOCK_REALTIME, &end);
+       delta = (long)((end.tv_sec*1000 + end.tv_nsec/1000000) -
+               (start.tv_sec*1000 + start.tv_nsec/1000000));
+
+       _R("%s operation time %ldms", __func__, delta);
+       if (!data)
+               goto out;
+       if (!data->buff) {
+               free(data);
+               goto out;
+       }
+       test_save_data_to_file(argv[3], data);
+       free(data->buff);
+       free(data);
+out:
+       return 0;
+}
+
+static void unit(char *unit, char *status)
+{
+}
+
+static void archive_init(void *data)
+{
+}
+
+static void archive_exit(void *data)
+{
+}
+
+static const struct test_ops archive_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "archive",
+       .init     = archive_init,
+       .exit    = archive_exit,
+       .unit    = archive_unit,
+};
+
+TEST_OPS_REGISTER(&archive_test_ops)
index ca4cc6d..8d45a28 100644 (file)
 
 #include "test.h"
 
+#define METHOD_GET_NUM "GetNum"
 #define METHOD_GET_SERIAL      "GetSerial"
 #define METHOD_GET_REVISION    "GetHWRev"
 
-void get_serial(void)
+void board_serial(void)
 {
        DBusError err;
        DBusMessage *msg;
@@ -46,9 +47,14 @@ void get_serial(void)
        dbus_error_free(&err);
 
        _D("%s %d", data, val);
+       if (val < 0)
+               _R("[NG] ---- %s     : V(if your target is eng, NG is Normal)",
+               __func__);
+       else
+               _R("[OK] ---- %s     : V(%s)", __func__, data);
 }
 
-static void get_revision(void)
+static void board_revision(void)
 {
        DBusError err;
        DBusMessage *msg;
@@ -76,13 +82,50 @@ static void get_revision(void)
        } else {
                _D("Rinato");
        }
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s   : V(%d)", __func__, val);
+}
+
+void board_numer(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, val;
+       char *data;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME, DEVICED_PATH_BOARD,
+               DEVICED_INTERFACE_BOARD, METHOD_GET_NUM, NULL, NULL);
+       if (!msg) {
+               _E("fail send message");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &data, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               return;
+       }
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s %d", data, val);
+       if (val < 0)
+               _R("[NG] ---- %s      : V(if your target is eng, NG is Normal)",
+               __func__);
+       else
+               _R("[OK] ---- %s      : V(%s)", __func__, data);
 }
 
 static void board_init(void *data)
 {
        _I("start test");
-       get_revision();
-       get_serial();
+       board_revision();
+       board_serial();
+       board_numer();
 }
 
 static void board_exit(void *data)
@@ -92,8 +135,9 @@ static void board_exit(void *data)
 
 static int board_unit(int argc, char **argv)
 {
-       get_revision();
-       get_serial();
+       board_revision();
+       board_serial();
+       board_numer();
        return 0;
 }
 
index 5374e57..7fd0c48 100644 (file)
@@ -109,16 +109,21 @@ static int broadcast_edbus_signal(const char *path, const char *interface,
                return -EPERM;
        }
 
-       e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL);
-
+       r = dbus_connection_send(conn, msg, NULL);
        dbus_message_unref(msg);
+
+       if (r != TRUE) {
+               _E("dbus_connection_send error (%s:%s-%s)", path, interface, name);
+               return -ECOMM;
+       }
        return 0;
 }
 
-static void poweroff_send_broadcast(char *status)
+static void poweroff_popup(char *status)
 {
        char *arr[2];
        char str_status[32];
+       int val;
 
        snprintf(str_status, sizeof(str_status), "%s", status);
        arr[0] = str_status;
@@ -126,8 +131,12 @@ static void poweroff_send_broadcast(char *status)
        _D("broadcast poweroff %s %s", arr[0], arr[1]);
 
        edbus_init();
-       broadcast_edbus_signal(DEVICED_OBJECT_PATH, DEVICED_INTERFACE_NAME,
+       val = broadcast_edbus_signal(DEVICED_OBJECT_PATH, DEVICED_INTERFACE_NAME,
                        "poweroffpopup", "si", arr);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s   : V(%s)", __func__, status);
        edbus_exit();
 }
 
@@ -140,7 +149,7 @@ static void unit(char *unit, char *status)
                    strcmp(status, boot_control_types[index].status) != 0)
                        continue;
                if (strcmp(unit, "poweroffpopup") == 0)
-                       poweroff_send_broadcast(boot_control_types[index].status);
+                       poweroff_popup(boot_control_types[index].status);
        }
 
 }
diff --git a/src/auto-test/cool-down.c b/src/auto-test/cool-down.c
new file mode 100644 (file)
index 0000000..eaa56d2
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * test
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 "test.h"
+
+#define METHOD_COOL_DOWN_STATUS                "GetCoolDownStatus"
+#define METHOD_COOL_DOWN_CHANGED       "CoolDownChanged"
+static int get_status(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret;
+       char *str;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_COOL_DOWN_STATUS, NULL, NULL);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_COOL_DOWN_STATUS);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &str,
+                       DBUS_TYPE_INVALID);
+       if (!ret)
+               _E("no message : [%s:%s]", err.name, err.message);
+
+       _I("%s", str);
+       if (ret < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s      : V(%s)", __func__, str);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       return ret;
+}
+
+static int cool_down(char *name, char *status)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, val;
+       char *param[4];
+
+       param[0] = METHOD_SET_DEVICE;
+       param[1] = "2";
+       param[2] = name;
+       param[3] = status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_COOL_DOWN_CHANGED, "siss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               val = -EBADMSG;
+       }
+       _I("%s %s", name, status);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s           : V(%s %s)",
+               __func__, name, status);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       return val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       cool_down(unit, status);
+       get_status();
+}
+
+static void cool_down_init(void *data)
+{
+}
+
+static void cool_down_exit(void *data)
+{
+}
+
+static int cool_down_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 4)
+               return -EAGAIN;
+
+       unit(argv[2], argv[3]);
+out:
+       return 0;
+}
+
+static const struct test_ops cool_down_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "cool-down",
+       .init     = cool_down_init,
+       .exit     = cool_down_exit,
+       .unit     = cool_down_unit,
+};
+
+TEST_OPS_REGISTER(&cool_down_test_ops)
index 9a5e156..8bac46e 100644 (file)
@@ -20,7 +20,7 @@
 
 #define METHOD_GET_REVISION    "GetRevision"
 
-static void get_revision(void)
+static void cpuinfo_revision(void)
 {
        DBusError err;
        DBusMessage *msg;
@@ -48,12 +48,16 @@ static void get_revision(void)
        } else {
                _D("Rinato");
        }
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s : V(%d)", __func__, val);
 }
 
 static void cpuinfo_init(void *data)
 {
        _I("start test");
-       get_revision();
+       cpuinfo_revision();
 }
 
 static void cpuinfo_exit(void *data)
@@ -63,7 +67,7 @@ static void cpuinfo_exit(void *data)
 
 static int cpuinfo_unit(int argc, char **argv)
 {
-       get_revision();
+       cpuinfo_revision();
        return 0;
 }
 
index 3abe136..eba5039 100644 (file)
@@ -32,7 +32,7 @@ static int test_cradle(void)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, level;
+       int ret, val;
 
        msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
                        DEVICED_PATH_SYSNOTI,
@@ -47,24 +47,28 @@ static int test_cradle(void)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val,
                        DBUS_TYPE_INVALID);
        if (!ret) {
                _E("no message : [%s:%s]", err.name, err.message);
-               level = -1;
+               val = -1;
        }
-       _I("%d", level);
+       _I("%d", val);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s      : V(%d)", __func__, val);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return level;
+       return val;
 }
 
-static int test(int index)
+static int cradle(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[4];
 
        param[0] = METHOD_SET_DEVICE;
@@ -85,17 +89,22 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (ret == 0) {
                _E("no message : [%s:%s]", err.name, err.message);
                dbus_error_free(&err);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
        _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s           : V(%s %s)",
+               __func__, device_change_types[index].name, device_change_types[index].status);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void unit(char *unit, char *status)
@@ -106,7 +115,7 @@ static void unit(char *unit, char *status)
                if (strcmp(unit, device_change_types[index].name) != 0 ||
                    strcmp(status, device_change_types[index].status) != 0)
                        continue;
-               test(index);
+               cradle(index);
                test_cradle();
        }
 }
@@ -117,7 +126,7 @@ static void cradle_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
-               test(index);
+               cradle(index);
 }
 
 static void cradle_exit(void *data)
@@ -134,7 +143,7 @@ static int cradle_unit(int argc, char **argv)
        if (argc != 4)
                return -EAGAIN;
 
-       unit(argv[2], argv[3]);
+       unit(argv[1], argv[2]);
 out:
        return 0;
 }
index 8643bdc..b883aae 100644 (file)
@@ -21,17 +21,17 @@ static const struct device_change_type {
        char *name;
        char *status;
 } device_change_types [] = {
-       {"jack",        "1"},
-       {"jack",        "0"},
-       {"key", "1"},
-       {"key", "0"},
+       {"earjack",     "1"},
+       {"earjack",     "0"},
+       {"earkey",      "1"},
+       {"earkey",      "0"},
 };
 
-static int test(int index)
+static int earjack(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[4];
 
        param[0] = METHOD_SET_DEVICE;
@@ -52,17 +52,22 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (ret == 0) {
                _E("no message : [%s:%s]", err.name, err.message);
                dbus_error_free(&err);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
        _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s          : V(%s %s)",
+               __func__, device_change_types[index].name, device_change_types[index].status);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void unit(char *unit, char *status)
@@ -73,7 +78,7 @@ static void unit(char *unit, char *status)
                if (strcmp(unit, device_change_types[index].name) != 0 ||
                    strcmp(status, device_change_types[index].status) != 0)
                        continue;
-               test(index);
+               earjack(index);
        }
 }
 
@@ -83,7 +88,7 @@ static void earjack_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
-               test(index);
+               earjack(index);
 }
 
 static void earjack_exit(void *data)
@@ -97,10 +102,10 @@ static int earjack_unit(int argc, char **argv)
 
        if (argv[1] == NULL)
                return -EINVAL;
-       if (argc != 3)
+       if (argc != 4)
                return -EAGAIN;
 
-       unit(argv[1], argv[2]);
+       unit(argv[2], argv[3]);
 out:
        return 0;
 }
index c1edf83..0fa383b 100644 (file)
@@ -33,7 +33,7 @@ static int test_hdmi(void)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, level;
+       int ret, val;
 
        msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
                        DEVICED_PATH_SYSNOTI,
@@ -48,24 +48,28 @@ static int test_hdmi(void)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val,
                        DBUS_TYPE_INVALID);
        if (!ret) {
                _E("no message : [%s:%s]", err.name, err.message);
-               level = -1;
+               val = -1;
        }
-       _I("%d", level);
+       _I("%d", val);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s        : V(%d)", __func__, val);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return level;
+       return val;
 }
 
 static int test_hdcp(void)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, level;
+       int ret, val;
 
        msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
                        DEVICED_PATH_SYSNOTI,
@@ -80,24 +84,28 @@ static int test_hdcp(void)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val,
                        DBUS_TYPE_INVALID);
        if (!ret) {
                _E("no message : [%s:%s]", err.name, err.message);
-               level = -1;
+               val = -1;
        }
-       _I("%d", level);
+       _I("%d", val);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s        : V(%d)", __func__, val);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return level;
+       return val;
 }
 
 static int test_hdmi_audio(void)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, level;
+       int ret, val;
 
        msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
                        DEVICED_PATH_SYSNOTI,
@@ -112,24 +120,28 @@ static int test_hdmi_audio(void)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val,
                        DBUS_TYPE_INVALID);
        if (!ret) {
                _E("no message : [%s:%s]", err.name, err.message);
-               level = -1;
+               val = -1;
        }
-       _I("%d", level);
+       _I("%d", val);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s  : V(%d)", __func__, val);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return level;
+       return val;
 }
 
-static int test(int index)
+static int hdmi(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[4];
 
        param[0] = METHOD_SET_DEVICE;
@@ -150,17 +162,22 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (ret == 0) {
                _E("no message : [%s:%s]", err.name, err.message);
                dbus_error_free(&err);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
        _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s             : V(%s %s)",
+               __func__, device_change_types[index].name, device_change_types[index].status);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void unit(char *unit, char *status)
@@ -171,7 +188,7 @@ static void unit(char *unit, char *status)
                if (strcmp(unit, device_change_types[index].name) != 0 ||
                    strcmp(status, device_change_types[index].status) != 0)
                        continue;
-               test(index);
+               hdmi(index);
        }
 }
 
@@ -181,7 +198,7 @@ static void hdmi_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
-               test(index);
+               hdmi(index);
                test_hdmi();
                test_hdcp();
                test_hdmi_audio();
index e9cec63..950ac62 100644 (file)
@@ -25,11 +25,11 @@ static const struct device_change_type {
        {"keyboard",    "0"},
 };
 
-static int test(int index)
+static int keyboard(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[4];
 
        param[0] = METHOD_SET_DEVICE;
@@ -50,17 +50,22 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (ret == 0) {
                _E("no message : [%s:%s]", err.name, err.message);
                dbus_error_free(&err);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
        _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s         : V(%s %s)",
+               __func__, device_change_types[index].name, device_change_types[index].status);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void unit(char *unit, char *status)
@@ -71,7 +76,7 @@ static void unit(char *unit, char *status)
                if (strcmp(unit, device_change_types[index].name) != 0 ||
                    strcmp(status, device_change_types[index].status) != 0)
                        continue;
-               test(index);
+               keyboard(index);
        }
 }
 
@@ -81,7 +86,7 @@ static void keyboard_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
-               test(index);
+               keyboard(index);
 }
 
 static void keyboard_exit(void *data)
index d63a577..bbda3d4 100644 (file)
 #define S_ENTER        1
 #define S_LEAVE        0
 
+enum apps_enable_type{
+       APPS_DISABLE = 0,
+       APPS_ENABLE = 1,
+};
+
 #define SIGNAL_CHARGE_NOW "ChargeNow"
 #define SIGNAL_CHARGER_STATUS "ChargerStatus"
 #define SIGNAL_TEMP_GOOD "TempGood"
 
+#define METHOD_LOWBAT_POPUP_DISABLE    "LowBatteryDisable"
+#define METHOD_LOWBAT_POPUP_ENABLE     "LowBatteryEnable"
+
 static E_DBus_Signal_Handler *edbus_charge_now_handler;
 static E_DBus_Signal_Handler *edbus_charger_status_handler;
 static E_DBus_Signal_Handler *edbus_temp_good_handler;
@@ -88,8 +96,12 @@ static struct power_supply_type {
 
        {"ta",   S_ENTER, "100","Charging",    "Good", "2", "1", "CHARGE"},   //charging
        {"ta",   S_LEAVE, "100","Discharging", "Good", "1", "1", "DISCHARGE"},//discharging
-       {"capacity",   S_ENTER, "100","Discharging", "Good", "1", "1", "CAPACITY"},//charging
-       {"capacity",   S_LEAVE, "100","Charging", "Good", "2", "1", "CAPACITY"},//discharging
+
+       {"full", S_ENTER, "100","Full",        "Good", "2", "1", "CHARGE"},   //full
+       {"full", S_LEAVE, "100","Discharging", "Good", "1", "1", "DISCHARGE"},//discharging
+
+       {"capa", S_ENTER, "100","Discharging", "Good", "1", "1", "CAPACITY"},//discharging
+       {"capa", S_LEAVE, "100","Charging",    "Good", "2", "1", "CAPACITY"},//charging
 };
 
 static void unregister_edbus_signal_handler(void)
@@ -248,7 +260,7 @@ edbus_handler_out:
        e_dbus_shutdown();
        return ret;
 }
-static void test_signal(void)
+static void power_supply_signal(void)
 {
        _I("test");
        register_charge_now_handler();
@@ -257,11 +269,11 @@ static void test_signal(void)
        ecore_main_loop_begin();
 }
 
-static int test(int index)
+static int power_supply(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[7];
 
        param[0] = POWER_SUBSYSTEM;
@@ -285,16 +297,16 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (ret == 0) {
                _E("no message : [%s:%s]", err.name, err.message);
                dbus_error_free(&err);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
 
        if (power_supply_types[index].name != NULL)
                _I("++++++++++[START] %s ++++++++++", power_supply_types[index].name);
-       _I("CAPACITY(%s , %s) P(%s) STATUS(%s) HEALTH(%s)",
+       _I("C(%s , %s) P(%s) STATUS(%s) HEALTH(%s)",
                power_supply_types[index].capacity,
                power_supply_types[index].online,
                power_supply_types[index].present,
@@ -302,11 +314,20 @@ static int test(int index)
                power_supply_types[index].health);
        if (power_supply_types[index].name != NULL)
                _I("++++++++++[END] %s ++++++++++", power_supply_types[index].name);
-
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s     : C(%s , %s) P(%s) S(%s) H(%s)",
+               __func__,
+               power_supply_types[index].capacity,
+               power_supply_types[index].online,
+               power_supply_types[index].present,
+               power_supply_types[index].charge_status,
+               power_supply_types[index].health);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void scenario(char *scenario)
@@ -316,7 +337,7 @@ static void scenario(char *scenario)
        for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
                if (strcmp(scenario, power_supply_types[index].scenario) != 0)
                        continue;
-               test(index);
+               power_supply(index);
        }
 }
 
@@ -332,7 +353,7 @@ static void unit(char *unit, int status)
                    power_supply_types[index].status != status)
                        continue;
                found = 1;
-               test(index);
+               power_supply(index);
        }
 
        if (found)
@@ -347,13 +368,73 @@ static void unit(char *unit, int status)
                return;
 
        for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
-               if (strcmp("capacity", power_supply_types[index].scenario) != 0 ||
+               if (strcmp("capa", power_supply_types[index].scenario) != 0 ||
                    power_supply_types[index].status != status)
                        continue;
                power_supply_types[index].capacity = unit;
                _D("%s", power_supply_types[index].capacity);
-               test(index);
+               power_supply(index);
+       }
+}
+
+static void full(char *unit, char *capacity, int status)
+{
+       int index;
+       for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
+               if (strcmp(unit, power_supply_types[index].scenario) != 0 ||
+                   power_supply_types[index].status != status)
+                       continue;
+               power_supply_types[index].capacity = capacity;
+               _D("%s", power_supply_types[index].capacity);
+               power_supply(index);
+       }
+}
+
+static void lowbat_popup(char *status)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, val;
+       char *method;
+
+       if (!status)
+               return;
+       val = atoi(status);
+       if (val != APPS_ENABLE && val != APPS_DISABLE)
+               return;
+
+       if (val == APPS_ENABLE)
+               method = METHOD_LOWBAT_POPUP_ENABLE;
+       else
+               method = METHOD_LOWBAT_POPUP_DISABLE;
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+               DEVICED_PATH_APPS,
+               DEVICED_INTERFACE_APPS,
+               method, NULL, NULL);
+
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_APPS, DEVICED_INTERFACE_APPS, method);
+               return;
        }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               val = -EBADMSG;
+       }
+
+       if (val < 0)
+               _R("[NG] ---- %s      : V(%s %d)", __func__, method, val);
+       else
+               _R("[OK] ---- %s      : V(%s %d)", __func__, method, val);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return;
 }
 
 static void power_supply_init(void *data)
@@ -362,7 +443,7 @@ static void power_supply_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(power_supply_types); index++)
-               test(index);
+               power_supply(index);
 }
 
 static void power_supply_exit(void *data)
@@ -374,16 +455,22 @@ static int power_supply_unit(int argc, char **argv)
 {
        if (argv[1] == NULL)
                return -EINVAL;
-       else if (argc != 4)
+       else if (argc < 4)
                return -EAGAIN;
        if (strcmp("wait", argv[2]) == 0)
-               test_signal();
+               power_supply_signal();
+       else if (strcmp("popup", argv[2]) == 0)
+               lowbat_popup(argv[3]);
        else if (strcmp("scenario", argv[2]) == 0)
                scenario(argv[3]);
        else if (strcmp("enter", argv[3]) == 0)
                unit(argv[2], S_ENTER);
        else if (strcmp("leave", argv[3]) == 0)
                unit(argv[2], S_LEAVE);
+       else if (strcmp("enter", argv[4]) == 0)
+               full(argv[2], argv[3], S_ENTER);
+       else if (strcmp("leave", argv[4]) == 0)
+               full(argv[2], argv[3], S_LEAVE);
        return 0;
 }
 
diff --git a/src/auto-test/result.c b/src/auto-test/result.c
new file mode 100644 (file)
index 0000000..00c1c3b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * test
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <errno.h>
+#include <E_DBus.h>
+
+#include "core/list.h"
+#include "core/common.h"
+
+#ifdef ENABLE_TEST_DLOG
+#define ENABLE_DLOG
+#endif
+
+#define LOG_TAG "ATR" //AUTO_TESTE_RESULT
+#include "shared/log-macro.h"
+
+#define BUF_MAX 256
+
+void _R (const char *format, ...)
+{
+       va_list args;
+       char buf[BUF_MAX];
+
+       va_start(args, format);
+       vsnprintf(buf, BUF_MAX, format, args);
+       va_end(args);
+
+       _D("%s", buf);
+}
\ No newline at end of file
index dad9a7c..c1a361f 100644 (file)
@@ -50,7 +50,7 @@ static int request_mem_trim(void)
        return ret;
 }
 
-static int test_storage(void)
+static int storage(void)
 {
        DBusError err;
        DBusMessage *msg;
@@ -76,6 +76,11 @@ static int test_storage(void)
                _E("no message : [%s:%s]", err.name, err.message);
        }
        _I("total : %4.4lf avail %4.4lf", dTotal, dAvail);
+       if (ret < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s          : T(%4.4lf) A(%4.4lf)",
+               __func__, dTotal, dAvail);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
@@ -85,7 +90,7 @@ static int test_storage(void)
 static void storage_init(void *data)
 {
        _I("start test");
-       test_storage();
+       storage();
 }
 
 static void storage_exit(void *data)
@@ -95,14 +100,14 @@ static void storage_exit(void *data)
 
 static int storage_unit(int argc, char **argv)
 {
-       int status;
-
        if (argv[1] == NULL)
                return -EINVAL;
-       test_storage();
-       request_mem_trim();
-       ecore_main_loop_begin();
-out:
+       if (strcmp(argv[2], "value") == 0)
+               storage();
+       else if (strcmp(argv[2], "signal") == 0) {
+               request_mem_trim();
+               ecore_main_loop_begin();
+       }
        return 0;
 }
 
index 2f68f3c..46ff24a 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef __TEST_H__
 #define __TEST_H__
 #include <stdio.h>
+#include <stdarg.h>
 #include <errno.h>
 #include <E_DBus.h>
 
@@ -103,5 +104,5 @@ DBusMessage *deviced_dbus_method_sync_with_reply(const char *dest, const char *p
 void add_test(const struct test_ops *c);
 void remove_test(const struct test_ops *c);
 const struct test_ops *find_test(const char *name);
-
+void _R (const char *format, ...);
 #endif
index 71edb14..69ab94a 100644 (file)
@@ -34,18 +34,21 @@ static void time_changed(void *data, DBusMessage *msg)
 {
        DBusError err;
        int val;
-       int r;
+       int ret;
 
        _I("edbus signal Received");
 
-       r = dbus_message_is_signal(msg, DEVICED_INTERFACE_TIME, TIME_CHANGE_SIGNAL);
-       if (!r) {
+       ret = dbus_message_is_signal(msg, DEVICED_INTERFACE_TIME, TIME_CHANGE_SIGNAL);
+       if (!ret) {
                _E("dbus_message_is_signal error");
                return;
        }
 
        _I("%s - %s", DEVICED_INTERFACE_TIME, TIME_CHANGE_SIGNAL);
-
+       if (ret < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s", __func__);
        unregister_edbus_signal_handler();
        ecore_shutdown();
 }
index 3b75459..25bc9d9 100644 (file)
@@ -25,11 +25,11 @@ static const struct device_change_type {
        {"tvout",       "0"},
 };
 
-static int test(int index)
+static int tvout(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[4];
 
        param[0] = METHOD_SET_DEVICE;
@@ -50,17 +50,22 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (ret == 0) {
                _E("no message : [%s:%s]", err.name, err.message);
                dbus_error_free(&err);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
        _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s            : V(%s %s)",
+               __func__, device_change_types[index].name, device_change_types[index].status);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void unit(char *unit, char *status)
@@ -71,7 +76,7 @@ static void unit(char *unit, char *status)
                if (strcmp(unit, device_change_types[index].name) != 0 ||
                    strcmp(status, device_change_types[index].status) != 0)
                        continue;
-               test(index);
+               tvout(index);
        }
 }
 
@@ -81,7 +86,7 @@ static void tvout_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
-               test(index);
+               tvout(index);
 }
 
 static void tvout_exit(void *data)
index c9818e3..d0cc910 100644 (file)
@@ -25,11 +25,11 @@ static const struct device_change_type {
        {"udev",                "stop"},
 };
 
-static int test(int index)
+static int udev(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[3];
 
        param[0] = UDEV;
@@ -48,16 +48,22 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (!ret) {
                _E("no message : [%s:%s]", err.name, err.message);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
-       _I("START");
+       _I("%s", device_change_types[index].status);
+       if (val < 0)
+               _R("[NG] ---- %s             : %s",
+               __func__, device_change_types[index].status);
+       else
+               _R("[OK] ---- %s             : %s",
+               __func__, device_change_types[index].status);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void unit(char *unit, char *status)
@@ -68,7 +74,7 @@ static void unit(char *unit, char *status)
                if (strcmp(unit, device_change_types[index].name) != 0 ||
                    strcmp(status, device_change_types[index].status) != 0)
                        continue;
-               test(index);
+               udev(index);
        }
 }
 
@@ -78,7 +84,7 @@ static void udev_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
-               test(index);
+               udev(index);
 }
 
 static void udev_exit(void *data)
index 2a8a901..93f7330 100644 (file)
@@ -25,11 +25,11 @@ static const struct device_change_type {
        {"usb",         "0"},
 };
 
-static int test(int index)
+static int usb(int index)
 {
        DBusError err;
        DBusMessage *msg;
-       int ret, ret_val;
+       int ret, val;
        char *param[4];
 
        param[0] = METHOD_SET_DEVICE;
@@ -50,17 +50,22 @@ static int test(int index)
 
        dbus_error_init(&err);
 
-       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
        if (ret == 0) {
                _E("no message : [%s:%s]", err.name, err.message);
                dbus_error_free(&err);
-               ret_val = -EBADMSG;
+               val = -EBADMSG;
        }
        _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       if (val < 0)
+               _R("[NG] ---- %s", __func__);
+       else
+               _R("[OK] ---- %s              : V(%s %s)",
+               __func__, device_change_types[index].name, device_change_types[index].status);
        dbus_message_unref(msg);
        dbus_error_free(&err);
        sleep(TEST_WAIT_TIME_INTERVAL);
-       return ret_val;
+       return val;
 }
 
 static void unit(char *unit, char *status)
@@ -71,7 +76,7 @@ static void unit(char *unit, char *status)
                if (strcmp(unit, device_change_types[index].name) != 0 ||
                    strcmp(status, device_change_types[index].status) != 0)
                        continue;
-               test(index);
+               usb(index);
        }
 }
 
@@ -81,7 +86,7 @@ static void usb_init(void *data)
 
        _I("start test");
        for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
-               test(index);
+               usb(index);
 }
 
 static void usb_exit(void *data)
diff --git a/src/battery/battery.c b/src/battery/battery.c
deleted file mode 100644 (file)
index a48ddfa..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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.
- */
-
-#define USE_LOGD 1
-
-#include <stdbool.h>
-#include <assert.h>
-#include <limits.h>
-#include "core/log.h"
-#include "core/devices.h"
-#include "core/udev.h"
-#include "device-node.h"
-#include "core/device-handler.h"
-#include "core/device-notifier.h"
-#include "core/edbus-handler.h"
-
-/*
- * get_capacity - get battery capacity value
- * using device_get_property
- */
-static int get_capacity(void)
-{
-       int val, ret;
-
-       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY, &val);
-       if (ret < 0) {
-               _E("fail to get battery capacity value");
-               val = ret;
-       }
-       return val;
-}
-
-static int update_battery(void *data)
-{
-       static int capacity = -1;
-       static int charge_now = -1;
-
-       if (battery.capacity != capacity) {
-               _D("capacity is changed %d -> %d", capacity, battery.capacity);
-               capacity = battery.capacity;
-       }
-
-       if (battery.charge_now != charge_now) {
-               _D("chaging status is changed %d -> %d", charge_now, battery.charge_now);
-               charge_now = battery.charge_now;
-       }
-       return 0;
-}
-
-static DBusMessage *edbus_get_percent(E_DBus_Object *obj, DBusMessage *msg)
-{
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       int ret;
-
-       ret = battery.capacity;
-
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
-       return reply;
-}
-
-static DBusMessage *edbus_get_percent_raw(E_DBus_Object *obj, DBusMessage *msg)
-{
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       int ret, val;
-
-       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY_RAW, &val);
-       if (ret < 0)
-               goto exit;
-
-       if (val > 10000)
-               val = 10000;
-
-       ret = val;
-
-exit:
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
-       return reply;
-}
-
-static DBusMessage *edbus_is_full(E_DBus_Object *obj, DBusMessage *msg)
-{
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       int ret;
-
-       ret = battery.charge_full;
-
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
-       return reply;
-}
-
-static DBusMessage *edbus_get_health(E_DBus_Object *obj, DBusMessage *msg)
-{
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       int ret;
-
-       ret = battery.health;
-
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
-       return reply;
-}
-
-static const struct edbus_method edbus_methods[] = {
-       { "GetPercent",    NULL,   "i", edbus_get_percent },
-       { "GetPercentRaw", NULL,   "i", edbus_get_percent_raw },
-       { "IsFull",        NULL,   "i", edbus_is_full },
-       { "GetHealth",     NULL,   "i", edbus_get_health },
-       /* Add methods here */
-};
-
-/* battery ops init funcion */
-static void battery_init(void *data)
-{
-       int ret;
-
-       /* init dbus interface */
-       ret = register_edbus_method(DEVICED_PATH_BATTERY,
-                       edbus_methods, ARRAY_SIZE(edbus_methods));
-       if (ret < 0)
-               _E("fail to init edbus method(%d)", ret);
-
-       /* get initial battery capacity */
-       battery.capacity = get_capacity();
-       battery.charge_now = POWER_SUPPLY_STATUS_UNKNOWN;
-
-       /* register notifier */
-       register_notifier(DEVICE_NOTIFIER_POWER_SUPPLY, update_battery);
-}
-
-/* battery ops exit funcion */
-static void battery_exit(void *data)
-{
-       /* unregister notifier */
-       unregister_notifier(DEVICE_NOTIFIER_POWER_SUPPLY, update_battery);
-}
-
-static const struct device_ops battery_device_ops = {
-       .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "battery",
-       .init     = battery_init,
-       .exit     = battery_exit,
-};
-
-DEVICE_OPS_REGISTER(&battery_device_ops)
index 5f68716..6acd38f 100644 (file)
 #ifndef __BATTERY_CONFIG_H__
 #define __BATTERY_CONFIG_H__
 
+#define BATTERY_FULL     100
+#define BATTERY_NORMAL   BATTERY_FULL
+#define BATTERY_WARNING  15
+#define BATTERY_CRITICAL 5
+#ifdef MICRO_DD
+#define BATTERY_POWEROFF 3
+#else
+#define BATTERY_POWEROFF 1
+#endif
+#define BATTERY_REALOFF  0
+
 void battery_config_load(struct battery_config_info *info);
 #endif /* __BATTERY_CONFIG_H__ */
index 3d82613..cea6266 100644 (file)
@@ -27,9 +27,6 @@
 #include "config.h"
 #include "core/log.h"
 #include "core/launch.h"
-#include "core/noti.h"
-#include "core/queue.h"
-#include "core/data.h"
 #include "core/devices.h"
 #include "core/device-handler.h"
 #include "core/device-notifier.h"
@@ -40,9 +37,7 @@
 #include "display/poll.h"
 #include "core/edbus-handler.h"
 #include "core/power-supply.h"
-
-#define PREDEF_LOWBAT                  "lowbat"
-#define PREDEF_LOWBAT_CHANGE_FREQ      "lowbat_change_freq"
+#include "power/power-handler.h"
 
 #define CHARGE_POWERSAVE_FREQ_ACT      "charge_powersave_freq_act"
 #define CHARGE_RELEASE_FREQ_ACT                "charge_release_freq_act"
@@ -50,7 +45,6 @@
 
 #define BATTERY_CHARGING       65535
 #define BATTERY_UNKNOWN                -1
-#define BATTERY_FULL           100
 
 #define WARNING_LOW_BAT_ACT            "warning_low_bat_act"
 #define CRITICAL_LOW_BAT_ACT           "critical_low_bat_act"
@@ -86,7 +80,13 @@ static int cur_bat_capacity = -1;
 
 static int lowbat_popup_option = 0;
 static int lowbat_freq = -1;
-static struct battery_config_info battery_info;
+static struct battery_config_info battery_info = {
+       .normal   = BATTERY_NORMAL,
+       .warning  = BATTERY_WARNING,
+       .critical = BATTERY_CRITICAL,
+       .poweroff = BATTERY_POWEROFF,
+       .realoff  = BATTERY_REALOFF,
+};
 
 static dd_list *lpe = NULL;
 static int scenario_count = 0;
@@ -102,7 +102,7 @@ static int lowbat_initialized(void *data)
        return status;
 }
 
-int lowbat_scenario(int old, int now, void *data)
+static int lowbat_scenario(int old, int now, void *data)
 {
        dd_list *n;
        struct lowbat_process_entry *scenario;
@@ -120,7 +120,7 @@ int lowbat_scenario(int old, int now, void *data)
        return found;
 }
 
-int lowbat_add_scenario(int old, int now, int (*func)(void *data))
+static int lowbat_add_scenario(int old, int now, int (*func)(void *data))
 {
        struct lowbat_process_entry *scenario;
 
@@ -155,21 +155,143 @@ static void print_lowbat_state(unsigned int bat_percent)
 #endif
 }
 
-int battery_check_act(void *data)
+static int power_execute(void)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, POWER_OPS_NAME);
+
+       return ops->execute(INTERNAL_PWROFF);
+}
+
+static int booting_done(void *data)
+{
+       static int done = 0;
+
+       if (data == NULL)
+               goto out;
+       done = (int)data;
+       if (!done)
+               goto out;
+       _I("booting done");
+out:
+       return done;
+}
+
+static int lowbat_popup(char *option)
+{
+       static int launched_poweroff = 0;
+       static const struct device_ops *apps = NULL;
+       struct popup_data *params;
+       int ret, state=0;
+       int r_disturb, s_disturb, r_block, s_block;
+       char *value;
+       pid_t pid;
+
+       if (!option)
+               return -1;
+
+       if (strcmp(option, POWER_OFF_BAT_ACT))
+               launched_poweroff = 0;
+
+       if (!strcmp(option, CRITICAL_LOW_BAT_ACT)) {
+#ifdef MICRO_DD
+               value = "lowbattery_critical";
+#else
+               value = "critical";
+#endif
+               lowbat_popup_option = LOWBAT_OPT_CHECK;
+       } else if (!strcmp(option, WARNING_LOW_BAT_ACT)) {
+               if (is_factory_mode() == 1)
+                       return 0;
+#ifdef MICRO_DD
+               value = "lowbattery_warning";
+#else
+               value = "warning";
+#endif
+               lowbat_popup_option = LOWBAT_OPT_WARNING;
+       } else if (!strcmp(option, POWER_OFF_BAT_ACT)) {
+               value = "poweroff";
+               lowbat_popup_option = LOWBAT_OPT_POWEROFF;
+       } else if (!strcmp(option, CHARGE_ERROR_ACT)) {
+               value = "chargeerr";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(option, CHARGE_ERROR_LOW_ACT)) {
+               value = "chargeerrlow";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(option, CHARGE_ERROR_HIGH_ACT)) {
+               value = "chargeerrhigh";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(option, CHARGE_ERROR_OVP_ACT)) {
+               value = "chargeerrovp";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(option, CHARGE_CHECK_ACT)) {
+               launched_poweroff = 0;
+               return 0;
+       } else
+               return -1;
+       _D("%s", value);
+       ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
+       if (state == 1 || ret != 0 || booting_done(NULL)) {
+
+               if (launched_poweroff == 1) {
+                       _I("will be foreced power off");
+                       power_execute();
+                       return 0;
+               }
+
+               if (lowbat_popup_option == LOWBAT_OPT_POWEROFF)
+                       launched_poweroff = 1;
+
+               pid = get_exec_pid(LOWBAT_EXEC_PATH);
+               if (pid > 0) {
+                       _I("pre launched %s destroy", LOWBAT_EXEC_PATH);
+                       kill(pid, SIGTERM);
+               }
+
+               FIND_DEVICE_INT(apps, "apps");
+
+               params = malloc(sizeof(struct popup_data));
+               if (params == NULL) {
+                       _E("Malloc failed");
+                       return -1;
+               }
+               r_disturb = vconf_get_int("memory/shealth/sleep/do_not_disturb", &s_disturb);
+               r_block = vconf_get_bool("db/setting/blockmode_wearable", &s_block);
+               if ((r_disturb != 0 && r_block != 0) ||
+                   (s_disturb == 0 && s_block == 0) ||
+                   lowbat_popup_option == LOWBAT_OPT_CHARGEERR)
+                       pm_change_internal(getpid(), LCD_NORMAL);
+               else
+                       _I("block LCD");
+               params->name = LOWBAT_POPUP_NAME;
+               params->key = POPUP_KEY_CONTENT;
+               params->value = strdup(value);
+               apps->init((void *)params);
+               free(params->value);
+               free(params);
+       } else {
+               _D("boot-animation running yet");
+       }
+
+       return 0;
+}
+
+static int battery_check_act(void *data)
 {
-       notify_action(PREDEF_LOWBAT, 1, CHARGE_CHECK_ACT);
+       lowbat_popup(CHARGE_CHECK_ACT);
        return 0;
 }
 
-int battery_warning_low_act(void *data)
+static int battery_warning_low_act(void *data)
 {
-       notify_action(PREDEF_LOWBAT, 1, WARNING_LOW_BAT_ACT);
+       lowbat_popup(WARNING_LOW_BAT_ACT);
        return 0;
 }
 
-int battery_critical_low_act(void *data)
+static int battery_critical_low_act(void *data)
 {
-       notify_action(PREDEF_LOWBAT, 1, CRITICAL_LOW_BAT_ACT);
+       lowbat_popup(CRITICAL_LOW_BAT_ACT);
        return 0;
 }
 
@@ -181,25 +303,25 @@ int battery_power_off_act(void *data)
 
 int battery_charge_err_act(void *data)
 {
-       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_ACT);
+       lowbat_popup(CHARGE_ERROR_ACT);
        return 0;
 }
 
 int battery_charge_err_low_act(void *data)
 {
-       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_LOW_ACT);
+       lowbat_popup(CHARGE_ERROR_LOW_ACT);
        return 0;
 }
 
 int battery_charge_err_high_act(void *data)
 {
-       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_HIGH_ACT);
+       lowbat_popup(CHARGE_ERROR_HIGH_ACT);
        return 0;
 }
 
 int battery_charge_err_ovp_act(void *data)
 {
-       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_OVP_ACT);
+       lowbat_popup(CHARGE_ERROR_OVP_ACT);
        return 0;
 }
 
@@ -222,10 +344,9 @@ static int battery_charge_act(void *data)
 static void lowbat_scenario_init(void)
 {
        lowbat_add_scenario(battery_info.normal, battery_info.warning, battery_warning_low_act);
-       lowbat_add_scenario(battery_info.warning, battery_info.critical, battery_warning_low_act);
-       lowbat_add_scenario(battery_info.critical, battery_info.poweroff, battery_critical_low_act);
+       lowbat_add_scenario(battery_info.warning, battery_info.critical, battery_critical_low_act);
        lowbat_add_scenario(battery_info.poweroff, battery_info.realoff, battery_power_off_act);
-       lowbat_add_scenario(battery_info.normal, battery_info.critical, battery_warning_low_act);
+       lowbat_add_scenario(battery_info.normal, battery_info.critical, battery_critical_low_act);
        lowbat_add_scenario(battery_info.warning, battery_info.poweroff, battery_critical_low_act);
        lowbat_add_scenario(battery_info.critical, battery_info.realoff, battery_power_off_act);
        lowbat_add_scenario(battery_info.normal, battery_info.poweroff, battery_critical_low_act);
@@ -276,14 +397,16 @@ static int lowbat_process(int bat_percent, void *ad)
        int status = -1;
        bool low_bat = false;
        bool full_bat = false;
+#ifdef MICRO_DD
        int extreme = 0;
+#endif
        int result = 0;
+       int lock = -1;
 
        new_bat_capacity = bat_percent;
        if (new_bat_capacity < 0)
                return -EINVAL;
        change_lowbat_level(new_bat_capacity);
-       pm_lock_internal(INTERNAL_LOCK_BATTERY, LCD_OFF, STAY_CUR_STATE, 0);
 
        if (new_bat_capacity != cur_bat_capacity) {
                _D("[BAT_MON] cur = %d new = %d", cur_bat_capacity, new_bat_capacity);
@@ -338,6 +461,7 @@ static int lowbat_process(int bat_percent, void *ad)
 
 
        if (status != -1) {
+               lock = pm_lock_internal(INTERNAL_LOCK_BATTERY, LCD_OFF, STAY_CUR_STATE, 0);
                ret = vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, status);
                power_supply_broadcast(CHARGE_LEVEL_SIGNAL, status);
                if (update_pm_setting)
@@ -348,12 +472,12 @@ static int lowbat_process(int bat_percent, void *ad)
                result = -EIO;
                goto exit;
        }
-
+#ifdef MICRO_DD
        if (vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &extreme) == 0 && extreme == TRUE &&
            (status > VCONFKEY_SYSMAN_BAT_POWER_OFF && status <= VCONFKEY_SYSMAN_BAT_FULL))
                if (vconf_set_int(VCONFKEY_PM_KEY_IGNORE, FALSE) == 0)
                        _I("release key ignore");
-
+#endif
        if (new_bat_capacity <= battery_info.warning)
                low_bat = true;
 
@@ -366,15 +490,17 @@ static int lowbat_process(int bat_percent, void *ad)
                cur_bat_state = battery_info.normal;
        result = lowbat_scenario(cur_bat_state, new_bat_state, NULL);
        if (result)
-               _I("cur_bat_state %d, new_bat_state %d", cur_bat_state, new_bat_state);
+               _I("cur %d, new %d(capacity %d)",
+               cur_bat_state, new_bat_state, bat_percent);
        cur_bat_state = new_bat_state;
 exit:
-       pm_unlock_internal(INTERNAL_LOCK_BATTERY, LCD_OFF, PM_SLEEP_MARGIN);
+       if (lock == 0)
+               pm_unlock_internal(INTERNAL_LOCK_BATTERY, LCD_OFF, PM_SLEEP_MARGIN);
 
        return result;
 }
 
-static int lowbat_read()
+static int lowbat_read(void)
 {
        int bat_percent, r;
 
@@ -385,6 +511,19 @@ static int lowbat_read()
        return bat_percent;
 }
 
+static int change_freq(char *option)
+{
+       int val = 0;
+
+       if (!option)
+               return -1;
+
+       if (!strcmp(option, CHARGE_POWERSAVE_FREQ_ACT))
+               val = 1;
+       device_notify(DEVICE_NOTIFIER_PMQOS_LOWBAT, (void*)val);
+       return 0;
+}
+
 static void change_lowbat_cpu_freq(int bat_percent)
 {
        static int init_cpu_freq = 0;
@@ -394,16 +533,16 @@ static void change_lowbat_cpu_freq(int bat_percent)
 
        if (bat_percent > battery_info.poweroff && init_cpu_freq == 0) {
                init_cpu_freq = 1;
-               notify_action(PREDEF_LOWBAT_CHANGE_FREQ, 1, CHARGE_RELEASE_FREQ_ACT);
+               change_freq(CHARGE_RELEASE_FREQ_ACT);
                return;
        }
 
        if (bat_percent <= battery_info.poweroff && power_save == 0) {
                power_save = 1;
-               notify_action(PREDEF_LOWBAT_CHANGE_FREQ, 1, CHARGE_POWERSAVE_FREQ_ACT);
+               change_freq(CHARGE_POWERSAVE_FREQ_ACT);
        } else if (power_save == 1) {
                power_save = 0;
-               notify_action(PREDEF_LOWBAT_CHANGE_FREQ, 1, CHARGE_RELEASE_FREQ_ACT);
+               change_freq(CHARGE_RELEASE_FREQ_ACT);
        }
 }
 
@@ -456,107 +595,6 @@ static int check_battery()
        return ret;
 }
 
-static int booting_done(void *data)
-{
-       static int done = 0;
-
-       if (data == NULL)
-               goto out;
-       done = (int)data;
-       if (!done)
-               goto out;
-       _I("booting done");
-out:
-       return done;
-}
-
-int lowbat_action(int argc, char **argv)
-{
-       int ret, state=0;
-       char argstr[128];
-       char* option = NULL;
-       char *value;
-       static int launched_poweroff = 0;
-       pid_t pid;
-       struct popup_data *params;
-       static const struct device_ops *apps = NULL;
-
-       if (argc < 1)
-               return -1;
-
-       if (strcmp(argv[0], POWER_OFF_BAT_ACT))
-               launched_poweroff = 0;
-
-       if (!strcmp(argv[0], CRITICAL_LOW_BAT_ACT)) {
-               value = "extreme";
-               lowbat_popup_option = LOWBAT_OPT_CHECK;
-       } else if (!strcmp(argv[0], WARNING_LOW_BAT_ACT)) {
-               if (is_factory_mode() == 1)
-                       return 0;
-               value = "warning";
-               lowbat_popup_option = LOWBAT_OPT_WARNING;
-       } else if (!strcmp(argv[0], POWER_OFF_BAT_ACT)) {
-               value = "poweroff";
-               lowbat_popup_option = LOWBAT_OPT_POWEROFF;
-       } else if (!strcmp(argv[0], CHARGE_ERROR_ACT)) {
-               value = "chargeerr";
-               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
-       } else if (!strcmp(argv[0], CHARGE_ERROR_LOW_ACT)) {
-               value = "chargeerrlow";
-               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
-       } else if (!strcmp(argv[0], CHARGE_ERROR_HIGH_ACT)) {
-               value = "chargeerrhigh";
-               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
-       } else if (!strcmp(argv[0], CHARGE_ERROR_OVP_ACT)) {
-               value = "chargeerrovp";
-               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
-       } else if (!strcmp(argv[0], CHARGE_CHECK_ACT)) {
-               launched_poweroff = 0;
-               return 0;
-       } else
-               return -1;
-       _D("%s", value);
-       ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
-       if (state == 1 || ret != 0 || booting_done(NULL)) {
-
-               if (launched_poweroff == 1) {
-                       _I("will be foreced power off");
-                       do_poweroff(0, NULL);
-                       return 0;
-               }
-
-               if (lowbat_popup_option == LOWBAT_OPT_POWEROFF)
-                       launched_poweroff = 1;
-
-               pid = predefine_get_pid(LOWBAT_EXEC_PATH);
-               if (pid > 0) {
-                       _I("pre launched %s destroy", LOWBAT_EXEC_PATH);
-                       kill(pid, SIGTERM);
-               }
-               if (apps == NULL) {
-                       apps = find_device("apps");
-                       if (apps == NULL)
-                               return 0;
-               }
-               params = malloc(sizeof(struct popup_data));
-               if (params == NULL) {
-                       _E("Malloc failed");
-                       return -1;
-               }
-               pm_change_internal(getpid(), LCD_NORMAL);
-               params->name = LOWBAT_POPUP_NAME;
-               params->key = POPUP_KEY_CONTENT;
-               params->value = strdup(value);
-               apps->init((void *)params);
-               free(params->value);
-               free(params);
-       } else {
-               _D("boot-animation running yet");
-       }
-
-       return 0;
-}
-
 static int check_power_save_mode(void)
 {
        int ret = 0;
@@ -574,19 +612,6 @@ static int check_power_save_mode(void)
        return ret;
 }
 
-int change_freq_action(int argc, char **argv)
-{
-       int val = 0;
-
-       if (argc < 1)
-               return -1;
-
-       if (!strcmp(argv[0], CHARGE_POWERSAVE_FREQ_ACT))
-               val = 1;
-       device_notify(DEVICE_NOTIFIER_PMQOS_LOWBAT, (void*)val);
-       return 0;
-}
-
 static int lowbat_monitor_init(void *data)
 {
        int status = 1;
@@ -597,8 +622,7 @@ static int lowbat_monitor_init(void *data)
        _I("%d %d %d %d %d", battery_info.normal, battery_info.warning,
                battery_info.critical, battery_info.poweroff, battery_info.realoff);
        lowbat_scenario_init();
-       register_action(PREDEF_LOWBAT, lowbat_action, NULL, NULL);
-       register_action(PREDEF_LOWBAT_CHANGE_FREQ, change_freq_action, NULL, NULL);
+       check_lowbat_percent(&battery.capacity);
        lowbat_process(battery.capacity, NULL);
        return 0;
 }
@@ -621,7 +645,7 @@ static const struct device_ops lowbat_device_ops = {
        .priority = DEVICE_PRIORITY_NORMAL,
        .name     = "lowbat",
        .init     = lowbat_init,
-       .exit    = lowbat_exit,
+       .exit     = lowbat_exit,
 };
 
 DEVICE_OPS_REGISTER(&lowbat_device_ops)
index 32b53f6..282aaf0 100644 (file)
 #define FILE_BUFF_MAX  1024
 #define NOT_INITIALIZED        (-1)
 
+#define METHOD_GET_NUM "GetNum"
 #define METHOD_GET_SERIAL      "GetSerial"
 #define SERIAL_PATH_NAME       "/csa/imei/serialno.dat"
 
 #define METHOD_GET_REVISION    "GetHWRev"
 #define PATH_NAME              "/proc/cpuinfo"
 #define REVISION_NAME  "Revision"
+#define SERIAL_NAME            "Serial"
+#define SERIAL_TOK_DELIMITER ","
 #define TOK_DELIMITER  ":"
 #define END_DELIMITER  " \n"
 
 #define CONVERT_TYPE   10
 #define REVISION_SIZE  4
 
+struct serial_info {
+       char serial[FILE_BUFF_MAX];
+       char num[FILE_BUFF_MAX];
+};
+
+static struct serial_info info;
+
 static int read_from_file(const char *path, char *buf, size_t size)
 {
        int fd;
@@ -111,6 +121,36 @@ static int get_revision(char *rev)
        return 0;
 }
 
+static int get_cpuinfo_serial(void)
+{
+       char buf[FILE_BUFF_MAX];
+       char *tag;
+       char *start, *ptr;
+
+       if (read_from_file(PATH_NAME, buf, FILE_BUFF_MAX) < 0) {
+               _E("fail to read %s\n", PATH_NAME);
+               return -1;
+       }
+
+       tag = strstr(buf, SERIAL_NAME);
+       if (tag == NULL) {
+               _E("cannot find Hardware in %s\n", PATH_NAME);
+               return -1;
+       }
+
+       start = strstr(tag, TOK_DELIMITER);
+       if (start == NULL) {
+               _E("cannot find Hardware in %s\n", PATH_NAME);
+               return -1;
+       }
+
+       start ++;
+       ptr = strtok(start, END_DELIMITER);
+       strncpy(info.serial, ptr, strlen(ptr));
+       _D("%s", info.serial);
+       return 0;
+}
+
 static DBusMessage *dbus_revision_handler(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
@@ -133,22 +173,78 @@ out:
        return reply;
 }
 
-static int get_serial(unsigned char *buf)
+static int get_serial(void)
 {
+       static int ret = -EIO;
        int fd;
        int r;
-       int ret = 0;
+       char *tag;
+       char *serial;
+       char buf[FILE_BUFF_MAX];
+
+       if (ret == 0)
+               return ret;
 
        fd = open(SERIAL_PATH_NAME, O_RDONLY, 0);
        if (fd < 0)
                return -ENOENT;
 
        r = read(fd, buf, FILE_BUFF_MAX);
-       if ((r >= 0) && (r < FILE_BUFF_MAX))
-               buf[r] = '\0';
-       else
-               ret = -EIO;
+       if (r < 0 || r >= FILE_BUFF_MAX)
+               goto out;
+       buf[r] = '\0';
+       tag = buf;
+       serial = strstr(buf, SERIAL_TOK_DELIMITER);
+       if (serial) {
+               serial = strtok(tag, SERIAL_TOK_DELIMITER);
+               if (!serial)
+                       goto out;
+               r = strlen(serial);
+               strncpy(info.serial, serial, r);
+       } else {
+               strncpy(info.serial, buf, r);
+       }
+       _D("%s %d", info.serial, r);
+       ret = 0;
+out:
+       close(fd);
+       return ret;
+}
+
+static int get_num(void)
+{
+       static int ret = -EIO;
+       int fd;
+       int r;
+       char *tag;
+       char *num;
+       char buf[FILE_BUFF_MAX];
+
+       if (ret == 0)
+               return ret;
+
+       fd = open(SERIAL_PATH_NAME, O_RDONLY, 0);
+       if (fd < 0)
+               return -ENOENT;
 
+       r = read(fd, buf, FILE_BUFF_MAX);
+       if (r < 0 || r >= FILE_BUFF_MAX)
+               goto out;
+       buf[r] = '\0';
+       num = strstr(buf, SERIAL_TOK_DELIMITER);
+       if (!num)
+               goto out;
+       tag = buf;
+       strtok(tag, SERIAL_TOK_DELIMITER);
+       strtok(NULL, SERIAL_TOK_DELIMITER);
+       num = strtok(NULL, END_DELIMITER);
+       if (!num)
+               goto out;
+       r = strlen(num);
+       strncpy(info.num, num, r);
+       _D("%s %d", info.num, r);
+       ret = 0;
+out:
        close(fd);
        return ret;
 }
@@ -158,20 +254,46 @@ static DBusMessage *dbus_serial_handler(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessageIter iter, arr;
        DBusMessage *reply;
        static int len = 0;
+       static int ret = NOT_INITIALIZED;
+       char buf[FILE_BUFF_MAX];
+       char *param = buf;
+
+       ret = get_serial();
+       if (ret < 0)
+               ret = get_cpuinfo_serial();
+       if (ret == 0) {
+               len = strlen(info.serial);
+               strncpy(buf, info.serial, len);
+               _D("%s %d", buf, len);
+               goto out;
+       }
+       _E("fail to get serial");
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &param);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_num_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter, arr;
+       DBusMessage *reply;
+       static int len = 0;
        static char buf[FILE_BUFF_MAX];
        static char *param = buf;
        static int ret = NOT_INITIALIZED;
 
-       if (ret == 0)
-               goto out;
-       ret = get_serial(buf);
+       ret = get_num();
        if (ret == 0) {
-               len = strlen(buf);
+               len = strlen(info.num);
+               strncpy(buf, info.num, len);
+               _D("%s %d", buf, len);
                goto out;
        }
-       _E("fail to get serial");
+       _E("fail to get num");
 out:
-       _D("serial : %s %d", buf, len);
        reply = dbus_message_new_method_return(msg);
        dbus_message_iter_init_append(reply, &iter);
        dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &param);
@@ -182,6 +304,7 @@ out:
 static const struct edbus_method edbus_methods[] = {
        { METHOD_GET_SERIAL,   NULL, "si", dbus_serial_handler },
        { METHOD_GET_REVISION,   NULL, "i", dbus_revision_handler },
+       { METHOD_GET_NUM,   NULL, "si", dbus_num_handler },
 };
 
 static void board_init(void *data)
@@ -191,6 +314,12 @@ static void board_init(void *data)
        ret = register_edbus_method(DEVICED_PATH_BOARD, edbus_methods, ARRAY_SIZE(edbus_methods));
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
+       ret = get_serial();
+       if (ret < 0)
+               _E("fail to get serial info(%d)", ret);
+       ret = get_num();
+       if (ret < 0)
+               _E("fail to get num info(%d)", ret);
 }
 
 static const struct device_ops board_device_ops = {
index dcb21a9..de90abb 100644 (file)
@@ -48,7 +48,7 @@ static int control_handler(int argc, char **argv)
        int device;
        bool enable;
        int ret;
-       const struct device_ops *dev_ops;
+       const struct device_ops *dev_ops = NULL;
 
        _I("argc : %d", argc);
        for (i = 0; i < argc; ++i)
@@ -71,11 +71,7 @@ static int control_handler(int argc, char **argv)
 
        if (i >= ARRAY_SIZE(devices))
                return -EINVAL;
-
-       dev_ops = find_device(devices[i].name);
-       if (!dev_ops)
-               return -ENODEV;
-
+       FIND_DEVICE_INT(dev_ops, devices[i].name);
        if (enable)
                ret = device_start(dev_ops);
        else
@@ -91,7 +87,7 @@ static int get_control_handler(int argc, char **argv)
        int device;
        bool enable;
        int ret;
-       const struct device_ops *dev_ops;
+       const struct device_ops *dev_ops = NULL;
 
        _I("argc : %d", argc);
        for (i = 0; i < argc; ++i)
@@ -114,9 +110,7 @@ static int get_control_handler(int argc, char **argv)
        if (i >= ARRAY_SIZE(devices))
                return -EINVAL;
 
-       dev_ops = find_device(devices[i].name);
-       if (!dev_ops)
-               return -ENODEV;
+       FIND_DEVICE_INT(dev_ops, devices[i].name);
 
        return device_get_status(dev_ops);
 }
@@ -225,8 +219,6 @@ static void control_init(void *data)
        ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
-
-       register_action(CONTROL_HANDLER_NAME, control_handler, NULL, NULL);
 }
 
 static const struct device_ops control_device_ops = {
diff --git a/src/cool-down/cool-down-micro.c b/src/cool-down/cool-down-micro.c
new file mode 100644 (file)
index 0000000..e15ac05
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <device-node.h>
+#include <sys/un.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <fcntl.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "core/config-parser.h"
+#include "core/udev.h"
+#include "hall/hall-handler.h"
+#include "display/poll.h"
+
+#define COOL_DOWN_DBUS_INTERFACE "org.tizen.trm.siop"
+#define COOL_DOWN_DBUS_PATH "/Org/Tizen/Trm/Siop"
+#define COOL_DOWN_DBUS_SIGNAL "ChangedCooldownMode"
+
+#define COOL_DOWN_POPUP_NAME           "cooldown-syspopup"
+
+#define SIGNAL_COOL_DOWN_SHUT_DOWN     "ShutDown"
+#define SIGNAL_COOL_DOWN_LIMIT_ACTION  "LimitAction"
+#define SIGNAL_COOL_DOWN_WARNING_ACTION        "WarningAction"
+#define SIGNAL_COOL_DOWN_RELEASE                       "Release"
+#define SIGNAL_COOL_DOWN_RESPONSE              "CoolDownResponse"
+
+#define METHOD_COOL_DOWN_STATUS                "GetCoolDownStatus"
+#define METHOD_COOL_DOWN_CHANGED       "CoolDownChanged"
+
+#define SIGNAL_STRING_MAX_LEN  30
+
+#define COOL_DOWN_LIMIT_ACTION_WAIT    60
+#define COOL_DOWN_SHUTDOWN_POPUP_WAIT  60
+#define COOL_DOWN_SHUTDOWN_FORCE_WAIT  30
+#define SYSTEMD_STOP_POWER_OFF         4
+
+#define VCONFKEY_SYSMAN_COOL_DOWN_MODE "db/private/sysman/cool_down_mode"
+
+enum cool_down_status_type {
+       COOL_DOWN_NONE_INIT,
+       COOL_DOWN_RELEASE,
+       COOL_DOWN_WARNING_ACTION,
+       COOL_DOWN_LIMIT_ACTION,
+       COOL_DOWN_SHUT_DOWN,
+};
+
+struct popup_data {
+       char *name;
+       char *key;
+};
+
+static int cool_down_level = 0;
+static const char *cool_down_status = NULL;
+static const struct device_ops *hall_ic = NULL;
+static int cool_down_lock = 0;
+
+static int hall_ic_status(void)
+{
+       int ret;
+
+       ret = device_get_status(hall_ic);
+       if (ret < 0)
+               return HALL_IC_OPENED;
+       return ret;
+}
+
+static int telephony_execute(void *data)
+{
+       static const struct device_ops *ops = NULL;
+       int mode = *(int *)data;
+       int old = 0;
+
+       vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &old);
+       if ((old == 0 && mode == 1) ||
+           (old == 1 && mode == 0))
+               return 0;
+
+       FIND_DEVICE_INT(ops, "telephony");
+
+       return ops->execute(data);
+}
+
+static void flight_mode_off(void)
+{
+       int mode = 1;
+
+       telephony_execute(&mode);
+}
+
+static void flight_mode_on(void)
+{
+       int mode = 0;
+
+       telephony_execute(&mode);
+}
+
+static int cool_down_popup(char *type)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+       int val;
+
+       val = hall_ic_status();
+       if (val == HALL_IC_CLOSED) {
+               _I("cover is closed");
+               return 0;
+       }
+
+       FIND_DEVICE_INT(apps, "apps");
+
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+       cool_down_lock = 1;
+       pm_change_internal(getpid(), LCD_NORMAL);
+       pm_lock_internal(INTERNAL_LOCK_COOL_DOWN, LCD_OFF, STAY_CUR_STATE, 0);
+       params->name = COOL_DOWN_POPUP_NAME;
+       params->key = type;
+       apps->init((void *)params);
+       free(params);
+       return 0;
+}
+
+static void broadcast_cool_down_status(int status)
+{
+       int ret;
+       char buf[SIGNAL_STRING_MAX_LEN];
+       char *param[1];
+       static int old = COOL_DOWN_NONE_INIT;
+
+       if (old == status)
+               return;
+
+       old = status;
+       if (cool_down_lock) {
+               cool_down_lock = 0;
+               pm_unlock_internal(INTERNAL_LOCK_COOL_DOWN, LCD_OFF, STAY_CUR_STATE);
+       }
+
+       switch(status)
+       {
+       case COOL_DOWN_RELEASE:
+               cool_down_status = SIGNAL_COOL_DOWN_RELEASE;
+               break;
+       case COOL_DOWN_WARNING_ACTION:
+               cool_down_status = SIGNAL_COOL_DOWN_WARNING_ACTION;
+               break;
+       case COOL_DOWN_LIMIT_ACTION:
+               cool_down_status = SIGNAL_COOL_DOWN_LIMIT_ACTION;
+               break;
+       case COOL_DOWN_SHUT_DOWN:
+               return;
+       default:
+               _E("abnormal value %d", status);
+               return;
+       }
+
+       snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
+       param[0] = buf;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+               METHOD_COOL_DOWN_CHANGED, "s", param);
+       device_notify(DEVICE_NOTIFIER_COOL_DOWN, (void *)status);
+       _I("%s", cool_down_status);
+}
+
+static int cool_down_booting_done(void *data)
+{
+       static int done = 0;
+       int mode;
+       int ret;
+
+       if (data == NULL)
+               goto out;
+
+       done = (int)data;
+
+       switch (cool_down_level)
+       {
+       case COOL_DOWN_RELEASE:
+               broadcast_cool_down_status(COOL_DOWN_RELEASE);
+               break;
+       case COOL_DOWN_WARNING_ACTION:
+               broadcast_cool_down_status(COOL_DOWN_WARNING_ACTION);
+               break;
+       case COOL_DOWN_LIMIT_ACTION:
+               flight_mode_on();
+               broadcast_cool_down_status(COOL_DOWN_LIMIT_ACTION);
+               break;
+       case COOL_DOWN_SHUT_DOWN:
+               cool_down_popup(SIGNAL_COOL_DOWN_SHUT_DOWN);
+               break;
+       default:
+               _E("abnormal value %d", cool_down_level);
+               break;
+       }
+out:
+       return done;
+}
+
+static int cool_down_execute(void *data)
+{
+       int booting_done;
+       static int old = COOL_DOWN_NONE_INIT;
+
+       cool_down_level = *(int *)data;
+       if (old == cool_down_level)
+               return 0;
+       _I("status %d", cool_down_level);
+       booting_done = cool_down_booting_done(NULL);
+       if (!booting_done)
+               return 0;
+       vconf_set_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, cool_down_level);
+       old = cool_down_level;
+
+       switch (cool_down_level)
+       {
+       case COOL_DOWN_RELEASE:
+               flight_mode_off();
+               broadcast_cool_down_status(COOL_DOWN_RELEASE);
+               break;
+       case COOL_DOWN_WARNING_ACTION:
+               broadcast_cool_down_status(COOL_DOWN_WARNING_ACTION);
+               break;
+       case COOL_DOWN_LIMIT_ACTION:
+               cool_down_popup(SIGNAL_COOL_DOWN_LIMIT_ACTION);
+               break;
+       case COOL_DOWN_SHUT_DOWN:
+               cool_down_popup(SIGNAL_COOL_DOWN_SHUT_DOWN);
+               break;
+       }
+       return 0;
+}
+
+static int changed_device(int level)
+{
+       int *state = NULL;
+       int status = level;
+
+       state = &status;
+       cool_down_execute((void *)state);
+out:
+       return 0;
+}
+
+static void cool_down_popup_response_signal_handler(void *data, DBusMessage *msg)
+{
+       flight_mode_on();
+       broadcast_cool_down_status(COOL_DOWN_LIMIT_ACTION);
+}
+
+static int get_action_id(char *action)
+{
+       int val;
+
+       if (MATCH(action, SIGNAL_COOL_DOWN_RELEASE))
+               val = COOL_DOWN_RELEASE;
+       else if (MATCH(action, SIGNAL_COOL_DOWN_WARNING_ACTION))
+               val = COOL_DOWN_WARNING_ACTION;
+       else if (MATCH(action, SIGNAL_COOL_DOWN_LIMIT_ACTION))
+               val = COOL_DOWN_LIMIT_ACTION;
+       else if (MATCH(action, SIGNAL_COOL_DOWN_SHUT_DOWN))
+               val = COOL_DOWN_SHUT_DOWN;
+       else
+               val = -EINVAL;
+
+       return val;
+}
+
+static void cool_down_edbus_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int val;
+       char *action;
+
+       if (dbus_message_is_signal(msg, COOL_DOWN_DBUS_INTERFACE, COOL_DOWN_DBUS_SIGNAL) == 0) {
+               _E("there is no cool down signal");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       if (dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &action, DBUS_TYPE_INVALID) == 0) {
+               _E("there is no message");
+               return;
+       }
+
+       val = get_action_id(action);
+
+       if (val < 0)
+               _E("Invalid argument! %s", action);
+       else
+               changed_device(val);
+}
+
+static DBusMessage *dbus_get_status(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char buf[SIGNAL_STRING_MAX_LEN];
+       char *param = buf;
+
+       switch(cool_down_level)
+       {
+       case COOL_DOWN_SHUT_DOWN:
+               cool_down_status = SIGNAL_COOL_DOWN_SHUT_DOWN;
+               break;
+       case COOL_DOWN_LIMIT_ACTION:
+               cool_down_status = SIGNAL_COOL_DOWN_LIMIT_ACTION;
+               break;
+       default:
+               cool_down_status = SIGNAL_COOL_DOWN_RELEASE;
+               break;
+       }
+
+       snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &param);
+       return reply;
+}
+
+static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret = 0;
+       int val;
+       int argc;
+       char *type_str;
+       char *argv[2];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0 || !argv[0] || !argv[1]){
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       val = get_action_id(argv[1]);
+
+       if (val < 0) {
+               _E("Invalid argument! %s", argv[1]);
+               ret = val;
+       } else {
+               changed_device(val);
+       }
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { METHOD_COOL_DOWN_STATUS,      NULL,   "s", dbus_get_status },
+       { METHOD_COOL_DOWN_CHANGED,     "siss", "i", dbus_device_handler },
+};
+
+static void cool_down_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+       register_edbus_signal_handler(COOL_DOWN_DBUS_PATH, COOL_DOWN_DBUS_INTERFACE,
+                       COOL_DOWN_DBUS_SIGNAL,
+                       cool_down_edbus_signal_handler);
+       register_edbus_signal_handler(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       SIGNAL_COOL_DOWN_RESPONSE,
+                       cool_down_popup_response_signal_handler);
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, cool_down_booting_done);
+       hall_ic = find_device(HALL_IC_NAME);
+}
+
+static const struct device_ops cool_down_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "cool-down",
+       .init     = cool_down_init,
+       .execute  = cool_down_execute,
+};
+
+DEVICE_OPS_REGISTER(&cool_down_device_ops)
diff --git a/src/cool-down/cool-down.c b/src/cool-down/cool-down.c
new file mode 100644 (file)
index 0000000..c8b10c8
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <device-node.h>
+#include <sys/un.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <fcntl.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "core/udev.h"
+#include "hall/hall-handler.h"
+
+#define COOL_DOWN_DBUS_INTERFACE "org.tizen.trm.siop"
+#define COOL_DOWN_DBUS_PATH "/Org/Tizen/Trm/Siop"
+#define COOL_DOWN_DBUS_SIGNAL "ChangedCooldownMode"
+
+#define COOL_DOWN_POPUP_NAME           "cooldown-syspopup"
+
+#define SIGNAL_COOL_DOWN_SHUT_DOWN     "ShutDown"
+#define SIGNAL_COOL_DOWN_NOTIFICATION  "Notification"
+#define SIGNAL_COOL_DOWN_LIMIT_ACTION  "LimitAction"
+#define SIGNAL_COOL_DOWN_RELEASE       "Release"
+
+#define METHOD_COOL_DOWN_STATUS                "GetCoolDownStatus"
+#define METHOD_COOL_DOWN_CHANGED       "CoolDownChanged"
+
+#define SIGNAL_STRING_MAX_LEN  30
+
+#define COOL_DOWN_LIMIT_ACTION_WAIT    60
+#define COOL_DOWN_SHUTDOWN_POPUP_WAIT  60
+#define COOL_DOWN_SHUTDOWN_FORCE_WAIT  30
+#define SYSTEMD_STOP_POWER_OFF         4
+
+#define VCONFKEY_SYSMAN_COOL_DOWN_MODE "db/private/sysman/cool_down_mode"
+
+enum cool_down_status_type {
+       COOL_DOWN_RELEASE       = 0,
+       COOL_DOWN_NOTIFICATION  = 1,
+       COOL_DOWN_SHUT_DOWN     = 2,
+};
+
+enum cool_down_timer_type {
+       COOL_DOWN_LIMIT_ACTION_TIMER    = 1,
+       COOL_DOWN_POPUP_TIMER           = 2,
+       COOL_DOWN_SHUT_DOWN_TIMER       = 3,
+};
+
+enum cool_down_timer_status {
+       COOL_DOWN_TIMER_DELETED_ALREADY = 0,
+       COOL_DOWN_TIMER_DELETED_NOW             = 1,
+};
+
+struct popup_data {
+       char *name;
+       char *key;
+};
+
+static int cool_down_level = 0;
+static const char *cool_down_status = NULL;
+static Ecore_Timer *app_limit_timer = NULL;
+static Ecore_Timer *shut_down_timer = NULL;
+static const struct device_ops *hall_ic = NULL;
+
+static void cool_down_timer_start(int type);
+static int cool_down_timer_stop(int type);
+
+static int hall_ic_status(void)
+{
+       int ret;
+
+       ret = device_get_status(hall_ic);
+       if (ret < 0)
+               return HALL_IC_OPENED;
+       return ret;
+}
+
+static int cool_down_popup(char *type)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+       int val;
+
+       val = hall_ic_status();
+       if (val == HALL_IC_CLOSED) {
+               _I("cover is closed");
+               return 0;
+       }
+
+       FIND_DEVICE_INT(apps, "apps");
+
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+       params->name = COOL_DOWN_POPUP_NAME;
+       params->key = type;
+       apps->init((void *)params);
+       free(params);
+       return 0;
+}
+
+static Eina_Bool broadcast_cool_down_limit_action(void *data)
+{
+       char buf[SIGNAL_STRING_MAX_LEN];
+       char *param[1];
+
+       cool_down_timer_stop(COOL_DOWN_LIMIT_ACTION_TIMER);
+
+       cool_down_status = SIGNAL_COOL_DOWN_LIMIT_ACTION;
+       snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
+       param[0] = buf;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+               METHOD_COOL_DOWN_CHANGED, "s", param);
+       _I("%s", SIGNAL_COOL_DOWN_LIMIT_ACTION);
+       return EINA_FALSE;
+}
+
+static Eina_Bool cool_down_shutdown_popup(void *data)
+{
+       cool_down_popup(SIGNAL_COOL_DOWN_SHUT_DOWN);
+       cool_down_timer_start(COOL_DOWN_SHUT_DOWN_TIMER);
+       return EINA_FALSE;
+}
+
+static Eina_Bool cool_down_shutdown_force(void *data)
+{
+       cool_down_timer_stop(COOL_DOWN_SHUT_DOWN_TIMER);
+       vconf_set_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, COOL_DOWN_SHUT_DOWN);
+       vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, SYSTEMD_STOP_POWER_OFF);
+       return EINA_FALSE;
+}
+
+static int cool_down_timer_stop(int type)
+{
+       if (type == COOL_DOWN_NOTIFICATION) {
+               if (!app_limit_timer)
+                       return COOL_DOWN_TIMER_DELETED_ALREADY;
+               ecore_timer_del(app_limit_timer);
+               app_limit_timer = NULL;
+       } else if (type == COOL_DOWN_POPUP_TIMER ||
+           type == COOL_DOWN_SHUT_DOWN_TIMER) {
+               if (!shut_down_timer)
+                       return COOL_DOWN_TIMER_DELETED_ALREADY;
+               ecore_timer_del(shut_down_timer);
+               shut_down_timer = NULL;
+       }
+       _D("stop %d", type);
+       return COOL_DOWN_TIMER_DELETED_NOW;
+}
+
+static void cool_down_timer_start(int type)
+{
+       cool_down_timer_stop(type);
+       if (type == COOL_DOWN_LIMIT_ACTION_TIMER) {
+               app_limit_timer = ecore_timer_add(COOL_DOWN_LIMIT_ACTION_WAIT,
+                               broadcast_cool_down_limit_action, NULL);
+               if (!app_limit_timer)
+                       _E("fail to add timer");
+       } else if (type == COOL_DOWN_POPUP_TIMER) {
+               shut_down_timer = ecore_timer_add(COOL_DOWN_SHUTDOWN_POPUP_WAIT,
+                               cool_down_shutdown_popup, NULL);
+               if (!shut_down_timer)
+                       _E("fail to add timer");
+       } else if (type == COOL_DOWN_SHUT_DOWN_TIMER) {
+               shut_down_timer = ecore_timer_add(COOL_DOWN_SHUTDOWN_FORCE_WAIT,
+                               cool_down_shutdown_force, NULL);
+               if (!shut_down_timer)
+                       _E("fail to add timer");
+       }
+       _D("start %d", type);
+}
+
+static void broadcast_cool_down_status(int status)
+{
+       int ret;
+       char buf[SIGNAL_STRING_MAX_LEN];
+       char *param[1];
+
+       switch(status)
+       {
+       case COOL_DOWN_RELEASE:
+               cool_down_status = SIGNAL_COOL_DOWN_RELEASE;
+               cool_down_timer_stop(COOL_DOWN_SHUT_DOWN_TIMER);
+               cool_down_timer_stop(COOL_DOWN_POPUP_TIMER);
+               cool_down_timer_stop(COOL_DOWN_LIMIT_ACTION_TIMER);
+               break;
+       case COOL_DOWN_NOTIFICATION:
+               cool_down_status = SIGNAL_COOL_DOWN_NOTIFICATION;
+               cool_down_timer_stop(COOL_DOWN_SHUT_DOWN_TIMER);
+               cool_down_timer_stop(COOL_DOWN_POPUP_TIMER);
+               cool_down_timer_start(COOL_DOWN_LIMIT_ACTION_TIMER);
+               break;
+       case COOL_DOWN_SHUT_DOWN:
+               ret = cool_down_timer_stop(COOL_DOWN_LIMIT_ACTION_TIMER);
+               if (ret == COOL_DOWN_TIMER_DELETED_NOW)
+                       broadcast_cool_down_limit_action(NULL);
+               cool_down_status = SIGNAL_COOL_DOWN_SHUT_DOWN;
+               cool_down_timer_start(COOL_DOWN_POPUP_TIMER);
+               break;
+       default:
+               _E("abnormal value %d", status);
+               return;
+       }
+
+       snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
+       param[0] = buf;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+               METHOD_COOL_DOWN_CHANGED, "s", param);
+       device_notify(DEVICE_NOTIFIER_COOL_DOWN, (void *)status);
+       _I("%s", cool_down_status);
+}
+
+static int cool_down_booting_done(void *data)
+{
+       static int done = 0;
+       int mode;
+       int ret;
+
+       if (data == NULL)
+               goto out;
+
+       done = (int)data;
+       if (cool_down_level) {
+               if (cool_down_level == COOL_DOWN_SHUT_DOWN) {
+                       broadcast_cool_down_status(COOL_DOWN_NOTIFICATION);
+                       broadcast_cool_down_limit_action(NULL);
+                       cool_down_timer_start(COOL_DOWN_POPUP_TIMER);
+                       goto out;
+               }
+               broadcast_cool_down_status(cool_down_level);
+               goto out;
+       }
+       ret = vconf_get_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, &mode);
+       vconf_set_int(VCONFKEY_SYSMAN_COOL_DOWN_MODE, cool_down_level);
+       if (ret == 0 && mode == COOL_DOWN_SHUT_DOWN)
+               cool_down_popup(SIGNAL_COOL_DOWN_RELEASE);
+out:
+       return done;
+}
+
+static int cool_down_execute(void *data)
+{
+       int booting_done;
+       static int old = COOL_DOWN_RELEASE;
+
+       cool_down_level = *(int *)data;
+       if (old == cool_down_level)
+               return 0;
+       _I("status %d", cool_down_level);
+
+       booting_done = cool_down_booting_done(NULL);
+       if (!booting_done)
+               return 0;
+
+       if (old == COOL_DOWN_RELEASE &&
+           cool_down_level == COOL_DOWN_SHUT_DOWN) {
+               old = cool_down_level;
+               broadcast_cool_down_status(COOL_DOWN_NOTIFICATION);
+               broadcast_cool_down_limit_action(NULL);
+               cool_down_timer_start(COOL_DOWN_POPUP_TIMER);
+               return 0;
+       }
+       old = cool_down_level;
+       broadcast_cool_down_status(cool_down_level);
+       return 0;
+}
+
+static int changed_device(int level)
+{
+       int *state = NULL;
+       int status = level;
+
+       state = &status;
+       cool_down_execute((void *)state);
+out:
+       return 0;
+}
+
+static void cool_down_edbus_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int val = 0;
+
+       if (dbus_message_is_signal(msg, COOL_DOWN_DBUS_INTERFACE, COOL_DOWN_DBUS_SIGNAL) == 0) {
+               _E("there is no cool down signal");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       if (dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID) == 0) {
+               _E("there is no message");
+               return;
+       }
+       changed_device(val);
+}
+
+static DBusMessage *dbus_get_status(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char buf[SIGNAL_STRING_MAX_LEN];
+       char *param = buf;
+
+       snprintf(buf, SIGNAL_STRING_MAX_LEN, "%s", cool_down_status);
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &param);
+       return reply;
+}
+
+static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int val;
+       int argc;
+       char *type_str;
+       char *argv[2];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0 || !argv[0] || !argv[1]){
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       val = atoi(argv[1]);
+       changed_device(val);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { METHOD_COOL_DOWN_STATUS,      NULL,   "s", dbus_get_status },
+       { METHOD_COOL_DOWN_CHANGED,     "siss", "i", dbus_device_handler },
+};
+
+static void cool_down_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+       register_edbus_signal_handler(COOL_DOWN_DBUS_PATH, COOL_DOWN_DBUS_INTERFACE,
+                       COOL_DOWN_DBUS_SIGNAL,
+                   cool_down_edbus_signal_handler);
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, cool_down_booting_done);
+       hall_ic = find_device(HALL_IC_NAME);
+}
+
+static const struct device_ops cool_down_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "cool-down",
+       .init     = cool_down_init,
+       .execute  = cool_down_execute,
+};
+
+DEVICE_OPS_REGISTER(&cool_down_device_ops)
diff --git a/src/core/buxton-helper.c b/src/core/buxton-helper.c
new file mode 100644 (file)
index 0000000..2d14a3c
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+/*
+ * @file buxton-helper.c
+ *
+ * @desc Helper function for simplification of using and
+ * for looking like vconf interface
+ *
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "buxton-helper.h"
+#include "log.h"
+#include "common.h"
+
+#define BUXTON_ATTEMPT_NUMBER 5
+
+static BuxtonClient client;
+
+struct callback_context {
+       struct buxton_variant *b_variant;
+       int error_code;
+};
+
+void general_get_callback(BuxtonResponse response, void *data)
+{
+       BuxtonKey key;
+       struct buxton_variant *b_variant;
+       struct callback_context *context;
+       void *p;
+       uint32_t ret;
+       BuxtonDataType key_type;
+
+       ret_msg_if(data == NULL,
+               "Invalid pointer argument!");
+       context = (struct callback_context *)data;
+       ret_msg_if(context->b_variant == NULL,
+               "Invalid b_variant argument!");
+
+       b_variant = context->b_variant;
+       context->error_code = -1;
+
+       ret = buxton_response_status(response);
+       ret_msg_if(ret, "Invalid buxton response");
+
+       p = buxton_response_value(response);
+
+       ret_msg_if(p == NULL, "Bad buxton response: %s", strerror(errno));
+
+       key = buxton_response_key(response);
+       if (!key) {
+               free(p);
+               return;
+       }
+
+       key_type = buxton_key_get_type(key);
+       if(key_type != b_variant->type) {
+               _E("Not proper type");
+               goto out;
+       }
+
+       switch (key_type) {
+       case STRING:
+               b_variant->string_value = (char *)p;
+               break;
+       case INT32:
+               b_variant->int32_value = *(int32_t *)p;
+               break;
+       case UINT32:
+               b_variant->uint32_value = *(uint32_t *)p;
+               break;
+       case INT64:
+               b_variant->int64_value = *(int64_t *)p;
+               break;
+       case UINT64:
+               b_variant->uint64_value = *(uint64_t *)p;
+               break;
+       case FLOAT:
+               b_variant->float_value = *(float *)p;
+               break;
+       case DOUBLE:
+               b_variant->double_value = *(double *)p;
+               break;
+       case BOOLEAN:
+               b_variant->bool_value = *(bool *)p;
+               break;
+       default:
+               break;
+       }
+
+       context->error_code = 0;
+out:
+       /* we need to free only in case of data types which was copied by
+        * _value_, string's pointer will be used by client */
+       if (key_type != STRING)
+               free(p);
+       free(key);
+}
+
+static int init_buxton_client(void)
+{
+       int ret;
+
+       if(client != NULL)
+               return 0;
+
+       ret = buxton_open(&client);
+       ret_value_msg_if(ret <= 0, -1, "couldn't connect to buxton server");
+
+       return 0;
+}
+
+void finilize_buxton_client(void)
+{
+       /* buxton_close is robust to null pointer */
+       buxton_close(client);
+}
+
+int buxton_get_var(char *layer_name, char *group_name,
+        char *key_name, struct buxton_variant *value)
+{
+       BuxtonKey key;
+       int ret;
+       int attempts = 0;
+
+       struct callback_context context = {
+               .b_variant = value,
+               .error_code = 0,
+       };
+
+       ret_value_msg_if(value == NULL, -1,
+               "Please provide valid pointer!");
+
+get_init:
+       ret = init_buxton_client();
+       ++attempts;
+       ret_value_if(ret, ret);
+
+       key = buxton_key_create(group_name, key_name,
+               layer_name, value->type);
+
+       ret = buxton_get_value(client, key, general_get_callback, &context,
+               true);
+       buxton_key_free(key);
+       /* don't return buxton error code, need to return internal error
+        * code */
+       if (errno == EPIPE && attempts < BUXTON_ATTEMPT_NUMBER) {
+               buxton_close(client);
+               client = NULL;
+               goto get_init;
+       }
+       return ret || context.error_code ? -1 : 0;
+}
+
+void general_set_callback(BuxtonResponse response, void *data)
+{
+       BuxtonKey key;
+       char *name;
+       int *ret;
+       int resp_ret;
+
+       ret_msg_if(data == NULL, "Please provide *data for return value!");
+       ret = data;
+       resp_ret = buxton_response_status(response);
+
+       if (resp_ret != 0) {
+               _E("Failed to set value\n");
+               *ret = resp_ret;
+               return;
+       }
+
+       key = buxton_response_key(response);
+       name = buxton_key_get_name(key);
+       _I("Set value for key %s\n", name);
+       buxton_key_free(key);
+       free(name);
+       *ret = 0;
+}
+
+/* for avoid ptr unligtment */
+static void *get_variant_align(struct buxton_variant *b_variant)
+{
+       switch (b_variant->type) {
+       case CONF_STRING:
+               return b_variant->string_value;
+       case CONF_INT32:
+               return &b_variant->int32_value;
+       case CONF_UINT32:
+               return &b_variant->uint32_value;
+       case CONF_INT64:
+               return &b_variant->int64_value;
+       case CONF_UINT64:
+               return &b_variant->uint64_value;
+       case CONF_FLOAT:
+               return &b_variant->float_value;
+       case CONF_DOUBLE:
+               return &b_variant->double_value;
+       case CONF_BOOLEAN:
+               return &b_variant->bool_value;
+       }
+       return NULL;
+}
+
+int buxton_set_var(char *layer_name, char *group_name,
+       char *key_name, struct buxton_variant *value)
+{
+       int ret_data = -1;
+        BuxtonKey key;
+       int ret;
+       int attempts = 0;
+       ret_value_msg_if(value == NULL, -1, "Please provide valid pointer");
+
+set_init:
+       ret = init_buxton_client();
+       ++attempts;
+       ret_value_if(ret, ret);
+
+       key = buxton_key_create(group_name, key_name,
+               layer_name, value->type);
+
+        ret = buxton_set_value(client, key, get_variant_align(value),
+               general_set_callback, &ret_data, true);
+       buxton_key_free(key);
+
+       if (errno == EPIPE && attempts < BUXTON_ATTEMPT_NUMBER) {
+               buxton_close(client);
+               client = NULL;
+               goto set_init;
+       }
+
+       return ret || ret_data ? -1 : 0;
+}
+
diff --git a/src/core/buxton-helper.h b/src/core/buxton-helper.h
new file mode 100644 (file)
index 0000000..c3885ca
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+/*
+ * @file buxton-helper.h
+ *
+ * @desc Helper function for simplification of using and
+ * for looking like vconf interface
+ *
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ */
+
+#ifndef __DEVICED_BUXTON_HELPER_H
+#define __DEVICED_BUXTON_HELPER_H
+
+#include <buxton.h>
+
+#define BUXTON_DEVICED_LAYER "base"
+#define BUXTON_DEVICED_SYSTEM_GROUP "deviced_system"
+#define BUXTON_DEVICED_APPS_GROUP "deviced_apps"
+
+/* This enum duplicates BuxtonDataType */
+typedef enum conf_data_type {
+       CONF_TYPE_MIN,
+       CONF_STRING, /**<Represents type of a string value */
+       CONF_INT32, /**<Represents type of an int32_t value */
+       CONF_UINT32, /**<Represents type of an uint32_t value */
+       CONF_INT64, /**<Represents type of a int64_t value */
+       CONF_UINT64, /**<Represents type of a uint64_t value */
+       CONF_FLOAT, /**<Represents type of a float value */
+       CONF_DOUBLE, /**<Represents type of a double value */
+       CONF_BOOLEAN, /**<Represents type of a boolean value */
+       CONF_TYPE_MAX
+} conf_data_type;
+
+struct buxton_variant {
+       union {
+               char *string_value;
+               int32_t int32_value;
+               uint32_t uint32_value;
+               int64_t int64_value;
+               uint64_t uint64_value;
+               float float_value;
+               double double_value;
+               bool bool_value;
+       };
+       conf_data_type type;
+};
+
+int buxton_get_var(char *layer_name, char *group_name, char *key_name,
+       struct buxton_variant *value);
+
+int buxton_set_var(char *layer_name, char *group_name, char *key_name,
+       struct buxton_variant *value);
+
+#endif /* __DEVICED_BUXTON_HELPER_H */
+
index 7370ce0..e264a7e 100644 (file)
@@ -23,6 +23,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <time.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <dirent.h>
@@ -335,3 +336,13 @@ int mount_check(const char* path)
        endmntent(fp);
        return ret;
 }
+
+void print_time(const char *prefix)
+{
+       struct timeval tv;
+       struct tm *tm;
+       gettimeofday(&tv, NULL);
+       tm = localtime(&(tv.tv_sec));
+       _D("%s --> %d:%02d:%02d %d",
+                       prefix, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
+}
index b25e101..7b00828 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef __CORE_COMMON_H__
 #define __CORE_COMMON_H__
 
+#include <Ecore.h>
 #include <stdio.h>
 #include <error.h>
 #include <stdbool.h>
 #define USEC_TO_MSEC(x)                ((double)x/1000)
 #endif
 
+#ifndef safe_free
+#define safe_free(x) safe_free_memory((void**)&(x))
+#endif
+
+static inline void safe_free_memory(void** mem)
+{
+       if (mem && *mem) {
+               free(*mem);
+               *mem = NULL;
+       }
+}
+
+#define ret_value_if(expr, val) do { \
+        if (expr) { \
+                _E("(%s)", #expr); \
+                return (val); \
+        } \
+} while (0)
+
+#define ret_value_msg_if(expr, val, fmt, arg...) do {  \
+       if (expr) {                             \
+               _E(fmt, ##arg);                 \
+               return val;                     \
+       }                                       \
+} while (0)
+
+#define ret_msg_if(expr, fmt, arg...) do {     \
+       if (expr) {                             \
+               _E(fmt, ##arg);                 \
+               return;                 \
+       }                                       \
+} while (0)
+
 FILE * open_proc_oom_score_adj_file(int pid, const char *mode);
 int get_exec_pid(const char *execpath);
 int get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size);
@@ -103,6 +137,7 @@ int sys_get_int(char *fname, int *val);
 int sys_set_int(char *fname, int val);
 int terminate_process(char* partition, bool force);
 int mount_check(const char* path);
+void print_time(const char *prefix);
 
 #endif /* __CORE_COMMON_H__ */
 
diff --git a/src/core/core.c b/src/core/core.c
deleted file mode 100644 (file)
index 1ee910d..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 "data.h"
-#include "queue.h"
-#include "log.h"
-#include "predefine.h"
-#include "core.h"
-#include "devices.h"
-#include "common.h"
-
-enum core_cmd_type {
-       CORE_ACT_RUN,
-       CORE_ACT_CLEAR
-};
-
-struct _internal_msg {
-       int type;
-       int pid;
-};
-
-static int core_pipe[2];
-Ecore_Fd_Handler *g_pipe_efd = NULL;
-
-static int __pipe_start(struct main_data *ad);
-static int __pipe_stop(int fd);
-
-static int _core_action_run(void *user_data,
-                              struct run_queue_entry *rq_entry)
-{
-       struct action_entry *act_entry = rq_entry->action_entry;
-       int ret;
-       char tmp[128];
-
-       rq_entry->state = STATE_RUNNING;
-       ret = act_entry->predefine_action(rq_entry->argc, rq_entry->argv);
-       if (ret <= 0) {
-               if (ret < 0)
-                       _E("predefine action failed");
-               goto fast_done;
-       } else {
-               snprintf(tmp, sizeof(tmp), "/proc/%d/status", ret);
-               if (access(tmp, R_OK) == 0)
-                       rq_entry->forked_pid = ret;
-               else
-                       goto fast_done;
-       }
-       return 0;
-
- fast_done:
-       rq_entry->forked_pid = -1;
-       rq_entry->state = STATE_DONE;
-       core_action_clear(-1);
-       return 0;
-}
-
-static Eina_Bool core_pipe_cb(void *userdata, Ecore_Fd_Handler * fd_handler)
-{
-       struct main_data *ad = (struct main_data *)userdata;
-       struct _internal_msg p_msg;
-       int retry_count = 0;
-       int r = -1;
-       if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
-               _E("ecore_main_fd_handler_active_get error , return");
-               return EINA_TRUE;
-       }
-
-       while (retry_count < 5) {
-               r = read(core_pipe[0], &p_msg, sizeof(struct _internal_msg));
-               if (r < 0) {
-                       if (errno == EINTR) {
-                               _D("Re-read for error(EINTR)");
-                               retry_count++;
-                               continue;
-                       } else {
-                               __pipe_stop(core_pipe[0]);
-                               __pipe_stop(core_pipe[1]);
-                               _D("restart pipe fd");
-                               __pipe_start(ad);
-                       }
-               } else {
-                       break;
-               }
-       }
-
-       switch (p_msg.type) {
-       case CORE_ACT_RUN:
-               run_queue_run(STATE_INIT, _core_action_run, ad);
-               break;
-       case CORE_ACT_CLEAR:
-               run_queue_del_bypid(p_msg.pid);
-               break;
-       }
-       return EINA_TRUE;
-}
-
-int core_action_run()
-{
-       struct _internal_msg p_msg;
-
-       p_msg.type = CORE_ACT_RUN;
-       p_msg.pid = 0;
-       write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
-
-       return 0;
-}
-
-int core_action_clear(int pid)
-{
-       struct _internal_msg p_msg;
-
-       p_msg.type = CORE_ACT_CLEAR;
-       p_msg.pid = pid;
-       write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
-
-       return 0;
-}
-
-static int __pipe_start(struct main_data *ad)
-{
-       if (pipe(core_pipe) < 0) {
-               _E("pipe cannot create");
-               exit(EXIT_FAILURE);
-       }
-
-       g_pipe_efd = ecore_main_fd_handler_add(core_pipe[0], ECORE_FD_READ,
-                                 core_pipe_cb, ad, NULL, NULL);
-       if (!g_pipe_efd) {
-               _E("error ecore_main_fd_handler_add");
-               return -1;
-       }
-       return 0;
-}
-
-static int __pipe_stop(int fd)
-{
-       if (g_pipe_efd) {
-               ecore_main_fd_handler_del(g_pipe_efd);
-               g_pipe_efd = NULL;
-       }
-       if (fd >=0)
-               close(fd);
-
-       return 0;
-}
-
-static void core_init(void *data)
-{
-       struct main_data *ad = (struct main_data*)data;
-
-       __pipe_stop(core_pipe[0]);
-       __pipe_stop(core_pipe[1]);
-
-       if (__pipe_start(ad) == -1)
-               _E("fail pipe control fd init");
-}
-
-static const struct device_ops core_device_ops = {
-       .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "core",
-       .init     = core_init,
-};
-
-DEVICE_OPS_REGISTER(&core_device_ops)
index bd3c8ba..aa9b53f 100644 (file)
 #include <dirent.h>
 #include <fnmatch.h>
 #include "dd-deviced.h"
-#include "queue.h"
 #include "log.h"
 #include "device-notifier.h"
 #include "device-handler.h"
 #include "device-node.h"
-#include "noti.h"
-#include "data.h"
-#include "predefine.h"
 #include "display/poll.h"
 #include "devices.h"
 #include "hall/hall-handler.h"
 #include "udev.h"
 #include "common.h"
-#include "common.h"
 #include "list.h"
+#include "ode/ode.h"
 #include "proc/proc-handler.h"
 #include "edbus-handler.h"
-#include "emulator.h"
 #include "devices.h"
 #include "power-supply.h"
 #include "display/setting.h"
 #include "display/core.h"
+#include "usb/usb-client.h"
 
-#define PREDEF_EARJACKCON              "earjack_predef_internal"
 #define PREDEF_DEVICE_CHANGED          "device_changed"
 #define PREDEF_POWER_CHANGED           POWER_SUBSYSTEM
 #define PREDEF_UDEV_CONTROL            UDEV
 #define BUFF_MAX               255
 #define SYS_CLASS_INPUT                "/sys/class/input"
 
-#ifdef MICRO_DD
-#define USB_STATE_PATH "/sys/devices/platform/jack/usb_online"
-#else
-#define USB_STATE_PATH "/sys/devices/virtual/switch/usb_cable/state"
-#endif
+#define USB_STATE_PLATFORM_PATH "/sys/devices/platform/jack/usb_online"
+#define USB_STATE_SWITCH_PATH "/sys/devices/virtual/switch/usb_cable/state"
 
 #define HDMI_NOT_SUPPORTED     (-1)
 #ifdef ENABLE_EDBUS_USE
@@ -165,6 +157,9 @@ enum snd_jack_types {
 #define SIGNAL_HDCP_STATE      "ChangedHDCP"
 #define SIGNAL_HDMI_AUDIO_STATE        "ChangedHDMIAudio"
 
+#define METHOD_FACTORY_MODE            "factorymode"
+#define VCONFKEY_SYSMAN_FACTORY_MODE   "memory/sysman/factory_mode"
+
 #define HDCP_HDMI_VALUE(HDCP, HDMI)    ((HDCP << 1) | HDMI)
 
 #define METHOD_GET_CRADLE      "GetCradle"
@@ -181,6 +176,11 @@ struct popup_data {
        char *value;
 };
 
+struct siop_data {
+       int siop;
+       int rear;
+};
+
 static int ss_flags = 0;
 
 static int input_device_number;
@@ -199,7 +199,8 @@ static int ufd_udev = -1;
 static dd_list *opt_uevent_list = NULL;
 static dd_list *opt_kernel_uevent_list = NULL;
 static int hdmi_status = 0;
-static const struct device_ops *lowbat_ops;
+
+static int factory_mode = 0;
 
 enum udev_subsystem_type {
        UDEV_HALL_IC,
@@ -333,8 +334,18 @@ int get_usb_state_direct(void)
        FILE *fp;
        char str[2];
        int state;
+       char *path;
 
-       fp = fopen(USB_STATE_PATH, "r");
+       if (access(USB_STATE_PLATFORM_PATH, F_OK) == 0)
+               path = USB_STATE_PLATFORM_PATH;
+       else if (access(USB_STATE_SWITCH_PATH, F_OK) == 0)
+               path = USB_STATE_SWITCH_PATH;
+       else {
+               _E("Cannot get direct path");
+               return -ENOENT;
+       }
+
+       fp = fopen(path, "r");
        if (!fp) {
                _E("Cannot open jack node");
                return -ENOMEM;
@@ -371,6 +382,7 @@ static void usb_chgdet_cb(void *data)
                        battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
                        _D("usb device notification");
                }
+               usb_state_changed(val);
        } else {
                _E("fail to get usb_online status");
        }
@@ -381,12 +393,7 @@ static void show_ticker_notification(char *text, int queue)
        struct ticker_data t_data;
        static const struct device_ops *ticker = NULL;
 
-       if (!ticker) {
-               ticker = find_device("ticker");
-               if (!ticker)
-                       return;
-       }
-
+       FIND_DEVICE_VOID(ticker, "ticker");
        t_data.name = text;
        t_data.type = queue;
        if (ticker->init)
@@ -398,11 +405,8 @@ static void launch_cradle(int val)
        struct popup_data *params;
        static const struct device_ops *apps = NULL;
 
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return;
-       }
+       FIND_DEVICE_VOID(apps, "apps");
+
        params = malloc(sizeof(struct popup_data));
        if (params == NULL) {
                _E("Malloc failed");
@@ -528,62 +532,6 @@ void sync_cradle_status(void)
                cradle_chgdet_cb(NULL);
 }
 
-static void ta_chgdet_cb(struct main_data *ad)
-{
-       int val = -1;
-       int ret = -1;
-       int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
-       char params[BUFF_MAX];
-
-       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_TA_ONLINE, &val) == 0) {
-               _I("jack - ta changed %d",val);
-               check_lowbat_charge_device(val);
-               vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS, val);
-               if (val == 0) {
-                       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_INSUSPEND_CHARGING_SUPPORT, &val);
-                       if (ret != 0)
-                               val = 0;
-                       if (val == 0)
-                               pm_unlock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE);
-                       device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)FALSE);
-               } else {
-                       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_INSUSPEND_CHARGING_SUPPORT, &val);
-                       if (ret != 0)
-                               val = 0;
-                       if (val == 0)
-                               pm_lock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE, 0);
-                       battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
-                       _D("ta device notification");
-                       device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)TRUE);
-               }
-               sync_cradle_status();
-       }
-       else
-               _E("failed to get ta status");
-}
-
-static void earjack_chgdet_cb(void *data)
-{
-       int val;
-       int ret = 0;
-
-       if (data)
-               val = *(int *)data;
-       else {
-               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val);
-               if (ret != 0) {
-                       _E("failed to get status");
-                       return;
-               }
-       }
-       _I("jack - earjack changed %d", val);
-       if (CONNECTED(val)) {
-               extcon_set_count(EXTCON_EARJACK);
-               predefine_pm_change_state(LCD_NORMAL);
-       }
-       vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
-}
-
 static void earkey_chgdet_cb(void *data)
 {
        int val;
@@ -646,6 +594,15 @@ static int hdcp_hdmi_cb(void *data)
        return old;
 }
 
+static int hdmi_cec_execute(void *data)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, "hdmi-cec");
+
+       return ops->execute(data);
+}
+
 static void hdmi_chgdet_cb(void *data)
 {
        int val;
@@ -682,6 +639,7 @@ static void hdmi_chgdet_cb(void *data)
                show_ticker_notification(HDMI_DISCONNECTED, 0);
                pm_unlock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, PM_SLEEP_MARGIN);
        }
+       hdmi_cec_execute((void *)val);
 }
 
 static void hdcp_send_broadcast(int status)
@@ -785,9 +743,6 @@ static void cb_xxxxx_signaled(void *data, DBusMessage * msg)
 {
        char *args;
        DBusError err;
-       struct main_data *ad;
-
-       ad = data;
 
        dbus_error_init(&err);
        if (dbus_message_get_args
@@ -871,6 +826,111 @@ static void check_present_status(const char *env_value)
        battery.present = atoi(env_value);
 }
 
+static int earjack_execute(void *data)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, "earjack");
+
+       return ops->execute(data);
+}
+
+static int hall_ic_execute(void)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, HALL_IC_NAME);
+
+       return ops->execute(NULL);
+}
+
+static int siop_execute(const char *siop, const char *rear)
+{
+       static const struct device_ops *ops = NULL;
+       struct siop_data params;
+
+       FIND_DEVICE_INT(ops, PROC_OPS_NAME);
+
+       if (!siop)
+               params.siop = 0;
+       else
+               params.siop = atoi(siop);
+       if (!rear)
+               params.rear = 0;
+       else
+               params.rear = atoi(rear);
+       return ops->execute((void *)&params);
+}
+
+static int changed_device(const char *name, const char *value)
+{
+       int val = 0;
+       int *state = NULL;
+       int i;
+
+       if (!name)
+               goto out;
+
+       if (value) {
+               val = atoi(value);
+               state = &val;
+       }
+
+       if (strncmp(name, USB_NAME, USB_NAME_LEN) == 0)
+               usb_chgdet_cb((void *)state);
+       else if (strncmp(name, EARJACK_NAME, EARJACK_NAME_LEN) == 0)
+               earjack_execute((void *)state);
+       else if (strncmp(name, EARKEY_NAME, EARKEY_NAME_LEN) == 0)
+               earkey_chgdet_cb((void *)state);
+       else if (strncmp(name, TVOUT_NAME, TVOUT_NAME_LEN) == 0)
+               tvout_chgdet_cb((void *)state);
+       else if (strncmp(name, HDMI_NAME, HDMI_NAME_LEN) == 0)
+               hdmi_chgdet_cb((void *)state);
+       else if (strncmp(name, HDCP_NAME, HDCP_NAME_LEN) == 0) {
+               hdcp_chgdet_cb((void *)state);
+               hdcp_hdmi_cb((void *)state);
+       }
+       else if (strncmp(name, HDMI_AUDIO_NAME, HDMI_AUDIO_LEN) == 0)
+               hdmi_audio_chgdet_cb((void *)state);
+       else if (strncmp(name, CRADLE_NAME, CRADLE_NAME_LEN) == 0)
+               cradle_chgdet_cb((void *)state);
+       else if (strncmp(name, KEYBOARD_NAME, KEYBOARD_NAME_LEN) == 0)
+               keyboard_chgdet_cb((void *)state);
+       else if (strncmp(name, POWER_SUBSYSTEM, POWER_SUPPLY_NAME_LEN) == 0)
+               power_supply((void *)state);
+out:
+       return 0;
+}
+
+static int booting_done(void *data)
+{
+       static int done = 0;
+       int ret;
+       int val;
+
+       if (data == NULL)
+               return done;
+       done = (int)data;
+       if (done == 0)
+               return done;
+
+       _I("booting done");
+
+       power_supply_timer_stop();
+       power_supply_init(NULL);
+
+       /* set initial state for devices */
+       input_device_number = 0;
+       cradle_chgdet_cb(NULL);
+       keyboard_chgdet_cb(NULL);
+       hdmi_chgdet_cb(NULL);
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &val);
+       if (ret == 0 && val != 0)
+               launch_cradle(val);
+       return done;
+}
+
 static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
 {
        struct udev_device *dev = NULL;
@@ -908,7 +968,7 @@ static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handl
        switch (udev_subsystems[i].type) {
        case UDEV_HALL_IC:
                if (!strncmp(devpath, HALL_IC_PATH, strlen(HALL_IC_PATH))) {
-                       notify_action(PREDEF_HALL_IC, 1, HALL_IC_NAME);
+                       hall_ic_execute();
                        goto out;
                }
                break;
@@ -936,20 +996,20 @@ static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handl
        case UDEV_SWITCH:
                env_name = udev_device_get_property_value(dev, "SWITCH_NAME");
                env_value = udev_device_get_property_value(dev, "SWITCH_STATE");
-               notify_action(PREDEF_DEVICE_CHANGED, 2, env_name, env_value);
+               changed_device(env_name, env_value);
                break;
        case UDEV_PLATFORM:
                if (!fnmatch(THERMISTOR_PATH, devpath, 0)) {
                        siop_level = udev_device_get_property_value(dev, "TEMPERATURE");
                        rear_level = udev_device_get_property_value(dev, "REAR_TEMPERATURE");
-                       notify_action(SIOP_CHANGED, 2, siop_level, rear_level);
+                       siop_execute(siop_level, rear_level);
                        goto out;
                }
 
                env_value = udev_device_get_property_value(dev, ENV_FILTER);
                if (!env_value)
                        break;
-               notify_action(PREDEF_DEVICE_CHANGED, 1, env_value);
+               changed_device(env_value, NULL);
                break;
        case UDEV_POWER:
                udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev)) {
@@ -978,11 +1038,13 @@ static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handl
                check_present_status(env_value);
                env_value = udev_device_get_property_value(dev, CAPACITY);
                check_capacity_status(env_value);
-               battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
+               ret = booting_done(NULL);
+               if (ret)
+                       battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
                if (env_value)
-                       notify_action(PREDEF_DEVICE_CHANGED, 2, subsystem, env_value);
+                       changed_device(subsystem, env_value);
                else
-                       notify_action(PREDEF_DEVICE_CHANGED, 1, subsystem);
+                       changed_device(subsystem, NULL);
                break;
        }
 
@@ -1239,7 +1301,6 @@ void unregister_uevent_control(const struct uevent_handler *uh)
                        continue;
 
                DD_LIST_REMOVE(opt_uevent_list, handler);
-               free(handler);
                break;
        }
 }
@@ -1323,107 +1384,6 @@ int uevent_udev_get_path(const char *subsystem, dd_list **list)
        return 0;
 }
 
-static int changed_device(int argc, char **argv)
-{
-       int val = 0;
-       int *state = NULL;
-       int i;
-
-       for (i = 0 ; i < argc ; i++) {
-               if (argv[i] == NULL) {
-                       _E("param is failed");
-                       return -EINVAL;
-               }
-       }
-
-       if (argc ==  2) {
-               if (argv[1] == NULL)
-                       val = 0;
-               else
-                       val = atoi(argv[1]);
-               state = &val;
-       }
-
-       if (strncmp(argv[0], USB_NAME, USB_NAME_LEN) == 0)
-               usb_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], EARJACK_NAME, EARJACK_NAME_LEN) == 0)
-               earjack_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], EARKEY_NAME, EARKEY_NAME_LEN) == 0)
-               earkey_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], TVOUT_NAME, TVOUT_NAME_LEN) == 0)
-               tvout_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], HDMI_NAME, HDMI_NAME_LEN) == 0)
-               hdmi_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], HDCP_NAME, HDCP_NAME_LEN) == 0) {
-               hdcp_chgdet_cb((void *)state);
-               hdcp_hdmi_cb((void *)state);
-       }
-       else if (strncmp(argv[0], HDMI_AUDIO_NAME, HDMI_AUDIO_LEN) == 0)
-               hdmi_audio_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], CRADLE_NAME, CRADLE_NAME_LEN) == 0)
-               cradle_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], KEYBOARD_NAME, KEYBOARD_NAME_LEN) == 0)
-               keyboard_chgdet_cb((void *)state);
-       else if (strncmp(argv[0], POWER_SUBSYSTEM, POWER_SUPPLY_NAME_LEN) == 0)
-               power_supply((void *)state);
-
-       return 0;
-}
-
-static int changed_dev_earjack(int argc, char **argv)
-{
-       int val;
-
-       /* TODO
-        * if we can recognize which type of jack is changed,
-        * should move following code for TVOUT to a new action function */
-       /*
-          if(device_get_property(DEVTYPE_JACK,JACK_PROP_TVOUT_ONLINE,&val) == 0)
-          {
-          if (val == 1 &&
-          vconf_get_int(VCONFKEY_SETAPPL_TVOUT_TVSYSTEM_INT, &val) == 0) {
-          _E("Start TV out %s\n", (val==0)?"NTSC":(val==1)?"PAL":"Unsupported");
-          switch (val) {
-          case 0:              // NTSC
-          launch_after_kill_if_exist(TVOUT_X_BIN, "-connect 2");
-          break;
-          case 1:              // PAL
-          launch_after_kill_if_exist(TVOUT_X_BIN, "-connect 3");
-          break;
-          default:
-          _E("Unsupported TV system type:%d \n", val);
-          return -1;
-          }
-          // UI clone on
-          launch_evenif_exist(TVOUT_X_BIN, "-clone 1");
-          ss_flags |= TVOUT_FLAG;
-          return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, VCONFKEY_SYSMAN_EARJACK_TVOUT);
-          }
-          else {
-          if(val == 1) {
-          _E("TV type is not set. Please set the TV type first.\n");
-          return -1;
-          }
-          if (ss_flags & TVOUT_FLAG) {
-          _E("TV out Jack is disconnected.\n");
-          // UI clone off
-          launch_after_kill_if_exist(TVOUT_X_BIN, "-clone 0");
-          ss_flags &= ~TVOUT_FLAG;
-          return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, VCONFKEY_SYSMAN_EARJACK_REMOVED);
-          }
-          // Current event is not TV out event. Fall through
-          }
-          }
-        */
-       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val) == 0) {
-               if (CONNECTED(val))
-                       extcon_set_count(EXTCON_EARJACK);
-               return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
-       }
-
-       return -1;
-}
-
 static DBusMessage *dbus_cradle_handler(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
@@ -1520,7 +1480,7 @@ static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
                goto out;
        }
 
-       changed_device(argc, (char **)&argv);
+       changed_device(argv[0], argv[1]);
 
 out:
        reply = dbus_message_new_method_return(msg);
@@ -1583,7 +1543,7 @@ static DBusMessage *dbus_battery_handler(E_DBus_Object *obj, DBusMessage *msg)
                battery.present,
                battery.temp);
        battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
-       notify_action(PREDEF_DEVICE_CHANGED, 2, POWER_SUBSYSTEM, argv[0]);
+       changed_device(POWER_SUBSYSTEM, argv[0]);
 out:
        reply = dbus_message_new_method_return(msg);
        dbus_message_iter_init_append(reply, &iter);
@@ -1643,58 +1603,89 @@ out:
        return reply;
 }
 
-static const struct edbus_method edbus_methods[] = {
-       { PREDEF_DEVICE_CHANGED,"siss",         "i",    dbus_device_handler },
-       { PREDEF_POWER_CHANGED, "sisssss",      "i",    dbus_battery_handler },
-       { PREDEF_UDEV_CONTROL,  "sis",          "i",    dbus_udev_handler },
-       { METHOD_GET_HDCP,      NULL,           "i",    dbus_hdcp_handler },
-       { METHOD_GET_HDMI_AUDIO,NULL,           "i",    dbus_hdmi_audio_handler },
-       { METHOD_GET_HDMI,      NULL,           "i",    dbus_hdcp_hdmi_handler },
-       { METHOD_GET_CRADLE,    NULL,           "i",    dbus_cradle_handler },
-};
+int is_factory_mode(void)
+{
+       return factory_mode;
+}
 
-static int booting_done(void *data)
+void internal_pm_change_state(unsigned int s_bits)
 {
-       static int done = 0;
-       int ret;
-       int val;
+       if (is_factory_mode() == 1)
+               _D("skip LCD control for factory mode");
+       else
+               pm_change_internal(getpid(), s_bits);
+}
 
-       if (data == NULL)
-               return done;
-       done = (int)data;
-       if (done == 0)
-               return done;
+static int set_factory_mode(int status)
+{
+       int ret = -1;
 
-       _I("booting done");
+       if (status == 1 || status == 0) {
+               factory_mode = status;
+               /* For USB-server to refer the value */
+               ret = vconf_set_int(VCONFKEY_SYSMAN_FACTORY_MODE, status);
+               if(ret != 0) {
+                       _E("FAIL: vconf_set_int()");
+               }
+       }
+       return factory_mode;
+}
 
-       register_action(PREDEF_EARJACKCON, changed_dev_earjack, NULL, NULL);
-       register_action(PREDEF_DEVICE_CHANGED, changed_device, NULL, NULL);
+static DBusMessage *dbus_factory_mode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv;
 
-       power_supply_timer_stop();
-       power_supply_init(NULL);
+       dbus_error_init(&err);
 
-       if (uevent_kernel_control_start() != 0) {
-               _E("fail uevent control init");
-               return 0;
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
        }
 
-       if (uevent_udev_control_start() != 0) {
-               _E("fail uevent control init");
-               return 0;
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
        }
 
-       /* set initial state for devices */
-       input_device_number = 0;
-       cradle_chgdet_cb(NULL);
-       keyboard_chgdet_cb(NULL);
-       hdmi_chgdet_cb(NULL);
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
 
-       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &val);
-       if (ret == 0 && val != 0)
-               launch_cradle(val);
-       return done;
+       ret = set_factory_mode(atoi(argv));
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
 }
 
+static const struct edbus_method edbus_methods[] = {
+       { PREDEF_DEVICE_CHANGED, "siss",    "i", dbus_device_handler },
+       { PREDEF_POWER_CHANGED,  "sisssss", "i", dbus_battery_handler },
+       { PREDEF_UDEV_CONTROL,   "sis","i", dbus_udev_handler },
+       { METHOD_GET_HDCP,       NULL, "i", dbus_hdcp_handler },
+       { METHOD_GET_HDMI_AUDIO, NULL, "i", dbus_hdmi_audio_handler },
+       { METHOD_GET_HDMI,       NULL, "i", dbus_hdcp_hdmi_handler },
+       { METHOD_GET_CRADLE,     NULL, "i", dbus_cradle_handler },
+       { METHOD_FACTORY_MODE,   "sis","i", dbus_factory_mode },
+};
+
 static int device_change_poweroff(void *data)
 {
        uevent_kernel_control_stop();
@@ -1716,20 +1707,6 @@ static void device_change_init(void *data)
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
 
-       /* for simple noti change cb */
-       emulator_add_callback("device_usb_chgdet", (void *)usb_chgdet_cb, NULL);
-       emulator_add_callback("device_ta_chgdet", (void *)ta_chgdet_cb, data);
-       emulator_add_callback("device_earjack_chgdet", (void *)earjack_chgdet_cb, data);
-       emulator_add_callback("device_earkey_chgdet", (void *)earkey_chgdet_cb, data);
-       emulator_add_callback("device_tvout_chgdet", (void *)tvout_chgdet_cb, data);
-       emulator_add_callback("device_hdmi_chgdet", (void *)hdmi_chgdet_cb, data);
-       emulator_add_callback("device_cradle_chgdet", (void *)cradle_chgdet_cb, data);
-       emulator_add_callback("device_keyboard_chgdet", (void *)keyboard_chgdet_cb, data);
-
-       emulator_add_callback("unmount_ums", (void *)ums_unmount_cb, NULL);
-
-       /* check and set earjack init status */
-       changed_dev_earjack(0, NULL);
        /* dbus noti change cb */
 #ifdef ENABLE_EDBUS_USE
        e_dbus_init();
@@ -1741,6 +1718,15 @@ static void device_change_init(void *data)
                                  "system.uevent.xxxxx",
                                  "Change", cb_xxxxx_signaled, data);
 #endif                         /* ENABLE_EDBUS_USE */
+       if (uevent_kernel_control_start() != 0) {
+               _E("fail uevent control init");
+               return;
+       }
+
+       if (uevent_udev_control_start() != 0) {
+               _E("fail uevent control init");
+               return;
+       }
 }
 
 static void device_change_exit(void *data)
index 071b882..49f0b55 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef __DEVICE_HANDLER_H__
 #define __DEVICE_HANDLER_H__
 
-#include "data.h"
+#include "common.h"
 
 enum extcon_type {
        EXTCON_TA = 0,
@@ -102,4 +102,5 @@ int get_usb_state_direct(void);
 
 void sync_cradle_status(void);
 
+void internal_pm_change_state(unsigned int s_bits);
 #endif /* __DEVICE_HANDLER_H__ */
index a02584a..41c1ac9 100644 (file)
 #include "device-notifier.h"
 #include "list.h"
 #include "common.h"
+#include <journal/system.h>
+
+#define LATE_INIT_WAIT_TIME    12
+#define DEFAULT_LATE_INIT_VALUE        ((Ecore_Timer *)0x0DEF0DEF)
 
 struct device_notifier {
        enum device_notifier_type status;
@@ -29,6 +33,7 @@ struct device_notifier {
 };
 
 static dd_list *device_notifier_list;
+static Ecore_Timer *late_init_timer = DEFAULT_LATE_INIT_VALUE;
 
 #define FIND_NOTIFIER(a, b, d, e, f) \
        DD_LIST_FOREACH(a, b, d) \
@@ -101,6 +106,60 @@ void device_notify(enum device_notifier_type status, void *data)
        }
 }
 
+static void late_init_stop(void)
+{
+       if (late_init_timer == NULL ||
+           late_init_timer == DEFAULT_LATE_INIT_VALUE)
+               return;
+       ecore_timer_del(late_init_timer);
+       late_init_timer = NULL;
+}
+
+static int booting_done(void *data)
+{
+       static int done = 0;
+
+       if (data == NULL)
+               goto out;
+
+       journal_system_booting_done();
+       done = (int)data;
+       if (late_init_timer == NULL)
+               return done;
+       late_init_stop();
+out:
+       return done;
+}
+
+static Eina_Bool late_init_timer_cb(void *data)
+{
+       int done;
+
+       late_init_stop();
+       done = booting_done(NULL);
+       if (done)
+               return EINA_FALSE;
+       _I("late booting done");
+       device_notify(DEVICE_NOTIFIER_BOOTING_DONE, (void *)TRUE);
+       return EINA_FALSE;
+}
+
+static void device_notifier_init(void *data)
+{
+       int ret;
+
+       ret = check_systemd_active();
+       if (ret == TRUE) {
+               _I("restart booting done");
+               return;
+       }
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       late_init_timer = ecore_timer_add(LATE_INIT_WAIT_TIME,
+                                               late_init_timer_cb, NULL);
+       if (!late_init_timer)
+               late_init_timer = DEFAULT_LATE_INIT_VALUE;
+}
+
 static void device_notifier_exit(void *data)
 {
        dd_list *n;
@@ -114,6 +173,7 @@ static void device_notifier_exit(void *data)
 static const struct device_ops notifier_device_ops = {
        .priority = DEVICE_PRIORITY_NORMAL,
        .name     = "notifier",
+       .init     = device_notifier_init,
        .exit     = device_notifier_exit,
 };
 
index 490a98d..e55ee14 100644 (file)
@@ -45,7 +45,9 @@ enum device_notifier_type {
        DEVICE_NOTIFIER_POWEROFF,
        DEVICE_NOTIFIER_POWEROFF_HAPTIC,
        DEVICE_NOTIFIER_PMQOS,
-       DEVICE_NOTIFIER_POWERSAVER,
+       DEVICE_NOTIFIER_PMQOS_ULTRAPOWERSAVING,
+       DEVICE_NOTIFIER_PMQOS_HALL,
+       DEVICE_NOTIFIER_COOL_DOWN,
        DEVICE_NOTIFIER_MAX,
 };
 
diff --git a/src/core/device-plugin.c b/src/core/device-plugin.c
deleted file mode 100644 (file)
index 3048892..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  deviced
- *
- * Copyright (c) 2000 - 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 <dlfcn.h>
-#include <unistd.h>
-
-#include "log.h"
-#include "device-plugin.h"
-
-static void *dlopen_handle;
-
-int _ss_devman_plugin_init()
-{
-       char *error;
-
-       dlopen_handle = dlopen(DEVMAN_PLUGIN_PATH, RTLD_NOW);
-       if (!dlopen_handle) {
-               _E("dlopen() failed");
-               return -1;
-       }
-
-       const OEM_sys_devman_plugin_interface *(*get_devman_plugin_interface) ();
-       get_devman_plugin_interface = dlsym(dlopen_handle, "OEM_sys_get_devman_plugin_interface");
-       if ((error = dlerror()) != NULL) {
-               _E("dlsym() failed: %s", error);
-               dlclose(dlopen_handle);
-               return -1;
-       }
-
-       plugin_intf = get_devman_plugin_interface();
-       if (!plugin_intf) {
-               _E("get_devman_plugin_interface() failed");
-               dlclose(dlopen_handle);
-               return -1;
-       }
-
-       return 0;
-}
-
-
-int _ss_devman_plugin_fini()
-{
-       if (dlopen_handle) {
-               dlclose(dlopen_handle);
-       }
-
-       return 0;
-}
-
-
index da2292f..de766f3 100644 (file)
 #include "common.h"
 #include "devices.h"
 
+static const struct device_ops default_ops = {
+       .name = "default-ops",
+};
+
 static dd_list *dev_head;
 
 void add_device(const struct device_ops *dev)
@@ -48,7 +52,14 @@ const struct device_ops *find_device(const char *name)
                if (!strcmp(dev->name, name))
                        return dev;
        }
-       return NULL;
+
+       dev = &default_ops;
+       return dev;
+}
+
+int check_default(const struct device_ops *dev)
+{
+       return (dev == &default_ops);
 }
 
 void devices_init(void *data)
index b4537ad..38bef89 100644 (file)
@@ -28,14 +28,28 @@ enum device_priority {
        DEVICE_PRIORITY_HIGH,
 };
 
+enum device_flags {
+       NORMAL_MODE                   = 0x00000001,
+       AMBIENT_MODE                  = 0x00000002,
+       CORE_LOGIC_MODE               = 0x00010000,
+       TOUCH_SCREEN_OFF_MODE         = 0x00020000,
+       LCD_PANEL_OFF_MODE            = 0x00040000,
+       LCD_PHASED_TRANSIT_MODE       = 0x00080000,
+       LCD_ON_BY_GESTURE             = 0x00100000,
+       LCD_ON_BY_POWER_KEY           = 0x00200000,
+       LCD_ON_BY_EVENT               = 0x00400000,
+       LCD_ON_BY_TOUCH               = 0x00800000,
+};
+
 struct device_ops {
        enum device_priority priority;
        char *name;
        void (*init) (void *data);
        void (*exit) (void *data);
-       int (*start) (void);
-       int (*stop) (void);
+       int (*start) (enum device_flags flags);
+       int (*stop) (enum device_flags flags);
        int (*status) (void);
+       int (*execute) (void *data);
 };
 
 enum device_ops_status {
@@ -51,7 +65,7 @@ void devices_exit(void *data);
 static inline int device_start(const struct device_ops *dev)
 {
        if (dev && dev->start)
-               return dev->start();
+               return dev->start(NORMAL_MODE);
 
        return -EINVAL;
 }
@@ -59,7 +73,25 @@ static inline int device_start(const struct device_ops *dev)
 static inline int device_stop(const struct device_ops *dev)
 {
        if (dev && dev->stop)
-               return dev->stop();
+               return dev->stop(NORMAL_MODE);
+
+       return -EINVAL;
+}
+
+static inline int device_exit(const struct device_ops *dev, void *data)
+{
+       if (dev && dev->exit) {
+               dev->exit(data);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static inline int device_execute(const struct device_ops *dev, void *data)
+{
+       if (dev && dev->execute)
+               return dev->execute(data);
 
        return -EINVAL;
 }
@@ -84,6 +116,19 @@ static void __DESTRUCTOR__ module_exit(void)        \
 
 void add_device(const struct device_ops *dev);
 void remove_device(const struct device_ops *dev);
+
 const struct device_ops *find_device(const char *name);
+int check_default(const struct device_ops *dev);
+
+#define NOT_SUPPORT_OPS(dev) \
+       ((check_default(dev))? 1 : 0)
+
+#define FIND_DEVICE_INT(dev, name) do { \
+       if (!dev) dev = find_device(name); if(check_default(dev)) return -ENODEV; \
+} while(0)
+
+#define FIND_DEVICE_VOID(dev, name) do { \
+       if (!dev) dev = find_device(name); if(check_default(dev)) return; \
+} while(0)
 
 #endif
index f03a051..eb9200f 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <stdbool.h>
 #include "core/log.h"
-#include "core/data.h"
 #include "core/edbus-handler.h"
 #include "core/common.h"
 #include "core/device-notifier.h"
@@ -60,14 +59,19 @@ static struct edbus_object {
        { DEVICED_PATH_CPU    , DEVICED_INTERFACE_CPU    , NULL, NULL },
        { DEVICED_PATH_PMQOS  , DEVICED_INTERFACE_PMQOS  , NULL, NULL },
        { DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI, NULL, NULL },
+       { DEVICED_PATH_USB    , DEVICED_INTERFACE_USB    , NULL, NULL },
        { DEVICED_PATH_USBHOST, DEVICED_INTERFACE_USBHOST, NULL, NULL },
        { DEVICED_PATH_EXTCON , DEVICED_INTERFACE_EXTCON , NULL, NULL },
        { DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY, NULL, NULL },
        { DEVICED_PATH_BOARD, DEVICED_INTERFACE_BOARD, NULL, NULL },
        { DEVICED_PATH_TESTMODE, DEVICED_INTERFACE_TESTMODE, NULL, NULL},
+       { DEVICED_PATH_APPS, DEVICED_INTERFACE_APPS, NULL, NULL},
+       { DEVICED_PATH_GPIO, DEVICED_INTERFACE_GPIO, NULL, NULL},
+       { DEVICED_PATH_HDMICEC, DEVICED_INTERFACE_HDMICEC, NULL, NULL},
        /* Add new object & interface here*/
 };
 
+static dd_list *edbus_owner_list;
 static dd_list *edbus_handler_list;
 static dd_list *edbus_watch_list;
 static int edbus_init_val;
@@ -254,9 +258,15 @@ int broadcast_edbus_signal(const char *path, const char *interface,
                return -EPERM;
        }
 
-       e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL);
-
+       r = dbus_connection_send(conn, msg, NULL);
        dbus_message_unref(msg);
+
+       if (r != TRUE) {
+               _E("dbus_connection_send error(%s:%s-%s)",
+                   path, interface, name);
+               return -ECOMM;
+       }
+
        return 0;
 }
 
@@ -502,6 +512,86 @@ static void request_name_cb(void *data, DBusMessage *msg, DBusError *error)
        _I("Request Name reply : %d", val);
 }
 
+static void check_owner_name(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       char *pa[1];
+       char exe_name[PATH_MAX];
+       char *entry;
+       dd_list *n;
+       int pid;
+
+       DD_LIST_FOREACH(edbus_owner_list, n, entry) {
+               pa[0] = entry;
+               msg = dbus_method_sync_with_reply(E_DBUS_FDO_BUS,
+                       E_DBUS_FDO_PATH,
+                       E_DBUS_FDO_INTERFACE,
+                       "GetConnectionUnixProcessID", "s", pa);
+
+               if (!msg) {
+                       _E("invalid DBusMessage!");
+                       return;
+               }
+
+               dbus_error_init(&err);
+               dbus_message_iter_init(msg, &iter);
+
+               dbus_message_iter_get_basic(&iter, &pid);
+               if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0)
+                       goto out;
+               _I("%s(%d)", exe_name, pid);
+
+out:
+               dbus_message_unref(msg);
+               dbus_error_free(&err);
+       }
+}
+
+static void check_owner_list(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       DBusMessageIter array, iter, item, iter_val;
+       char *pa[1];
+       char *name;
+       char *entry;
+
+       pa[0] = DEVICED_BUS_NAME;
+       msg = dbus_method_sync_with_reply(E_DBUS_FDO_BUS,
+                       E_DBUS_FDO_PATH,
+                       E_DBUS_FDO_INTERFACE,
+                       "ListQueuedOwners", "s", pa);
+
+       if (!msg) {
+               _E("invalid DBusMessage!");
+               return;
+       }
+
+       dbus_error_init(&err);
+       dbus_message_iter_init(msg, &array);
+
+       if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
+               goto out;
+       dbus_message_iter_recurse(&array, &item);
+       while (dbus_message_iter_get_arg_type(&item) == DBUS_TYPE_STRING) {
+               dbus_message_iter_get_basic(&item, &name);
+               entry = strndup(name, strlen(name));
+               DD_LIST_APPEND(edbus_owner_list, entry);
+               if (!edbus_owner_list) {
+                       _E("append failed");
+                       free(entry);
+                       goto out;
+               }
+               dbus_message_iter_next(&item);
+       }
+
+out:
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+}
+
 void edbus_init(void *data)
 {
        DBusError error;
@@ -568,6 +658,8 @@ void edbus_init(void *data)
                }
                _D("add new obj for %s", edbus_objects[i].interface);
        }
+       check_owner_list();
+       check_owner_name();
        return;
 
 out3:
index 1c664da..303f6b7 100755 (executable)
@@ -64,10 +64,18 @@ int run_child(int argc, const char *argv[])
        pid_t pid;
        struct sigaction act, oldact;
        int r;
+       FILE *fp;
 
        if (!argv)
                return -EINVAL;
 
+       fp = fopen(argv[0], "r");
+       if (fp == NULL) {
+               _E("fail %s (%s)", argv[0], strerror(errno));
+               return -errno;
+       }
+       fclose(fp);
+
        /* Use default signal handler */
        act.sa_handler = SIG_DFL;
        act.sa_sigaction = NULL;
index b688dec..d3fa641 100644 (file)
@@ -59,6 +59,37 @@ typedef Eina_List dd_list;
 #else
 #include <glib.h>
 typedef GList dd_list;
+
+/*
+   cover crash from corrupted double linked list under the glib 2.36.4
+   if glib version upper than 2.36.3, exchange it to g_list_remove
+*/
+static inline GList* g_list_check_remove(GList* list, gpointer data)
+{
+       GList *temp;
+       temp = list;
+       if (!temp)
+               goto out;
+       while (temp != NULL) {
+               if (temp->data != data)
+                       temp = temp->next;
+               else {
+                       if (temp->prev != NULL && temp->prev->next == temp)
+                               temp->prev->next = temp->next;
+                       if (temp->next != NULL && temp->next->prev == temp)
+                               temp->next->prev = temp->prev;
+                       if (temp == list)
+                               list = list->next;
+                       temp->prev = NULL;
+                       temp->next = NULL;
+                       g_list_free(list);
+                       break;
+               }
+       }
+out:
+       return list;
+}
+
 #define DD_LIST_PREPEND(a, b)          \
        a = g_list_prepend(a, (gpointer)b)
 #define DD_LIST_APPEND(a, b)           \
similarity index 60%
rename from src/core/device-plugin.h
rename to src/core/log.c
index 3c6df87..04aa3da 100644 (file)
  * limitations under the License.
  */
 
+#include <stdio.h>
+#include "log.h"
 
-#ifndef __SS_DEVICE_PLUGIN_H__
-#define __SS_DEVICE_PLUGIN_H__
+#ifdef DEBUG
+void __cyg_profile_func_enter(void *, void *)
+    __attribute__ ((no_instrument_function));
+void __cyg_profile_func_exit(void *, void *)
+    __attribute__ ((no_instrument_function));
 
-#include "devman-plugin-intf.h"
+int g_trace_depth = -2;
 
-#define DEVMAN_PLUGIN_PATH      "/usr/lib/libslp_devman_plugin.so"
+void __cyg_profile_func_enter(void *func, void *caller)
+{
+       g_trace_depth++;
+}
 
-int _ss_devman_plugin_init(void);
-int _ss_devman_plugin_fini(void);
-
-const OEM_sys_devman_plugin_interface *plugin_intf;
-
-#endif  /* __SS_DEVICE_PLUGIN_H__ */
+void __cyg_profile_func_exit(void *func, void *caller)
+{
+       g_trace_depth--;
+}
+#endif
index 758151e..9684f38 100644 (file)
@@ -30,5 +30,4 @@
 
 #define LOG_TAG "DEVICED"
 #include "shared/log-macro.h"
-
 #endif
index 977eb06..ab3e80c 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "display/core.h"
 #include "log.h"
-#include "data.h"
+#include "common.h"
 #include "edbus-handler.h"
 #include "devices.h"
 #include "shared/dbus.h"
 
 #define PIDFILE_PATH           "/var/run/.deviced.pid"
 
-static void init_ad(struct main_data *ad)
-{
-       memset(ad, 0x0, sizeof(struct main_data));
-}
-
 static void writepid(char *pidpath)
 {
        FILE *fp;
@@ -59,63 +54,24 @@ static void sig_usr1(int signo)
        ecore_main_loop_quit();
 }
 
-static void check_systemd_active(void)
+static int deviced_main(int argc, char **argv)
 {
-       DBusError err;
-       DBusMessage *msg;
-       DBusMessageIter iter, sub;
-       const char *state;
-       char *pa[2];
-
-       pa[0] = "org.freedesktop.systemd1.Unit";
-       pa[1] = "ActiveState";
-
-       _I("%s %s", pa[0], pa[1]);
-
-       msg = dbus_method_sync_with_reply("org.freedesktop.systemd1",
-                       "/org/freedesktop/systemd1/unit/default_2etarget",
-                       "org.freedesktop.DBus.Properties",
-                       "Get", "ss", pa);
-       if (!msg)
-               return;
-
-       dbus_error_init(&err);
-
-       if (!dbus_message_iter_init(msg, &iter) ||
-           dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
-               goto out;
+       int ret;
 
-       dbus_message_iter_recurse(&iter, &sub);
-
-       if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
-               goto out;
-
-       dbus_message_iter_get_basic(&sub, &state);
-
-       if (strncmp(state, "active", 6) == 0) {
+       edbus_init(NULL);
+       devices_init(NULL);
+       ret = check_systemd_active();
+       if (ret == TRUE) {
                _I("notify relaunch");
                device_notify(DEVICE_NOTIFIER_BOOTING_DONE, (void *)TRUE);
        }
-out:
-       dbus_message_unref(msg);
-       dbus_error_free(&err);
-}
-
-static int system_main(int argc, char **argv)
-{
-       struct main_data ad;
-
-       init_ad(&ad);
-       edbus_init(&ad);
-       devices_init(&ad);
-       check_systemd_active();
        signal(SIGTERM, sig_quit);
        signal(SIGUSR1, sig_usr1);
 
        ecore_main_loop_begin();
 
-       devices_exit(&ad);
-       edbus_exit(&ad);
+       devices_exit(NULL);
+       edbus_exit(NULL);
        ecore_shutdown();
        return 0;
 }
@@ -124,5 +80,5 @@ int main(int argc, char **argv)
 {
        writepid(PIDFILE_PATH);
        ecore_init();
-       return system_main(argc, argv);
+       return deviced_main(argc, argv);
 }
diff --git a/src/core/noti.c b/src/core/noti.c
deleted file mode 100644 (file)
index 8eda5d6..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 <heynoti.h>
-#include "log.h"
-#include "data.h"
-#include "devices.h"
-#include "common.h"
-
-static int noti_fd;
-
-int noti_getfd()
-{
-       return noti_fd;
-}
-
-int noti_send(char *filename)
-{
-       return heynoti_publish(filename);
-}
-
-int noti_add(const char *noti, void (*cb) (void *), void *data)
-{
-       if (noti_fd < 0)
-               return -1;
-
-       return heynoti_subscribe(noti_fd, noti, cb, data);
-}
-
-static void noti_init(void *data)
-{
-       struct main_data *ad = (struct main_data*)data;
-
-       if ((ad->noti_fd = heynoti_init()) < 0) {
-               _E("Hey Notification Initialize failed");
-               return;
-       }
-       if (heynoti_attach_handler(ad->noti_fd) != 0) {
-               _E("fail to attach hey noti handler");
-               return;
-       }
-
-       noti_fd = heynoti_init();
-       if (noti_fd < 0) {
-               _E("heynoti_init error");
-               return;
-       }
-
-       if (heynoti_attach_handler(noti_fd) < 0) {
-               _E("heynoti_attach_handler error");
-               return;
-       }
-}
-
-static void noti_exit(void *data)
-{
-       struct main_data *ad = (struct main_data*)data;
-
-       heynoti_close(ad->noti_fd);
-       heynoti_close(noti_fd);
-}
-
-static const struct device_ops noti_device_ops = {
-       .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "noti",
-       .init     = noti_init,
-       .exit     = noti_exit,
-};
-
-DEVICE_OPS_REGISTER(&noti_device_ops)
index e058023..2c24723 100644 (file)
 #include <vconf.h>
 #include <Ecore.h>
 #include <device-node.h>
-
+#include <journal/system.h>
 #include "devices.h"
-#include "predefine.h"
 #include "device-handler.h"
 #include "device-notifier.h"
 #include "udev.h"
 #include "log.h"
-#include "emulator.h"
 #include "display/poll.h"
 #include "display/setting.h"
 #include "proc/proc-handler.h"
 #include "config-parser.h"
 #include "power-supply.h"
+#include "sleep/sleep.h"
 
 #define BUFF_MAX               255
 #define POPUP_KEY_CONTENT              "_SYSPOPUP_CONTENT_"
 
-#define PREDEF_BATTERY_CF_OPENED       "battery_cf_opened"
 #define SIGNAL_CHARGEERR_RESPONSE      "ChargeErrResponse"
 #define SIGNAL_TEMP_GOOD               "TempGood"
 
 #define BATT_CHARGE_NOTI "0"
 #define BATT_FULL_NOTI   "2"
 #endif
+
+enum power_supply_init_type {
+       POWER_SUPPLY_NOT_READY = 0,
+       POWER_SUPPLY_INITIALIZED = 1,
+};
+
 struct popup_data {
        char *name;
        char *key;
        char *value;
 };
 
+static int alert_popup = 0;
 static Ecore_Timer *power_timer = NULL;
 static Ecore_Timer *abnormal_timer = NULL;
 extern int battery_power_off_act(void *data);
@@ -74,7 +79,7 @@ static void pm_check_and_change(int bInserted)
        static int old = -1;
        if (old != bInserted) {
                old = bInserted;
-               predefine_pm_change_state(LCD_NORMAL);
+               internal_pm_change_state(LCD_NORMAL);
        }
 }
 
@@ -100,15 +105,10 @@ int check_lowbat_charge_device(int bInserted)
                        if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state) == 0) {
                                if(bat_state < VCONFKEY_SYSMAN_BAT_NORMAL
                                                || bat_state == VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF) {
-                                       if (apps == NULL) {
-                                               apps = find_device("apps");
-                                               if (apps == NULL)
-                                                       return 0;
-                                       }
+                                       FIND_DEVICE_INT(apps, "apps");
+
                                        if(bat_state == VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF)
                                                value = "poweroff";
-                                       else if (bat_state == VCONFKEY_SYSMAN_BAT_POWER_OFF)
-                                               value = "extreme";
                                        else
                                                value = "warning";
                                        params = malloc(sizeof(struct popup_data));
@@ -134,21 +134,12 @@ int check_lowbat_charge_device(int bInserted)
        return -1;
 }
 
-static int changed_battery_cf(int argc, char **argv)
+static int changed_battery_cf(enum present_type status)
 {
-       int present_status;
        struct popup_data *params;
        static const struct device_ops *apps = NULL;
 
-       if (argc != 1)
-               return -EINVAL;
-       present_status = atoi(argv[0]);
-
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return 0;
-       }
+       FIND_DEVICE_INT(apps, "apps");
        params = malloc(sizeof(struct popup_data));
        if (params == NULL) {
                _E("Malloc failed");
@@ -159,7 +150,7 @@ static int changed_battery_cf(int argc, char **argv)
        params->value = "battdisconnect";
        if (apps->init == NULL || apps->exit == NULL)
                goto out;
-       if (present_status == PRESENT_ABNORMAL)
+       if (status == PRESENT_ABNORMAL)
                apps->init((void *)params);
        else
                apps->exit((void *)params);
@@ -197,11 +188,7 @@ static int clean_health_popup(void)
        struct popup_data *params;
        static const struct device_ops *apps = NULL;
 
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return 0;
-       }
+       FIND_DEVICE_INT(apps, "apps");
        params = malloc(sizeof(struct popup_data));
        if (params == NULL) {
                _E("Malloc failed");
@@ -275,18 +262,35 @@ static void full_noti_cb(void *data, DBusMessage *msg, DBusError *err)
        _D("Inserted battery full noti : %d", noti_id);
 }
 
-static int send_full_noti(enum charge_full_type state)
+static int check_noti(void)
 {
-       int ret = 0;
 #ifdef MICRO_DD
-       char params[BUFF_MAX];
-       snprintf(params, sizeof(params), "%s %d", BATT_FULL_NOTI, state);
-       launch_evenif_exist(DEVICE_NOTIFIER, params);
+       int r_disturb, s_disturb, r_block, s_block;
+       r_disturb = vconf_get_int("memory/shealth/sleep/do_not_disturb", &s_disturb);
+       r_block = vconf_get_bool("db/setting/blockmode_wearable", &s_block);
+       if ((r_disturb != 0 && r_block != 0) ||
+           (s_disturb == 0 && s_block == 0)) {
+           return 1;
+       }
+       return 0;
 #else
+       return 1;
+#endif
+}
+
+static int send_full_noti(enum charge_full_type state)
+{
+       int ret = 0;
+       int noti;
        int retry;
        char str_id[32];
        char *arr[1];
 
+       noti = check_noti();
+
+       if (!noti)
+               return noti;
+
        switch (state) {
        case CHARGING_FULL:
                for (retry = RETRY_MAX; retry > 0 ;retry--) {
@@ -322,16 +326,12 @@ static int send_full_noti(enum charge_full_type state)
                _E("Failed to call dbus method (err: %d)", ret);
        break;
        }
-#endif
        return ret;
 }
 
 int send_charge_noti(void)
 {
        int ret = 0;
-#ifdef MICRO_DD
-       launch_evenif_exist(DEVICE_NOTIFIER, BATT_CHARGE_NOTI);
-#else
        int retry;
 
        for (retry = RETRY_MAX; retry > 0 ;retry--) {
@@ -346,7 +346,6 @@ int send_charge_noti(void)
                }
        }
        _E("Failed to call dbus method (err: %d)", ret);
-#endif
        return ret;
 }
 
@@ -358,6 +357,8 @@ void battery_noti(enum battery_noti_type type, enum battery_noti_status status)
 
        if (type == DEVICE_NOTI_BATT_FULL && status == DEVICE_NOTI_ON &&
            full == CHARGING_NOT_FULL) {
+               if (charge == CHARGER_DISCHARGING)
+                       send_charge_noti();
                ret = send_full_noti(CHARGING_FULL);
                if (ret == 0)
                        full = CHARGING_FULL;
@@ -383,7 +384,10 @@ static void noti_batt_full(void)
 {
        char params[BUFF_MAX];
        static int bat_full_noti = 0;
+       int r_disturb, s_disturb, r_block, s_block;
 
+       r_disturb = vconf_get_int("memory/shealth/sleep/do_not_disturb", &s_disturb);
+       r_block = vconf_get_bool("db/setting/blockmode_wearable", &s_block);
        if (!battery.charge_full && bat_full_noti == 1) {
                battery_noti(DEVICE_NOTI_BATT_FULL, DEVICE_NOTI_OFF);
                bat_full_noti = 0;
@@ -394,7 +398,11 @@ static void noti_batt_full(void)
                battery_noti(DEVICE_NOTI_BATT_FULL, DEVICE_NOTI_ON);
                bat_full_noti = 1;
                /* turn on LCD, if battery is full charged */
-               pm_change_internal(getpid(), LCD_NORMAL);
+               if ((r_disturb != 0 && r_block != 0) ||
+                   (s_disturb == 0 && s_block == 0))
+                       pm_change_internal(getpid(), LCD_NORMAL);
+               else
+                       _I("block LCD");
                /* on the full charge state */
                device_notify(DEVICE_NOTIFIER_FULLBAT, (void*)true);
        }
@@ -423,7 +431,7 @@ static void check_power_supply(int state)
        else
                pm_lock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE, 0);
 out:
-       _I("ta device %d", state);
+       _I("ta device %d(capacity %d)", state, battery.capacity);
 
        sync_cradle_status();
 }
@@ -431,7 +439,7 @@ out:
 static void update_present(enum battery_noti_status status)
 {
        static int old = DEVICE_NOTI_OFF;
-       char params[BUFF_MAX];
+       enum present_type present;
 
        if (old == status)
                return;
@@ -439,10 +447,10 @@ static void update_present(enum battery_noti_status status)
        old = status;
        pm_change_internal(getpid(), LCD_NORMAL);
        if (status == DEVICE_NOTI_ON)
-               snprintf(params, sizeof(params), "%d", PRESENT_ABNORMAL);
+               present = PRESENT_ABNORMAL;
        else
-               snprintf(params, sizeof(params), "%d", PRESENT_NORMAL);
-       notify_action(PREDEF_BATTERY_CF_OPENED, 1, params);
+               present = PRESENT_NORMAL;
+       changed_battery_cf(present);
 }
 
 static void update_health(enum battery_noti_status status)
@@ -453,6 +461,12 @@ static void update_health(enum battery_noti_status status)
                return;
        _I("charge %d health %d", battery.charge_now, battery.health);
        old = status;
+
+       if (alert_popup && status == DEVICE_NOTI_ON) {
+               _I("silent health popup");
+               return;
+       }
+
        pm_change_internal(getpid(), LCD_NORMAL);
        if (status == DEVICE_NOTI_ON) {
                _I("popup - Battery health status is not good");
@@ -545,65 +559,6 @@ static void check_online(void)
        }
 }
 
-static void charge_cb(struct main_data *ad)
-{
-       int val = -1;
-       int ret;
-       static int present_status = PRESENT_NORMAL;
-
-       lowbat_monitor(NULL);
-
-       if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &battery.charge_now) != 0 ||
-           device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY, &battery.capacity) != 0)
-               _E("fail to get battery node value");
-
-       if (battery.charge_now > 0)
-               battery.charge_now = CHARGER_CHARGING;
-       else
-               battery.charge_now = CHARGER_DISCHARGING;
-
-       if (battery.charge_now != CHARGER_CHARGING && battery.capacity == 0) {
-               _I("target will be shut down");
-               battery_power_off_act(NULL);
-               return;
-       }
-
-       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_PRESENT, &val);
-       if (ret != 0) {
-               battery.present = PRESENT_NORMAL;
-               _E("fail to get battery present value");
-               goto check_health;
-       }
-check_health:
-       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_HEALTH, &val);
-       if (ret != 0) {
-               battery.health = HEALTH_GOOD;
-               battery.ovp = OVP_NORMAL;
-               _E("failed to get battery health status");
-               goto check_full;
-       }
-       if (val != BATTERY_GOOD)
-               _I("Battery health status is not good (%d)", val);
-       if (val == BATTERY_OVERHEAT) {
-               battery.health = HEALTH_BAD;
-               battery.charge_now = CHARGER_ABNORMAL;
-               battery.temp = TEMP_HIGH;
-       } else if (val == BATTERY_COLD) {
-               battery.health = HEALTH_BAD;
-               battery.charge_now = CHARGER_ABNORMAL;
-               battery.temp = TEMP_LOW;
-       } else {
-               battery.health = HEALTH_GOOD;
-       }
-check_full:
-       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_FULL, &val);
-       if (ret == 0)
-               battery.charge_full = val;
-       noti_batt_full();
-       check_battery_status();
-       device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)battery.charge_now);
-}
-
 static int load_uevent(struct parse_result *result, void *user_data)
 {
        struct battery_status *info = user_data;
@@ -634,29 +589,75 @@ static int load_uevent(struct parse_result *result, void *user_data)
 static void power_load_uevent(void)
 {
        int ret;
+       static int initialized = POWER_SUPPLY_NOT_READY;
+
+       if (initialized == POWER_SUPPLY_INITIALIZED)
+               return;
        ret = config_parse(POWER_SUPPLY_UEVENT, load_uevent, &battery);
        if (ret < 0)
                _E("Failed to load %s, %d Use default value!", POWER_SUPPLY_UEVENT, ret);
+       else
+               initialized = POWER_SUPPLY_INITIALIZED;
+}
+
+static int sleep_execute(void *data)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, DEVICE_SLEEP_OPS);
+       return ops->execute(data);
 }
 
 void power_supply(void *data)
 {
        int ret;
+       int status = POWER_SUPPLY_STATUS_DISCHARGING;
+       static struct battery_status old;
 
-       static int old_charge;
+       if (old.charge_now != battery.charge_now || battery.charge_now == CHARGER_ABNORMAL) {
+               vconf_set_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, battery.charge_now);
+               power_supply_broadcast(CHARGE_NOW_SIGNAL, battery.charge_now);
+       }
 
-       if (old_charge != battery.charge_now || battery.charge_now == CHARGER_ABNORMAL) {
-               old_charge = battery.charge_now;
-               vconf_set_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, old_charge);
-               power_supply_broadcast(CHARGE_NOW_SIGNAL, old_charge);
+       if (old.capacity != battery.capacity)
+               journal_system_battery_level(battery.capacity);
+       if (old.online != battery.online ||
+           old.charge_now != battery.charge_now ||
+           old.charge_full != battery.charge_full) {
+               switch (battery.charge_now)
+               {
+               case CHARGER_ABNORMAL:
+                       status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+                       break;
+               case CHARGER_DISCHARGING:
+                       if (battery.charge_full == CHARGING_FULL)
+                               status = POWER_SUPPLY_STATUS_FULL;
+                       else
+                               status = POWER_SUPPLY_STATUS_DISCHARGING;
+                       break;
+               case CHARGER_CHARGING:
+                       status = POWER_SUPPLY_STATUS_CHARGING;
+                       break;
+               }
+               journal_system_power_supply_status(battery.online, status);
        }
 
        lowbat_monitor(data);
        check_online();
-       noti_batt_full();
+       if (old.charge_full != battery.charge_full) {
+               noti_batt_full();
+       }
+
+       old.capacity = battery.capacity;
+       old.online = battery.online;
+       old.charge_now = battery.charge_now;
+       old.charge_full = battery.charge_full;
+
        check_battery_status();
        device_notify(DEVICE_NOTIFIER_POWER_SUPPLY, NULL);
        device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)battery.charge_now);
+       if (battery.online > POWER_SUPPLY_TYPE_BATTERY)
+               sleep_execute(NULL);
 }
 
 void power_supply_status_init(void)
@@ -786,15 +787,96 @@ static DBusMessage *dbus_get_charge_level(E_DBus_Object *obj, DBusMessage *msg)
        return reply;
 }
 
+static DBusMessage *dbus_get_percent(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = battery.capacity;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_get_percent_raw(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret, val;
+
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY_RAW, &val);
+       if (ret < 0)
+               goto out;
+
+       if (val > 10000)
+               val = 10000;
+
+       ret = val;
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_is_full(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = battery.charge_full;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_get_health(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = battery.health;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
 static const struct edbus_method edbus_methods[] = {
-       { CHARGER_STATUS_SIGNAL, NULL, "i", dbus_get_charger_status },
-       { CHARGE_NOW_SIGNAL,     NULL, "i", dbus_get_charge_now },
-       { CHARGE_LEVEL_SIGNAL,   NULL, "i", dbus_get_charge_level },
+       { CHARGER_STATUS_SIGNAL,      NULL, "i", dbus_get_charger_status },
+       { CHARGE_NOW_SIGNAL,          NULL, "i", dbus_get_charge_now },
+       { CHARGE_LEVEL_SIGNAL,        NULL, "i", dbus_get_charge_level },
+       { CHARGE_CAPACITY_SIGNAL,     NULL, "i", dbus_get_percent },
+       { CHARGE_CAPACITY_LAW_SIGNAL, NULL, "i", dbus_get_percent_raw },
+       { CHARGE_FULL_SIGNAL,         NULL, "i", dbus_is_full },
+       { CHARGE_HEALTH_SIGNAL,       NULL, "i", dbus_get_health },
 };
 
+static int alert_popup_cb(keynode_t *key_nodes, void *data)
+{
+       alert_popup = vconf_keynode_get_bool(key_nodes);
+       _D("changed alert popup %d", alert_popup);
+       return alert_popup;
+}
+
 int power_supply_init(void *data)
 {
        int ret;
+
+       ret = vconf_get_bool(VCONFKEY_TESTMODE_TEMP_ALERT_POPUP, &alert_popup);
+       if (ret < 0)
+               _E("fail to get alert popup status");
+       vconf_notify_key_changed(VCONFKEY_TESTMODE_TEMP_ALERT_POPUP, (void *)alert_popup_cb, NULL);
+
        ret = register_edbus_method(DEVICED_PATH_BATTERY, edbus_methods, ARRAY_SIZE(edbus_methods));
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
@@ -804,11 +886,7 @@ int power_supply_init(void *data)
        if (ret < 0)
                _E("fail to init edbus signal(%d)", ret);
 
-       register_action(PREDEF_BATTERY_CF_OPENED, changed_battery_cf,
-               NULL, NULL);
-
        /* for simple noti change cb */
-       emulator_add_callback("device_charge_chgdet", (void *)charge_cb, data);
        power_supply_status_init();
        power_supply(NULL);
        return ret;
index 3dd2f94..49d3ea1 100644 (file)
 #ifndef __POWER_SUPPLY_H__
 #define __POWER_SUPPLY_H__
 
-#define CHARGER_STATUS_SIGNAL "ChargerStatus"
-#define CHARGE_NOW_SIGNAL     "ChargeNow"
-#define CHARGE_LEVEL_SIGNAL   "BatteryStatusLow"
+#define CHARGER_STATUS_SIGNAL      "ChargerStatus"
+#define CHARGE_NOW_SIGNAL          "ChargeNow"
+#define CHARGE_LEVEL_SIGNAL        "BatteryStatusLow"
+#define CHARGE_CAPACITY_SIGNAL     "GetPercent"
+#define CHARGE_CAPACITY_LAW_SIGNAL "GetPercentRaw"
+#define CHARGE_HEALTH_SIGNAL       "GetHealth"
+#define CHARGE_FULL_SIGNAL         "IsFull"
 
 int check_abnormal_popup(void);
 int check_lowbat_charge_device(int bInserted);
diff --git a/src/core/predefine.c b/src/core/predefine.c
deleted file mode 100755 (executable)
index 3b6c515..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 <limits.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <vconf.h>
-
-#include <sys/reboot.h>
-#include <sys/time.h>
-#include <mntent.h>
-#include <sys/mount.h>
-#include "dd-deviced.h"
-#include "log.h"
-#include "launch.h"
-#include "queue.h"
-#include "device-handler.h"
-#include "device-node.h"
-#include "predefine.h"
-#include "proc/proc-handler.h"
-#include "data.h"
-#include "common.h"
-#include "display/poll.h"
-#include "display/setting.h"
-#include "devices.h"
-#include "battery/battery.h"
-#include "edbus-handler.h"
-
-#define VCONFKEY_SYSMAN_FACTORY_MODE                   "memory/sysman/factory_mode"
-
-#define PREDEFINE_SO_DIR               PREFIX"/lib/ss_predefine/"
-#define PREDEF_CALL                    "call"
-#define PREDEF_FACTORY_MODE            "factorymode"
-
-#define CALL_EXEC_PATH                 PREFIX"/bin/call"
-
-#define LOWBAT_EXEC_PATH               PREFIX"/bin/lowbatt-popup"
-
-#define HDMI_NOTI_EXEC_PATH            PREFIX"/bin/hdmi_connection_noti"
-
-
-static int bFactoryMode = 0;
-
-int predefine_get_pid(const char *execpath)
-{
-       DIR *dp;
-       struct dirent *dentry;
-       int pid = -1, fd;
-       int ret;
-       char buf[PATH_MAX];
-       char buf2[PATH_MAX];
-
-       dp = opendir("/proc");
-       if (!dp) {
-               _E("FAIL: open /proc");
-               return -1;
-       }
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (!isdigit(dentry->d_name[0]))
-                       continue;
-
-               pid = atoi(dentry->d_name);
-
-               snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
-               fd = open(buf, O_RDONLY);
-               if (fd < 0)
-                       continue;
-               ret = read(fd, buf2, PATH_MAX);
-               close(fd);
-
-               if (ret < 0 || ret >=PATH_MAX)
-                       continue;
-
-               buf2[ret] = '\0';
-
-               if (!strcmp(buf2, execpath)) {
-                       closedir(dp);
-                       return pid;
-               }
-       }
-
-       errno = ESRCH;
-       closedir(dp);
-       return -1;
-}
-
-#ifdef NOUSE
-int call_predefine_action(int argc, char **argv)
-{
-       char argstr[128];
-       int pid;
-
-       if (argc < 2)
-               return -1;
-
-       snprintf(argstr, sizeof(argstr), "-t MT -n %s -i %s", argv[0], argv[1]);
-       pid = launch_if_noexist(CALL_EXEC_PATH, argstr);
-       if (pid < 0) {
-               _E("call predefine action failed");
-               return -1;
-       }
-       return pid;
-}
-#endif
-
-void predefine_pm_change_state(unsigned int s_bits)
-{
-       if (is_factory_mode() == 1)
-               _D("skip LCD control for factory mode");
-       else
-               pm_change_internal(getpid(), s_bits);
-}
-
-int is_factory_mode(void)
-{
-       return bFactoryMode;
-}
-int set_factory_mode(int bOn)
-{
-       int ret = -1;
-       if ( bOn==1 || bOn==0 ) {
-               bFactoryMode = bOn;
-               /* For USB-server to refer the value */
-               ret = vconf_set_int(VCONFKEY_SYSMAN_FACTORY_MODE, bOn);
-               if(ret != 0) {
-                       _E("FAIL: vconf_set_int()");
-               }
-       }
-       return bFactoryMode;
-}
-
-int factory_mode_action(int argc, char **argv)
-{
-       int bOn;
-       if (argc != 1 || argv[0] == NULL) {
-               _E("Factory Mode Set predefine action failed");
-               return -1;
-       }
-       bOn = atoi(argv[0]);
-       bOn = set_factory_mode(bOn);
-       return 0;
-
-}
-
-static void action_entry_load_from_sodir()
-{
-       DIR *dp;
-       struct dirent *dentry;
-       struct sysnoti *msg;
-       char *ext;
-       char tmp[128];
-
-       dp = opendir(PREDEFINE_SO_DIR);
-       if (!dp) {
-               _E("fail open %s", PREDEFINE_SO_DIR);
-               return;
-       }
-
-       msg = malloc(sizeof(struct sysnoti));
-       if (msg == NULL) {
-               _E("Malloc failed");
-               closedir(dp);
-               return;
-       }
-
-       msg->pid = getpid();
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if ((ext = strstr(dentry->d_name, ".so")) == NULL)
-                       continue;
-
-               snprintf(tmp, sizeof(tmp), "%s/%s", PREDEFINE_SO_DIR,
-                        dentry->d_name);
-               msg->path = tmp;
-               *ext = 0;
-               msg->type = &(dentry->d_name[3]);
-               register_msg(msg);
-       }
-       free(msg);
-
-       closedir(dp);
-}
-
-static DBusMessage *dbus_factory_mode(E_DBus_Object *obj, DBusMessage *msg)
-{
-       DBusError err;
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       pid_t pid;
-       int ret;
-       int argc;
-       char *type_str;
-       char *argv;
-
-       dbus_error_init(&err);
-
-       if (!dbus_message_get_args(msg, &err,
-                   DBUS_TYPE_STRING, &type_str,
-                   DBUS_TYPE_INT32, &argc,
-                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
-               _E("there is no message");
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (argc < 0) {
-               _E("message is invalid!");
-               ret = -EINVAL;
-               goto out;
-       }
-
-       pid = get_edbus_sender_pid(msg);
-       if (kill(pid, 0) == -1) {
-               _E("%d process does not exist, dbus ignored!", pid);
-               ret = -ESRCH;
-               goto out;
-       }
-
-       ret = set_factory_mode(atoi(argv));
-out:
-       reply = dbus_message_new_method_return(msg);
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
-
-       return reply;
-}
-
-static const struct edbus_method edbus_methods[] = {
-       { PREDEF_FACTORY_MODE, "sis", "i", dbus_factory_mode },
-};
-
-static void predefine_init(void *data)
-{
-       /* telephony initialize */
-       int ret;
-
-       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
-       if (ret < 0)
-               _E("fail to init edbus method(%d)", ret);
-#ifdef NOUSE
-       register_action(PREDEF_CALL, call_predefine_action, NULL, NULL);
-#endif
-       register_action(PREDEF_FACTORY_MODE, factory_mode_action, NULL, NULL);
-
-       action_entry_load_from_sodir();
-}
-
-static const struct device_ops predefine_device_ops = {
-       .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "predefine",
-       .init     = predefine_init,
-};
-
-DEVICE_OPS_REGISTER(&predefine_device_ops)
diff --git a/src/core/queue.c b/src/core/queue.c
deleted file mode 100644 (file)
index d0da9b2..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 <dlfcn.h>
-#include "data.h"
-#include "core.h"
-#include "queue.h"
-#include "log.h"
-#include "list.h"
-
-#define PREDEFINE_ACT_FUNC_STR         "predefine_action"
-#define IS_ACCESSIBLE_FUNC_STR         "is_accessible"
-#define UI_VIEWABLE_FUNC_STR                   "ui_viewable"
-
-static dd_list *predef_act_list;
-static dd_list *run_queue;
-
-static struct action_entry *find_action_entry(char *type)
-{
-       dd_list *tmp;
-       struct action_entry *data;
-
-       DD_LIST_FOREACH(predef_act_list, tmp, data) {
-               if (!strcmp(data->type, type))
-                       return data;
-       }
-
-       return NULL;
-}
-
-int register_action(char *type,
-                                int (*predefine_action) (),
-                                int (*ui_viewable) (),
-                                int (*is_accessible) (int))
-{
-       struct action_entry *data;
-
-       data = malloc(sizeof(struct action_entry));
-
-       if (data == NULL) {
-               _E("Malloc failed");
-               return -1;
-       }
-
-       data->type = NULL;
-       if (find_action_entry(type) != NULL)
-               goto err;
-
-       data->handle = NULL;
-       data->predefine_action = predefine_action;
-       if (data->predefine_action == NULL)
-               goto err;
-
-       data->is_accessible = is_accessible;
-       data->ui_viewable = ui_viewable;
-       data->owner_pid = getpid();
-       data->type = strdup(type);
-       data->path = strdup("");
-
-       DD_LIST_PREPEND(predef_act_list, data);
-
-       _D("add predefine action entry suceessfully - %s",
-                 data->type);
-       return 0;
- err:
-       if (data->type != NULL)
-               _E("adding predefine action entry failed - %s",
-                             data->type);
-       free(data);
-       return -1;
-}
-
-int register_msg(struct sysnoti *msg)
-{
-       struct action_entry *data;
-
-       data = malloc(sizeof(struct action_entry));
-
-       if (data == NULL) {
-               _E("Malloc failed");
-               return -1;
-       }
-
-       if (find_action_entry(msg->type) != NULL)
-               goto err;
-
-       data->handle = dlopen(msg->path, RTLD_LAZY);
-       if (!data->handle) {
-               _E("cannot find such library");
-               goto err;
-       }
-
-       data->predefine_action = dlsym(data->handle, PREDEFINE_ACT_FUNC_STR);
-       if (data->predefine_action == NULL) {
-               _E("cannot find predefine_action symbol : %s",
-                             PREDEFINE_ACT_FUNC_STR);
-               goto err;
-       }
-
-       data->is_accessible = dlsym(data->handle, IS_ACCESSIBLE_FUNC_STR);
-       data->ui_viewable = dlsym(data->handle, UI_VIEWABLE_FUNC_STR);
-       data->owner_pid = msg->pid;
-       data->type = strdup(msg->type);
-       data->path = strdup(msg->path);
-
-       DD_LIST_PREPEND(predef_act_list, data);
-
-       _D("add predefine action entry suceessfully - %s",
-                 data->type);
-       return 0;
- err:
-       _E("adding predefine action entry failed - %s", msg->type);
-       free(data);
-       return -1;
-}
-
-int notify_action(char *type, int argc, ...)
-{
-       dd_list *tmp;
-       struct action_entry *data;
-       va_list argptr;
-       int i;
-       int ret;
-       char *args = NULL;
-       char *argv[SYSMAN_MAXARG];
-
-       if (argc > SYSMAN_MAXARG || type == NULL)
-               return -1;
-
-       DD_LIST_FOREACH(predef_act_list, tmp, data) {
-               if (strcmp(data->type, type))
-                       continue;
-               va_start(argptr, argc);
-               for (i = 0; i < argc; i++) {
-                       args = va_arg(argptr, char *);
-                       if (args != NULL)
-                               argv[i] = strdup(args);
-                       else
-                               argv[i] = NULL;
-               }
-               va_end(argptr);
-               ret=run_queue_add(data, argc, argv);
-               ret=core_action_run();
-               return 0;
-       }
-
-       return 0;
-}
-
-int notify_msg(struct sysnoti *msg, int sockfd)
-{
-       dd_list *tmp;
-       struct action_entry *data;
-       int ret;
-
-       DD_LIST_FOREACH(predef_act_list, tmp, data) {
-               if (strcmp(data->type, msg->type))
-                       continue;
-               if (data->is_accessible != NULL
-                   && data->is_accessible(sockfd) == 0) {
-                       _E("%d cannot call that predefine module", msg->pid);
-                       return -1;
-               }
-               ret=run_queue_add(data, msg->argc, msg->argv);
-               ret=core_action_run();
-               return 0;
-       }
-
-       _E("cannot found action");
-       return -1;
-}
-
-int run_queue_add(struct action_entry *act_entry, int argc, char **argv)
-{
-       struct run_queue_entry *rq_entry;
-       int i;
-
-       rq_entry = malloc(sizeof(struct run_queue_entry));
-
-       if (rq_entry == NULL) {
-               _E("Malloc failed");
-               return -1;
-       }
-
-       rq_entry->state = STATE_INIT;
-       rq_entry->action_entry = act_entry;
-       rq_entry->forked_pid = 0;
-       if ( argc < 0 ) {
-               rq_entry->argc = 0;
-       } else {
-               rq_entry->argc = argc;
-               for (i = 0; i < argc; i++)
-                       rq_entry->argv[i] = argv[i];
-       }
-
-       DD_LIST_PREPEND(run_queue, rq_entry);
-
-       return 0;
-}
-
-int run_queue_run(enum run_state state,
-                    int (*run_func) (void *, struct run_queue_entry *),
-                    void *user_data)
-{
-       dd_list *tmp;
-       struct run_queue_entry *rq_entry;
-
-       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
-               if (rq_entry->state == state)
-                       run_func(user_data, rq_entry);
-       }
-
-       return 0;
-}
-
-struct run_queue_entry *run_queue_find_bypid(int pid)
-{
-       dd_list *tmp;
-       struct run_queue_entry *rq_entry;
-
-       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
-               if (rq_entry->forked_pid == pid)
-                       return rq_entry;
-       }
-
-       return NULL;
-}
-
-int run_queue_del(struct run_queue_entry *entry)
-{
-       dd_list *tmp;
-       struct run_queue_entry *rq_entry;
-       int i;
-
-       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
-               if (rq_entry == entry) {
-                       DD_LIST_REMOVE(run_queue, rq_entry);
-                       for (i = 0; i < rq_entry->argc; i++) {
-                               if (rq_entry->argv[i])
-                                       free(rq_entry->argv[i]);
-                       }
-                       free(rq_entry);
-               }
-       }
-
-       return 0;
-}
-
-int run_queue_del_bypid(int pid)
-{
-       dd_list *tmp;
-       struct run_queue_entry *rq_entry;
-       int i;
-
-       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
-               if (rq_entry->forked_pid == pid) {
-                       DD_LIST_REMOVE(run_queue, rq_entry);
-                       for (i = 0; i < rq_entry->argc; i++) {
-                               if (rq_entry->argv[i])
-                                       free(rq_entry->argv[i]);
-                       }
-                       free(rq_entry);
-               }
-       }
-
-       return 0;
-}
diff --git a/src/core/queue.h b/src/core/queue.h
deleted file mode 100644 (file)
index dee1e7e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 __QUEUE_H__
-#define __QUEUE_H__
-
-#include "sysnoti.h"
-
-struct action_entry {
-       int owner_pid;
-       void *handle;
-       char *type;
-       char *path;
-       int (*predefine_action) ();
-       int (*ui_viewable) ();
-       int (*is_accessible) (int caller_sockfd);
-};
-
-enum run_state {
-       STATE_INIT,
-       STATE_RUNNING,
-       STATE_DONE
-};
-
-struct run_queue_entry {
-       enum run_state state;
-       struct action_entry *action_entry;
-       int forked_pid;
-       int argc;
-       char *argv[SYSMAN_MAXARG];
-};
-
-int register_action(char *type,
-                                int (*predefine_action) (),
-                                int (*ui_viewable) (),
-                                int (*is_accessible) (int));
-int notify_action(char *type, int argc, ...);
-
-int register_msg(struct sysnoti *msg);
-int notify_msg(struct sysnoti *msg, int sockfd);
-
-int run_queue_run(enum run_state state,
-                    int (*run_func) (void *, struct run_queue_entry *),
-                    void *user_data);
-
-struct run_queue_entry *run_queue_find_bypid(int pid);
-int run_queue_add(struct action_entry *act_entry, int argc, char **argv);
-int run_queue_del(struct run_queue_entry *entry);
-int run_queue_del_bypid(int pid);
-
-#endif /* __QUEUE_H__ */
index 89deee8..13e9544 100644 (file)
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <vconf.h>
-#include "core.h"
 #include "log.h"
 #include "edbus-handler.h"
 #include "display/poll.h"
diff --git a/src/core/sysnoti.c b/src/core/sysnoti.c
deleted file mode 100755 (executable)
index 7fe6b2f..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 <limits.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include "data.h"
-#include "log.h"
-#include "queue.h"
-#include "common.h"
-#include "devices.h"
-
-#define SYSNOTI_SOCKET_PATH "/tmp/sn"
-#define RETRY_READ_COUNT       5
-enum sysnoti_cmd {
-       REGISTER_MSG,
-       NOTIFY_MSG
-};
-
-static Ecore_Fd_Handler *sysnoti_efd = NULL;
-static int sysnoti_fd;
-static int __sysnoti_start(void);
-static int __sysnoti_stop(int fd);
-
-static void print_sysnoti_msg(const char *title, struct sysnoti *msg)
-{
-       int i;
-       char exe_name[PATH_MAX];
-
-       if (get_cmdline_name(msg->pid, exe_name, PATH_MAX) < 0)
-               snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
-
-       _SD("pid : %d name: %s cmd : %d type : %s path : %s",
-                       msg->pid, exe_name, msg->cmd, msg->type, msg->path);
-}
-
-static inline int recv_int(int fd)
-{
-       int val, r = -1;
-       int retry_count = 0;
-       while (retry_count < RETRY_READ_COUNT) {
-               r = read(fd, &val, sizeof(int));
-               if (r < 0) {
-                       if(errno == EINTR) {
-                               _D("Re-read for error(EINTR)");
-                               retry_count++;
-                               continue;
-                       }
-                       else {
-                               _E("Read fail for int");
-                               return -1;
-                       }
-               } else {
-                       return val;
-               }
-       }
-       return -1;
-}
-
-static inline char *recv_str(int fd)
-{
-       int len, r = -1;
-       int retry_count = 0;
-       char *str;
-
-       while (retry_count < RETRY_READ_COUNT) {
-               r = read(fd, &len, sizeof(int));
-               if (r < 0) {
-                       if(errno == EINTR) {
-                               _D("Re-read for error(EINTR)");
-                               retry_count++;
-                               continue;
-                       }
-                       else {
-                               _E("Read fail for str length");
-                               return NULL;
-                       }
-               } else
-                       break;
-       }
-       if (retry_count == RETRY_READ_COUNT) {
-               _E("Read retry failed");
-               return NULL;
-       }
-       if (len <= 0)
-               return NULL;
-
-       if (len >= INT_MAX) {
-               _E("size is over INT_MAX");
-               return NULL;
-       }
-
-       str = (char *)malloc(len + 1);
-       if (str == NULL) {
-               _E("Not enough memory");
-               return NULL;
-       }
-       retry_count = 0;
-       while (retry_count < RETRY_READ_COUNT) {
-               r = read(fd, str, len);
-               if(r < 0) {
-                       if(errno == EINTR) {
-                               _D("Re-read for error(EINTR)");
-                               retry_count++;
-                               continue;
-                       } else {
-                               _E("Read fail for str");
-                               free(str);
-                               str = NULL;
-                               return NULL;
-                       }
-               } else
-                       break;
-       }
-       if (retry_count == RETRY_READ_COUNT) {
-               _E("Read retry failed");
-               free(str);
-               str = NULL;
-               return NULL;
-       }
-
-       str[len] = 0;
-       return str;
-}
-
-static int read_message(int fd, struct sysnoti *msg)
-{
-       int i;
-
-       if ((msg->pid = recv_int(fd)) == -1)
-               return -1;
-       if ((msg->cmd = recv_int(fd)) == -1)
-               return -1;
-       if ((msg->type = recv_str(fd)) == NULL)
-               return -1;
-       msg->path = recv_str(fd);
-       msg->argc = recv_int(fd);
-
-       if (msg->argc < 0)
-               return -1;
-       for (i = 0; i < msg->argc; i++)
-               msg->argv[i] = recv_str(fd);
-
-       return 0;
-}
-
-static inline void internal_free(char *str)
-{
-       if (str)
-               free(str);
-}
-
-static inline void free_message(struct sysnoti *msg)
-{
-       internal_free(msg->type);
-       internal_free(msg->path);
-       free(msg);
-}
-
-static Eina_Bool sysnoti_cb(void *data, Ecore_Fd_Handler * fd_handler)
-{
-       struct sysnoti *msg;
-       int ret = -1;
-       struct sockaddr_un client_address;
-       int client_sockfd;
-       int client_len;
-
-       if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
-               _E("ecore_main_fd_handler_active_get error , return");
-               goto out;
-       }
-
-       msg = malloc(sizeof(struct sysnoti));
-       if (msg == NULL) {
-               _E("Not enough memory");
-               goto out;
-       }
-
-       client_len = sizeof(client_address);
-       client_sockfd = accept(sysnoti_fd, (struct sockaddr *)&client_address, (socklen_t *)&client_len);
-
-       if (client_sockfd == -1) {
-               _E("socket accept error");
-               free(msg);
-               goto out;
-       }
-       if (read_message(client_sockfd, msg) < 0) {
-               _E("recv error msg");
-               print_sysnoti_msg(__FUNCTION__, msg);
-               free_message(msg);
-               write(client_sockfd, &ret, sizeof(int));
-               close(client_sockfd);
-               __sysnoti_stop(sysnoti_fd);
-               __sysnoti_start();
-               goto out;
-       }
-
-       print_sysnoti_msg(__FUNCTION__, msg);
-       if (msg->argc > SYSMAN_MAXARG) {
-               _E("error argument");
-               free_message(msg);
-               write(client_sockfd, &ret, sizeof(int));
-               close(client_sockfd);
-               goto out;
-       }
-
-       switch (msg->cmd) {
-#ifdef NOUSE
-       case REGISTER_MSG:
-               ret = register_msg(msg);
-               _E("%d", ret);
-               break;
-#endif
-       case NOTIFY_MSG:
-               ret = notify_msg(msg, client_sockfd);
-               break;
-       default:
-               ret = -1;
-       }
-
-
-       write(client_sockfd, &ret, sizeof(int));
-       close(client_sockfd);
-
-       free_message(msg);
-out:
-       return EINA_TRUE;
-}
-
-static int sysnoti_server_init(void)
-{
-       int fd;
-       struct sockaddr_un serveraddr;
-
-       if (access(SYSNOTI_SOCKET_PATH, F_OK) == 0)
-               unlink(SYSNOTI_SOCKET_PATH);
-
-       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (fd < 0) {
-               _E("socket create failed");
-               return -1;
-       }
-       if((fsetxattr(fd, "security.SMACK64IPOUT", "@", 2, 0)) < 0 ) {
-               _E("Socket SMACK labeling failed");
-               if(errno != EOPNOTSUPP) {
-                       close(fd);
-                       return -1;
-               }
-       }
-
-       if((fsetxattr(fd, "security.SMACK64IPIN", "*", 2, 0)) < 0 ) {
-               _E("Socket SMACK labeling failed");
-               if(errno != EOPNOTSUPP) {
-                       close(fd);
-                       return -1;
-               }
-       }
-
-       bzero(&serveraddr, sizeof(struct sockaddr_un));
-       serveraddr.sun_family = AF_UNIX;
-       strncpy(serveraddr.sun_path, SYSNOTI_SOCKET_PATH,
-               sizeof(serveraddr.sun_path));
-
-       if (bind(fd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr)) < 0) {
-               _E("socket bind failed");
-               close(fd);
-               return -1;
-       }
-
-       if (chmod(SYSNOTI_SOCKET_PATH, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0)      /* 0777 */
-               _E("failed to change the socket permission");
-
-       if (listen(fd, 5) < 0) {
-               _E("failed to listen");
-               close(fd);
-               return -1;
-       }
-
-       return fd;
-}
-
-static int __sysnoti_start(void)
-{
-       sysnoti_fd = sysnoti_server_init();
-       if ( sysnoti_fd < 0 )
-               return -1;
-       sysnoti_efd = ecore_main_fd_handler_add(sysnoti_fd, ECORE_FD_READ, sysnoti_cb, NULL, NULL,
-                                 NULL);
-       if (!sysnoti_efd) {
-               _E("error ecore_main_fd_handler_add");
-               close(sysnoti_fd);
-               return -1;
-       }
-       return 0;
-}
-
-static int __sysnoti_stop(int fd)
-{
-       if (sysnoti_efd) {
-               ecore_main_fd_handler_del(sysnoti_efd);
-               sysnoti_efd = NULL;
-       }
-       if (fd >=0) {
-               close(fd);
-               fd = -1;
-       }
-       return 0;
-}
-
-static void sysnoti_init(void *data)
-{
-       struct main_data *ad = (struct main_data*)data;
-
-       if (__sysnoti_start() == -1)
-               _E("fail sys socket fd init");
-}
-
-static const struct device_ops sysnoti_device_ops = {
-       .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "sysnoti",
-       .init     = sysnoti_init,
-};
-
-DEVICE_OPS_REGISTER(&sysnoti_device_ops)
index bc17054..297a1c0 100644 (file)
 
 #include "core/list.h"
 #include "core/log.h"
-#include "core/data.h"
 #include "core/devices.h"
 #include "core/edbus-handler.h"
 #include "core/common.h"
 #include "core/device-notifier.h"
 #include "proc/proc-handler.h"
 
-#define PREDEF_SET_MAX_FREQUENCY       "set_max_frequency"
-#define PREDEF_SET_MIN_FREQUENCY       "set_min_frequency"
-#define PREDEF_RELEASE_MAX_FREQUENCY   "release_max_frequency"
-#define PREDEF_RELEASE_MIN_FREQUENCY   "release_min_frequency"
-#define PREDEF_CPU_COUNT       "set_cpu_count"
+#define SET_MAX_FREQ   "set_max_frequency"
+#define SET_MIN_FREQ   "set_min_frequency"
+#define SET_FREQ_LEN   17
+
+#define RELEASE_MAX_FREQ       "release_max_frequency"
+#define RELEASE_MIN_FREQ       "release_min_frequency"
+#define RELEASE_FREQ_LEN       21
 
 #define POWER_SAVING_CPU_FREQ_RATE     (0.7)
 
@@ -343,13 +344,12 @@ static void set_emergency_limit(void)
                _E("failed to get vconf key");
                return;
        }
-       if (val != SETTING_PSMODE_EMERGENCY)
-               return;
-
-       val = EMERGENCY_LOCK;
-       device_notify(DEVICE_NOTIFIER_PMQOS_EMERGENCY, (void*)val);
-
+       if (val == SETTING_PSMODE_EMERGENCY) {
+               val = EMERGENCY_LOCK;
+               device_notify(DEVICE_NOTIFIER_PMQOS_EMERGENCY, (void*)val);
+       }
 }
+
 static int emergency_cpu_cb(keynode_t *key_nodes, void *data)
 {
        int val;
@@ -485,44 +485,6 @@ static int add_entry_to_cpu_number_list(int pid, int number)
        return 0;
 }
 
-int set_cpu_number_action(int argc, char **argv)
-{
-       int r;
-
-       if(cur_siop_level() != 0)
-               return -EINVAL;
-
-       if (argc == 1) {// release cpu number
-               r = remove_entry_from_cpu_number_list(atoi(argv[0]));
-               if (r < 0) {
-                       _E("Remove entry failed");
-                       return r;
-               }
-
-               if (cur_cpu_number == INT_MAX)
-                       cur_cpu_number = cpu_number_limit;
-
-               r = write_cpu_number(cur_cpu_number);
-               if (r < 0) {
-                       _E("Write cpu number failed");
-                       return r;
-               }
-       } else if (argc ==2) {//set cpu number
-               r = add_entry_to_cpu_number_list(atoi(argv[0]), atoi(argv[1]));
-               if (r < 0) {
-                       _E("Add entry failed");
-                       return r;
-               }
-
-               r = write_cpu_number(cur_cpu_number);
-               if (r < 0) {
-                       _E("Write entry failed");
-                       return r;
-               }
-       }
-       return 0;
-}
-
 static int booting_done(void *data)
 {
        set_freq_limit();
@@ -566,13 +528,13 @@ static DBusMessage *dbus_cpu_handler(E_DBus_Object *obj, DBusMessage *msg)
                goto out;
        }
 
-       if (strncmp(type_str, PREDEF_SET_MAX_FREQUENCY, strlen(PREDEF_SET_MAX_FREQUENCY)) == 0)
+       if (!strncmp(type_str, SET_MAX_FREQ, SET_FREQ_LEN))
                ret = set_max_frequency_action(argc, (char **)&argv);
-       else if (strncmp(type_str, PREDEF_SET_MIN_FREQUENCY, strlen(PREDEF_SET_MIN_FREQUENCY)) == 0)
+       else if (!strncmp(type_str, SET_MIN_FREQ, SET_FREQ_LEN))
                ret = set_min_frequency_action(argc, (char **)&argv);
-       else if (strncmp(type_str, PREDEF_RELEASE_MAX_FREQUENCY, strlen(PREDEF_RELEASE_MAX_FREQUENCY)) == 0)
+       else if (!strncmp(type_str, RELEASE_MAX_FREQ, RELEASE_FREQ_LEN))
                ret = release_max_frequency_action(argc, (char **)&argv);
-       else if (strncmp(type_str, PREDEF_RELEASE_MIN_FREQUENCY, strlen(PREDEF_RELEASE_MIN_FREQUENCY)) == 0)
+       else if (!strncmp(type_str, RELEASE_MIN_FREQ, RELEASE_FREQ_LEN))
                ret = release_min_frequency_action(argc, (char **)&argv);
 out:
        reply = dbus_message_new_method_return(msg);
@@ -583,10 +545,10 @@ out:
 }
 
 static const struct edbus_method edbus_methods[] = {
-       { PREDEF_SET_MAX_FREQUENCY,     "siss", "i", dbus_cpu_handler },
-       { PREDEF_SET_MIN_FREQUENCY,     "siss", "i", dbus_cpu_handler },
-       { PREDEF_RELEASE_MAX_FREQUENCY, "siss", "i", dbus_cpu_handler },
-       { PREDEF_RELEASE_MIN_FREQUENCY, "siss", "i", dbus_cpu_handler },
+       { SET_MAX_FREQ,     "siss", "i", dbus_cpu_handler },
+       { SET_MIN_FREQ,     "siss", "i", dbus_cpu_handler },
+       { RELEASE_MAX_FREQ, "siss", "i", dbus_cpu_handler },
+       { RELEASE_MIN_FREQ, "siss", "i", dbus_cpu_handler },
 };
 
 static void cpu_init(void *data)
@@ -598,11 +560,6 @@ static void cpu_init(void *data)
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
        set_cpu_number_limit();
-       register_action(PREDEF_SET_MAX_FREQUENCY, set_max_frequency_action, NULL, NULL);
-       register_action(PREDEF_SET_MIN_FREQUENCY, set_min_frequency_action, NULL, NULL);
-       register_action(PREDEF_RELEASE_MAX_FREQUENCY, release_max_frequency_action, NULL, NULL);
-       register_action(PREDEF_RELEASE_MIN_FREQUENCY, release_min_frequency_action, NULL, NULL);
-       register_action(PREDEF_CPU_COUNT, set_cpu_number_action, NULL, NULL);
 
        vconf_notify_key_changed(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU, (void *)power_saving_cpu_cb, NULL);
        vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, (void *)emergency_cpu_cb, NULL);
index 5d12dc4..b5e2e3c 100755 (executable)
@@ -7,6 +7,7 @@ ENDIF()
 
 SET(SRCS
        devicectl.c
+       usb.c
 )
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
 
index d9dcfef..18f195f 100644 (file)
@@ -23,6 +23,7 @@
 #include <dbus/dbus.h>
 #include <shared/dbus.h>
 #include <core/common.h>
+#include "usb.h"
 
 /*
  * devicectl [device] [action]
@@ -35,6 +36,7 @@ enum device_type {
        DEVICE_DISPLAY,
        DEVICE_LED,
        DEVICE_PASS,
+       DEVICE_USB,
        DEVICE_MAX,
        DEVICE_ALL,
 };
@@ -50,6 +52,7 @@ static const struct device {
        { DEVICE_DISPLAY, "display", DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY },
        { DEVICE_LED,     "led",     DEVICED_PATH_LED,     DEVICED_INTERFACE_LED     },
        { DEVICE_PASS,    "pass",    DEVICED_PATH_PASS,    DEVICED_INTERFACE_PASS    },
+       { DEVICE_USB,     "usb",     DEVICED_PATH_USB,     DEVICED_INTERFACE_USB     },
 };
 
 static int start_device(char **args)
@@ -144,28 +147,64 @@ static int save_log(char **args)
        return 0;
 }
 
+static int set_usb_mode(char **args)
+{
+       return load_usb_mode(args[3]);
+}
+
+static int unset_usb_mode(char **args)
+{
+       return unload_usb_mode(args[3]);
+}
+
 static const struct action {
        const enum device_type id;
        const char *action;
        const int argc;
        int (* const func)(char **args);
+       const char *option;
 } actions[] = {
-       { DEVICE_ALL,       "start",           3, start_device          },
-       { DEVICE_ALL,       "stop",            3, stop_device           },
-       { DEVICE_DISPLAY,   "dumpmode",        4, dump_mode             },
-       { DEVICE_LED,       "dumpmode",        4, dump_mode             },
-       { DEVICE_DISPLAY,   "savelog",         3, save_log              },
+       { DEVICE_ALL,       "start",           3, start_device,      ""            },
+       { DEVICE_ALL,       "stop",            3, stop_device,       ""            },
+       { DEVICE_DISPLAY,   "dumpmode",        4, dump_mode,         "[on|off]"    },
+       { DEVICE_LED,       "dumpmode",        4, dump_mode,         "[on|off]"    },
+       { DEVICE_DISPLAY,   "savelog",         3, save_log,          ""            },
+       { DEVICE_USB,       "set",             4, set_usb_mode,      "[sdb|ssh]"   },
+       { DEVICE_USB,       "unset",           4, unset_usb_mode,    "[sdb|ssh]"   },
 };
 
 static inline void usage()
 {
        printf("[usage] devicectl <device_name> <action>\n");
+       printf("Please use option --help to check options\n");
+}
+
+static void help()
+{
+       int i;
+
+       printf("[usage] devicectl <device_name> <action> <option>\n");
+       printf("device name & action & option\n");
+       for (i = 0; i < ARRAY_SIZE(actions); i++) {
+               if (actions[i].id == DEVICE_ALL) {
+                       printf("    [all-device] %s %s\n", actions[i].action,
+                           actions[i].option);
+               } else {
+                       printf("    %s %s %s\n", devices[actions[i].id].name,
+                           actions[i].action, actions[i].option);
+               }
+       }
 }
 
 int main(int argc, char *argv[])
 {
        int i;
 
+       if (argc == 2 && !strcmp(argv[1], "--help")) {
+               help();
+               return 0;
+       }
+
        if (argc < 3) {
                usage();
                return -EINVAL;
diff --git a/src/devicectl/usb.c b/src/devicectl/usb.c
new file mode 100644 (file)
index 0000000..4e0efa6
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * devicectl
+ *
+ * Copyright (c) 2012 - 2014 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 <errno.h>
+#include <stdlib.h>
+#include <core/common.h>
+#include <core/launch.h>
+#include "usb.h"
+
+#define USB_SDB "sdb"
+#define USB_SSH "ssh"
+
+#define ARG_MAX 10
+#define CMD_MAX 128
+
+static struct usb_sysfs {
+       char *path;
+       char *value;
+} usb_confs[] = {
+       { "/sys/class/usb_mode/usb0/enable",          "0"    },
+       { "/sys/class/usb_mode/usb0/idVendor",        "04e8" },
+       { "/sys/class/usb_mode/usb0/idProduct",       NULL   },
+       { "/sys/class/usb_mode/usb0/funcs_fconf",     NULL   },
+       { "/sys/class/usb_mode/usb0/funcs_sconf",     NULL   },
+       { "/sys/class/usb_mode/usb0/bDeviceClass",    "239"  },
+       { "/sys/class/usb_mode/usb0/bDeviceSubClass", "2"    },
+       { "/sys/class/usb_mode/usb0/bDeviceProtocol", "1"    },
+       { "/sys/class/usb_mode/usb0/enable",          "1"    },
+};
+
+static int launch_app(char **argv)
+{
+       pid_t pid;
+
+       if (!argv || !argv[0])
+               return -EINVAL;
+
+       pid = fork();
+
+       if (pid < 0) {
+               printf("fork() failed\n");
+               return -ENOMEM;
+       }
+
+       if (pid > 0) { /*parent*/
+               return pid;
+       }
+
+       /*child*/
+
+       if (execvp(argv[0], argv) < 0)
+               printf("execvp failed (%d)\n", errno);
+
+       return 0;
+}
+
+static int write_sysfs(char *path, char *value)
+{
+       FILE *fp;
+       int ret;
+
+       if (!path || !value)
+               return -ENOMEM;
+
+       fp = fopen(path, "w");
+       if (!fp) {
+               printf("FAIL: fopen(%s)\n", path);
+               return -ENOMEM;
+       }
+
+       ret = fwrite(value, sizeof(char), strlen(value), fp);
+       fclose(fp);
+       if (ret < strlen(value)) {
+               printf("FAIL: fwrite(%s)\n", value);
+               ret = -ENOMEM;
+       }
+
+       return ret;
+}
+
+static int set_usb_configuration(char *idproduct, char *fconf, char *sconf)
+{
+       int i, ret;
+
+       usb_confs[2].value = idproduct;
+       usb_confs[3].value = fconf;
+       usb_confs[4].value = sconf;
+
+       for (i = 0 ; i < ARRAY_SIZE(usb_confs) ; i++) {
+               ret = write_sysfs(usb_confs[i].path, usb_confs[i].value);
+               if (ret < 0) {
+                       printf("usb setting fails (%s), (%s)\n", usb_confs[i].path, usb_confs[i].value);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int divide_cmd(char **command, int len, char *cmd)
+{
+       char *param, *next, *term;
+       int cnt = 0;
+
+       if (!cmd)
+               return -EINVAL;
+
+       term = strchr(cmd, '\0');
+       if (!term)
+               return -EINVAL;
+
+       memset(command, 0, len);
+
+       param = cmd;
+       while (1) {
+               if (*param == '\0')
+                       break;
+               if (*param == ' ') {
+                       param++;
+                       continue;
+               }
+
+               next = strchr(param, ' ');
+               if (!next) {
+                       command[cnt++] = param;
+                       break;
+               }
+
+               if (next == param) {
+                       param++;
+                       continue;
+               }
+
+               *next = '\0';
+               command[cnt++] = param;
+               param = next + 1;
+       }
+
+       return 0;
+}
+
+static int run_cmd(char *cmd)
+{
+       int ret;
+       char *command[ARG_MAX];
+       char in_cmd[CMD_MAX];
+
+       if (!cmd)
+               return -EINVAL;
+
+       snprintf(in_cmd, sizeof(in_cmd), "%s", cmd);
+
+       ret = divide_cmd(command, sizeof(command), in_cmd);
+       if (ret < 0)
+               return ret;
+
+       ret = launch_app(command);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+
+}
+
+static int load_sdb(void)
+{
+       int ret;
+       char *cmd[ARG_MAX];
+
+       ret = set_usb_configuration("6860", "mtp", "mtp,acm,sdb");
+       if (ret < 0)
+               return ret;
+
+       return run_cmd("/usr/bin/systemctl start sdbd.service");
+}
+
+static int load_ssh(void)
+{
+       int ret;
+
+       ret = set_usb_configuration("6863", "rndis", " ");
+       if (ret < 0)
+               return ret;
+
+       ret = run_cmd("/sbin/ifconfig usb0 192.168.129.3 up");
+       if (ret < 0)
+               return ret;
+
+       ret = run_cmd("/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0");
+       if (ret < 0)
+               return ret;
+
+       ret = run_cmd("/usr/bin/systemctl start sshd.service");
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int unload_sdb(void)
+{
+       int ret;
+
+       ret = write_sysfs(usb_confs[0].path, usb_confs[0].value);
+       if (ret < 0)
+               return ret;
+
+       ret = run_cmd("/usr/bin/systemctl stop sdbd.service");
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int unload_ssh(void)
+{
+       int ret;
+
+       ret = write_sysfs(usb_confs[0].path, usb_confs[0].value);
+       if (ret < 0)
+               return ret;
+
+       ret = run_cmd("/sbin/ifconfig usb0 down");
+       if (ret < 0)
+               return ret;
+
+       ret = run_cmd("/usr/bin/systemctl stop sshd.service");
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int load_usb_mode(char *opt)
+{
+       if (!opt) {
+               printf("Failed: Forth parameter is NULL\n");
+               return -EINVAL;
+       }
+
+       if (!strncmp(opt, USB_SDB, strlen(opt)))
+               return load_sdb();
+
+       if (!strncmp(opt, USB_SSH, strlen(opt)))
+               return load_ssh();
+
+       printf("Failed: Forth parameter is invalid (%s)\n", opt);
+       return -EINVAL;
+}
+
+int unload_usb_mode(char *opt)
+{
+       if (!opt) {
+               printf("Failed: Forth parameter is NULL\n");
+               return -EINVAL;
+       }
+
+       if (!strncmp(opt, USB_SDB, strlen(opt)))
+               return unload_sdb();
+
+       if (!strncmp(opt, USB_SSH, strlen(opt)))
+               return unload_ssh();
+
+       printf("Failed: Forth parameter is invalid (%s)\n", opt);
+       return -EINVAL;
+}
diff --git a/src/devicectl/usb.h b/src/devicectl/usb.h
new file mode 100644 (file)
index 0000000..e2285d8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * devicectl
+ *
+ * Copyright (c) 2012 - 2014 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 __DEVICECTL_USBCLIENT_H__
+#define __DEVICECTL_USBCLIENT_H__
+
+int load_usb_mode(char *opt);
+int unload_usb_mode(char *opt);
+
+#endif /* __DEVICECTL_USBCLIENT_H__*/
index 92ef751..5f63520 100644 (file)
@@ -78,10 +78,10 @@ enum dump_log_type {
  *                     The allocated memory size must be large enough to store the file name.
  *                     The result will include the terminating null byte('\0') at the end of the string.
  * @param[in] cmdline_size
- * @return 0 on success, -1 if failed.\n
- *         If the size of cmdline is smaller than the result, it will return -1 and  \n
+ * @return 0 on success, negative value if failed.\n
+ *         If the size of cmdline is smaller than the result, it will return -75 and  \n
  *         errno will be set as EOVERFLOW. \n
- *         If the function cannot open /proc/%d/cmdline file then it will return -1 and \n
+ *         If the function cannot open /proc/%d/cmdline file then it will return -3 and \n
  *         errno will be set as ESRCH.
  */
 int deviced_get_cmdline_name(pid_t pid, char *cmdline,
@@ -230,6 +230,17 @@ int deviced_set_timezone(char *tzpath_str);
 int deviced_call_predef_action(const char *type, int num, ...);
 
 /**
+ * @fn int deviced_change_flightmode(int mode)
+ * @brief This API call notifies about flight mode.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_change_flightmode(int mode);
+
+/**
  * @fn int deviced_inform_foregrd(void)
  * @brief This API call notifies that current process is running in foreground.
  * @return 0 or positive value on success and negative value if failed.
index 02b3364..e8e7f4f 100644 (file)
@@ -87,7 +87,7 @@ typedef enum
  * @brief Enumerations of unlimited duration for the Haptic API.
  */
 typedef enum {
-       HAPTIC_DURATION_UNLIMITED = 0xFFFFFFFF,
+       HAPTIC_DURATION_UNLIMITED = 0x7FFFFFFF,
 } haptic_duration_e;
 
 /**
index b00efd6..a3809ec 100644 (file)
@@ -52,6 +52,8 @@ enum LED_MODE {
        LED_CHARGING_ERROR,
        LED_MISSED_NOTI,
        LED_VOICE_RECORDING,
+       LED_REMOTE_CONTROLLER,
+       LED_AIR_WAKEUP,
        LED_POWER_OFF,
        LED_CUSTOM,
        LED_MODE_MAX,
@@ -127,7 +129,7 @@ int led_set_brightness_with_noti(int val, bool enable);
  *  This API is used to set command of the irled.\n
  *  It sets the command to control irled by calling device_set_property() function.\n
  * @param[in] value string that you want to set
- * @return 0 on success, -1 if failed
+ * @return 0 on success, negative value if failed
  * @see led_set_brightness_with_noti()
  * @par Example
  * @code
index b387e3e..e2860c1 100644 (file)
@@ -39,10 +39,13 @@ extern "C" {
  */
 
 /**
- * @par Description:
- *      This API is used to mount mmc.\n
+ * @fn int mmc_secure_mount(const char *mount_point)
+ * @brief This API is used to mount mmc.\n
+ *              [mount fail value] \n
+ *              -1 : operation not permmitted \n
+ *              -22 : Invalid argument \n
  * @param[in] mount_point pointer to the character buffer containing the path
- * @return 0 on success, -1 if failed
+ * @return 0 on success, negative value if failed
  * @par Example
  * @code
  *  ...
@@ -54,10 +57,13 @@ extern "C" {
 int mmc_secure_mount(const char *mount_point);
 
 /**
- * @par Description:
- *      This API is used to unmount mmc.\n
+ * @fn int mmc_secure_unmount(const char *mount_point)
+ * @brief This API is used to unmount mmc.\n
+ *              [unmount fail value] \n
+ *              -1 : operation not permmitted \n
+ *              -22 : Invalid argument \n
  * @param[in] mount_point pointer to the character buffer containing the path
- * @return 0 on success, -1 if failed
+ * @return 0 on success, negative value if failed
  * @par Example
  * @code
  *  ...
index ba72d32..68d171e 100644 (file)
@@ -51,6 +51,13 @@ typedef enum
 } haptic_module_feedback;
 
 /**
+ * @brief Enumerations of unlimited duration for the Haptic Module API.
+ */
+typedef enum {
+       HAPTIC_MODULE_DURATION_UNLIMITED = 0x7FFFFFFF,
+} haptic_module_duration;
+
+/**
  * @brief Enumerations of iteration count for the Haptic Module API.
  */
 typedef enum
index 3a0770c..9c50e04 100644 (file)
 #include "display-ops.h"
 #include "weaks.h"
 #include "core/edbus-handler.h"
+#include "core/devices.h"
+
+/*
+ * this definition will be removed,
+ * after the key is merge to all branch.
+ */
+#ifndef VCONFKEY_SETAPPL_AMBIENT_MODE_BOOL
+#define VCONFKEY_SETAPPL_AMBIENT_MODE_BOOL "db/setting/ambient_mode"
+#endif
+
+#define ALPM_BUS_NAME          "org.tizen.graphics.alpmclock"
+#define ALPM_OBJECT_PATH       "/Org/Tizen/Graphics/AlpmClock"
+#define ALPM_PATH_LCD          ALPM_OBJECT_PATH"/LCD"
+#define ALPM_INTERFACE_LCD     ALPM_BUS_NAME".LCD"
+#define ALPM_NODE_STATUS       "alpm_node_status"
 
 #define ON             "on"
 #define OFF            "off"
 #define SIGNAL_ALPM_OFF                        "ALPMOff"
 #define CLOCK_START                    "clockstart"
 #define CLOCK_END                      "clockend"
-#define ALPM_MAX_TIME                  30      /* minutes */
+#define TIMEOUT_NONE                   (-1)
+#define ALPM_CLOCK_WAITING_TIME        5000 /* ms */
 
 static char *alpm_path;
 static int update_count;
 static int alpm_state;
+static pid_t alpm_pid;
+static int ambient_mode;
+
+int get_ambient_mode(void)
+{
+       return ambient_mode;
+}
 
 void broadcast_alpm_state(int state)
 {
@@ -49,6 +72,36 @@ void broadcast_alpm_state(int state)
            signal, NULL, NULL);
 }
 
+bool check_suspend_direct(pid_t pid)
+{
+       struct state *st;
+
+       if (pm_cur_state == S_NORMAL ||
+           pm_cur_state == S_LCDDIM)
+               return false;
+
+       if (pid != alpm_pid)
+               return false;
+
+       if (check_lock_state(S_SLEEP) == true)
+               return false;
+
+       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
+               return false;
+
+       _I("goto sleep state direct!");
+
+       reset_timeout(TIMEOUT_NONE);
+       pm_old_state = pm_cur_state;
+       pm_cur_state = S_SLEEP;
+       st = &states[pm_cur_state];
+
+       if (st->action)
+               st->action(TIMEOUT_NONE);
+
+       return true;
+}
+
 int alpm_get_state(void)
 {
        char state[4];
@@ -73,6 +126,9 @@ int alpm_get_state(void)
 
 int alpm_set_state(int on)
 {
+       if (!ambient_mode)
+               return 0;
+
        if (!alpm_path)
                return -ENODEV;
 
@@ -80,6 +136,9 @@ int alpm_set_state(int on)
 
        update_count = 0;
 
+       if (!on)
+               alpm_pid = 0;
+
        _D("ALPM is %s", (on ? ON : OFF));
 
        alpm_state = on;
@@ -87,61 +146,84 @@ int alpm_set_state(int on)
        return sys_set_str(alpm_path, (on ? ON : OFF));
 }
 
-static void start_clock(void)
+int check_alpm_lcdon_ready(void)
 {
-       struct timespec now_time;
-       static struct timespec start_time;
-       int diff_time;
+       int ret;
 
-       if (pm_cur_state == S_NORMAL ||
-           pm_cur_state == S_LCDDIM ||
-           alpm_state == false)
-               return;
+       if (!ambient_mode) {
+               _E("It's not always on mode");
+               return 0;
+       }
 
-       _D("lcd on");
+       if (alpm_get_state() == false) {
+               _E("Now alpm node is off!");
+               return 0;
+       }
 
-       if (update_count == 0)
-               clock_gettime(CLOCK_REALTIME, &start_time);
+       _D("wating until updating alpm clock");
 
-       update_count++;
+       ret = dbus_method_sync(ALPM_BUS_NAME,
+               ALPM_PATH_LCD, ALPM_INTERFACE_LCD,
+               ALPM_NODE_STATUS, NULL, NULL);
 
-       _D("clock update count : %d", update_count);
+       _D("it's ready for lcd on");
 
-       clock_gettime(CLOCK_REALTIME, &now_time);
-       diff_time = (now_time.tv_sec - start_time.tv_sec) / 60;
+       return ret;
+}
 
-       if (diff_time >= ALPM_MAX_TIME) {
-               _D("Exit ALPM state, LCD off");
-               alpm_set_state(false);
-               backlight_ops.on();
-               backlight_ops.off();
+void check_alpm_invalid_state(void)
+{
+       if (backlight_ops.get_lcd_power() == PM_LCD_POWER_OFF)
                return;
-       }
 
-       /* change pmstate in order that apps can know the state */
-       set_setting_pmstate(S_NORMAL);
-       backlight_ops.on();
+       if (alpm_get_state() == false)
+               return;
 
-       sleep(1);
+       _E("Invalid state! alpm state is change to off!");
 
-       _D("lcd off");
-       set_setting_pmstate(S_LCDOFF);
-       backlight_ops.off();
+       /* If lcd_power is on and alpm state is true
+        * when pm state is changed to sleep
+        * deviced doesn't get the clock signal.
+        * deviced just turns off lcd in this case. */
 
-       _D("finished!");
+       alpm_set_state(false);
+       backlight_ops.off(NORMAL_MODE);
 }
 
-static void end_clock(void)
+static void start_clock(void)
 {
        if (pm_cur_state == S_NORMAL ||
            pm_cur_state == S_LCDDIM ||
            alpm_state == false)
                return;
 
-       _D("end clock : lcd off");
+       pm_lock_internal(INTERNAL_LOCK_ALPM,
+           LCD_OFF, STAY_CUR_STATE, ALPM_CLOCK_WAITING_TIME);
 }
 
-int set_alpm_screen(char *screen)
+static void end_clock(pid_t pid)
+{
+       if (pm_cur_state == S_NORMAL ||
+           pm_cur_state == S_LCDDIM ||
+           alpm_state == false)
+               return;
+
+       if (update_count == 0) {
+               _D("lcd off");
+               backlight_ops.off(NORMAL_MODE);
+               pm_unlock_internal(INTERNAL_LOCK_ALPM,
+                   LCD_OFF, PM_SLEEP_MARGIN);
+       }
+
+       update_count++;
+
+       _I("enter real alpm state by %d (%d)",
+           alpm_pid, update_count);
+
+       alpm_pid = pid;
+}
+
+int set_alpm_screen(char *screen, pid_t pid)
 {
        if (!screen)
                return -EINVAL;
@@ -154,15 +236,44 @@ int set_alpm_screen(char *screen)
                start_clock();
        } else if (!strncmp(screen, CLOCK_END,
            strlen(CLOCK_END))) {
-               end_clock();
+               end_clock(pid);
        }
 
        return 0;
 }
 
+static void set_ambient_mode(keynode_t *key_nodes, void *data)
+{
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+
+       ambient_mode = vconf_keynode_get_bool(key_nodes);
+       _I("ambient mode is %d", ambient_mode);
+
+       if (!ambient_mode)
+               pm_unlock_internal(INTERNAL_LOCK_ALPM, LCD_OFF,
+                   PM_SLEEP_MARGIN);
+
+       set_dim_state(ambient_mode ? false : true);
+}
+
 static void alpm_init(void *data)
 {
        int fd;
+       int ret;
+
+       ret = vconf_get_bool(VCONFKEY_SETAPPL_AMBIENT_MODE_BOOL,
+           &ambient_mode);
+       if (ret < 0) {
+               _E("Failed to get ambient mode! (%d)", ret);
+               ambient_mode = false;
+       }
+       _I("ambient mode is %d", ambient_mode);
+
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_AMBIENT_MODE_BOOL,
+           set_ambient_mode, NULL);
 
        alpm_path = getenv("ALPM_NODE");
 
index 45356f4..0e8cff6 100644 (file)
 #include <sys/types.h>
 #include <fcntl.h>
 #include <vconf.h>
-#include <sensor.h>
+#include <sensor_internal.h>
 #include <Ecore.h>
 
 #include "util.h"
 #include "core.h"
 #include "display-ops.h"
 #include "device-node.h"
+#include "weaks.h"
+#include "hbm.h"
 #include "proc/proc-handler.h"
+#include "core/device-notifier.h"
+#include "core/config-parser.h"
 
 #define DISP_FORCE_SHIFT       12
 #define DISP_FORCE_CMD(prop, force)    (((force) << DISP_FORCE_SHIFT) | prop)
@@ -45,7 +49,6 @@
 #define MAX_AUTOMATIC_COUNT    11
 #define AUTOMATIC_DEVIDE_VAL   10
 #define AUTOMATIC_DELAY_TIME   0.5     /* 0.5 sec */
-#define MAX_NORMAL_LUX         10000
 
 #define RADIAN_VALUE           (57.2957)
 #define ROTATION_90            90
 #define WORKING_ANGLE_MAX      20
 
 #define ISVALID_AUTOMATIC_INDEX(index) (index >= 0 && index < MAX_AUTOMATIC_COUNT)
+#define BOARD_CONF_FILE "/etc/deviced/display.conf"
+
+#define ON_LUX         -1
+#define OFF_LUX                -1
+#define ON_COUNT       1
+#define OFF_COUNT      1
+
+struct lbm_config {
+       int on;
+       int off;
+       int on_count;
+       int off_count;
+};
+
+struct lbm_config lbm_conf = {
+       .on             = ON_LUX,
+       .off            = OFF_LUX,
+       .on_count       = ON_COUNT,
+       .off_count      = OFF_COUNT,
+};
 
 static int (*_default_action) (int);
 static Ecore_Timer *alc_timeout_id = 0;
@@ -63,8 +86,8 @@ static int fault_count = 0;
 static int automatic_brt = DEFAULT_AUTOMATIC_BRT;
 static int min_brightness = PM_MIN_BRIGHTNESS;
 static char *min_brightness_name = 0;
-static int last_autobrightness = 0;
 static int value_table[MAX_AUTOMATIC_COUNT];
+static int lbm_state = -1;
 
 static bool update_working_position(void)
 {
@@ -72,6 +95,9 @@ static bool update_working_position(void)
        int ret;
        float x, y, z, pitch, realg;
 
+       if (!display_conf.accel_sensor_on)
+               return false;
+
        ret = sf_get_data(accel_handle, ACCELEROMETER_BASE_DATA_SET, &data);
        if (ret < 0) {
                _E("Fail to get accelerometer data! %d", ret);
@@ -122,7 +148,8 @@ static void alc_set_brightness(int setting, int value, int lux)
                value = get_siop_brightness(value);
 
        if (tmp_value != value) {
-               if (!setting && min_brightness == PM_MIN_BRIGHTNESS) {
+               if (!setting && min_brightness == PM_MIN_BRIGHTNESS &&
+                   display_conf.accel_sensor_on == true) {
                        position = update_working_position();
                        if (!position && (old > lux)) {
                                _D("It's not working position, "
@@ -150,7 +177,6 @@ static void alc_set_brightness(int setting, int value, int lux)
 
                        backlight_ops.set_default_brt(tmp_value);
                        backlight_ops.update();
-                       last_autobrightness = tmp_value;
                }
                _I("load light data:%d lux,auto brt %d,min brightness %d,"
                    "brightness %d", lux, automatic_brt, min_brightness, value);
@@ -158,11 +184,53 @@ static void alc_set_brightness(int setting, int value, int lux)
        }
 }
 
+static bool check_lbm(int lux, int setting)
+{
+       static int on_count, off_count;
+
+       if (lux < 0)
+               return false;
+
+       if (lbm_conf.on < 0 || lbm_conf.off < 0)
+               return true;
+
+       if (lux <= lbm_conf.on && lbm_state != true) {
+               off_count = 0;
+               on_count++;
+               if (on_count >= lbm_conf.on_count || setting) {
+                       on_count = 0;
+                       lbm_state = true;
+                       _D("LBM is on");
+                       return true;
+               }
+       } else if (lux >= lbm_conf.off && lbm_state != false) {
+               on_count = 0;
+               off_count++;
+               if (off_count >= lbm_conf.off_count || setting) {
+                       off_count = 0;
+                       lbm_state = false;
+                       _D("LBM is off");
+                       return true;
+               }
+       } else if (lux > lbm_conf.on && lux < lbm_conf.off) {
+               off_count = 0;
+               on_count = 0;
+       }
+
+       if (setting)
+               return true;
+
+       return false;
+}
+
 static bool check_brightness_changed(int value)
 {
        int i;
        static int values[MAX_SAMPLING_COUNT], count = 0;
 
+       if (!get_hallic_open())
+               return false;
+
        if (count >= MAX_SAMPLING_COUNT || count < 0)
                count = 0;
 
@@ -174,63 +242,38 @@ static bool check_brightness_changed(int value)
        return true;
 }
 
-static void set_brightness_direct(void)
-{
-       int ret, cmd, value;
-       sensor_data_t light_data;
-
-       if (pm_cur_state != S_NORMAL || !get_hallic_open())
-               return;
-
-       /* direct update if it's previous value */
-       if (last_autobrightness > 0) {
-               backlight_ops.set_default_brt(last_autobrightness);
-               backlight_ops.update();
-               return;
-       }
-
-       /* get lux value from light sensor */
-       ret = sf_get_data(light_handle, LIGHT_LUX_DATA_SET, &light_data);
-       if (ret < 0 || (int)light_data.values[0] < 0)
-               return;
-
-       /* get brightness by lux */
-       cmd = DISP_FORCE_CMD(PROP_DISPLAY_BRIGHTNESS_BY_LUX, true);
-       cmd = DISP_CMD(cmd, (int)light_data.values[0]);
-       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, value_table);
-       if (ret < 0)
-               return;
-
-       /* get auto brightness level from value table*/
-       value = (ISVALID_AUTOMATIC_INDEX(automatic_brt) ?
-           value_table[automatic_brt] : value_table[DEFAULT_AUTOMATIC_BRT]);
-
-       /* update brightness actually */
-       backlight_ops.set_default_brt(value);
-       backlight_ops.update();
-       last_autobrightness = value;
-}
-
 static bool check_hbm(int lux)
 {
        int ret, old_state, new_state;
+       static int on_count, off_count;
 
-       ret = device_get_property(DEVICE_TYPE_DISPLAY,
-           PROP_DISPLAY_HBM_CONTROL, &old_state);
-       if (ret < 0) {
+       if (hbm_get_state == NULL)
+               return false;
+
+       old_state = hbm_get_state();
+       if (old_state < 0) {
                _E("Failed to get HBM state!");
                return false;
        }
 
-       if (old_state)
-               new_state = (lux <= MAX_NORMAL_LUX ? 0 : 1);
-       else
-               new_state = (lux >= display_conf.hbm_lux_threshold ? 1 : 0);
+       if (old_state) {
+               if (lux <= hbm_conf.off)
+                       off_count++;
+               else
+                       off_count = 0;
+               new_state = (off_count >= hbm_conf.off_count ? 0 : 1);
+       } else {
+               if (lux >= hbm_conf.on)
+                       on_count++;
+               else
+                       on_count = 0;
+               new_state = (on_count >= hbm_conf.on_count ? 1 : 0);
+       }
 
        if (old_state != new_state) {
+               on_count = off_count = 0;
                _D("hbm is %s", (new_state ? "on" : "off"));
-               ret = device_set_property(DEVICE_TYPE_DISPLAY,
-                   PROP_DISPLAY_HBM_CONTROL, new_state);
+               ret = hbm_set_state(new_state);
                if (ret < 0)
                        _E("Failed to set HBM state!");
                /*
@@ -238,7 +281,7 @@ static bool check_hbm(int lux)
                 * when hbm state is changed from on to off
                 */
                if (!new_state)
-                       set_brightness_direct();
+                       display_info.update_auto_brightness(true);
        }
 
        return (new_state ? true : false);
@@ -276,7 +319,11 @@ static bool alc_update_brt(bool setting)
                        if (check_hbm((int)light_data.values[0]))
                                return EINA_TRUE;
 
-                       if (!check_brightness_changed(value) && !setting)
+                       if (!check_lbm((int)light_data.values[0], setting))
+                               return EINA_TRUE;
+
+                       if (display_conf.continuous_sampling &&
+                           !check_brightness_changed(value) && !setting)
                                return EINA_TRUE;
 
                        alc_set_brightness(setting, value, (int)light_data.values[0]);
@@ -350,6 +397,11 @@ static int connect_sfsvc(void)
                light_handle = -1;
                goto error;
        }
+       sf_change_sensor_option(light_handle, 1);
+
+       if (!display_conf.accel_sensor_on)
+               goto success;
+
        /* accelerometer sensor */
        accel_handle = sf_connect(ACCELEROMETER_SENSOR);
        if (accel_handle < 0) {
@@ -363,7 +415,9 @@ static int connect_sfsvc(void)
                accel_handle = -1;
                goto error;
        }
+       sf_change_sensor_option(accel_handle, 1);
 
+success:
        fault_count = 0;
        return 0;
 
@@ -373,7 +427,7 @@ error:
                sf_disconnect(light_handle);
                light_handle = -1;
        }
-       if (accel_handle >= 0) {
+       if (display_conf.accel_sensor_on && accel_handle >= 0) {
                sf_stop(accel_handle);
                sf_disconnect(accel_handle);
                accel_handle = -1;
@@ -391,7 +445,7 @@ static int disconnect_sfsvc(void)
                light_handle = -1;
        }
        /* accelerometer sensor*/
-       if(accel_handle >= 0) {
+       if (display_conf.accel_sensor_on && accel_handle >= 0) {
                sf_stop(accel_handle);
                sf_disconnect(accel_handle);
                accel_handle = -1;
@@ -438,7 +492,8 @@ static int set_autobrightness_state(int status)
                        _default_action = states[S_NORMAL].action;
                states[S_NORMAL].action = alc_action;
 
-               set_brightness_direct();
+               display_info.update_auto_brightness(true);
+
                alc_timeout_id =
                    ecore_timer_add(display_conf.lightsensor_interval,
                            (Ecore_Task_Cb)alc_handler, NULL);
@@ -446,9 +501,11 @@ static int set_autobrightness_state(int status)
                _I("auto brightness paused!");
                disconnect_sfsvc();
                backlight_ops.hbm_off();
+               lbm_state = 0;
        } else {
                disconnect_sfsvc();
                backlight_ops.hbm_off();
+               lbm_state = 0;
                /* escape dim state if it's in low battery.*/
                set_brtch_state();
 
@@ -549,10 +606,7 @@ static Eina_Bool update_handler(void* data)
                return EINA_FALSE;
 
        _D("auto brightness is working!");
-
-       sf_change_sensor_option(light_handle, 1);
        alc_update_brt(true);
-       sf_change_sensor_option(light_handle, 0);
 
        return EINA_FALSE;
 }
@@ -599,7 +653,7 @@ static int prepare_lsensor(void *data)
        return 0;
 }
 
-static inline void update_brightness_direct(void)
+static void update_brightness_direct(void)
 {
        int ret, status;
 
@@ -656,12 +710,63 @@ static int reset_autobrightness_min(char *name, enum watch_id id)
        return 0;
 }
 
+static int lcd_changed_cb(void *data)
+{
+       int lcd_state = (int)data;
+
+       if (lcd_state == S_LCDOFF && alc_timeout_id > 0) {
+               ecore_timer_del(alc_timeout_id);
+               alc_timeout_id = NULL;
+       }
+
+       return 0;
+}
+
+static int lbm_load_config(struct parse_result *result, void *user_data)
+{
+       struct lbm_config *c = user_data;
+
+       _D("%s,%s,%s", result->section, result->name, result->value);
+
+       if (!c)
+               return -EINVAL;
+
+       if (!MATCH(result->section, "LBM"))
+               return 0;
+
+       if (MATCH(result->name, "on")) {
+               SET_CONF(c->on, atoi(result->value));
+               _D("on lux is %d", c->on);
+       } else if (MATCH(result->name, "off")) {
+               SET_CONF(c->off, atoi(result->value));
+               _D("off lux is %d", c->off);
+       } else if (MATCH(result->name, "on_count")) {
+               SET_CONF(c->on_count, atoi(result->value));
+               _D("on count is %d", c->on_count);
+       } else if (MATCH(result->name, "off_count")) {
+               SET_CONF(c->off_count, atoi(result->value));
+               _D("off count is %d", c->off_count);
+       }
+
+       return 0;
+}
+
 static void auto_brightness_init(void *data)
 {
+       int ret;
+
        display_info.update_auto_brightness = update_auto_brightness;
        display_info.set_autobrightness_min = set_autobrightness_min;
        display_info.reset_autobrightness_min = reset_autobrightness_min;
 
+       /* load configutation */
+       ret = config_parse(BOARD_CONF_FILE, lbm_load_config, &lbm_conf);
+       if (ret < 0)
+               _W("Failed to load %s, %s Use default value!",
+                   BOARD_CONF_FILE, ret);
+
+       register_notifier(DEVICE_NOTIFIER_LCD, lcd_changed_cb);
+
        prepare_lsensor(NULL);
 }
 
@@ -673,6 +778,8 @@ static void auto_brightness_exit(void *data)
        vconf_ignore_key_changed(VCONFKEY_SETAPPL_LCD_AUTOMATIC_BRIGHTNESS,
            set_alc_automatic_brt);
 
+       unregister_notifier(DEVICE_NOTIFIER_LCD, lcd_changed_cb);
+
        set_autobrightness_state(SETTING_BRIGHTNESS_AUTOMATIC_OFF);
 }
 
index 6cfa81a..c527d88 100644 (file)
@@ -43,8 +43,6 @@
 #include "device-node.h"
 #include "lock-detector.h"
 #include "display-ops.h"
-#include "core/queue.h"
-#include "core/data.h"
 #include "core/devices.h"
 #include "core/device-notifier.h"
 #include "core/device-handler.h"
 #define LOCK_SCREEN_INPUT_TIMEOUT      10000
 #define LOCK_SCREEN_CONTROL_TIMEOUT    5000
 #define DD_LCDOFF_INPUT_TIMEOUT                3000
+#define ALWAYS_ON_TIMEOUT                      3600000
+
+#define GESTURE_STR            "gesture"
+#define POWER_KEY_STR          "powerkey"
+#define TOUCH_STR              "touch"
+#define EVENT_STR              "event"
+#define UNKNOWN_STR            "unknown"
 
 unsigned int pm_status_flag;
 
@@ -94,6 +99,10 @@ static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
 static int hdmi_state = 0;
 static int tts_state = false;
 static struct timeval lcdon_tv;
+static int lcd_paneloff_mode = false;
+static int stay_touchscreen_off = false;
+static Eina_List *lcdon_ops = NULL;
+static bool lcdon_broadcast = false;
 
 /* default transition, action fuctions */
 static int default_trans(int evt);
@@ -138,8 +147,8 @@ static int trans_table[S_END][EVENT_END] = {
 #define GET_STANDBY_MODE_STATE(x) ((x >> SHIFT_LOCK_FLAG) & STANDBY_MODE_BIT)
 #define MASK32                         0xffffffff
 #define BOOTING_DONE_WATING_TIME       60000   /* 1 minute */
-#define LOCK_TIME_ERROR                        600     /* 600 seconds */
 #define LOCK_TIME_WARNING              60      /* 60 seconds */
+#define ALPM_CLOCK_WAITING_TIME                3000    /* 3 seconds */
 
 #define ACTIVE_ACT "active"
 #define INACTIVE_ACT "inactive"
@@ -152,6 +161,8 @@ static int trans_table[S_END][EVENT_END] = {
 #define BRIGHTNESS_CHANGE_STEP         10
 #define HBM_LUX_THRESHOLD              32768   /* lux */
 #define LCD_ALWAYS_ON                  0
+#define ACCEL_SENSOR_ON                        1
+#define CONTINUOUS_SAMPLING            1
 #define LCDOFF_TIMEOUT                 500     /* milli second */
 
 #define DIFF_TIMEVAL_MS(a, b) \
@@ -171,6 +182,8 @@ struct display_config display_conf = {
        .control_display        = 0,
        .powerkey_doublepress   = 0,
        .alpm_on                = 0,
+       .accel_sensor_on        = ACCEL_SENSOR_ON,
+       .continuous_sampling    = CONTINUOUS_SAMPLING,
 };
 
 struct display_function_info display_info = {
@@ -211,6 +224,14 @@ static void set_process_active(bool flag, pid_t pid)
                _E("Fail to send dbus signal to resourced!!");
 }
 
+bool check_lock_state(int state)
+{
+       if (cond_head[state] != NULL)
+               return true;
+
+       return false;
+}
+
 int get_standby_state(void)
 {
        return standby_state;
@@ -222,10 +243,23 @@ static inline void set_standby_state(bool state)
                standby_state = state;
 }
 
-void broadcast_lcd_on(void)
+void broadcast_lcd_on(enum device_flags flags)
 {
+       char *arr[1];
+
+       if (flags & LCD_ON_BY_GESTURE)
+               arr[0] = GESTURE_STR;
+       else if (flags & LCD_ON_BY_POWER_KEY)
+               arr[0] = POWER_KEY_STR;
+       else if (flags & LCD_ON_BY_EVENT)
+               arr[0] = EVENT_STR;
+       else if (flags & LCD_ON_BY_TOUCH)
+               arr[0] = TOUCH_STR;
+       else
+               arr[0] = UNKNOWN_STR;
+
        broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
-           SIGNAL_LCD_ON, NULL, NULL);
+           SIGNAL_LCD_ON, "s", arr);
 }
 
 void broadcast_lcd_off(void)
@@ -245,40 +279,149 @@ void tts_lcd_off(void)
                _E("Failed to tts(%d)", ret);
 }
 
-inline void lcd_on_procedure(void)
+static unsigned long get_lcd_on_flags(void)
+{
+       unsigned long flags = NORMAL_MODE;
+
+       if (lcd_paneloff_mode)
+               flags |= LCD_PANEL_OFF_MODE;
+
+       if (stay_touchscreen_off)
+               flags |= TOUCH_SCREEN_OFF_MODE;
+
+       if (get_ambient_mode != NULL &&
+           get_ambient_mode() == true) {
+               flags |= AMBIENT_MODE;
+               flags |= LCD_PHASED_TRANSIT_MODE;
+       }
+       return flags;
+}
+
+void lcd_on_procedure(int state, enum device_flags flag)
 {
-       broadcast_lcd_on();
+       Eina_List *l = NULL;
+       const struct device_ops *ops = NULL;
+       unsigned long flags = get_lcd_on_flags();
+       flags |= flag;
+
+       /* send LCDOn dbus signal */
+       if (!lcdon_broadcast) {
+               broadcast_lcd_on(flags);
+               lcdon_broadcast = true;
+       }
+
+       if (flags & AMBIENT_MODE &&
+           check_alpm_lcdon_ready != NULL)
+               check_alpm_lcdon_ready();
+
        /* AMOLED Low Power Mode off */
-       if (display_conf.alpm_on == true &&
-           alpm_set_state != NULL) {
-               if (alpm_set_state(false) < 0)
+       if (flags & AMBIENT_MODE) {
+               pm_unlock_internal(INTERNAL_LOCK_ALPM, LCD_OFF,
+                   PM_SLEEP_MARGIN);
+
+               if (alpm_get_state != NULL &&
+                   alpm_get_state() == false &&
+                   backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
+                       return;
+               if (alpm_set_state != NULL &&
+                   alpm_set_state(false) < 0)
                        _E("Failed to ALPM off");
        }
-       backlight_ops.update();
-       backlight_ops.on();
-       touch_ops.screen_on();
+
+       if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
+               /* Update brightness level */
+               if (state == LCD_DIM)
+                       backlight_ops.dim();
+               else if (state == LCD_NORMAL)
+                       backlight_ops.update();
+       }
+
+       if (flags & AMBIENT_MODE) {
+               if (state == LCD_DIM)
+                       set_setting_pmstate(S_LCDDIM);
+               else if (state == LCD_NORMAL)
+                       set_setting_pmstate(S_NORMAL);
+       }
+
+       EINA_LIST_FOREACH(lcdon_ops, l, ops)
+               ops->start(flags);
+
+       if (CHECK_OPS(keyfilter_ops, backlight_enable))
+               keyfilter_ops->backlight_enable(true);
+}
+
+static inline unsigned long get_lcd_off_flags(void)
+{
+       unsigned long flags = NORMAL_MODE;
+
+       if (get_ambient_mode != NULL &&
+           get_ambient_mode() == true)
+               flags |= AMBIENT_MODE;
+
+       if (flags & AMBIENT_MODE)
+               flags |= LCD_PHASED_TRANSIT_MODE;
+
+       return flags;
 }
 
 inline void lcd_off_procedure(void)
 {
+       Eina_List *l = NULL;
+       const struct device_ops *ops = NULL;
+       unsigned long flags = get_lcd_off_flags();
+
        if (standby_mode) {
                _D("standby mode! lcd off logic is skipped");
                return;
        }
        /* AMOLED Low Power Mode on */
-       if (display_conf.alpm_on == true &&
-           alpm_set_state != NULL) {
-               if (alpm_set_state(true) < 0)
+       if (flags & AMBIENT_MODE) {
+               if (alpm_get_state != NULL &&
+                   alpm_get_state() == true)
+                       return;
+               if (alpm_set_state != NULL &&
+                   alpm_set_state(true) < 0)
                        _E("Failed to ALPM on!");
+
+               pm_lock_internal(INTERNAL_LOCK_ALPM, LCD_OFF,
+                   STAY_CUR_STATE, ALPM_CLOCK_WAITING_TIME);
+       }
+
+       if (lcdon_broadcast) {
+               broadcast_lcd_off();
+               lcdon_broadcast = false;
        }
-       broadcast_lcd_off();
-       backlight_ops.off();
-       touch_ops.screen_off();
+       if (CHECK_OPS(keyfilter_ops, backlight_enable))
+               keyfilter_ops->backlight_enable(false);
+
+       if (flags & AMBIENT_MODE)
+               set_setting_pmstate(S_LCDOFF);
+
+       EINA_LIST_REVERSE_FOREACH(lcdon_ops, l, ops)
+               ops->stop(flags);
 
        if (tts_state)
                tts_lcd_off();
 }
 
+void set_stay_touchscreen_off(int val)
+{
+       _D("stay touch screen off : %d", val);
+       stay_touchscreen_off = val;
+
+       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
+       set_setting_pmstate(LCD_NORMAL);
+}
+
+void set_lcd_paneloff_mode(int val)
+{
+       _D("lcd paneloff mode : %d", val);
+       lcd_paneloff_mode = val;
+
+       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
+       set_setting_pmstate(LCD_NORMAL);
+}
+
 int low_battery_state(int val)
 {
        switch (val) {
@@ -390,10 +533,8 @@ static void print_node(int next)
                diff = difftime(now, n->time);
                ctime_r(&n->time, buf);
 
-               if (diff > LOCK_TIME_ERROR)
-                       _E("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
-               else if (diff > LOCK_TIME_WARNING)
-                       _I("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
+               if (diff > LOCK_TIME_WARNING)
+                       _W("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
                else
                        _I("pid: %5d, lock time: %s", n->pid, buf);
 
@@ -433,7 +574,7 @@ static Eina_Bool del_dim_cond(void *data)
        char pname[PATH_MAX];
        pid_t pid = (pid_t)data;
 
-       _I("delete prohibit dim condition by timeout\n");
+       _I("delete prohibit dim condition by timeout (%d)", pid);
 
        tmp = find_node(S_LCDDIM, pid);
        del_node(S_LCDDIM, tmp);
@@ -452,7 +593,7 @@ static Eina_Bool del_off_cond(void *data)
        char pname[PATH_MAX];
        pid_t pid = (pid_t)data;
 
-       _I("delete prohibit off condition by timeout\n");
+       _I("delete prohibit off condition by timeout (%d)", pid);
 
        tmp = find_node(S_LCDOFF, pid);
        del_node(S_LCDOFF, tmp);
@@ -471,7 +612,11 @@ static Eina_Bool del_sleep_cond(void *data)
        char pname[PATH_MAX];
        pid_t pid = (pid_t)data;
 
-       _I("delete prohibit sleep condition by timeout\n");
+       _I("delete prohibit sleep condition by timeout (%d)", pid);
+
+       if (pid == INTERNAL_LOCK_ALPM &&
+           check_alpm_invalid_state != NULL)
+               check_alpm_invalid_state();
 
        tmp = find_node(S_SLEEP, pid);
        del_node(S_SLEEP, tmp);
@@ -482,6 +627,7 @@ static Eina_Bool del_sleep_cond(void *data)
                states[pm_cur_state].trans(EVENT_TIMEOUT);
 
        set_process_active(EINA_FALSE, (pid_t)data);
+
        return EINA_FALSE;
 }
 
@@ -499,14 +645,14 @@ Eina_Bool timeout_handler(void *data)
        return EINA_FALSE;
 }
 
-inline static void reset_timeout(int timeout)
+void reset_timeout(int timeout)
 {
        if (timeout_src_id != 0) {
                ecore_timer_del(timeout_src_id);
                timeout_src_id = NULL;
        }
        if (timeout > 0)
-               timeout_src_id = ecore_timer_add(MSEC_TO_SEC(timeout),
+               timeout_src_id = ecore_timer_add(MSEC_TO_SEC((double)timeout),
                    (Ecore_Task_Cb)timeout_handler, NULL);
        else if (timeout == 0)
                states[pm_cur_state].trans(EVENT_TIMEOUT);
@@ -590,16 +736,27 @@ static void update_display_time(void)
 
        /* default setting */
        ret = get_run_timeout(&run_timeout);
-       if (ret < 0 || run_timeout <= 0) {
+       if (ret < 0 || run_timeout < 0) {
                _E("Can not get run timeout. set default %d ms",
                    DEFAULT_NORMAL_TIMEOUT);
                run_timeout = DEFAULT_NORMAL_TIMEOUT;
        }
+
+       /* for sdk
+        * if the run_timeout is zero, it regards AlwaysOn state
+        */
+       if (run_timeout == 0) {
+               trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
+               run_timeout = ALWAYS_ON_TIMEOUT;
+               _I("LCD Always On");
+       } else
+               trans_table[S_NORMAL][EVENT_TIMEOUT] = S_LCDDIM;
+
        states[S_NORMAL].timeout = run_timeout;
 
        get_dim_timeout(&val);
        states[S_LCDDIM].timeout = val;
-       
+
        _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
        _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
 }
@@ -610,7 +767,16 @@ static void update_display_locktime(int time)
        update_display_time();
 }
 
-void lcd_on_direct(void)
+
+void set_dim_state(bool on)
+{
+       _I("dim state is %d", on);
+       update_display_time();
+       states[pm_cur_state].trans(EVENT_INPUT);
+}
+
+
+void lcd_on_direct(enum device_flags flags)
 {
        int ret, call_state;
 
@@ -627,20 +793,31 @@ void lcd_on_direct(void)
        gettimeofday(&lcdon_tv, NULL);
        if (hbm_check_timeout != NULL)
                hbm_check_timeout();
-       lcd_on_procedure();
+       lcd_on_procedure(LCD_NORMAL, flags);
        reset_timeout(DD_LCDOFF_INPUT_TIMEOUT);
 #else
        ret = vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
        if ((ret >= 0 && call_state != VCONFKEY_CALL_OFF) ||
            (get_lock_screen_state() == VCONFKEY_IDLE_LOCK)) {
                _D("LOCK state, lcd is on directly");
-               lcd_on_procedure();
+               lcd_on_procedure(LCD_NORMAL, flags);
        }
        reset_timeout(display_conf.lcdoff_timeout);
 #endif
        update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
 }
 
+static inline bool check_lcd_on(void)
+{
+       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+               return true;
+
+       if (alpm_get_state != NULL && alpm_get_state() == true)
+               return true;
+
+       return false;
+}
+
 int custom_lcdon(int timeout)
 {
        struct state *st;
@@ -648,8 +825,8 @@ int custom_lcdon(int timeout)
        if (timeout <= 0)
                return -EINVAL;
 
-       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
-               lcd_on_direct();
+       if (check_lcd_on() == true)
+               lcd_on_direct(LCD_ON_BY_GESTURE);
 
        _I("custom lcd on %d ms", timeout);
        if (set_custom_lcdon_timeout(timeout) == true)
@@ -673,6 +850,7 @@ static int proc_change_state(unsigned int cond, pid_t pid)
        int next_state = 0;
        struct state *st;
        int i;
+       char pname[PATH_MAX];
 
        for (i = S_NORMAL; i < S_END; i++) {
                if ((cond >> (SHIFT_CHANGE_STATE + i)) & 0x1) {
@@ -680,11 +858,14 @@ static int proc_change_state(unsigned int cond, pid_t pid)
                        break;
                }
        }
+
+       get_pname(pid, pname);
+
        _I("Change State to %s (%d)", state_string[next_state], pid);
 
        if (next_state == S_NORMAL) {
-               if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
-                       lcd_on_direct();
+               if (check_lcd_on() == true)
+                       lcd_on_direct(LCD_ON_BY_EVENT);
        } else if (next_state == S_LCDOFF) {
                if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
                        lcd_off_procedure();
@@ -743,14 +924,22 @@ static int proc_change_state(unsigned int cond, pid_t pid)
 
 static int standby_action(int timeout)
 {
-       if (backlight_ops.standby() < 0) {
+       const struct device_ops *ops = NULL;
+
+       if (backlight_ops.standby(false) < 0) {
                _E("Fail to start standby mode!");
                return -EIO;
        }
        if (CHECK_OPS(keyfilter_ops, backlight_enable))
                keyfilter_ops->backlight_enable(false);
-       touch_ops.key_off();
-       touch_ops.screen_off();
+
+       ops = find_device("touchkey");
+       if (!check_default(ops))
+               ops->stop(NORMAL_MODE);
+
+       ops = find_device("touchscreen");
+       if (!check_default(ops))
+               ops->stop(NORMAL_MODE);
 
        set_standby_state(true);
 
@@ -969,6 +1158,9 @@ static int proc_condition(PMMsg *data)
                _SD("[%s] unlocked by pid %d - process %s\n", "S_LCDOFF",
                        pid, pname);
                set_unlock_time(pname, S_LCDOFF);
+
+               if (check_suspend_direct != NULL && check_suspend_direct(pid))
+                       return 0;
        }
        val = val >> 8;
        if (val != 0) {
@@ -1315,20 +1507,6 @@ int check_lcdoff_direct(void)
 {
        int ret, lock, cradle;
 
-       if (standby_mode)
-               return false;
-
-       lock = get_lock_screen_state();
-       if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
-               return false;
-
-       if (hdmi_state)
-               return false;
-
-       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
-       if (ret >= 0 && cradle == DOCK_SOUND)
-               return false;
-
        if (pm_old_state != S_NORMAL)
                return false;
 
@@ -1343,6 +1521,29 @@ int check_lcdoff_direct(void)
            (check_abnormal_popup() == HEALTH_BAD))
                return false;
 
+       /*
+        * LCD on -> off directly in ambient mode
+        */
+       if (get_ambient_mode != NULL &&
+           get_ambient_mode() == true &&
+           check_lock_state(S_LCDOFF) == false) {
+               return true;
+       }
+
+       if (standby_mode)
+               return false;
+
+       lock = get_lock_screen_state();
+       if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
+               return false;
+
+       if (hdmi_state)
+               return false;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
+       if (ret >= 0 && cradle == DOCK_SOUND)
+               return false;
+
        _D("Goto LCDOFF direct(%d,%d,%d)", lock, hdmi_state, cradle);
 
        return true;
@@ -1431,12 +1632,9 @@ static Eina_Bool lcd_on_expired(void *data)
        if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
                return EINA_FALSE;
 
-       if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
-               return EINA_FALSE;
-
        /* lock screen is not launched yet, but lcd is on */
-       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
-               lcd_on_procedure();
+       if (check_lcd_on() == true)
+               lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
 
        return EINA_FALSE;
 }
@@ -1479,8 +1677,8 @@ static void check_lock_screen(void)
        return;
 
 lcd_on:
-       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
-               lcd_on_procedure();
+       if (check_lcd_on() == true)
+               lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
 }
 
 /* default enter action function */
@@ -1526,7 +1724,9 @@ static int default_action(int timeout)
        if (pm_cur_state != pm_old_state && pm_cur_state != S_SLEEP) {
                if (power_ops.get_power_lock_support())
                        power_ops.power_lock();
-               if (pm_cur_state != S_LCDOFF)
+               if (pm_cur_state != S_LCDOFF &&
+                   (get_ambient_mode == NULL ||
+                   get_ambient_mode() == false))
                        set_setting_pmstate(pm_cur_state);
                device_notify(DEVICE_NOTIFIER_LCD, (void *)pm_cur_state);
        }
@@ -1552,6 +1752,9 @@ static int default_action(int timeout)
                        check_lock_screen();
                } else if (pm_old_state == S_LCDDIM)
                        backlight_ops.update();
+
+               if (check_lcd_on() == true)
+                       lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
                set_standby_state(false);
                break;
 
@@ -1561,12 +1764,9 @@ static int default_action(int timeout)
                        backlight_ops.save_custom_brightness();
                /* lcd dim state : dim the brightness */
                backlight_ops.dim();
-               if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP) {
-                       broadcast_lcd_on();
-                       backlight_ops.on();
-                       touch_ops.screen_on();
-                       touch_ops.key_on();
-               }
+
+               if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP)
+                       lcd_on_procedure(LCD_DIM, NORMAL_MODE);
                set_standby_state(false);
                break;
 
@@ -1576,7 +1776,10 @@ static int default_action(int timeout)
                        /* lcd off state : turn off the backlight */
                        if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
                                lcd_off_procedure();
-                       set_setting_pmstate(pm_cur_state);
+
+                       if (get_ambient_mode == NULL ||
+                           get_ambient_mode() == false)
+                               set_setting_pmstate(pm_cur_state);
 
                        if (pre_suspend_flag == false) {
                                pre_suspend_flag = true;
@@ -1584,7 +1787,8 @@ static int default_action(int timeout)
                        }
                }
 
-               if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
+               if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF
+                   || lcd_paneloff_mode)
                        lcd_off_procedure();
                break;
 
@@ -1723,7 +1927,9 @@ static int poll_callback(int condition, PMMsg *data)
                if (pm_cur_state == S_LCDOFF || pm_cur_state == S_SLEEP)
                        _I("Power key input");
                time(&now);
-               if (last_t != now) {
+               if (last_t != now ||
+                   pm_cur_state == S_LCDOFF ||
+                   pm_cur_state == S_SLEEP) {
                        states[pm_cur_state].trans(EVENT_INPUT);
                        last_t = now;
                }
@@ -1745,18 +1951,10 @@ static int update_setting(int key_idx, int val)
        char buf[PATH_MAX];
        int ret = -1;
        int run_timeout = -1;
-       int power_saving_stat = -1;
-       int power_saving_display_stat = -1;
 
        switch (key_idx) {
        case SETTING_TO_NORMAL:
-               ret = get_run_timeout(&run_timeout);
-               if (ret < 0 || run_timeout <= 0) {
-                       _E("Can not get run timeout. set default %.2f ms",
-                           DEFAULT_NORMAL_TIMEOUT);
-                       run_timeout = DEFAULT_NORMAL_TIMEOUT;
-               }
-               states[S_NORMAL].timeout = run_timeout;
+               update_display_time();
                states[pm_cur_state].trans(EVENT_INPUT);
                break;
        case SETTING_HALLIC_OPEN:
@@ -1824,7 +2022,7 @@ static int update_setting(int key_idx, int val)
                if (pm_cur_state == S_NORMAL &&
                    val == VCONFKEY_IDLE_LOCK &&
                    backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
-                       lcd_on_procedure();
+                       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
                stop_lock_timer();
                update_display_time();
                if (pm_cur_state == S_NORMAL) {
@@ -1838,33 +2036,6 @@ static int update_setting(int key_idx, int val)
                        states[pm_cur_state].trans(EVENT_INPUT);
                }
                break;
-       case SETTING_POWER_SAVING:
-               if (val == 1)
-                       vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
-                                &power_saving_display_stat);
-               if (power_saving_display_stat != 1)
-                       power_saving_display_stat = 0;
-               if (device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_FRAME_RATE,
-                   power_saving_display_stat) < 0) {
-                       _E("Fail to set display frame rate!");
-               }
-               backlight_ops.update();
-               break;
-       case SETTING_POWER_SAVING_DISPLAY:
-               vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
-                       &power_saving_stat);
-               if (power_saving_stat == 1) {
-                       if (val == 1)
-                               power_saving_display_stat = 1;
-                       else
-                               power_saving_display_stat = 0;
-                       if (device_set_property(DEVICE_TYPE_DISPLAY,
-                           PROP_DISPLAY_FRAME_RATE, power_saving_display_stat) < 0) {
-                               _E("Fail to set display frame rate!");
-                       }
-                       backlight_ops.update();
-               }
-               break;
        case SETTING_SMART_STAY:
                if (!val) {
                        pm_status_flag &= ~SMAST_FLAG;
@@ -1922,8 +2093,6 @@ static void check_seed_status(void)
        int max_brt = 0;
        int brt = 0;
        int lock_state = -1;
-       int power_saving_stat = -1;
-       int power_saving_display_stat = -1;
        int smart_stay_on = 0;
 
        /* Charging check */
@@ -1949,10 +2118,7 @@ static void check_seed_status(void)
                        pm_status_flag |= LOWBT_FLAG;
                }
        }
-       backlight_ops.update();
-       backlight_ops.on();
-       touch_ops.screen_on();
-       touch_ops.key_on();
+       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
 
        /* lock screen check */
        ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
@@ -1963,22 +2129,6 @@ static void check_seed_status(void)
                        " for lock screen", lock_screen_timeout);
        }
 
-       /* power saving display stat */
-       vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
-           &power_saving_stat);
-       if (power_saving_stat <= 0) {
-               power_saving_display_stat = 0;
-       } else {
-               vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
-                   &power_saving_display_stat);
-       }
-       if (power_saving_display_stat < 0) {
-               _E("failed to read power saving display stat!");
-       } else {
-               _I("power saving display stat : %d",
-                   power_saving_display_stat);
-       }
-
        /* Smart stay status */
        vconf_get_int(VCONFKEY_SETAPPL_SMARTSCREEN_SMARTSTAY_STATUS, &smart_stay_on);
        if (!smart_stay_on) {
@@ -1997,6 +2147,33 @@ static void check_seed_status(void)
        return;
 }
 
+static void init_lcd_operation(void)
+{
+       const struct device_ops *ops = NULL;
+
+       ops = find_device("display");
+       if (!check_default(ops))
+               EINA_LIST_APPEND(lcdon_ops, ops);
+
+       ops = find_device("touchscreen");
+       if (!check_default(ops))
+               EINA_LIST_APPEND(lcdon_ops, ops);
+
+       ops = find_device("touchkey");
+       if (!check_default(ops))
+               EINA_LIST_APPEND(lcdon_ops, ops);
+}
+
+static void exit_lcd_operation(void)
+{
+       Eina_List *l = NULL;
+       Eina_List *l_next = NULL;
+       const struct device_ops *ops = NULL;
+
+       EINA_LIST_FOREACH_SAFE(lcdon_ops, l, l_next, ops)
+               EINA_LIST_REMOVE_LIST(lcdon_ops, l);
+}
+
 enum {
        INIT_SETTING = 0,
        INIT_INTERFACE,
@@ -2014,21 +2191,38 @@ static const char *errMSG[INIT_END] = {
        [INIT_DBUS] = "d-bus init error",
 };
 
+static void esd_action()
+{
+       _I("ESD on");
+
+       if (pm_cur_state == S_NORMAL) {
+               backlight_ops.off(NORMAL_MODE);
+               backlight_ops.on(NORMAL_MODE);
+       } else if (pm_cur_state == S_LCDDIM) {
+               backlight_ops.off(NORMAL_MODE);
+               backlight_ops.dim();
+       } else if (alpm_get_state != NULL &&
+           alpm_get_state() == true) {
+               proc_change_state(S_NORMAL <<
+                   (SHIFT_CHANGE_STATE + S_NORMAL), getpid());
+               backlight_ops.off(NORMAL_MODE);
+               backlight_ops.on(NORMAL_MODE);
+       }
+}
+
 static int input_action(char* input_act, char* input_path)
 {
-       int ret = -EINVAL;
-       Eina_List *list_node = NULL;
+       int ret = 0;
        Eina_List *l = NULL;
        Eina_List *l_next = NULL;
        indev *data = NULL;
-       PmLockNode *tmp = NULL;
 
        if (!strcmp("add", input_act)) {
                _I("add input path : %s", input_path);
                ret = init_pm_poll_input(poll_callback, input_path);
        } else if (!strcmp("remove", input_act)) {
                EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data)
-                       if(!strcmp(input_path, data->dev_path)) {
+                       if (!strcmp(input_path, data->dev_path)) {
                                _I("remove %s", input_path);
                                ecore_main_fd_handler_del(data->dev_fd);
                                close(data->fd);
@@ -2036,19 +2230,11 @@ static int input_action(char* input_act, char* input_path)
                                free(data);
                                indev_list = eina_list_remove_list(indev_list, l);
                        }
-               ret = 0;
        } else if (!strcmp("change", input_act)) {
-               if (!strcmp("ESD", input_path)) {
-                       _I("ESD on");
-                       if (pm_cur_state == S_NORMAL) {
-                               backlight_ops.off();
-                               backlight_ops.on();
-                       } else if (pm_cur_state == S_LCDDIM) {
-                               backlight_ops.off();
-                               backlight_ops.dim();
-                       }
-                       ret = 0;
-               }
+               if (!strcmp("ESD", input_path))
+                       esd_action();
+       } else {
+               ret = -EINVAL;
        }
        return ret;
 }
@@ -2068,6 +2254,8 @@ int set_lcd_timeout(int on, int dim, int holdkey_block, char *name)
        }
        /* Apply new backlight time */
        update_display_time();
+       if (pm_cur_state == S_NORMAL)
+               states[pm_cur_state].trans(EVENT_INPUT);
 
        if (holdkey_block) {
                custom_holdkey_block = true;
@@ -2142,6 +2330,9 @@ static int hall_ic_open(void *data)
 
        update_pm_setting(SETTING_HALLIC_OPEN, open);
 
+       if (display_info.update_auto_brightness)
+               display_info.update_auto_brightness(false);
+
        return 0;
 }
 
@@ -2221,7 +2412,7 @@ static int display_load_config(struct parse_result *result, void *user_data)
                return -EINVAL;
 
        if (!MATCH(result->section, "Display"))
-               return -EINVAL;
+               return 0;
 
        if (MATCH(result->name, "LockScreenWaitingTime")) {
                SET_CONF(c->lock_wait_time, atof(result->value));
@@ -2262,6 +2453,12 @@ static int display_load_config(struct parse_result *result, void *user_data)
        } else if (MATCH(result->name, "UseALPM")) {
                c->alpm_on = (MATCH(result->value, "yes") ? 1 : 0);
                _D("UseALPM is %d", c->alpm_on);
+       } else if (MATCH(result->name, "AccelSensorOn")) {
+               c->accel_sensor_on = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("AccelSensorOn is %d", c->accel_sensor_on);
+       } else if (MATCH(result->name, "ContinuousSampling")) {
+               c->continuous_sampling = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("ContinuousSampling is %d", c->continuous_sampling);
        }
 
        return 0;
@@ -2328,6 +2525,7 @@ static void display_init(void *data)
 #ifdef ENABLE_PM_LOG
                pm_history_init();
 #endif
+               init_lcd_operation();
                check_seed_status();
 
                if (display_conf.lcd_always_on) {
@@ -2346,7 +2544,7 @@ static void display_init(void *data)
                                timeout = DEFAULT_NORMAL_TIMEOUT;
 
                        reset_timeout(timeout);
-
+                       status = DEVICE_OPS_STATUS_START;
                        /*
                         * Lock lcd off until booting is done.
                         * deviced guarantees all booting script is executing.
@@ -2358,7 +2556,6 @@ static void display_init(void *data)
                if (CHECK_OPS(keyfilter_ops, init))
                        keyfilter_ops->init();
        }
-       status = DEVICE_OPS_STATUS_START;
 }
 
 static void display_exit(void *data)
@@ -2371,7 +2568,7 @@ static void display_exit(void *data)
        pm_cur_state = S_NORMAL;
        set_setting_pmstate(pm_cur_state);
        /* timeout is not needed */
-       reset_timeout(0);
+       reset_timeout(TIMEOUT_NONE);
 
        if (CHECK_OPS(keyfilter_ops, exit))
                keyfilter_ops->exit();
@@ -2403,13 +2600,30 @@ static void display_exit(void *data)
                        break;
                }
        }
+
+       exit_lcd_operation();
        free_lock_info_list();
 
        _I("Stop power manager");
 }
 
-static int display_start(void)
+static int display_start(enum device_flags flags)
 {
+       /* NORMAL MODE */
+       if (flags & NORMAL_MODE) {
+               if (flags & LCD_PANEL_OFF_MODE)
+                       /* standby on */
+                       backlight_ops.standby(true);
+               else
+                       /* normal lcd on */
+                       backlight_ops.on(flags);
+               return 0;
+       }
+
+       /* CORE LOGIC MODE */
+       if (!(flags & CORE_LOGIC_MODE))
+               return 0;
+
        if (status == DEVICE_OPS_STATUS_START)
                return -EALREADY;
 
@@ -2418,8 +2632,18 @@ static int display_start(void)
        return 0;
 }
 
-static int display_stop(void)
+static int display_stop(enum device_flags flags)
 {
+       /* NORMAL MODE */
+       if (flags & NORMAL_MODE) {
+               backlight_ops.off(flags);
+               return 0;
+       }
+
+       /* CORE LOGIC MODE */
+       if (!(flags & CORE_LOGIC_MODE))
+               return 0;
+
        if (status == DEVICE_OPS_STATUS_STOP)
                return -EALREADY;
 
index c5bf7e1..063a597 100644 (file)
@@ -121,6 +121,8 @@ struct display_config {
        int control_display;
        int powerkey_doublepress;
        int alpm_on;
+       int accel_sensor_on;
+       int continuous_sampling;
 };
 
 /*
index fe95194..68b7268 100644 (file)
 #include <string.h>
 #include <unistd.h>
 #include <limits.h>
+#include <math.h>
+#include <journal/display.h>
 
 #include "core/log.h"
+#include "core/devices.h"
 #include "util.h"
 #include "device-interface.h"
 #include "vconf.h"
 #define TOUCH_ON       1
 #define TOUCH_OFF      0
 
+#define LCD_PHASED_MIN_BRIGHTNESS      1
+#define LCD_PHASED_MAX_BRIGHTNESS      100
+#define LCD_PHASED_CHANGE_STEP         5
+#define LCD_PHASED_DELAY               35000 /* microsecond */
+
 typedef struct _PMSys PMSys;
 struct _PMSys {
        int def_brt;
@@ -48,17 +56,13 @@ struct _PMSys {
        int (*sys_get_power_lock_support) (PMSys *);
        int (*sys_get_lcd_power) (PMSys *);
        int (*bl_onoff) (PMSys *, int);
-       int (*bl_brt) (PMSys *, int);
+       int (*bl_brt) (PMSys *, int, int);
 };
 
 static PMSys *pmsys;
 struct _backlight_ops backlight_ops;
-struct _touch_ops touch_ops;
 struct _power_ops power_ops;
 
-static char *touchscreen_node;
-static char *touchkey_node;
-
 #ifdef ENABLE_X_LCD_ONOFF
 #include "x-lcd-on.c"
 static bool x_dpms_enable = false;
@@ -77,12 +81,15 @@ static int _bl_onoff(PMSys *p, int on)
        return device_set_property(DEVICE_TYPE_DISPLAY, cmd, on);
 }
 
-static int _bl_brt(PMSys *p, int brightness)
+static int _bl_brt(PMSys *p, int brightness, int delay)
 {
        int ret = -1;
        int cmd;
        int prev;
 
+       if (delay > 0)
+               usleep(delay);
+
        if (force_brightness > 0 && brightness != p->dim_brt) {
                _I("brightness(%d), force brightness(%d)",
                    brightness, force_brightness);
@@ -299,74 +306,50 @@ static int backlight_hbm_off(void)
        return 0;
 #endif
 }
-
-static int touchscreen_on(void)
-{
-       int ret;
-
-       if (!touchscreen_node)
-               return -ENOENT;
-
-       ret = sys_set_int(touchscreen_node, TOUCH_ON);
-       if (ret < 0)
-               _E("Failed to on touch screen!");
-
-       return ret;
-
-}
-
-static int touchscreen_off(void)
+void change_brightness(int start, int end, int step)
 {
-       int ret;
-
-       if (!touchscreen_node)
-               return -ENOENT;
-
-       if (display_conf.alpm_on == true)
-               return -EPERM;
-
-       ret = sys_set_int(touchscreen_node, TOUCH_OFF);
-       if (ret < 0)
-               _E("Failed to off touch screen!");
-
-       return ret;
-}
+       int diff, val;
+       int ret = -1;
+       int cmd;
+       int prev;
 
-static int touchkey_on(void)
-{
-       int ret;
+       if ((pm_status_flag & PWRSV_FLAG) &&
+           !(pm_status_flag & BRTCH_FLAG))
+               return;
 
-       if (!touchkey_node)
-               return -ENOENT;
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &prev);
 
-       ret = sys_set_int(touchkey_node, TOUCH_ON);
-       if (ret < 0)
-               _E("Failed to on touch key!");
+       if (prev == end)
+               return;
 
-       return ret;
+       _D("start %d end %d step %d", start, end, step);
 
-}
+       diff = end - start;
 
-static int touchkey_off(void)
-{
-       int ret;
+       if (abs(diff) < step)
+               val = (diff > 0 ? 1 : -1);
+       else
+               val = (int)ceil(diff / step);
 
-       if (!touchkey_node)
-               return -ENOENT;
+       while (start != end) {
+               if (val == 0) break;
 
-       ret = sys_set_int(touchkey_node, TOUCH_OFF);
-       if (ret < 0)
-               _E("Failed to off touch key!");
+               start += val;
+               if ((val > 0 && start > end) ||
+                   (val < 0 && start < end))
+                       start = end;
 
-       return ret;
+               pmsys->bl_brt(pmsys, start, LCD_PHASED_DELAY);
+       }
 }
 
-static int backlight_on(void)
+static int backlight_on(enum device_flags flags)
 {
        int ret = -1;
        int i;
 
-       _D("LCD on");
+       _D("LCD on %x", flags);
 
        if (!pmsys || !pmsys->bl_onoff)
                return -1;
@@ -377,6 +360,7 @@ static int backlight_on(void)
 #ifdef ENABLE_PM_LOG
                        pm_history_save(PM_LOG_LCD_ON, pm_cur_state);
 #endif
+                       journal_display_on(pmsys->def_brt);
                        break;
                } else {
 #ifdef ENABLE_PM_LOG
@@ -391,19 +375,30 @@ static int backlight_on(void)
                }
        }
 
+       if (flags & LCD_PHASED_TRANSIT_MODE)
+               change_brightness(LCD_PHASED_MIN_BRIGHTNESS,
+                   pmsys->def_brt, LCD_PHASED_CHANGE_STEP);
+
        return ret;
 }
 
-static int backlight_off(void)
+static int backlight_off(enum device_flags flags)
 {
        int ret = -1;
        int i;
 
-       _D("LCD off");
+       _D("LCD off %x", flags);
 
        if (!pmsys || !pmsys->bl_onoff)
                return -1;
 
+       if (flags & LCD_PHASED_TRANSIT_MODE)
+               change_brightness(pmsys->def_brt,
+                   LCD_PHASED_MIN_BRIGHTNESS, LCD_PHASED_CHANGE_STEP);
+
+       if (flags & AMBIENT_MODE)
+               return 0;
+
        for (i = 0; i < PM_LCD_RETRY_CNT; i++) {
 #ifdef ENABLE_X_LCD_ONOFF
                if (x_dpms_enable == false)
@@ -414,6 +409,7 @@ static int backlight_off(void)
 #ifdef ENABLE_PM_LOG
                        pm_history_save(PM_LOG_LCD_OFF, pm_cur_state);
 #endif
+                       journal_display_off();
                        break;
                } else {
 #ifdef ENABLE_PM_LOG
@@ -434,7 +430,7 @@ static int backlight_dim(void)
 {
        int ret = 0;
        if (pmsys && pmsys->bl_brt) {
-               ret = pmsys->bl_brt(pmsys, pmsys->dim_brt);
+               ret = pmsys->bl_brt(pmsys, pmsys->dim_brt, 0);
 #ifdef ENABLE_PM_LOG
                if (!ret)
                        pm_history_save(PM_LOG_LCD_DIM, pm_cur_state);
@@ -480,7 +476,7 @@ static int custom_backlight_update(void)
                ret = backlight_dim();
        } else if (pmsys && pmsys->bl_brt) {
                _I("custom brightness restored! %d", custom_brightness);
-               ret = pmsys->bl_brt(pmsys, custom_brightness);
+               ret = pmsys->bl_brt(pmsys, custom_brightness, 0);
        }
 
        return ret;
@@ -512,18 +508,18 @@ static int backlight_update(void)
        if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG)) {
                ret = backlight_dim();
        } else if (pmsys && pmsys->bl_brt) {
-               ret = pmsys->bl_brt(pmsys, pmsys->def_brt);
+               ret = pmsys->bl_brt(pmsys, pmsys->def_brt, 0);
        }
        return ret;
 }
 
-static int backlight_standby(void)
+static int backlight_standby(int force)
 {
        int ret = -1;
        if (!pmsys || !pmsys->bl_onoff)
                return -1;
 
-       if (get_lcd_power() == PM_LCD_POWER_ON) {
+       if ((get_lcd_power() == PM_LCD_POWER_ON) || force) {
                _I("LCD standby");
                ret = pmsys->bl_onoff(pmsys, STATUS_STANDBY);
        }
@@ -569,11 +565,6 @@ void _init_ops(void)
        backlight_ops.custom_update = custom_backlight_update;
        backlight_ops.set_force_brightness = set_force_brightness;
 
-       touch_ops.screen_on = touchscreen_on;
-       touch_ops.screen_off = touchscreen_off;
-       touch_ops.key_on = touchkey_on;
-       touch_ops.key_off = touchkey_off;
-
        power_ops.suspend = system_suspend;
        power_ops.pre_suspend = system_pre_suspend;
        power_ops.post_resume = system_post_resume;
@@ -603,12 +594,6 @@ int init_sysfs(unsigned int flags)
                return -1;
        }
 
-       touchscreen_node = getenv("PM_TOUCHSCREEN");
-       _D("touchscreen node : %s", touchscreen_node);
-
-       touchkey_node = getenv("PM_TOUCHKEY");
-       _D("touchkey node : %s", touchkey_node);
-
        _init_ops();
 
        return 0;
@@ -617,16 +602,23 @@ int init_sysfs(unsigned int flags)
 int exit_sysfs(void)
 {
        int fd;
+       const struct device_ops *ops = NULL;
 
        fd = open("/tmp/sem.pixmap_1", O_RDONLY);
        if (fd == -1) {
                _E("X server disable");
-               backlight_on();
+               backlight_on(NORMAL_MODE);
        }
 
        backlight_update();
-       touchscreen_on();
-       touchkey_on();
+
+       ops = find_device("touchscreen");
+       if (!check_default(ops))
+               ops->start(NORMAL_MODE);
+
+       ops = find_device("touchkey");
+       if (!check_default(ops))
+               ops->start(NORMAL_MODE);
 
        free(pmsys);
        pmsys = NULL;
index f50f1da..05df9d5 100644 (file)
@@ -25,6 +25,7 @@
 #define __DEVICE_INTERFACE_H__
 
 #include <stdbool.h>
+#include "core/devices.h"
 
 #define FLAG_X_DPMS            0x2
 
@@ -57,11 +58,11 @@ extern int init_sysfs(unsigned int);
 extern int exit_sysfs(void);
 
 struct _backlight_ops {
-       int (*off)(void);
+       int (*off)(enum device_flags);
        int (*dim)(void);
-       int (*on)(void);
+       int (*on)(enum device_flags);
        int (*update)(void);
-       int (*standby)(void);
+       int (*standby)(int);
        int (*hbm_off)(void);
        int (*set_default_brt)(int level);
        int (*get_lcd_power)(void);
@@ -72,13 +73,6 @@ struct _backlight_ops {
        int (*set_force_brightness)(int level);
 };
 
-struct _touch_ops {
-       int (*screen_on)(void);
-       int (*screen_off)(void);
-       int (*key_on)(void);
-       int (*key_off)(void);
-};
-
 struct _power_ops {
        int (*suspend)(void);
        int (*pre_suspend)(void);
@@ -90,7 +84,6 @@ struct _power_ops {
 };
 
 extern struct _backlight_ops backlight_ops;
-extern struct _touch_ops touch_ops;
 extern struct _power_ops power_ops;
 
 #endif
diff --git a/src/display/display-actor.c b/src/display/display-actor.c
new file mode 100644 (file)
index 0000000..bab8630
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 "util.h"
+#include "display-actor.h"
+#include "core/list.h"
+#include "core/common.h"
+
+static dd_list *actor_head;
+
+void display_add_actor(struct display_actor_ops *actor)
+{
+       DD_LIST_APPEND(actor_head, actor);
+}
+
+static struct display_actor_ops *display_find_actor(enum display_actor_id id)
+{
+       dd_list *elem;
+       struct display_actor_ops *actor;
+
+       DD_LIST_FOREACH(actor_head, elem, actor) {
+               if (actor->id == id)
+                       return actor;
+       }
+       return NULL;
+}
+
+int display_set_caps(enum display_actor_id id, unsigned int caps)
+{
+       struct display_actor_ops *actor;
+
+       if (id <= 0 || !caps)
+               return -EINVAL;
+
+       actor = display_find_actor(id);
+       if (!actor)
+               return -EINVAL;
+
+       actor->caps |= caps;
+
+       return 0;
+}
+
+int display_reset_caps(enum display_actor_id id, unsigned int caps)
+{
+       struct display_actor_ops *actor;
+
+       if (id <= 0 || !caps)
+               return -EINVAL;
+
+       actor = display_find_actor(id);
+       if (!actor)
+               return -EINVAL;
+
+       actor->caps &= ~caps;
+
+       return 0;
+}
+
+unsigned int display_get_caps(enum display_actor_id id)
+{
+       struct display_actor_ops *actor;
+
+       if (id <= 0)
+               return 0;
+
+       actor = display_find_actor(id);
+       if (!actor)
+               return 0;
+
+       return actor->caps;
+}
+
+int display_has_caps(unsigned int total_caps, unsigned int caps)
+{
+       if (!total_caps || !caps)
+               return false;
+
+       if ((total_caps & caps) == caps)
+               return true;
+
+       return false;
+}
+
diff --git a/src/display/display-actor.h b/src/display/display-actor.h
new file mode 100644 (file)
index 0000000..301d9ce
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 __DISPLAY_ACTOR_H__
+#define __DISPLAY_ACTOR_H__
+
+#include <errno.h>
+#include "core/common.h"
+
+enum display_actor_id {
+       DISPLAY_ACTOR_POWER_KEY = 1,
+       DISPLAY_ACTOR_MENU_KEY,
+       DISPLAY_ACTOR_API,
+       DISPLAY_ACTOR_GESTURE,
+};
+
+struct display_actor_ops {
+       enum display_actor_id id;
+       unsigned int caps;
+};
+
+enum display_capability {
+       DISPLAY_CAPA_BRIGHTNESS         = 1 << 0,
+       DISPLAY_CAPA_LCDON              = 1 << 1,
+       DISPLAY_CAPA_LCDOFF             = 1 << 2,
+       DISPLAY_CAPA_POWEROFF           = 1 << 3,
+};
+
+void display_add_actor(struct display_actor_ops *actor);
+int display_set_caps(enum display_actor_id id, unsigned int caps);
+int display_reset_caps(enum display_actor_id id, unsigned int caps);
+unsigned int display_get_caps(enum display_actor_id id);
+int display_has_caps(unsigned int total_caps, unsigned int caps);
+
+#endif
+
index e533f51..fcaa3ad 100644 (file)
@@ -35,6 +35,7 @@
 #include "core/common.h"
 #include "core/devices.h"
 #include "dd-display.h"
+#include "display-actor.h"
 
 #define TELEPHONY_PATH                 "/org/tizen/telephony/SAMSUNG_QMI"
 #define TELEPHONY_INTERFACE_SIM                "org.tizen.telephony.Sim"
 
 static DBusMessage *edbus_start(E_DBus_Object *obj, DBusMessage *msg)
 {
-       static const struct device_ops *display_device_ops;
+       static const struct device_ops *display_device_ops = NULL;
 
-       if (!display_device_ops) {
+       if (!display_device_ops)
                display_device_ops = find_device("display");
-               if (!display_device_ops)
-                       return dbus_message_new_method_return(msg);
-       }
+       if (NOT_SUPPORT_OPS(display_device_ops))
+               return dbus_message_new_method_return(msg);
 
-       display_device_ops->start();
+       display_device_ops->start(CORE_LOGIC_MODE);
        return dbus_message_new_method_return(msg);
 }
 
 static DBusMessage *edbus_stop(E_DBus_Object *obj, DBusMessage *msg)
 {
-       static const struct device_ops *display_device_ops;
+       static const struct device_ops *display_device_ops = NULL;
 
-       if (!display_device_ops) {
+       if (!display_device_ops)
                display_device_ops = find_device("display");
-               if (!display_device_ops)
-                       return dbus_message_new_method_return(msg);
-       }
+       if (NOT_SUPPORT_OPS(display_device_ops))
+               return dbus_message_new_method_return(msg);
 
-       display_device_ops->stop();
+       display_device_ops->stop(CORE_LOGIC_MODE);
        return dbus_message_new_method_return(msg);
 }
 
@@ -96,6 +95,7 @@ static DBusMessage *edbus_lockstate(E_DBus_Object *obj, DBusMessage *msg)
        int state;
        int flag;
        int ret;
+       unsigned int caps;
 
        dbus_error_init(&err);
 
@@ -148,6 +148,23 @@ static DBusMessage *edbus_lockstate(E_DBus_Object *obj, DBusMessage *msg)
        else if (!strcmp(option2_str, STANDBYMODE_STR))
                flag |= STANDBY_MODE;
 
+       if (flag & GOTO_STATE_NOW) {
+               caps = display_get_caps(DISPLAY_ACTOR_API);
+
+               if (!display_has_caps(caps, DISPLAY_CAPA_LCDON) &&
+                   state == LCD_NORMAL) {
+                       _D("No lcdon capability!");
+                       ret = -EPERM;
+                       goto out;
+               }
+               if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF) &&
+                   state == LCD_OFF) {
+                       _D("No lcdoff capability!");
+                       ret = -EPERM;
+                       goto out;
+               }
+       }
+
        if (check_dimstay(state, flag) == true) {
                _E("LCD state can not be changed to OFF state now!");
                flag &= ~GOTO_STATE_NOW;
@@ -239,6 +256,7 @@ static DBusMessage *edbus_changestate(E_DBus_Object *obj, DBusMessage *msg)
        pid_t pid;
        int state;
        int ret;
+       unsigned int caps;
 
        dbus_error_init(&err);
 
@@ -276,6 +294,21 @@ static DBusMessage *edbus_changestate(E_DBus_Object *obj, DBusMessage *msg)
                goto out;
        }
 
+       caps = display_get_caps(DISPLAY_ACTOR_API);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDON) &&
+           state == LCD_NORMAL) {
+               _D("No lcdon capability!");
+               ret = -EPERM;
+               goto out;
+       }
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF) &&
+           state == LCD_OFF) {
+               _D("No lcdoff capability!");
+               ret = -EPERM;
+               goto out;
+       }
+
        if (check_dimstay(state, GOTO_STATE_NOW) == true) {
                _E("LCD state can not be changed to OFF state!");
                ret = -EBUSY;
@@ -369,7 +402,15 @@ static DBusMessage *edbus_setbrightness(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
        DBusMessage *reply;
-       int cmd, brt, powersaver, autobrt, ret;
+       int cmd, brt, powersaver, autobrt, ret, caps;
+
+       caps = display_get_caps(DISPLAY_ACTOR_API);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_BRIGHTNESS)) {
+               _D("No brightness changing capability!");
+               ret = -EPERM;
+               goto error;
+       }
 
        dbus_message_iter_init(msg, &iter);
        dbus_message_iter_get_basic(&iter, &brt);
@@ -424,7 +465,15 @@ static DBusMessage *edbus_holdbrightness(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
        DBusMessage *reply;
-       int cmd, brt, powersaver, autobrt, ret;
+       int cmd, brt, powersaver, autobrt, ret, caps;
+
+       caps = display_get_caps(DISPLAY_ACTOR_API);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_BRIGHTNESS)) {
+               _D("No brightness changing capability!");
+               ret = -EPERM;
+               goto error;
+       }
 
        dbus_message_iter_init(msg, &iter);
        dbus_message_iter_get_basic(&iter, &brt);
@@ -675,14 +724,14 @@ static DBusMessage *edbus_setrefreshrate(E_DBus_Object *obj, DBusMessage *msg)
        control = display_conf.control_display;
 
        if (control)
-               backlight_ops.off();
+               backlight_ops.off(NORMAL_MODE);
 
        _D("app : %d, value : %d", app, val);
        cmd = DISP_CMD(PROP_DISPLAY_FRAME_RATE, DEFAULT_DISPLAY);
        ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, val);
 
        if (control)
-               backlight_ops.on();
+               backlight_ops.on(NORMAL_MODE);
 
 error:
        reply = dbus_message_new_method_return(msg);
@@ -1078,6 +1127,88 @@ error:
        return reply;
 }
 
+static DBusMessage *edbus_staytouchscreenoff(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+       int val;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &val,
+                   DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to get stay touchscreen off state %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       set_stay_touchscreen_off(val);
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_lcdpaneloffmode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+       int val;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &val,
+                   DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to get lcd panel off mode %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       set_lcd_paneloff_mode(val);
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_actorcontrol(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0, val, actor;
+       char *op;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &op,
+                   DBUS_TYPE_INT32, &actor, DBUS_TYPE_INT32, &val,
+                   DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to update actor control %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!strcmp(op, "set"))
+               ret = display_set_caps(actor, val);
+       else if (!strcmp(op, "reset"))
+               ret = display_reset_caps(actor, val);
+       else
+               ret = -EINVAL;
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
 static const struct edbus_method edbus_methods[] = {
        { "start",           NULL,  NULL, edbus_start },
        { "stop",            NULL,  NULL, edbus_stop },
@@ -1117,6 +1248,9 @@ static const struct edbus_method edbus_methods[] = {
        { "PowerKeyIgnore",   "i",  NULL, edbus_powerkeyignore },
        { "PowerKeyLCDOff",  NULL,   "i", edbus_powerkeylcdoff },
        { "CustomLCDOn",      "i",   "i", edbus_customlcdon },
+       { "StayTouchScreenOff","i",  "i", edbus_staytouchscreenoff },
+       { "LCDPanelOffMode",  "i",   "i", edbus_lcdpaneloffmode },
+       { "ActorControl",   "sii",   "i", edbus_actorcontrol },
        /* Add methods here */
 };
 
@@ -1126,6 +1260,11 @@ static void sim_signal_handler(void *data, DBusMessage *msg)
        int ret, val;
        static int state = false;
 
+       if (!find_display_feature("auto-brightness")) {
+               _D("auto brightness is not supported!");
+               return;
+       }
+
        if (state)
                return;
 
@@ -1166,7 +1305,7 @@ static void homescreen_signal_handler(void *data, DBusMessage *msg)
        DBusError err;
        int ret;
        char *screen;
-
+       pid_t pid;
 
        ret = dbus_message_is_signal(msg, DEVICED_INTERFACE_NAME,
            SIGNAL_HOMESCREEN);
@@ -1186,10 +1325,12 @@ static void homescreen_signal_handler(void *data, DBusMessage *msg)
 
        _D("screen : %s", screen);
 
-       if (set_alpm_screen)
-               set_alpm_screen(screen);
-       else
+       if (set_alpm_screen) {
+               pid = get_edbus_sender_pid(msg);
+               set_alpm_screen(screen, pid);
+       } else {
                _E("alpm screen mode is not supported!");
+       }
 }
 
 static void extreme_signal_handler(void *data, DBusMessage *msg)
@@ -1228,17 +1369,42 @@ static void not_extreme_signal_handler(void *data, DBusMessage *msg)
                _E("failed to set vconf status");
 }
 
+/*
+ * Default capability
+ * api      := LCDON | LCDOFF | BRIGHTNESS
+ * gesture  := LCDON
+ */
+static struct display_actor_ops display_api_actor = {
+       .id     = DISPLAY_ACTOR_API,
+       .caps   = DISPLAY_CAPA_LCDON |
+                 DISPLAY_CAPA_LCDOFF |
+                 DISPLAY_CAPA_BRIGHTNESS,
+};
+
+static struct display_actor_ops display_gesture_actor = {
+       .id     = DISPLAY_ACTOR_GESTURE,
+       .caps   = DISPLAY_CAPA_LCDON,
+};
+
 int init_pm_dbus(void)
 {
        int ret;
 
+       display_add_actor(&display_api_actor);
+       display_add_actor(&display_gesture_actor);
+
        ret = register_edbus_method(DEVICED_PATH_DISPLAY,
                    edbus_methods, ARRAY_SIZE(edbus_methods));
        if (ret < 0) {
                _E("Failed to register edbus method! %d", ret);
                return ret;
        }
-
+/*
+ * Auto-brightness feature has been implemented in wearable-device.
+ * But UX is not determined, then Block sim-check-logic temporary.
+ * This logic'll be re-enabled when UX concept related to sim is confirmed.
+ */
+/*
        ret = register_edbus_signal_handler(TELEPHONY_PATH,
                    TELEPHONY_INTERFACE_SIM, SIGNAL_SIM_STATUS,
                    sim_signal_handler);
@@ -1246,7 +1412,7 @@ int init_pm_dbus(void)
                _E("Failed to register signal handler! %d", ret);
                return ret;
        }
-
+*/
        ret = register_edbus_signal_handler(DEVICED_OBJECT_PATH,
                    DEVICED_INTERFACE_NAME, SIGNAL_HOMESCREEN,
                    homescreen_signal_handler);
similarity index 89%
rename from src/display/display-exynos.conf
rename to src/display/display-emul-mobile.conf
index 8924ae9..2ca7f30 100644 (file)
@@ -5,7 +5,7 @@ LockScreenWaitingTime=0.3      #second
 
 # Power-off popup is launched when power key is long pressed.
 # This is duration of pressing power key.
-LongPressInterval=2            #second
+LongPressInterval=1            #second
 
 # This is polling time of auto brightness.
 LightSensorSamplingInterval=1  #second
@@ -33,8 +33,5 @@ ChangedFrameRateAllowed=all           # all
 ControlDisplay=no              # yes or no
 
 # LCD is not turned off when this value is yes and key double pressed
-PowerKeyDoublePressSupport=yes  # yes or no
-
-# ALPM(AMOLED Low Power Mode)
-UseALPM=no                     # yes or no
+PowerKeyDoublePressSupport=no  # yes or no
 
similarity index 92%
rename from src/display/display-msm.conf
rename to src/display/display-mobile.conf
index f9d065f..86352d1 100644 (file)
@@ -5,7 +5,7 @@ LockScreenWaitingTime=0.3      #second
 
 # Power-off popup is launched when power key is long pressed.
 # This is duration of pressing power key.
-LongPressInterval=2            #second
+LongPressInterval=0.4          #second
 
 # This is polling time of auto brightness.
 LightSensorSamplingInterval=1  #second
@@ -35,3 +35,6 @@ ControlDisplay=yes            # yes or no
 # LCD is not turned off when this value is yes and key double pressed
 PowerKeyDoublePressSupport=no  # yes or no
 
+# ALPM(AMOLED Low Power Mode)
+UseALPM=yes                    # yes or no
+
index 172b707..22b9137 100644 (file)
@@ -36,7 +36,7 @@ void remove_display(const struct display_ops *disp)
        DD_LIST_REMOVE(disp_head, disp);
 }
 
-const struct display_ops *find_display(const char *name)
+const struct display_ops *find_display_feature(const char *name)
 {
        dd_list *elem;
        const struct display_ops *disp;
index c11e188..1c1102d 100644 (file)
@@ -44,6 +44,6 @@ static void __DESTRUCTOR__ module_exit(void)  \
 
 void add_display(const struct display_ops *disp);
 void remove_display(const struct display_ops *disp);
-const struct display_ops *find_display(const char *name);
+const struct display_ops *find_display_feature(const char *name);
 
 #endif
diff --git a/src/display/display-wearable.conf b/src/display/display-wearable.conf
new file mode 100644 (file)
index 0000000..832f9b4
--- /dev/null
@@ -0,0 +1,64 @@
+[Display]
+# deviced is pending lcd on until lock screen shows.
+# This is the maximum pending time.
+LockScreenWaitingTime=0.3      #second
+
+# Power-off popup is launched when power key is long pressed.
+# This is duration of pressing power key.
+LongPressInterval=2            #second
+
+# This is polling time of auto brightness.
+LightSensorSamplingInterval=1  #second
+
+# display state is changed to SLEEP state after this time.
+# If this value is large, it causes power consumption problem.
+LCDOffTimeout=500              # milli second
+
+# This is n step of auto brightness.
+# If brightness is change from a to b, brightness's changed n times from a to b.
+BrightnessChangeStep=10
+
+# This is threshold value of light sensor.
+# If lux value is greater than threshold,
+# HBM(High Brightness Mode) is on.
+HBMLuxThreshold=39768
+
+# If this value is yes, LCD is always on except pressing power key.
+# Default value is no, LCD is turned off by lcd timeout.
+LCDAlwaysOn=no                 # yes or no
+
+# Just below application only allow to change display frame rate.
+# refer to enum refresh_app
+ChangedFrameRateAllowed=all            # all
+ControlDisplay=no              # yes or no
+
+# LCD is not turned off when this value is yes and key double pressed
+PowerKeyDoublePressSupport=yes  # yes or no
+
+# ALPM(AMOLED Low Power Mode)
+UseALPM=yes                    # yes or no
+
+# Use Accelator sensor when autobrightness is on.
+AccelSensorOn=no               # yes or no
+
+# Use Continuous Sampling when autobrightness is on.
+ContinuousSampling=no          # yes or no
+
+[HBM]
+# hbm on lux
+on=5000
+
+# hbm off lux
+off=1000
+
+# sampling count
+on_count=1
+off_count=3
+
+[LBM]
+# Low brightness
+on=10
+off=30
+on_count=3
+off_count=2
+
index fb7a2e7..b758cb8 100644 (file)
@@ -28,9 +28,7 @@
 #include <vconf.h>
 #include <vconf-keys.h>
 #include "core.h"
-#include "core/data.h"
 #include "core/devices.h"
-#include "core/queue.h"
 #include "core/log.h"
 #include "core/common.h"
 #include "proc/proc-handler.h"
@@ -50,6 +48,9 @@
 #define CLUSTER_HOME   "cluster-home"
 #define BROWSER_NAME   "browser"
 
+#define SIGNAL_GLOVEMODE_ON    "GloveModeOn"
+#define SIGNAL_GLOVEMODE_OFF   "GloveModeOff"
+
 enum lcd_enhance_type{
        ENHANCE_MODE = 0,
        ENHANCE_SCENARIO,
@@ -91,6 +92,12 @@ void switch_glove_key(int val)
        }
 }
 
+static void broadcast_glove_mode(int state)
+{
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           (state ? SIGNAL_GLOVEMODE_ON : SIGNAL_GLOVEMODE_OFF), NULL, NULL);
+}
+
 static int check_default_process(int pid, char *default_name)
 {
        char exe_name[PATH_MAX];
@@ -322,7 +329,7 @@ static int add_entry_to_enhance_ctl_list(int pid, int index, int val)
        return 0;
 }
 
-static void enhance_control_pid_cb(keynode_t *in_key, struct main_data *ad)
+static void enhance_control_pid_cb(keynode_t *in_key, void *data)
 {
        int pid;
 
@@ -335,7 +342,7 @@ static void enhance_control_pid_cb(keynode_t *in_key, struct main_data *ad)
        restore_enhance_status(&default_enhance);
 }
 
-static void enhance_auto_control_cb(keynode_t *in_key, struct main_data *ad)
+static void enhance_auto_control_cb(keynode_t *in_key, void *data)
 {
        int val;
 
@@ -631,6 +638,7 @@ static DBusMessage *edbus_setenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
                _E("fail to set touch screen glove mode (%d)", val);
                goto error;
        }
+       broadcast_glove_mode(val);
 
 error:
        reply = dbus_message_new_method_return(msg);
index 2251acc..ad79862 100644 (file)
 #include <fcntl.h>
 #include <Ecore.h>
 
+#include "hbm.h"
 #include "util.h"
 #include "core.h"
 #include "display-ops.h"
 #include "core/common.h"
 #include "core/device-notifier.h"
 #include "core/edbus-handler.h"
+#include "core/config-parser.h"
+
+#define BOARD_CONF_FILE "/etc/deviced/display.conf"
 
 #define ON             "on"
 #define OFF            "off"
 
+#define ON_LUX         39768
+#define OFF_LUX                10000
+#define ON_COUNT       1
+#define OFF_COUNT      1
+
 #define SIGNAL_HBM_OFF "HBMOff"
 
 #define DEFAULT_BRIGHTNESS_LEVEL       80
 
+struct hbm_config hbm_conf = {
+       .on             = ON_LUX,
+       .off            = OFF_LUX,
+       .on_count       = ON_COUNT,
+       .off_count      = OFF_COUNT,
+};
+
 static Ecore_Timer *timer = NULL;
 static struct timespec offtime;
 static char *hbm_path;
@@ -227,6 +243,35 @@ static int lcd_state_changed(void *data)
        return 0;
 }
 
+static int hbm_load_config(struct parse_result *result, void *user_data)
+{
+       struct hbm_config *c = user_data;
+
+       _D("%s,%s,%s", result->section, result->name, result->value);
+
+       if (!c)
+               return -EINVAL;
+
+       if (!MATCH(result->section, "HBM"))
+               return 0;
+
+       if (MATCH(result->name, "on")) {
+               SET_CONF(c->on, atoi(result->value));
+               _D("on lux is %d", c->on);
+       } else if (MATCH(result->name, "off")) {
+               SET_CONF(c->off, atoi(result->value));
+               _D("off lux is %d", c->off);
+       } else if (MATCH(result->name, "on_count")) {
+               SET_CONF(c->on_count, atoi(result->value));
+               _D("on count is %d", c->on_count);
+       } else if (MATCH(result->name, "off_count")) {
+               SET_CONF(c->off_count, atoi(result->value));
+               _D("off count is %d", c->off_count);
+       }
+
+       return 0;
+}
+
 static void hbm_init(void *data)
 {
        int fd, ret;
@@ -241,6 +286,12 @@ static void hbm_init(void *data)
        }
        close(fd);
 
+       /* load configutation */
+       ret = config_parse(BOARD_CONF_FILE, hbm_load_config, &hbm_conf);
+       if (ret < 0)
+               _W("Failed to load %s, %s Use default value!",
+                   BOARD_CONF_FILE, ret);
+
        /* register notifier */
        register_notifier(DEVICE_NOTIFIER_LCD, lcd_state_changed);
 }
@@ -249,6 +300,17 @@ static void hbm_exit(void *data)
 {
        /* unregister notifier */
        unregister_notifier(DEVICE_NOTIFIER_LCD, lcd_state_changed);
+
+       /*
+        * set default brightness
+        * if display logic is stopped in hbm state.
+        */
+       if (hbm_get_state() == true) {
+               hbm_set_offtime(0);
+               vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
+                   DEFAULT_BRIGHTNESS_LEVEL);
+               _I("set brightness to default value!");
+       }
 }
 
 static const struct display_ops display_hbm_ops = {
diff --git a/src/display/hbm.h b/src/display/hbm.h
new file mode 100644 (file)
index 0000000..6122550
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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.
+ */
+
+
+/**
+ * @file       hbm.h
+ * @brief      High Brightness Mode header file
+ */
+#ifndef __HBM_H__
+#define __HBM_H__
+
+/*
+ * @brief Configuration structure
+ */
+struct hbm_config {
+       int on;
+       int off;
+       int on_count;
+       int off_count;
+};
+
+/*
+ * Global variables
+ *   hbm_conf : configuration of hbm
+ */
+extern struct hbm_config hbm_conf;
+
+/**
+ * @}
+ */
+
+#endif
index 731e9e6..d8f8295 100644 (file)
 #include "util.h"
 #include "core.h"
 #include "poll.h"
+#include "weaks.h"
 #include "brightness.h"
 #include "device-node.h"
-#include "core/queue.h"
 #include "core/common.h"
-#include "core/data.h"
+#include "core/devices.h"
 #include "core/device-notifier.h"
 #include "core/edbus-handler.h"
 #include "core/device-handler.h"
+#include "power/power-handler.h"
 
 #include <linux/input.h>
 
@@ -57,6 +58,15 @@ static inline int current_state_in_on(void)
        return (pm_cur_state == S_LCDDIM || pm_cur_state == S_NORMAL);
 }
 
+static int power_execute(void *data)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, POWER_OPS_NAME);
+
+       return ops->execute(data);
+}
+
 static void longkey_pressed()
 {
        int val, ret;
@@ -76,7 +86,8 @@ static void longkey_pressed()
         * when power-off popup is disabled for testmode.
         */
        _I("power off action!");
-       notify_action(POWEROFF_ACT, 0);
+
+       power_execute(POWEROFF_ACT);
 }
 
 static Eina_Bool longkey_pressed_cb(void *data)
@@ -107,11 +118,13 @@ static inline bool switch_on_lcd(void)
                return false;
 
        if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
-               return false;
+               if (alpm_get_state == NULL ||
+                   alpm_get_state() == false)
+                       return false;
 
        broadcast_lcdon_by_powerkey();
 
-       lcd_on_direct();
+       lcd_on_direct(LCD_ON_BY_POWER_KEY);
 
        return true;
 }
@@ -225,7 +238,8 @@ static int check_key_filter(int length, char buf[], int fd)
                case EV_ABS:
                        if (current_state_in_on())
                                ignore = false;
-                       else if (display_conf.alpm_on == true) {
+                       if (get_ambient_mode != NULL &&
+                           get_ambient_mode() == true) {
                                switch_on_lcd();
                                ignore = false;
                        }
@@ -262,11 +276,14 @@ static int powerkey_lcdoff(void)
        }
 
        _I("power key lcdoff");
+
+       if (display_info.update_auto_brightness)
+               display_info.update_auto_brightness(false);
        switch_off_lcd();
        delete_condition(S_LCDOFF);
        delete_condition(S_LCDDIM);
        update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
-       recv_data.pid = -1;
+       recv_data.pid = getpid();
        recv_data.cond = 0x400;
        (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
 
index acb6192..e75239c 100644 (file)
 #include "poll.h"
 #include "brightness.h"
 #include "device-node.h"
-#include "core/queue.h"
+#include "display-actor.h"
 #include "core/common.h"
-#include "core/data.h"
+#include "core/devices.h"
 #include "core/device-notifier.h"
 #include "core/edbus-handler.h"
 #include "core/device-handler.h"
+#include "power/power-handler.h"
 
 #include <linux/input.h>
 #ifndef KEY_SCREENLOCK
@@ -67,6 +68,8 @@
 #define KEY_COMBINATION_SCREENCAPTURE  2
 
 #define SIGNAL_CHANGE_HARDKEY          "ChangeHardkey"
+#define SIGNAL_LCDON_BY_POWERKEY       "LCDOnByPowerkey"
+#define SIGNAL_LCDOFF_BY_POWERKEY      "LCDOffByPowerkey"
 
 #define NORMAL_POWER(val)              (val == 0)
 #define KEY_TEST_MODE_POWER(val)       (val == 2)
@@ -88,7 +91,7 @@ static Ecore_Timer *combination_timeout_id = NULL;
 static Ecore_Timer *hardkey_timeout_id = NULL;
 static int cancel_lcdoff;
 static int key_combination = KEY_COMBINATION_STOP;
-static int volumedown_pressed = false;
+static int menu_pressed = false;
 static int hardkey_duration;
 static bool touch_pressed = false;
 static int skip_lcd_off = false;
@@ -106,21 +109,40 @@ static inline void restore_custom_brightness(void)
                backlight_ops.custom_update();
 }
 
+static int power_execute(void *data)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, POWER_OPS_NAME);
+
+       return ops->execute(data);
+}
+
 static void longkey_pressed()
 {
        int val = 0;
        int ret;
        int csc_mode;
        char *opt;
+       unsigned int caps;
+
        _I("Power key long pressed!");
        cancel_lcdoff = 1;
 
-       /* change state - LCD on */
-       recv_data.pid = -1;
-       recv_data.cond = 0x100;
-       (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+       caps = display_get_caps(DISPLAY_ACTOR_POWER_KEY);
+
+       if (display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
+               /* change state - LCD on */
+               recv_data.pid = getpid();
+               recv_data.cond = 0x100;
+               (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+               (*g_pm_callback)(INPUT_POLL_EVENT, NULL);
+       }
 
-       (*g_pm_callback) (INPUT_POLL_EVENT, NULL);
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF)) {
+               _D("No poweroff capability!");
+               return;
+       }
 
        ret = vconf_get_int(VCONFKEY_TESTMODE_POWER_OFF_POPUP, &val);
        if (ret != 0 || NORMAL_POWER(val)) {
@@ -139,7 +161,7 @@ static void longkey_pressed()
        }
        opt = POWEROFF_ACT;
 entry_call:
-       notify_action(opt, 0);
+       power_execute(opt);
 }
 
 static Eina_Bool longkey_pressed_cb(void *data)
@@ -185,6 +207,18 @@ static inline void check_key_pair(int code, int new, int *old)
                *old = new;
 }
 
+static inline void broadcast_lcdon_by_powerkey(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_LCDON_BY_POWERKEY, NULL, NULL);
+}
+
+static inline void broadcast_lcdoff_by_powerkey(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_LCDOFF_BY_POWERKEY, NULL, NULL);
+}
+
 static inline bool switch_on_lcd(void)
 {
        if (current_state_in_on())
@@ -193,7 +227,9 @@ static inline bool switch_on_lcd(void)
        if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
                return false;
 
-       lcd_on_direct();
+       broadcast_lcdon_by_powerkey();
+
+       lcd_on_direct(LCD_ON_BY_POWER_KEY);
 
        return true;
 }
@@ -206,15 +242,59 @@ static inline void switch_off_lcd(void)
        if (backlight_ops.get_lcd_power() == PM_LCD_POWER_OFF)
                return;
 
+       broadcast_lcdoff_by_powerkey();
+
        lcd_off_procedure();
 }
 
+static void process_combination_key(struct input_event *pinput)
+{
+       if (pinput->value == KEY_PRESSED) {
+               if (key_combination == KEY_COMBINATION_STOP) {
+                       key_combination = KEY_COMBINATION_START;
+                       combination_timeout_id = ecore_timer_add(
+                           COMBINATION_INTERVAL,
+                           (Ecore_Task_Cb)combination_failed_cb, NULL);
+               } else if (key_combination == KEY_COMBINATION_START) {
+                       if (combination_timeout_id > 0) {
+                               ecore_timer_del(combination_timeout_id);
+                               combination_timeout_id = NULL;
+                       }
+                       if (longkey_timeout_id > 0) {
+                               ecore_timer_del(longkey_timeout_id);
+                               longkey_timeout_id = NULL;
+                       }
+                       _I("capture mode");
+                       key_combination = KEY_COMBINATION_SCREENCAPTURE;
+                       skip_lcd_off = true;
+               }
+               menu_pressed = true;
+       } else if (pinput->value == KEY_RELEASED) {
+               if (key_combination != KEY_COMBINATION_SCREENCAPTURE)
+                       stop_key_combination();
+               menu_pressed = false;
+       }
+}
+
+
 static int process_menu_key(struct input_event *pinput)
 {
-       if (pinput->value == KEY_PRESSED)
+       int caps;
+
+       caps = display_get_caps(DISPLAY_ACTOR_MENU_KEY);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
+               if (current_state_in_on()) {
+                       process_combination_key(pinput);
+                       return false;
+               }
+               _D("No lcd-on capability!");
+               return true;
+       } else if (pinput->value == KEY_PRESSED) {
                switch_on_lcd();
+       }
 
-       stop_key_combination();
+       process_combination_key(pinput);
 
        return false;
 }
@@ -243,7 +323,7 @@ static int decide_lcdoff(void)
                return false;
 
        /* LCD-off is blocked at the moment volumedown key is pressed */
-       if (volumedown_pressed)
+       if (menu_pressed)
                return false;
 
        /* LCD-off is blocked when powerkey and volmedown key are pressed */
@@ -269,7 +349,7 @@ static int lcdoff_powerkey(void)
                        delete_condition(S_LCDOFF);
                        delete_condition(S_LCDDIM);
                        update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
-                       recv_data.pid = -1;
+                       recv_data.pid = getpid();
                        recv_data.cond = 0x400;
                        (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
                }
@@ -285,6 +365,9 @@ static int process_power_key(struct input_event *pinput)
 {
        int ignore = true;
        static int value = KEY_RELEASED;
+       unsigned int caps;
+
+       caps = display_get_caps(DISPLAY_ACTOR_POWER_KEY);
 
        switch (pinput->value) {
        case KEY_RELEASED:
@@ -292,11 +375,17 @@ static int process_power_key(struct input_event *pinput)
                check_key_pair(pinput->code, pinput->value, &value);
 
                if (!display_conf.powerkey_doublepress) {
-                       ignore = lcdoff_powerkey();
+                       if (display_has_caps(caps, DISPLAY_CAPA_LCDOFF))
+                               ignore = lcdoff_powerkey();
+                       else
+                               _D("No lcdoff capability!");
                } else if (skip_lcd_off) {
                        ignore = false;
                }
 
+               if (!display_has_caps(caps, DISPLAY_CAPA_LCDON))
+                       ignore = true;
+
                stop_key_combination();
                if (longkey_timeout_id > 0) {
                        ecore_timer_del(longkey_timeout_id);
@@ -306,7 +395,12 @@ static int process_power_key(struct input_event *pinput)
                break;
        case KEY_PRESSED:
                powerkey_pressed = true;
-               skip_lcd_off = switch_on_lcd();
+               if (display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
+                       skip_lcd_off = switch_on_lcd();
+               } else {
+                       _D("No lcdon capability!");
+                       skip_lcd_off = false;
+               }
                check_key_pair(pinput->code, pinput->value, &value);
                _I("power key pressed");
                pressed_time.tv_sec = (pinput->time).tv_sec;
@@ -344,43 +438,6 @@ static int process_power_key(struct input_event *pinput)
        return ignore;
 }
 
-static int process_volumedown_key(struct input_event *pinput)
-{
-       int ignore = true;
-
-       if (pinput->value == KEY_PRESSED) {
-               if (key_combination == KEY_COMBINATION_STOP) {
-                       key_combination = KEY_COMBINATION_START;
-                       combination_timeout_id = ecore_timer_add(
-                                   COMBINATION_INTERVAL,
-                                   (Ecore_Task_Cb)combination_failed_cb, NULL);
-               } else if (key_combination == KEY_COMBINATION_START) {
-                       if (combination_timeout_id > 0) {
-                               ecore_timer_del(combination_timeout_id);
-                               combination_timeout_id = NULL;
-                       }
-                       if (longkey_timeout_id > 0) {
-                               ecore_timer_del(longkey_timeout_id);
-                               longkey_timeout_id = NULL;
-                       }
-                       _I("capture mode");
-                       key_combination = KEY_COMBINATION_SCREENCAPTURE;
-                       skip_lcd_off = true;
-                       ignore = false;
-               }
-               volumedown_pressed = true;
-       } else if (pinput->value == KEY_RELEASED) {
-               if (key_combination != KEY_COMBINATION_SCREENCAPTURE) {
-                       stop_key_combination();
-                       if (current_state_in_on())
-                               ignore = false;
-               }
-               volumedown_pressed = false;
-       }
-
-       return ignore;
-}
-
 static int process_brightness_key(struct input_event *pinput, int action)
 {
        if (pinput->value == KEY_RELEASED) {
@@ -534,9 +591,6 @@ static int check_key(struct input_event *pinput, int fd)
        case KEY_POWER:
                ignore = process_power_key(pinput);
                break;
-       case KEY_VOLUMEDOWN:
-               ignore = process_volumedown_key(pinput);
-               break;
        case KEY_BRIGHTNESSDOWN:
                ignore = process_brightness_key(pinput, BRIGHTNESS_DOWN);
                break;
@@ -557,6 +611,7 @@ static int check_key(struct input_event *pinput, int fd)
                }
                break;
        case KEY_VOLUMEUP:
+       case KEY_VOLUMEDOWN:
        case KEY_CAMERA:
        case KEY_EXIT:
        case KEY_CONFIG:
@@ -593,31 +648,6 @@ static int check_key(struct input_event *pinput, int fd)
        return ignore;
 }
 
-static inline int check_powerkey_delay(struct input_event *pinput)
-{
-       struct timespec tp;
-       int delay;
-
-       if (pinput->code != KEY_POWER ||
-           pinput->value != KEY_PRESSED)
-               return false;
-
-       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
-               return false;
-
-       clock_gettime(CLOCK_MONOTONIC, &tp);
-
-       delay = SEC_TO_MSEC(tp.tv_sec) +
-           NSEC_TO_MSEC(tp.tv_nsec) -
-           (SEC_TO_MSEC((pinput->time).tv_sec) +
-           USEC_TO_MSEC((pinput->time).tv_usec));
-
-       if (delay < KEY_MAX_DELAY_TIME)
-               return false;
-
-       return true;
-}
-
 static int check_key_filter(int length, char buf[], int fd)
 {
        struct input_event *pinput;
@@ -633,14 +663,6 @@ static int check_key_filter(int length, char buf[], int fd)
                            pinput->value == KEY_RELEASED)
                                touch_pressed = false;
                        /*
-                        * The later inputs are going to be ignored when
-                        * powerkey is pressed several times for a short time
-                        */
-                       if (check_powerkey_delay(pinput) == true) {
-                               _D("power key is delayed, then ignored!");
-                               return 0;
-                       }
-                       /*
                         * Normally, touch press/release events don't occur
                         * in lcd off state. But touch release events can occur
                         * in the state abnormally. Then touch events are ignored
@@ -790,8 +812,28 @@ static int hardkey_lcd_changed_cb(void *data)
        return 0;
 }
 
+/*
+ * Default capability
+ * powerkey := LCDON | LCDOFF | POWEROFF
+ * homekey  := LCDON
+ */
+static struct display_actor_ops display_powerkey_actor = {
+       .id     = DISPLAY_ACTOR_POWER_KEY,
+       .caps   = DISPLAY_CAPA_LCDON |
+                 DISPLAY_CAPA_LCDOFF |
+                 DISPLAY_CAPA_POWEROFF,
+};
+
+static struct display_actor_ops display_menukey_actor = {
+       .id     = DISPLAY_ACTOR_MENU_KEY,
+       .caps   = DISPLAY_CAPA_LCDON,
+};
+
 static void keyfilter_init(void)
 {
+       display_add_actor(&display_powerkey_actor);
+       display_add_actor(&display_menukey_actor);
+
        /* get touchkey light duration setting */
        if (vconf_get_int(VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION, &hardkey_duration) < 0) {
                _W("Fail to get VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION!!");
index 652df6d..ecdba47 100644 (file)
@@ -80,13 +80,9 @@ static Eina_Bool pm_handler(void *data, Ecore_Fd_Handler *fd_handler)
 
        int fd = (int)data;
        int ret;
-       static const struct device_ops *display_device_ops;
+       static const struct device_ops *display_device_ops = NULL;
 
-       if (!display_device_ops) {
-               display_device_ops = find_device("display");
-               if (!display_device_ops)
-                       return -ENODEV;
-       }
+       FIND_DEVICE_INT(display_device_ops, "display");
 
        if (device_get_status(display_device_ops) != DEVICE_OPS_STATUS_START) {
                _E("display is not started!");
@@ -122,7 +118,7 @@ int init_pm_poll(int (*pm_callback) (int, PMMsg *))
                _I("Getting input device path from environment: %s",
                       pm_input_env);
                /* Add 2 bytes for following strncat() */
-               dev_paths_size =  strlen(pm_input_env) + 1;
+               dev_paths_size =  strlen(pm_input_env) + 2;
                dev_paths = (char *)malloc(dev_paths_size);
                if (!dev_paths) {
                        _E("Fail to malloc for dev path");
@@ -131,7 +127,7 @@ int init_pm_poll(int (*pm_callback) (int, PMMsg *))
                snprintf(dev_paths, dev_paths_size, "%s", pm_input_env);
        } else {
                /* Add 2 bytes for following strncat() */
-               dev_paths_size = strlen(DEFAULT_DEV_PATH) + 1;
+               dev_paths_size = strlen(DEFAULT_DEV_PATH) + 2;
                dev_paths = (char *)malloc(dev_paths_size);
                if (!dev_paths) {
                        _E("Fail to malloc for dev path");
@@ -142,7 +138,6 @@ int init_pm_poll(int (*pm_callback) (int, PMMsg *))
 
        /* add the UNIX domain socket file path */
        strncat(dev_paths, DEV_PATH_DLM, strlen(DEV_PATH_DLM));
-       dev_paths[dev_paths_size - 1] = '\0';
 
        path_tok = strtok_r(dev_paths, DEV_PATH_DLM, &save_ptr);
        if (path_tok == NULL) {
index 30268d9..47ccb12 100644 (file)
@@ -46,6 +46,7 @@ enum {
 
 enum {
        INTERNAL_LOCK_BASE = 100000,
+       INTERNAL_LOCK_ALPM,
        INTERNAL_LOCK_BATTERY,
        INTERNAL_LOCK_BOOTING,
        INTERNAL_LOCK_DUMPMODE,
@@ -56,6 +57,8 @@ enum {
        INTERNAL_LOCK_TA,
        INTERNAL_LOCK_TIME,
        INTERNAL_LOCK_USB,
+       INTERNAL_LOCK_POWEROFF,
+       INTERNAL_LOCK_COOL_DOWN,
 };
 
 #define SIGNAL_NAME_LCD_CONTROL                "lcdcontol"
index 2fc1dfd..d73f151 100644 (file)
 #include "core.h"
 #include "util.h"
 #include "setting.h"
+#include "weaks.h"
 
-#define LCD_DIM_RATIO          0.2
+#define LCD_DIM_RATIO          0.3
 #define LCD_MAX_DIM_TIMEOUT    7000
+#define LCD_MIN_DIM_TIMEOUT    500
 
 static const char *setting_keys[SETTING_GET_END] = {
        [SETTING_TO_NORMAL] = VCONFKEY_SETAPPL_LCD_TIMEOUT_NORMAL,
        [SETTING_BRT_LEVEL] = VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
        [SETTING_LOCK_SCREEN] = VCONFKEY_IDLE_LOCK_STATE,
-       [SETTING_POWER_SAVING] = VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
-       [SETTING_POWER_SAVING_DISPLAY] = VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
        [SETTING_SMART_STAY] = VCONFKEY_SETAPPL_SMARTSCREEN_SMARTSTAY_STATUS,
        [SETTING_BOOT_POWER_ON_STATUS] = VCONFKEY_DEVICED_BOOT_POWER_ON_STATUS,
        [SETTING_POWER_CUSTOM_BRIGHTNESS] = VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS,
@@ -122,6 +122,12 @@ int get_dim_timeout(int *dim_timeout)
                return 0;
        }
 
+       if (get_ambient_mode != NULL &&
+           get_ambient_mode() == true) {
+               *dim_timeout = LCD_MIN_DIM_TIMEOUT;
+               return 0;
+       }
+
        ret = vconf_get_int(setting_keys[SETTING_TO_NORMAL], &vconf_timeout);
        if (ret != 0) {
                _E("Failed ro get setting timeout!");
@@ -165,14 +171,17 @@ int get_run_timeout(int *timeout)
        else
                on_timeout = SEC_TO_MSEC(vconf_timeout);
 
-       get_dim_timeout(&dim_timeout);
+       if (on_timeout < 0)
+               return -ERANGE;
 
-       if (on_timeout <= 0)
-               ret = -ERANGE;
-       else
-               *timeout = on_timeout - dim_timeout;
+       if (on_timeout == 0) {
+               *timeout = on_timeout;
+               return 0;
+       }
 
-       return ret;
+       get_dim_timeout(&dim_timeout);
+       *timeout = on_timeout - dim_timeout;
+       return 0;
 }
 
 int set_custom_lcdon_timeout(int timeout)
@@ -207,8 +216,6 @@ static int setting_cb(keynode_t *key_nodes, void *data)
        }
        if (update_pm_setting != NULL) {
                switch((int)data) {
-                       case SETTING_POWER_SAVING:
-                       case SETTING_POWER_SAVING_DISPLAY:
                        case SETTING_ACCESSIBILITY_TTS:
                                update_pm_setting((int)data, vconf_keynode_get_bool(tmp));
                                break;
index 7c48397..6d7a29d 100644 (file)
@@ -36,8 +36,6 @@ enum {
        SETTING_TO_NORMAL = SETTING_BEGIN,
        SETTING_BRT_LEVEL,
        SETTING_LOCK_SCREEN,
-       SETTING_POWER_SAVING,
-       SETTING_POWER_SAVING_DISPLAY,
        SETTING_SMART_STAY,
        SETTING_BOOT_POWER_ON_STATUS,
        SETTING_POWER_CUSTOM_BRIGHTNESS,
index 6f9cb32..e7ad2a4 100644 (file)
@@ -29,7 +29,7 @@
 #include "core/device-handler.h"
 
 #define SMART_STAY     2
-#define SMART_DETECTION_LIB "/usr/lib/sensor_framework/libsmart_detection.so"
+#define SMART_DETECTION_LIB "/usr/lib/libsmart_detection.so"
 #define CB_TIMEOUT     3 /* seconds */
 #define OCCUPIED_FAIL  -2
 
index 88c887d..88f8638 100644 (file)
@@ -33,7 +33,12 @@ int __WEAK__ control_brightness_key(int action);
 
 /* src/display/alpm.c */
 int __WEAK__ alpm_set_state(int);
-int __WEAK__ set_alpm_screen(char *);
+int __WEAK__ alpm_get_state(void);
+int __WEAK__ set_alpm_screen(char *, pid_t pid);
+bool __WEAK__ check_suspend_direct(pid_t pid);
+int __WEAK__ get_ambient_mode(void);
+void __WEAK__ check_alpm_invalid_state(void);
+int __WEAK__ check_alpm_lcdon_ready(void);
 
 #endif
 
diff --git a/src/earjack/earjack.c b/src/earjack/earjack.c
new file mode 100644 (file)
index 0000000..bcc785e
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <vconf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <assert.h>
+#include <device-node.h>
+#include <Ecore.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-handler.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "display/poll.h"
+
+#define SIGNAL_EARJACK_STATE   "ChangedEarjack"
+
+static int earjack_status = 0;
+
+static void earjack_send_broadcast(int status)
+{
+       static int old = 0;
+       char *arr[1];
+       char str_status[32];
+
+       if (old == status)
+               return;
+
+       _I("broadcast earjack status %d", status);
+       old = status;
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       SIGNAL_EARJACK_STATE, "i", arr);
+}
+
+static void earjack_chgdet_cb(void *data)
+{
+       int val;
+       int ret = 0;
+
+       if (data)
+               val = *(int *)data;
+       else {
+               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val);
+               if (ret != 0) {
+                       _E("failed to get status");
+                       return;
+               }
+       }
+       _I("jack - earjack changed %d", val);
+       vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
+       earjack_send_broadcast(val);
+       if (CONNECTED(val)) {
+               extcon_set_count(EXTCON_EARJACK);
+               internal_pm_change_state(LCD_NORMAL);
+       }
+}
+
+static DBusMessage *dbus_get_status(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val;
+
+       val = earjack_status;
+       _D("get hall status %d", val);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &val);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "getstatus",       NULL,   "i", dbus_get_status },
+       /* Add methods here */
+};
+
+static void earjack_init(void *data)
+{
+       int ret, val;
+
+       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val) == 0) {
+               if (CONNECTED(val))
+                       extcon_set_count(EXTCON_EARJACK);
+               vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
+       }
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+static int earjack_get_status(void)
+{
+       return earjack_status;
+}
+
+static int earjack_execute(void *data)
+{
+       earjack_chgdet_cb(data);
+       return 0;
+}
+
+static const struct device_ops earjack_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "earjack",
+       .init     = earjack_init,
+       .status   = earjack_get_status,
+       .execute  = earjack_execute,
+};
+
+DEVICE_OPS_REGISTER(&earjack_device_ops)
diff --git a/src/fsck-msdos/CMakeLists.txt b/src/fsck-msdos/CMakeLists.txt
new file mode 100644 (file)
index 0000000..335a53e
--- /dev/null
@@ -0,0 +1,45 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(fsck_msdosfs C)
+
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_ENGINEER_MODE")
+    OPTION(USE_ENGINEER_MODE "Use Engineer mode" ON)
+ENDIF()
+
+SET(SRCS
+       boot.c
+       check.c
+       dir.c
+       fat.c
+       main.c
+       )
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+IF(USE_ENGINEER_MODE)
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+ELSE()
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+ENDIF()
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+IF( $ENV{ARCH} MATCHES "arm" )
+       ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+ADD_DEFINITIONS("-DSLP_DEBUG")
+ADD_DEFINITIONS("-DSLP_PROF")
+ADD_DEFINITIONS("-D_GNU_SOURCE")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/src/fsck-msdos/LICENSE b/src/fsck-msdos/LICENSE
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/fsck-msdos/boot.c b/src/fsck-msdos/boot.c
new file mode 100644 (file)
index 0000000..f51fc6f
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 1995, 1997 Wolfgang Solfrank
+ * Copyright (c) 1995 Martin Husemann
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Martin Husemann
+ *     and Wolfgang Solfrank.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <sys/cdefs.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "ext.h"
+#include "fsutil.h"
+
+int
+readboot(dosfs, boot)
+       int dosfs;
+       struct bootblock *boot;
+{
+       u_char block[DOSBOOTBLOCKSIZE];
+       u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
+       u_char backup[DOSBOOTBLOCKSIZE];
+       int ret = FSOK;
+
+       if (read(dosfs, block, sizeof block) < sizeof block) {
+               perror("could not read boot block");
+                exit(2);
+       }
+
+       if (block[510] != 0x55 || block[511] != 0xaa) {
+               pfatal("Invalid signature in boot block: %02x%02x", block[511], block[510]);
+                exit(2);
+       }
+
+       memset(boot, 0, sizeof *boot);
+       boot->ValidFat = -1;
+
+       /* decode bios parameter block */
+       boot->BytesPerSec = block[11] + (block[12] << 8);
+       boot->SecPerClust = block[13];
+       boot->ResSectors = block[14] + (block[15] << 8);
+       boot->FATs = block[16];
+       boot->RootDirEnts = block[17] + (block[18] << 8);
+       boot->Sectors = block[19] + (block[20] << 8);
+       boot->Media = block[21];
+       boot->FATsmall = block[22] + (block[23] << 8);
+       boot->SecPerTrack = block[24] + (block[25] << 8);
+       boot->Heads = block[26] + (block[27] << 8);
+       boot->HiddenSecs = block[28] + (block[29] << 8) + (block[30] << 16) + (block[31] << 24);
+       boot->HugeSectors = block[32] + (block[33] << 8) + (block[34] << 16) + (block[35] << 24);
+
+       boot->FATsecs = boot->FATsmall;
+
+       if (!boot->RootDirEnts)
+               boot->flags |= FAT32;
+       if (boot->flags & FAT32) {
+               boot->FATsecs = block[36] + (block[37] << 8)
+                               + (block[38] << 16) + (block[39] << 24);
+               if (block[40] & 0x80)
+                       boot->ValidFat = block[40] & 0x0f;
+
+               /* check version number: */
+               if (block[42] || block[43]) {
+                       /* Correct?                             XXX */
+                       pfatal("Unknown file system version: %x.%x",
+                              block[43], block[42]);
+                        exit(2);
+               }
+               boot->RootCl = block[44] + (block[45] << 8)
+                              + (block[46] << 16) + (block[47] << 24);
+               boot->FSInfo = block[48] + (block[49] << 8);
+               boot->Backup = block[50] + (block[51] << 8);
+
+               if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
+                   != boot->FSInfo * boot->BytesPerSec
+                   || read(dosfs, fsinfo, sizeof fsinfo)
+                   != sizeof fsinfo) {
+                       perror("could not read fsinfo block");
+                       return FSFATAL;
+               }
+               if (memcmp(fsinfo, "RRaA", 4)
+                   || memcmp(fsinfo + 0x1e4, "rrAa", 4)
+                   || fsinfo[0x1fc]
+                   || fsinfo[0x1fd]
+                   || fsinfo[0x1fe] != 0x55
+                   || fsinfo[0x1ff] != 0xaa
+                   || fsinfo[0x3fc]
+                   || fsinfo[0x3fd]
+                   || fsinfo[0x3fe] != 0x55
+                   || fsinfo[0x3ff] != 0xaa) {
+                       pwarn("Invalid signature in fsinfo block\n");
+                       if (ask(1, "fix")) {
+                               memcpy(fsinfo, "RRaA", 4);
+                               memcpy(fsinfo + 0x1e4, "rrAa", 4);
+                               fsinfo[0x1fc] = fsinfo[0x1fd] = 0;
+                               fsinfo[0x1fe] = 0x55;
+                               fsinfo[0x1ff] = 0xaa;
+                               fsinfo[0x3fc] = fsinfo[0x3fd] = 0;
+                               fsinfo[0x3fe] = 0x55;
+                               fsinfo[0x3ff] = 0xaa;
+                               if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
+                                   != boot->FSInfo * boot->BytesPerSec
+                                   || write(dosfs, fsinfo, sizeof fsinfo)
+                                   != sizeof fsinfo) {
+                                       perror("Unable to write FSInfo");
+                                       return FSFATAL;
+                               }
+                               ret = FSBOOTMOD;
+                       } else
+                               boot->FSInfo = 0;
+               }
+               if (boot->FSInfo) {
+                       boot->FSFree = fsinfo[0x1e8] + (fsinfo[0x1e9] << 8)
+                                      + (fsinfo[0x1ea] << 16)
+                                      + (fsinfo[0x1eb] << 24);
+                       boot->FSNext = fsinfo[0x1ec] + (fsinfo[0x1ed] << 8)
+                                      + (fsinfo[0x1ee] << 16)
+                                      + (fsinfo[0x1ef] << 24);
+               }
+
+               if (lseek(dosfs, boot->Backup * boot->BytesPerSec, SEEK_SET)
+                   != boot->Backup * boot->BytesPerSec
+                   || read(dosfs, backup, sizeof backup) != sizeof  backup) {
+                       perror("could not read backup bootblock");
+                       return FSFATAL;
+               }
+               backup[65] = block[65];                         /* XXX */
+               if (memcmp(block + 11, backup + 11, 79)) {
+                        char tmp[255];
+                        int i;
+
+                       /*
+                        * For now, lets not bail out if they don't match
+                        * It seems a lot of sdcards are formatted with
+                        * the backup either empty or containing garbage.
+                        */
+
+                       pwarn("Primary/Backup bootblock miscompare\n");
+
+                        strcpy(tmp, "");
+                        pwarn("Primary:\n");
+                       for (i = 0; i < 79; i++) {
+                               char tmp2[16];
+                                snprintf(tmp2, sizeof(tmp2), "%.2x ", block[11 + i]);
+                               strcat(tmp, tmp2);
+                        }
+                        pwarn("%s\n", tmp);
+
+                       strcpy(tmp, "");
+                        pwarn("Backup:\n");
+                       for (i = 0; i < 79; i++) {
+                               char tmp2[16];
+                                snprintf(tmp2, sizeof(tmp2), "%.2x ", backup[11 + i]);
+                               strcat(tmp, tmp2);
+                        }
+                        pwarn("%s\n", tmp);
+               }
+               /* Check backup FSInfo?                                 XXX */
+       }
+
+       if (boot->BytesPerSec % DOSBOOTBLOCKSIZE != 0) {
+               pfatal("Invalid sector size: %u", boot->BytesPerSec);
+               return FSFATAL;
+       }
+       if (boot->SecPerClust == 0) {
+               pfatal("Invalid cluster size: %u", boot->SecPerClust);
+               return FSFATAL;
+       }
+       if (boot->BytesPerSec == 0) {
+               pfatal("Invalid sector size: %u", boot->BytesPerSec);
+               return FSFATAL;
+       }
+       if (boot->FATs == 0) {
+               pfatal("Invalid number of FATs: %u", boot->FATs);
+               return FSFATAL;
+       }
+       if (boot->Sectors) {
+               boot->HugeSectors = 0;
+               boot->NumSectors = boot->Sectors;
+       } else
+               boot->NumSectors = boot->HugeSectors;
+
+       boot->ClusterOffset = (boot->RootDirEnts * 32 + boot->BytesPerSec - 1)
+           / boot->BytesPerSec
+           + boot->ResSectors
+           + boot->FATs * boot->FATsecs
+           - CLUST_FIRST * boot->SecPerClust;
+
+       boot->NumClusters = (boot->NumSectors - boot->ClusterOffset) / boot->SecPerClust;
+
+       if (boot->flags&FAT32)
+               boot->ClustMask = CLUST32_MASK;
+       else if (boot->NumClusters < (CLUST_RSRVD&CLUST12_MASK))
+               boot->ClustMask = CLUST12_MASK;
+       else if (boot->NumClusters < (CLUST_RSRVD&CLUST16_MASK))
+               boot->ClustMask = CLUST16_MASK;
+       else {
+               pfatal("Filesystem too big (%u clusters) for non-FAT32 partition",
+                      boot->NumClusters);
+               return FSFATAL;
+       }
+
+       switch (boot->ClustMask) {
+       case CLUST32_MASK:
+               boot->NumFatEntries = (boot->FATsecs * boot->BytesPerSec) / 4;
+               break;
+       case CLUST16_MASK:
+               boot->NumFatEntries = (boot->FATsecs * boot->BytesPerSec) / 2;
+               break;
+       default:
+               boot->NumFatEntries = (boot->FATsecs * boot->BytesPerSec * 2) / 3;
+               break;
+       }
+
+       if (boot->NumFatEntries < boot->NumClusters) {
+               pfatal("FAT size too small, %u entries won't fit into %u sectors\n",
+                      boot->NumClusters, boot->FATsecs);
+               return FSFATAL;
+       }
+       boot->ClusterSize = boot->BytesPerSec * boot->SecPerClust;
+
+       boot->NumFiles = 1;
+       boot->NumFree = 0;
+
+       return ret;
+}
+
+int
+writefsinfo(dosfs, boot)
+       int dosfs;
+       struct bootblock *boot;
+{
+       u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
+
+       if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
+           != boot->FSInfo * boot->BytesPerSec
+           || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
+               perror("could not read fsinfo block");
+               return FSFATAL;
+       }
+       fsinfo[0x1e8] = (u_char)boot->FSFree;
+       fsinfo[0x1e9] = (u_char)(boot->FSFree >> 8);
+       fsinfo[0x1ea] = (u_char)(boot->FSFree >> 16);
+       fsinfo[0x1eb] = (u_char)(boot->FSFree >> 24);
+       fsinfo[0x1ec] = (u_char)boot->FSNext;
+       fsinfo[0x1ed] = (u_char)(boot->FSNext >> 8);
+       fsinfo[0x1ee] = (u_char)(boot->FSNext >> 16);
+       fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24);
+       if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
+           != boot->FSInfo * boot->BytesPerSec
+           || write(dosfs, fsinfo, sizeof fsinfo)
+           != sizeof fsinfo) {
+               perror("Unable to write FSInfo");
+               return FSFATAL;
+       }
+       /*
+        * Technically, we should return FSBOOTMOD here.
+        *
+        * However, since Win95 OSR2 (the first M$ OS that has
+        * support for FAT32) doesn't maintain the FSINFO block
+        * correctly, it has to be fixed pretty often.
+        *
+        * Therefor, we handle the FSINFO block only informally,
+        * fixing it if necessary, but otherwise ignoring the
+        * fact that it was incorrect.
+        */
+       return 0;
+}
diff --git a/src/fsck-msdos/check.c b/src/fsck-msdos/check.c
new file mode 100644 (file)
index 0000000..bb5fbc2
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
+ * Copyright (c) 1995 Martin Husemann
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Martin Husemann
+ *     and Wolfgang Solfrank.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "ext.h"
+#include "fsutil.h"
+
+/*
+ * If the FAT > this size then skip comparing, lest we risk
+ * OOMing the framework. in the future we need to just re-write
+ * this whole thing and optimize for less memory
+ */
+#define FAT_COMPARE_MAX_KB 4096
+
+int
+checkfilesys(const char *fname)
+{
+       int dosfs;
+       struct bootblock boot;
+       struct fatEntry *fat = NULL;
+       int i, finish_dosdirsection=0;
+       int mod = 0;
+       int ret = 8;
+        int quiet = 0;
+        int skip_fat_compare = 0;
+
+       rdonly = alwaysno;
+       if (!quiet)
+               printf("** %s", fname);
+
+       dosfs = open(fname, rdonly ? O_RDONLY : O_RDWR, 0);
+       if (dosfs < 0 && !rdonly) {
+               dosfs = open(fname, O_RDONLY, 0);
+               if (dosfs >= 0)
+                       pwarn(" (NO WRITE)\n");
+               else if (!quiet)
+                       printf("\n");
+               rdonly = 1;
+       } else if (!quiet)
+               printf("\n");
+
+       if (dosfs < 0) {
+               perror("Can't open");
+               return 8;
+       }
+
+       if (readboot(dosfs, &boot) == FSFATAL) {
+               close(dosfs);
+               printf("\n");
+               return 8;
+       }
+
+       if (skipclean && preen && checkdirty(dosfs, &boot)) {
+               printf("%s: ", fname);
+               printf("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
+               ret = 0;
+               goto out;
+       }
+
+        if (((boot.FATsecs * boot.BytesPerSec) / 1024) > FAT_COMPARE_MAX_KB)
+            skip_fat_compare = 1;
+
+       if (!quiet)  {
+                if (skip_fat_compare)
+                        printf("** Phase 1 - Read FAT (compare skipped)\n");
+               else if (boot.ValidFat < 0)
+                       printf("** Phase 1 - Read and Compare FATs\n");
+               else
+                       printf("** Phase 1 - Read FAT\n");
+       }
+
+       mod |= readfat(dosfs, &boot, boot.ValidFat >= 0 ? boot.ValidFat : 0, &fat);
+       if (mod & FSFATAL) {
+               printf("Fatal error during readfat()\n");
+               if (fat)
+                       free(fat);
+               close(dosfs);
+               return 8;
+       }
+
+       if (!skip_fat_compare && boot.ValidFat < 0)
+               for (i = 1; i < (int)boot.FATs; i++) {
+                       struct fatEntry *currentFat;
+
+                       mod |= readfat(dosfs, &boot, i, &currentFat);
+
+                       if (mod & FSFATAL) {
+                               printf("Fatal error during readfat() for comparison\n");
+                               goto out;
+                       }
+
+                       mod |= comparefat(&boot, fat, currentFat, i);
+                       free(currentFat);
+                       if (mod & FSFATAL) {
+                               printf("Fatal error during FAT comparison\n");
+                               goto out;
+                       }
+               }
+
+       if (!quiet)
+               printf("** Phase 2 - Check Cluster Chains\n");
+
+       mod |= checkfat(&boot, fat);
+       if (mod & FSFATAL) {
+               printf("Fatal error during FAT check\n");
+               goto out;
+       }
+       /* delay writing FATs */
+
+       if (!quiet)
+               printf("** Phase 3 - Checking Directories\n");
+
+       mod |= resetDosDirSection(&boot, fat);
+       finish_dosdirsection = 1;
+       if (mod & FSFATAL) {
+               printf("Fatal error during resetDosDirSection()\n");
+               goto out;
+       }
+       /* delay writing FATs */
+
+       mod |= handleDirTree(dosfs, &boot, fat);
+       if (mod & FSFATAL)
+               goto out;
+
+       if (!quiet)
+               printf("** Phase 4 - Checking for Lost Files\n");
+
+       mod |= checklost(dosfs, &boot, fat);
+       if (mod & FSFATAL)
+               goto out;
+
+       /* now write the FATs */
+       if (mod & FSFATMOD) {
+               if (ask(1, "Update FATs")) {
+                       mod |= writefat(dosfs, &boot, fat, mod & FSFIXFAT);
+                       if (mod & FSFATAL) {
+                               printf("Fatal error during writefat()\n");
+                               goto out;
+                       }
+               } else
+                       mod |= FSERROR;
+       }
+
+       if (boot.NumBad)
+               pwarn("%d files, %d free (%d clusters), %d bad (%d clusters)\n",
+                     boot.NumFiles,
+                     boot.NumFree * boot.ClusterSize / 1024, boot.NumFree,
+                     boot.NumBad * boot.ClusterSize / 1024, boot.NumBad);
+       else
+               pwarn("%d files, %d free (%d clusters)\n",
+                     boot.NumFiles,
+                     boot.NumFree * boot.ClusterSize / 1024, boot.NumFree);
+
+       if (mod && (mod & FSERROR) == 0) {
+               if (mod & FSDIRTY) {
+                       if (ask(1, "MARK FILE SYSTEM CLEAN") == 0)
+                               mod &= ~FSDIRTY;
+
+                       if (mod & FSDIRTY) {
+                               pwarn("MARKING FILE SYSTEM CLEAN\n");
+                               mod |= writefat(dosfs, &boot, fat, 1);
+                       } else {
+                               pwarn("\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n");
+                               mod |= FSERROR; /* file system not clean */
+                       }
+               }
+       }
+
+       if (mod & (FSFATAL | FSERROR))
+               goto out;
+
+       ret = 0;
+
+    out:
+       if (finish_dosdirsection)
+               finishDosDirSection();
+       free(fat);
+       close(dosfs);
+
+       if (mod & (FSFATMOD|FSDIRMOD)) {
+               pwarn("\n***** FILE SYSTEM WAS MODIFIED *****\n");
+               return 4;
+       }
+
+       return ret;
+}
diff --git a/src/fsck-msdos/dir.c b/src/fsck-msdos/dir.c
new file mode 100644 (file)
index 0000000..f5224dd
--- /dev/null
@@ -0,0 +1,1100 @@
+/*
+ * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
+ * Copyright (c) 1995 Martin Husemann
+ * Some structure declaration borrowed from Paul Popelka
+ * (paulp@uts.amdahl.com), see /sys/msdosfs/ for reference.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Martin Husemann
+ *     and Wolfgang Solfrank.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <sys/param.h>
+
+#include "ext.h"
+#include "fsutil.h"
+
+#define        SLOT_EMPTY      0x00            /* slot has never been used */
+#define        SLOT_E5         0x05            /* the real value is 0xe5 */
+#define        SLOT_DELETED    0xe5            /* file in this slot deleted */
+
+#define        ATTR_NORMAL     0x00            /* normal file */
+#define        ATTR_READONLY   0x01            /* file is readonly */
+#define        ATTR_HIDDEN     0x02            /* file is hidden */
+#define        ATTR_SYSTEM     0x04            /* file is a system file */
+#define        ATTR_VOLUME     0x08            /* entry is a volume label */
+#define        ATTR_DIRECTORY  0x10            /* entry is a directory name */
+#define        ATTR_ARCHIVE    0x20            /* file is new or modified */
+
+#define        ATTR_WIN95      0x0f            /* long name record */
+
+/*
+ * This is the format of the contents of the deTime field in the direntry
+ * structure.
+ * We don't use bitfields because we don't know how compilers for
+ * arbitrary machines will lay them out.
+ */
+#define DT_2SECONDS_MASK       0x1F    /* seconds divided by 2 */
+#define DT_2SECONDS_SHIFT      0
+#define DT_MINUTES_MASK                0x7E0   /* minutes */
+#define DT_MINUTES_SHIFT       5
+#define DT_HOURS_MASK          0xF800  /* hours */
+#define DT_HOURS_SHIFT         11
+
+/*
+ * This is the format of the contents of the deDate field in the direntry
+ * structure.
+ */
+#define DD_DAY_MASK            0x1F    /* day of month */
+#define DD_DAY_SHIFT           0
+#define DD_MONTH_MASK          0x1E0   /* month */
+#define DD_MONTH_SHIFT         5
+#define DD_YEAR_MASK           0xFE00  /* year - 1980 */
+#define DD_YEAR_SHIFT          9
+
+
+/* dir.c */
+static struct dosDirEntry *newDosDirEntry(void);
+static void freeDosDirEntry(struct dosDirEntry *);
+static struct dirTodoNode *newDirTodo(void);
+static void freeDirTodo(struct dirTodoNode *);
+static char *fullpath(struct dosDirEntry *);
+static u_char calcShortSum(u_char *);
+static int delete(int, struct bootblock *, struct fatEntry *, cl_t, int,
+    cl_t, int, int);
+static int removede(int, struct bootblock *, struct fatEntry *, u_char *,
+    u_char *, cl_t, cl_t, cl_t, char *, int);
+static int checksize(struct bootblock *, struct fatEntry *, u_char *,
+    struct dosDirEntry *);
+static int readDosDirSection(int, struct bootblock *, struct fatEntry *,
+    struct dosDirEntry *);
+
+/*
+ * Manage free dosDirEntry structures.
+ */
+static struct dosDirEntry *freede;
+
+static struct dosDirEntry *
+newDosDirEntry(void)
+{
+       struct dosDirEntry *de;
+
+       if (!(de = freede)) {
+               if (!(de = (struct dosDirEntry *)malloc(sizeof *de)))
+                       return 0;
+       } else
+               freede = de->next;
+       return de;
+}
+
+static void
+freeDosDirEntry(struct dosDirEntry *de)
+{
+       de->next = freede;
+       freede = de;
+}
+
+/*
+ * The same for dirTodoNode structures.
+ */
+static struct dirTodoNode *freedt;
+
+static struct dirTodoNode *
+newDirTodo(void)
+{
+       struct dirTodoNode *dt;
+
+       if (!(dt = freedt)) {
+               if (!(dt = (struct dirTodoNode *)malloc(sizeof *dt)))
+                       return 0;
+       } else
+               freedt = dt->next;
+       return dt;
+}
+
+static void
+freeDirTodo(struct dirTodoNode *dt)
+{
+       dt->next = freedt;
+       freedt = dt;
+}
+
+/*
+ * The stack of unread directories
+ */
+struct dirTodoNode *pendingDirectories = NULL;
+
+/*
+ * Return the full pathname for a directory entry.
+ */
+static char *
+fullpath(struct dosDirEntry *dir)
+{
+       static char namebuf[MAXPATHLEN + 1];
+       char *cp, *np;
+       int nl;
+
+       cp = namebuf + sizeof namebuf - 1;
+       *cp = '\0';
+       do {
+               np = dir->lname[0] ? dir->lname : dir->name;
+               nl = strlen(np);
+               if ((cp -= nl) <= namebuf + 1)
+                       break;
+               memcpy(cp, np, nl);
+               *--cp = '/';
+       } while ((dir = dir->parent) != NULL);
+       if (dir)
+               *--cp = '?';
+       else
+               cp++;
+       return cp;
+}
+
+/*
+ * Calculate a checksum over an 8.3 alias name
+ */
+static u_char
+calcShortSum(u_char *p)
+{
+       u_char sum = 0;
+       int i;
+
+       for (i = 0; i < 11; i++) {
+               sum = (sum << 7)|(sum >> 1);    /* rotate right */
+               sum += p[i];
+       }
+
+       return sum;
+}
+
+/*
+ * Global variables temporarily used during a directory scan
+ */
+static char longName[DOSLONGNAMELEN] = "";
+static u_char *buffer = NULL;
+static u_char *delbuf = NULL;
+
+struct dosDirEntry *rootDir;
+static struct dosDirEntry *lostDir;
+
+/*
+ * Init internal state for a new directory scan.
+ */
+int
+resetDosDirSection(struct bootblock *boot, struct fatEntry *fat)
+{
+       int b1, b2;
+       cl_t cl;
+       int ret = FSOK;
+
+       b1 = boot->RootDirEnts * 32;
+       b2 = boot->SecPerClust * boot->BytesPerSec;
+
+       if (!(buffer = malloc(b1 > b2 ? b1 : b2))
+           || !(delbuf = malloc(b2))
+           || !(rootDir = newDosDirEntry())) {
+               perror("No space for directory");
+               return FSFATAL;
+       }
+       memset(rootDir, 0, sizeof *rootDir);
+       if (boot->flags & FAT32) {
+               if (boot->RootCl < CLUST_FIRST || boot->RootCl >= boot->NumClusters) {
+                       pfatal("Root directory starts with cluster out of range(%u)",
+                              boot->RootCl);
+                       return FSFATAL;
+               }
+               cl = fat[boot->RootCl].next;
+               if (cl < CLUST_FIRST
+                   || (cl >= CLUST_RSRVD && cl< CLUST_EOFS)
+                   || fat[boot->RootCl].head != boot->RootCl) {
+                       if (cl == CLUST_FREE)
+                               pwarn("Root directory starts with free cluster\n");
+                       else if (cl >= CLUST_RSRVD)
+                               pwarn("Root directory starts with cluster marked %s\n",
+                                     rsrvdcltype(cl));
+                       else {
+                               pfatal("Root directory doesn't start a cluster chain");
+                               return FSFATAL;
+                       }
+                       if (ask(1, "Fix")) {
+                               fat[boot->RootCl].next = CLUST_FREE;
+                               ret = FSFATMOD;
+                       } else
+                               ret = FSFATAL;
+               }
+
+               fat[boot->RootCl].flags |= FAT_USED;
+               rootDir->head = boot->RootCl;
+       }
+
+       return ret;
+}
+
+/*
+ * Cleanup after a directory scan
+ */
+void
+finishDosDirSection(void)
+{
+       struct dirTodoNode *p, *np;
+       struct dosDirEntry *d, *nd;
+
+       for (p = pendingDirectories; p; p = np) {
+               np = p->next;
+               freeDirTodo(p);
+       }
+       pendingDirectories = 0;
+       for (d = rootDir; d; d = nd) {
+               if ((nd = d->child) != NULL) {
+                       d->child = 0;
+                       continue;
+               }
+               if (!(nd = d->next))
+                       nd = d->parent;
+               freeDosDirEntry(d);
+       }
+       rootDir = lostDir = NULL;
+       free(buffer);
+       free(delbuf);
+       buffer = NULL;
+       delbuf = NULL;
+}
+
+/*
+ * Delete directory entries between startcl, startoff and endcl, endoff.
+ */
+static int
+delete(int f, struct bootblock *boot, struct fatEntry *fat, cl_t startcl,
+    int startoff, cl_t endcl, int endoff, int notlast)
+{
+       u_char *s, *e;
+       loff_t off;
+       int clsz = boot->SecPerClust * boot->BytesPerSec;
+
+       s = delbuf + startoff;
+       e = delbuf + clsz;
+       while (startcl >= CLUST_FIRST && startcl < boot->NumClusters) {
+               if (startcl == endcl) {
+                       if (notlast)
+                               break;
+                       e = delbuf + endoff;
+               }
+               off = startcl * boot->SecPerClust + boot->ClusterOffset;
+               off *= boot->BytesPerSec;
+               if (lseek64(f, off, SEEK_SET) != off) {
+                       printf("off = %llu\n", off);
+                       perror("Unable to lseek64");
+                       return FSFATAL;
+               }
+               if (read(f, delbuf, clsz) != clsz) {
+                       perror("Unable to read directory");
+                       return FSFATAL;
+               }
+               while (s < e) {
+                       *s = SLOT_DELETED;
+                       s += 32;
+               }
+               if (lseek64(f, off, SEEK_SET) != off) {
+                       printf("off = %llu\n", off);
+                       perror("Unable to lseek64");
+                       return FSFATAL;
+               }
+               if (write(f, delbuf, clsz) != clsz) {
+                       perror("Unable to write directory");
+                       return FSFATAL;
+               }
+               if (startcl == endcl)
+                       break;
+               startcl = fat[startcl].next;
+               s = delbuf;
+       }
+       return FSOK;
+}
+
+static int
+removede(int f, struct bootblock *boot, struct fatEntry *fat, u_char *start,
+    u_char *end, cl_t startcl, cl_t endcl, cl_t curcl, char *path, int type)
+{
+       switch (type) {
+       case 0:
+               pwarn("Invalid long filename entry for %s\n", path);
+               break;
+       case 1:
+               pwarn("Invalid long filename entry at end of directory %s\n", path);
+               break;
+       case 2:
+               pwarn("Invalid long filename entry for volume label\n");
+               break;
+       }
+       if (ask(1, "Remove")) {
+               if (startcl != curcl) {
+                       if (delete(f, boot, fat,
+                                  startcl, start - buffer,
+                                  endcl, end - buffer,
+                                  endcl == curcl) == FSFATAL)
+                               return FSFATAL;
+                       start = buffer;
+               }
+               if (endcl == curcl)
+                       for (; start < end; start += 32)
+                               *start = SLOT_DELETED;
+               return FSDIRMOD;
+       }
+       return FSERROR;
+}
+
+/*
+ * Check an in-memory file entry
+ */
+static int
+checksize(struct bootblock *boot, struct fatEntry *fat, u_char *p,
+    struct dosDirEntry *dir)
+{
+       /*
+        * Check size on ordinary files
+        */
+       int32_t physicalSize;
+
+       if (dir->head == CLUST_FREE)
+               physicalSize = 0;
+       else {
+               if (dir->head < CLUST_FIRST || dir->head >= boot->NumClusters)
+                       return FSERROR;
+               physicalSize = fat[dir->head].length * boot->ClusterSize;
+       }
+       if (physicalSize < dir->size) {
+               pwarn("size of %s is %u, should at most be %u\n",
+                     fullpath(dir), dir->size, physicalSize);
+               if (ask(1, "Truncate")) {
+                       dir->size = physicalSize;
+                       p[28] = (u_char)physicalSize;
+                       p[29] = (u_char)(physicalSize >> 8);
+                       p[30] = (u_char)(physicalSize >> 16);
+                       p[31] = (u_char)(physicalSize >> 24);
+                       return FSDIRMOD;
+               } else
+                       return FSERROR;
+       } else if (physicalSize - dir->size >= boot->ClusterSize) {
+               pwarn("%s has too many clusters allocated\n",
+                     fullpath(dir));
+               if (ask(1, "Drop superfluous clusters")) {
+                       cl_t cl;
+                       u_int32_t sz = 0;
+
+                       for (cl = dir->head; (sz += boot->ClusterSize) < dir->size;)
+                               cl = fat[cl].next;
+                       clearchain(boot, fat, fat[cl].next);
+                       fat[cl].next = CLUST_EOF;
+                       return FSFATMOD;
+               } else
+                       return FSERROR;
+       }
+       return FSOK;
+}
+
+
+static u_char  dot_header[16]={0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00};
+static u_char  dot_dot_header[16]={0x2E, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00};
+
+/*
+ * Check for missing or broken '.' and '..' entries.
+ */
+static int
+check_dot_dot(int f, struct bootblock *boot, struct fatEntry *fat,struct dosDirEntry *dir)
+{
+       u_char *p, *buf;
+       loff_t off;
+       int last;
+       cl_t cl;
+       int rc=0, n_count;
+
+       int dot, dotdot;
+       dot = dotdot = 0;
+       cl = dir->head;
+
+       if (dir->parent && (cl < CLUST_FIRST || cl >= boot->NumClusters)) {
+               return rc;
+       }
+
+       do {
+               if (!(boot->flags & FAT32) && !dir->parent) {
+                       last = boot->RootDirEnts * 32;
+                       off = boot->ResSectors + boot->FATs * boot->FATsecs;
+               } else {
+                       last = boot->SecPerClust * boot->BytesPerSec;
+                       off = cl * boot->SecPerClust + boot->ClusterOffset;
+               }
+
+               off *= boot->BytesPerSec;
+               buf = malloc(last);
+               if (!buf) {
+                       perror("Unable to malloc");
+                       return FSFATAL;
+               }
+               if (lseek64(f, off, SEEK_SET) != off) {
+                       printf("off = %llu\n", off);
+                       perror("Unable to lseek64");
+                       free(buf);
+                       return FSFATAL;
+               }
+               if (read(f, buf, last) != last) {
+                       perror("Unable to read");
+                       free(buf);
+                       return FSFATAL;
+               }
+               last /= 32;
+               p = buf;
+               for (n_count=0, rc=0; n_count < 11; n_count++) {
+                       if (dot_header[n_count] != p[n_count]) {
+                               rc=-1;
+                               break;
+                       }
+               }
+                if(!rc)
+                       dot=1;
+
+               for (n_count = 0, rc = 0; n_count < 11; n_count++) {
+                       if (dot_dot_header[n_count] != p[n_count+32]) {
+                               rc=-1;
+                               break;
+                       }
+               }
+               if(!rc)
+                       dotdot=1;
+               free(buf);
+       } while ((cl = fat[cl].next) >= CLUST_FIRST && cl < boot->NumClusters);
+
+       if (!dot || !dotdot) {
+               if (!dot)
+                       pwarn("%s: '.' absent for %s.\n",__func__,dir->name);
+
+               if (!dotdot)
+                       pwarn("%s: '..' absent for %s. \n",__func__,dir->name);
+               return -1;
+       }
+       return 0;
+}
+
+/*
+ * Read a directory and
+ *   - resolve long name records
+ *   - enter file and directory records into the parent's list
+ *   - push directories onto the todo-stack
+ */
+static int
+readDosDirSection(int f, struct bootblock *boot, struct fatEntry *fat,
+    struct dosDirEntry *dir)
+{
+       struct dosDirEntry dirent, *d;
+       u_char *p, *vallfn, *invlfn, *empty;
+       loff_t off;
+       int i, j, k, last;
+       cl_t cl, valcl = ~0, invcl = ~0, empcl = ~0;
+       char *t;
+       u_int lidx = 0;
+       int shortSum;
+       int mod = FSOK;
+       int n_count=0;
+       int rc=0;
+#define        THISMOD 0x8000                  /* Only used within this routine */
+
+       cl = dir->head;
+       if (dir->parent && (cl < CLUST_FIRST || cl >= boot->NumClusters)) {
+               /*
+                * Already handled somewhere else.
+                */
+               return FSOK;
+       }
+       shortSum = -1;
+       vallfn = invlfn = empty = NULL;
+       int dot,dotdot;
+       dot = dotdot = 0;
+
+       do {
+               if (!(boot->flags & FAT32) && !dir->parent) {
+                       last = boot->RootDirEnts * 32;
+                       off = boot->ResSectors + boot->FATs * boot->FATsecs;
+               } else {
+                       last = boot->SecPerClust * boot->BytesPerSec;
+                       off = cl * boot->SecPerClust + boot->ClusterOffset;
+               }
+
+               off *= boot->BytesPerSec;
+               if (lseek64(f, off, SEEK_SET) != off) {
+                        printf("off = %llu\n", off);
+                       perror("Unable to lseek64");
+                       return FSFATAL;
+                }
+                if (read(f, buffer, last) != last) {
+                       perror("Unable to read");
+                       return FSFATAL;
+                }
+               last /= 32;
+               for (p = buffer, i = 0; i < last; i++, p += 32) {
+                       if (dir->fsckflags & DIREMPWARN) {
+                               *p = SLOT_EMPTY;
+                               continue;
+                       }
+
+                       if (*p == SLOT_EMPTY || *p == SLOT_DELETED) {
+                               if (*p == SLOT_EMPTY) {
+                                       dir->fsckflags |= DIREMPTY;
+                                       empty = p;
+                                       empcl = cl;
+                               }
+                               continue;
+                       }
+
+                       if (dir->fsckflags & DIREMPTY) {
+                               if (!(dir->fsckflags & DIREMPWARN)) {
+                                       pwarn("%s has entries after end of directory\n",
+                                             fullpath(dir));
+                                       if (ask(1, "Extend")) {
+                                               u_char *q;
+
+                                               dir->fsckflags &= ~DIREMPTY;
+                                               if (delete(f, boot, fat,
+                                                          empcl, empty - buffer,
+                                                          cl, p - buffer, 1) == FSFATAL)
+                                                       return FSFATAL;
+                                               q = empcl == cl ? empty : buffer;
+                                               for (; q < p; q += 32)
+                                                       *q = SLOT_DELETED;
+                                               mod |= THISMOD|FSDIRMOD;
+                                       } else if (ask(1, "Truncate"))
+                                               dir->fsckflags |= DIREMPWARN;
+                               }
+                               if (dir->fsckflags & DIREMPWARN) {
+                                       *p = SLOT_DELETED;
+                                       mod |= THISMOD|FSDIRMOD;
+                                       continue;
+                               } else if (dir->fsckflags & DIREMPTY)
+                                       mod |= FSERROR;
+                               empty = NULL;
+                       }
+
+                       if (p[11] == ATTR_WIN95) {
+                               if (*p & LRFIRST) {
+                                       if (shortSum != -1) {
+                                               if (!invlfn) {
+                                                       invlfn = vallfn;
+                                                       invcl = valcl;
+                                               }
+                                       }
+                                       memset(longName, 0, sizeof longName);
+                                       shortSum = p[13];
+                                       vallfn = p;
+                                       valcl = cl;
+                               } else if (shortSum != p[13]
+                                          || lidx != (*p & LRNOMASK)) {
+                                       if (!invlfn) {
+                                               invlfn = vallfn;
+                                               invcl = valcl;
+                                       }
+                                       if (!invlfn) {
+                                               invlfn = p;
+                                               invcl = cl;
+                                       }
+                                       vallfn = NULL;
+                               }
+                               lidx = *p & LRNOMASK;
+                               t = longName + --lidx * 13;
+                               for (k = 1; k < 11 && t < longName + sizeof(longName); k += 2) {
+                                       if (!p[k] && !p[k + 1])
+                                               break;
+                                       *t++ = p[k];
+                                       /*
+                                        * Warn about those unusable chars in msdosfs here?     XXX
+                                        */
+                                       if (p[k + 1])
+                                               t[-1] = '?';
+                               }
+                               if (k >= 11)
+                                       for (k = 14; k < 26 && t < longName + sizeof(longName); k += 2) {
+                                               if (!p[k] && !p[k + 1])
+                                                       break;
+                                               *t++ = p[k];
+                                               if (p[k + 1])
+                                                       t[-1] = '?';
+                                       }
+                               if (k >= 26)
+                                       for (k = 28; k < 32 && t < longName + sizeof(longName); k += 2) {
+                                               if (!p[k] && !p[k + 1])
+                                                       break;
+                                               *t++ = p[k];
+                                               if (p[k + 1])
+                                                       t[-1] = '?';
+                                       }
+                               if (t >= longName + sizeof(longName)) {
+                                       pwarn("long filename too long\n");
+                                       if (!invlfn) {
+                                               invlfn = vallfn;
+                                               invcl = valcl;
+                                       }
+                                       vallfn = NULL;
+                               }
+                               if (p[26] | (p[27] << 8)) {
+                                       pwarn("long filename record cluster start != 0\n");
+                                       if (!invlfn) {
+                                               invlfn = vallfn;
+                                               invcl = cl;
+                                       }
+                                       vallfn = NULL;
+                               }
+                               continue;       /* long records don't carry further
+                                                * information */
+                       }
+
+                       /*
+                        * This is a standard msdosfs directory entry.
+                        */
+                       memset(&dirent, 0, sizeof dirent);
+
+                       /*
+                        * it's a short name record, but we need to know
+                        * more, so get the flags first.
+                        */
+                       dirent.flags = p[11];
+
+                       /*
+                        * Translate from 850 to ISO here               XXX
+                        */
+                       for (j = 0; j < 8; j++)
+                               dirent.name[j] = p[j];
+                       dirent.name[8] = '\0';
+                       for (k = 7; k >= 0 && dirent.name[k] == ' '; k--)
+                               dirent.name[k] = '\0';
+                       if (dirent.name[k] != '\0')
+                               k++;
+                       if (dirent.name[0] == SLOT_E5)
+                               dirent.name[0] = 0xe5;
+
+                       if (dirent.flags & ATTR_VOLUME) {
+                               if (vallfn || invlfn) {
+                                       mod |= removede(f, boot, fat,
+                                                       invlfn ? invlfn : vallfn, p,
+                                                       invlfn ? invcl : valcl, -1, 0,
+                                                       fullpath(dir), 2);
+                                       vallfn = NULL;
+                                       invlfn = NULL;
+                               }
+                               continue;
+                       }
+
+                       if (p[8] != ' ')
+                               dirent.name[k++] = '.';
+                       for (j = 0; j < 3; j++)
+                               dirent.name[k++] = p[j+8];
+                       dirent.name[k] = '\0';
+                       for (k--; k >= 0 && dirent.name[k] == ' '; k--)
+                               dirent.name[k] = '\0';
+
+                       if (vallfn && shortSum != calcShortSum(p)) {
+                               if (!invlfn) {
+                                       invlfn = vallfn;
+                                       invcl = valcl;
+                               }
+                               vallfn = NULL;
+                       }
+                       dirent.head = p[26] | (p[27] << 8);
+                       if (boot->ClustMask == CLUST32_MASK)
+                               dirent.head |= (p[20] << 16) | (p[21] << 24);
+                       dirent.size = p[28] | (p[29] << 8) | (p[30] << 16) | (p[31] << 24);
+                       if (vallfn) {
+                               strcpy(dirent.lname, longName);
+                               longName[0] = '\0';
+                               shortSum = -1;
+                       }
+
+                       dirent.parent = dir;
+                       dirent.next = dir->child;
+
+                       if (invlfn) {
+                               mod |= k = removede(f, boot, fat,
+                                                   invlfn, vallfn ? vallfn : p,
+                                                   invcl, vallfn ? valcl : cl, cl,
+                                                   fullpath(&dirent), 0);
+                               if (mod & FSFATAL)
+                                       return FSFATAL;
+                               if (vallfn
+                                   ? (valcl == cl && vallfn != buffer)
+                                   : p != buffer)
+                                       if (k & FSDIRMOD)
+                                               mod |= THISMOD;
+                       }
+
+                       vallfn = NULL; /* not used any longer */
+                       invlfn = NULL;
+
+                       if (dirent.size == 0 && !(dirent.flags & ATTR_DIRECTORY)) {
+                               if (dirent.head != 0) {
+                                       pwarn("%s has clusters, but size 0\n",
+                                             fullpath(&dirent));
+                                       if (ask(1, "Drop allocated clusters")) {
+                                               p[26] = p[27] = 0;
+                                               if (boot->ClustMask == CLUST32_MASK)
+                                                       p[20] = p[21] = 0;
+                                               clearchain(boot, fat, dirent.head);
+                                               dirent.head = 0;
+                                               mod |= THISMOD|FSDIRMOD|FSFATMOD;
+                                       } else
+                                               mod |= FSERROR;
+                               }
+                       } else if (dirent.head == 0
+                                  && !strcmp(dirent.name, "..")
+                                  && dir->parent                       /* XXX */
+                                  && !dir->parent->parent) {
+                               /*
+                                *  Do nothing, the parent is the root
+                                */
+                       } else if (dirent.head < CLUST_FIRST
+                                  || dirent.head >= boot->NumClusters
+                                  || fat[dirent.head].next == CLUST_FREE
+                                  || (fat[dirent.head].next >= CLUST_RSRVD
+                                      && fat[dirent.head].next < CLUST_EOFS)
+                                  || fat[dirent.head].head != dirent.head) {
+                               if (dirent.head == 0)
+                                       pwarn("%s has no clusters\n",
+                                             fullpath(&dirent));
+                               else if (dirent.head < CLUST_FIRST
+                                        || dirent.head >= boot->NumClusters)
+                                       pwarn("%s starts with cluster out of range(%u)\n",
+                                             fullpath(&dirent),
+                                             dirent.head);
+                               else if (fat[dirent.head].next == CLUST_FREE)
+                                       pwarn("%s starts with free cluster\n",
+                                             fullpath(&dirent));
+                               else if (fat[dirent.head].next >= CLUST_RSRVD)
+                                       pwarn("%s starts with cluster marked %s\n",
+                                             fullpath(&dirent),
+                                             rsrvdcltype(fat[dirent.head].next));
+                               else
+                                       pwarn("%s doesn't start a cluster chain\n",
+                                             fullpath(&dirent));
+                               if (dirent.flags & ATTR_DIRECTORY) {
+                                       if (ask(1, "Remove")) {
+                                               *p = SLOT_DELETED;
+                                               mod |= THISMOD|FSDIRMOD;
+                                       } else
+                                               mod |= FSERROR;
+                                       continue;
+                               } else {
+                                       if (ask(1, "Truncate")) {
+                                               p[28] = p[29] = p[30] = p[31] = 0;
+                                               p[26] = p[27] = 0;
+                                               if (boot->ClustMask == CLUST32_MASK)
+                                                       p[20] = p[21] = 0;
+                                               dirent.size = 0;
+                                               mod |= THISMOD|FSDIRMOD;
+                                       } else
+                                               mod |= FSERROR;
+                               }
+                       }
+
+                       if (dirent.head >= CLUST_FIRST && dirent.head < boot->NumClusters)
+                               fat[dirent.head].flags |= FAT_USED;
+
+                       if (dirent.flags & ATTR_DIRECTORY) {
+                               /*
+                                * gather more info for directories
+                                */
+                               struct dirTodoNode *n;
+
+                               if (dirent.size) {
+                                       pwarn("Directory %s has size != 0\n",
+                                             fullpath(&dirent));
+                                       if (ask(1, "Correct")) {
+                                               p[28] = p[29] = p[30] = p[31] = 0;
+                                               dirent.size = 0;
+                                               mod |= THISMOD|FSDIRMOD;
+                                       } else
+                                               mod |= FSERROR;
+                               }
+                               /*
+                                * handle '.' and '..' specially
+                                */
+                               if (strcmp(dirent.name, ".") == 0) {
+                                       if (dirent.head != dir->head) {
+                                               pwarn("'.' entry in %s has incorrect start cluster\n",
+                                                     fullpath(dir));
+                                               if (ask(1, "Correct")) {
+                                                       dirent.head = dir->head;
+                                                       p[26] = (u_char)dirent.head;
+                                                       p[27] = (u_char)(dirent.head >> 8);
+                                                       if (boot->ClustMask == CLUST32_MASK) {
+                                                               p[20] = (u_char)(dirent.head >> 16);
+                                                               p[21] = (u_char)(dirent.head >> 24);
+                                                       }
+                                                       mod |= THISMOD|FSDIRMOD;
+                                               } else
+                                                       mod |= FSERROR;
+                                       }
+                                       continue;
+                } else if (strcmp(dirent.name, "..") == 0) {
+                                       if (dir->parent) {              /* XXX */
+                                               if (!dir->parent->parent) {
+                                                       if (dirent.head) {
+                                                               pwarn("'..' entry in %s has non-zero start cluster\n",
+                                                                     fullpath(dir));
+                                                               if (ask(1, "Correct")) {
+                                                                       dirent.head = 0;
+                                                                       p[26] = p[27] = 0;
+                                                                       if (boot->ClustMask == CLUST32_MASK)
+                                                                               p[20] = p[21] = 0;
+                                                                       mod |= THISMOD|FSDIRMOD;
+                                                               } else
+                                                                       mod |= FSERROR;
+                                                       }
+                                               } else if (dirent.head != dir->parent->head) {
+                                                       pwarn("'..' entry in %s has incorrect start cluster\n",
+                                                             fullpath(dir));
+                                                       if (ask(1, "Correct")) {
+                                                               dirent.head = dir->parent->head;
+                                                               p[26] = (u_char)dirent.head;
+                                                               p[27] = (u_char)(dirent.head >> 8);
+                                                               if (boot->ClustMask == CLUST32_MASK) {
+                                                                       p[20] = (u_char)(dirent.head >> 16);
+                                                                       p[21] = (u_char)(dirent.head >> 24);
+                                                               }
+                                                               mod |= THISMOD|FSDIRMOD;
+                                                       } else
+                                                               mod |= FSERROR;
+                                               }
+                                       }
+                                       continue;
+                               } else { //only one directory entry can point to dir->head, it's  '.'
+                                       if (dirent.head == dir->head) {
+                                               pwarn("%s entry in %s has incorrect start cluster.remove\n",
+                                                               dirent.name, fullpath(dir));
+                                               //we have to remove this directory entry rigth now rigth here
+                                               if (ask(1, "Remove")) {
+                                                       *p = SLOT_DELETED;
+                                                       mod |= THISMOD|FSDIRMOD;
+                                               } else
+                                                       mod |= FSERROR;
+                                               continue;
+                                       }
+                                       /* Consistency checking. a directory must have at least two entries:
+                                          a dot (.) entry that points to itself, and a dot-dot (..)
+                                          entry that points to its parent.
+                                        */
+                                       if (check_dot_dot(f,boot,fat,&dirent)) {
+                                               //mark directory entry as deleted.
+                                               if (ask(1, "Remove")) {
+                                                       *p = SLOT_DELETED;
+                                                       mod |= THISMOD|FSDIRMOD;
+                                               } else
+                                                       mod |= FSERROR;
+                                               continue;
+                    }
+                               }
+
+                               /* create directory tree node */
+                               if (!(d = newDosDirEntry())) {
+                                       perror("No space for directory");
+                                       return FSFATAL;
+                               }
+                               memcpy(d, &dirent, sizeof(struct dosDirEntry));
+                               /* link it into the tree */
+                               dir->child = d;
+#if 0
+                               printf("%s: %s : 0x%02x:head %d, next 0x%0x parent 0x%0x child 0x%0x\n",
+                                               __func__,d->name,d->flags,d->head,d->next,d->parent,d->child);
+#endif
+                               /* Enter this directory into the todo list */
+                               if (!(n = newDirTodo())) {
+                                       perror("No space for todo list");
+                                       return FSFATAL;
+                               }
+                               n->next = pendingDirectories;
+                               n->dir = d;
+                               pendingDirectories = n;
+                       } else {
+                               mod |= k = checksize(boot, fat, p, &dirent);
+                               if (k & FSDIRMOD)
+                                       mod |= THISMOD;
+                       }
+                       boot->NumFiles++;
+               }
+               if (mod & THISMOD) {
+                       last *= 32;
+                       if (lseek64(f, off, SEEK_SET) != off
+                           || write(f, buffer, last) != last) {
+                               perror("Unable to write directory");
+                               return FSFATAL;
+                       }
+                       mod &= ~THISMOD;
+               }
+       } while ((cl = fat[cl].next) >= CLUST_FIRST && cl < boot->NumClusters);
+       if (invlfn || vallfn)
+               mod |= removede(f, boot, fat,
+                               invlfn ? invlfn : vallfn, p,
+                               invlfn ? invcl : valcl, -1, 0,
+                               fullpath(dir), 1);
+       return mod & ~THISMOD;
+}
+
+int
+handleDirTree(int dosfs, struct bootblock *boot, struct fatEntry *fat)
+{
+       int mod;
+
+       mod = readDosDirSection(dosfs, boot, fat, rootDir);
+       if (mod & FSFATAL)
+               return FSFATAL;
+
+       /*
+        * process the directory todo list
+        */
+       while (pendingDirectories) {
+               struct dosDirEntry *dir = pendingDirectories->dir;
+               struct dirTodoNode *n = pendingDirectories->next;
+
+               /*
+                * remove TODO entry now, the list might change during
+                * directory reads
+                */
+               freeDirTodo(pendingDirectories);
+               pendingDirectories = n;
+
+               /*
+                * handle subdirectory
+                */
+               mod |= readDosDirSection(dosfs, boot, fat, dir);
+               if (mod & FSFATAL)
+                       return FSFATAL;
+       }
+
+       return mod;
+}
+
+/*
+ * Try to reconnect a FAT chain into dir
+ */
+static u_char *lfbuf;
+static cl_t lfcl;
+static loff_t lfoff;
+
+int
+reconnect(int dosfs, struct bootblock *boot, struct fatEntry *fat, cl_t head)
+{
+       struct dosDirEntry d;
+       u_char *p;
+
+       if (!ask(1, "Reconnect"))
+               return FSERROR;
+
+       if (!lostDir) {
+               for (lostDir = rootDir->child; lostDir; lostDir = lostDir->next) {
+                       if (!strcmp(lostDir->name, LOSTDIR))
+                               break;
+               }
+               if (!lostDir) {         /* Create LOSTDIR?              XXX */
+                       pwarn("No %s directory\n", LOSTDIR);
+                       return FSERROR;
+               }
+       }
+       if (!lfbuf) {
+               lfbuf = malloc(boot->ClusterSize);
+               if (!lfbuf) {
+                       perror("No space for buffer");
+                       return FSFATAL;
+               }
+               p = NULL;
+       } else
+               p = lfbuf;
+       while (1) {
+               if (p)
+                       for (; p < lfbuf + boot->ClusterSize; p += 32)
+                               if (*p == SLOT_EMPTY
+                                   || *p == SLOT_DELETED)
+                                       break;
+               if (p && p < lfbuf + boot->ClusterSize)
+                       break;
+               lfcl = p ? fat[lfcl].next : lostDir->head;
+               if (lfcl < CLUST_FIRST || lfcl >= boot->NumClusters) {
+                       /* Extend LOSTDIR?                              XXX */
+                       pwarn("No space in %s\n", LOSTDIR);
+                       lfcl = (lostDir->head < boot->NumClusters) ? lostDir->head : 0;
+                       return FSERROR;
+               }
+               lfoff = lfcl * boot->ClusterSize
+                   + boot->ClusterOffset * boot->BytesPerSec;
+               if (lseek64(dosfs, lfoff, SEEK_SET) != lfoff
+                   || read(dosfs, lfbuf, boot->ClusterSize) != boot->ClusterSize) {
+                       perror("could not read LOST.DIR");
+                       return FSFATAL;
+               }
+               p = lfbuf;
+       }
+
+       boot->NumFiles++;
+       /* Ensure uniqueness of entry here!                             XXX */
+       memset(&d, 0, sizeof d);
+       (void)snprintf(d.name, sizeof(d.name), "%u", head);
+       d.flags = 0;
+       d.head = head;
+       d.size = fat[head].length * boot->ClusterSize;
+
+       memset(p, 0, 32);
+       memset(p, ' ', 11);
+       memcpy(p, d.name, strlen(d.name));
+       p[26] = (u_char)d.head;
+       p[27] = (u_char)(d.head >> 8);
+       if (boot->ClustMask == CLUST32_MASK) {
+               p[20] = (u_char)(d.head >> 16);
+               p[21] = (u_char)(d.head >> 24);
+       }
+       p[28] = (u_char)d.size;
+       p[29] = (u_char)(d.size >> 8);
+       p[30] = (u_char)(d.size >> 16);
+       p[31] = (u_char)(d.size >> 24);
+       fat[head].flags |= FAT_USED;
+       if (lseek64(dosfs, lfoff, SEEK_SET) != lfoff
+           || write(dosfs, lfbuf, boot->ClusterSize) != boot->ClusterSize) {
+               perror("could not write LOST.DIR");
+               return FSFATAL;
+       }
+       return FSDIRMOD;
+}
+
+void
+finishlf(void)
+{
+       if (lfbuf)
+               free(lfbuf);
+       lfbuf = NULL;
+}
diff --git a/src/fsck-msdos/dosfs.h b/src/fsck-msdos/dosfs.h
new file mode 100644 (file)
index 0000000..5420e25
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
+ * Copyright (c) 1995 Martin Husemann
+ * Some structure declaration borrowed from Paul Popelka
+ * (paulp@uts.amdahl.com), see /sys/msdosfs/ for reference.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Martin Husemann
+ *     and Wolfgang Solfrank.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *     $NetBSD: dosfs.h,v 1.4 1997/01/03 14:32:48 ws Exp $
+ * $FreeBSD: src/sbin/fsck_msdosfs/dosfs.h,v 1.3 2003/12/26 17:24:37 trhodes Exp $
+ */
+
+#ifndef DOSFS_H
+#define DOSFS_H
+
+#define DOSBOOTBLOCKSIZE 512
+
+typedef        u_int32_t       cl_t;   /* type holding a cluster number */
+
+/*
+ * architecture independent description of all the info stored in a
+ * FAT boot block.
+ */
+struct bootblock {
+       u_int   BytesPerSec;            /* bytes per sector */
+       u_int   SecPerClust;            /* sectors per cluster */
+       u_int   ResSectors;             /* number of reserved sectors */
+       u_int   FATs;                   /* number of FATs */
+       u_int   RootDirEnts;            /* number of root directory entries */
+       u_int   Media;                  /* media descriptor */
+       u_int   FATsmall;               /* number of sectors per FAT */
+       u_int   SecPerTrack;            /* sectors per track */
+       u_int   Heads;                  /* number of heads */
+       u_int32_t Sectors;              /* total number of sectors */
+       u_int32_t HiddenSecs;           /* # of hidden sectors */
+       u_int32_t HugeSectors;          /* # of sectors if bpbSectors == 0 */
+       u_int   FSInfo;                 /* FSInfo sector */
+       u_int   Backup;                 /* Backup of Bootblocks */
+       cl_t    RootCl;                 /* Start of Root Directory */
+       cl_t    FSFree;                 /* Number of free clusters acc. FSInfo */
+       cl_t    FSNext;                 /* Next free cluster acc. FSInfo */
+
+       /* and some more calculated values */
+       u_int   flags;                  /* some flags: */
+#define        FAT32           1               /* this is a FAT32 file system */
+                                       /*
+                                        * Maybe, we should separate out
+                                        * various parts of FAT32?      XXX
+                                        */
+       int     ValidFat;               /* valid fat if FAT32 non-mirrored */
+       cl_t    ClustMask;              /* mask for entries in FAT */
+       cl_t    NumClusters;            /* # of entries in a FAT */
+       u_int32_t NumSectors;           /* how many sectors are there */
+       u_int32_t FATsecs;              /* how many sectors are in FAT */
+       u_int32_t NumFatEntries;        /* how many entries really are there */
+       u_int   ClusterOffset;          /* at what sector would sector 0 start */
+       u_int   ClusterSize;            /* Cluster size in bytes */
+
+       /* Now some statistics: */
+       u_int   NumFiles;               /* # of plain files */
+       u_int   NumFree;                /* # of free clusters */
+       u_int   NumBad;                 /* # of bad clusters */
+};
+
+struct fatEntry {
+       cl_t    next;                   /* pointer to next cluster */
+       cl_t    head;                   /* pointer to start of chain */
+       u_int32_t length;               /* number of clusters on chain */
+       int     flags;                  /* see below */
+};
+
+#define        CLUST_FREE      0               /* 0 means cluster is free */
+#define        CLUST_FIRST     2               /* 2 is the minimum valid cluster number */
+#define        CLUST_RSRVD     0xfffffff6      /* start of reserved clusters */
+#define        CLUST_BAD       0xfffffff7      /* a cluster with a defect */
+#define        CLUST_EOFS      0xfffffff8      /* start of EOF indicators */
+#define        CLUST_EOF       0xffffffff      /* standard value for last cluster */
+
+/*
+ * Masks for cluster values
+ */
+#define        CLUST12_MASK    0xfff
+#define        CLUST16_MASK    0xffff
+#define        CLUST32_MASK    0xfffffff
+
+#define        FAT_USED        1               /* This fat chain is used in a file */
+
+#define        DOSLONGNAMELEN  256             /* long name maximal length */
+#define LRFIRST                0x40            /* first long name record */
+#define        LRNOMASK        0x1f            /* mask to extract long record
+                                        * sequence number */
+
+/*
+ * Architecture independent description of a directory entry
+ */
+struct dosDirEntry {
+       struct dosDirEntry
+               *parent,                /* previous tree level */
+               *next,                  /* next brother */
+               *child;                 /* if this is a directory */
+       char name[8+1+3+1];             /* alias name first part */
+       char lname[DOSLONGNAMELEN];     /* real name */
+       uint flags;                     /* attributes */
+       cl_t head;                      /* cluster no */
+       u_int32_t size;                 /* filesize in bytes */
+       uint fsckflags;                 /* flags during fsck */
+};
+/* Flags in fsckflags: */
+#define        DIREMPTY        1
+#define        DIREMPWARN      2
+
+/*
+ *  TODO-list of unread directories
+ */
+struct dirTodoNode {
+       struct dosDirEntry *dir;
+       struct dirTodoNode *next;
+};
+
+#endif
diff --git a/src/fsck-msdos/ext.h b/src/fsck-msdos/ext.h
new file mode 100644 (file)
index 0000000..6d183e9
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
+ * Copyright (c) 1995 Martin Husemann
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Martin Husemann
+ *     and Wolfgang Solfrank.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *     $NetBSD: ext.h,v 1.6 2000/04/25 23:02:51 jdolecek Exp $
+ * $FreeBSD: src/sbin/fsck_msdosfs/ext.h,v 1.10.20.1 2009/04/15 03:14:26 kensmith Exp $
+ */
+
+#ifndef EXT_H
+#define EXT_H
+
+#include <sys/types.h>
+
+#include "dosfs.h"
+
+#define        LOSTDIR "LOST.DIR"
+
+/*
+ * Options:
+ */
+extern int alwaysno;   /* assume "no" for all questions */
+extern int alwaysyes;  /* assume "yes" for all questions */
+extern int preen;      /* we are preening */
+extern int rdonly;     /* device is opened read only (supersedes above) */
+extern int skipclean;  /* skip clean file systems if preening */
+
+extern struct dosDirEntry *rootDir;
+
+/*
+ * function declarations
+ */
+int ask(int, const char *, ...);
+
+/*
+ * Check the dirty flag.  If the file system is clean, then return 1.
+ * Otherwise, return 0 (this includes the case of FAT12 file systems --
+ * they have no dirty flag, so they must be assumed to be unclean).
+ */
+int checkdirty(int, struct bootblock *);
+
+/*
+ * Check file system given as arg
+ */
+int checkfilesys(const char *);
+
+/*
+ * Return values of various functions
+ */
+#define        FSOK            0               /* Check was OK */
+#define        FSBOOTMOD       1               /* Boot block was modified */
+#define        FSDIRMOD        2               /* Some directory was modified */
+#define        FSFATMOD        4               /* The FAT was modified */
+#define        FSERROR         8               /* Some unrecovered error remains */
+#define        FSFATAL         16              /* Some unrecoverable error occured */
+#define FSDIRTY                32              /* File system is dirty */
+#define FSFIXFAT       64              /* Fix file system FAT */
+
+/*
+ * read a boot block in a machine independend fashion and translate
+ * it into our struct bootblock.
+ */
+int readboot(int, struct bootblock *);
+
+/*
+ * Correct the FSInfo block.
+ */
+int writefsinfo(int, struct bootblock *);
+
+/*
+ * Read one of the FAT copies and return a pointer to the new
+ * allocated array holding our description of it.
+ */
+int readfat(int, struct bootblock *, int, struct fatEntry **);
+
+/*
+ * Check two FAT copies for consistency and merge changes into the
+ * first if neccessary.
+ */
+int comparefat(struct bootblock *, struct fatEntry *, struct fatEntry *, int);
+
+/*
+ * Check a FAT
+ */
+int checkfat(struct bootblock *, struct fatEntry *);
+
+/*
+ * Write back FAT entries
+ */
+int writefat(int, struct bootblock *, struct fatEntry *, int);
+
+/*
+ * Read a directory
+ */
+int resetDosDirSection(struct bootblock *, struct fatEntry *);
+void finishDosDirSection(void);
+int handleDirTree(int, struct bootblock *, struct fatEntry *);
+
+/*
+ * Cross-check routines run after everything is completely in memory
+ */
+/*
+ * Check for lost cluster chains
+ */
+int checklost(int, struct bootblock *, struct fatEntry *);
+/*
+ * Try to reconnect a lost cluster chain
+ */
+int reconnect(int, struct bootblock *, struct fatEntry *, cl_t);
+void finishlf(void);
+
+/*
+ * Small helper functions
+ */
+/*
+ * Return the type of a reserved cluster as text
+ */
+char *rsrvdcltype(cl_t);
+
+/*
+ * Clear a cluster chain in a FAT
+ */
+void clearchain(struct bootblock *, struct fatEntry *, cl_t);
+
+#endif
diff --git a/src/fsck-msdos/fat.c b/src/fsck-msdos/fat.c
new file mode 100644 (file)
index 0000000..7be04e5
--- /dev/null
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 1995, 1996, 1997 Wolfgang Solfrank
+ * Copyright (c) 1995 Martin Husemann
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Martin Husemann
+ *     and Wolfgang Solfrank.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "ext.h"
+#include "fsutil.h"
+
+static int checkclnum(struct bootblock *, int, cl_t, cl_t *);
+static int clustdiffer(cl_t, cl_t *, cl_t *, int);
+static int tryclear(struct bootblock *, struct fatEntry *, cl_t, cl_t *);
+static int _readfat(int, struct bootblock *, int, u_char **);
+
+/*-
+ * The first 2 FAT entries contain pseudo-cluster numbers with the following
+ * layout:
+ *
+ * 31...... ........ ........ .......0
+ * rrrr1111 11111111 11111111 mmmmmmmm         FAT32 entry 0
+ * rrrrsh11 11111111 11111111 11111xxx         FAT32 entry 1
+ *
+ *                   11111111 mmmmmmmm         FAT16 entry 0
+ *                   sh111111 11111xxx         FAT16 entry 1
+ *
+ * r = reserved
+ * m = BPB media ID byte
+ * s = clean flag (1 = dismounted; 0 = still mounted)
+ * h = hard error flag (1 = ok; 0 = I/O error)
+ * x = any value ok
+ */
+
+int
+checkdirty(int fs, struct bootblock *boot)
+{
+       off_t off;
+       u_char *buffer;
+       int ret = 0;
+
+       if (boot->ClustMask != CLUST16_MASK && boot->ClustMask != CLUST32_MASK)
+               return 0;
+
+       off = boot->ResSectors;
+       off *= boot->BytesPerSec;
+
+       buffer = malloc(boot->BytesPerSec);
+       if (buffer == NULL) {
+               perror("No space for FAT");
+               return 1;
+       }
+
+       if (lseek(fs, off, SEEK_SET) != off) {
+               perror("Unable to read FAT");
+               goto err;
+       }
+
+       if (read(fs, buffer, boot->BytesPerSec) != boot->BytesPerSec) {
+               perror("Unable to read FAT");
+               goto err;
+       }
+
+       /*
+        * If we don't understand the FAT, then the file system must be
+        * assumed to be unclean.
+        */
+       if (buffer[0] != boot->Media || buffer[1] != 0xff)
+               goto err;
+       if (boot->ClustMask == CLUST16_MASK) {
+               if ((buffer[2] & 0xf8) != 0xf8 || (buffer[3] & 0x3f) != 0x3f)
+                       goto err;
+       } else {
+               if (buffer[2] != 0xff || (buffer[3] & 0x0f) != 0x0f
+                   || (buffer[4] & 0xf8) != 0xf8 || buffer[5] != 0xff
+                   || buffer[6] != 0xff || (buffer[7] & 0x03) != 0x03)
+                       goto err;
+       }
+
+       /*
+        * Now check the actual clean flag (and the no-error flag).
+        */
+       if (boot->ClustMask == CLUST16_MASK) {
+               if ((buffer[3] & 0xc0) == 0xc0)
+                       ret = 1;
+       } else {
+               if ((buffer[7] & 0x0c) == 0x0c)
+                       ret = 1;
+       }
+
+err:
+       free(buffer);
+       return ret;
+}
+
+/*
+ * Check a cluster number for valid value
+ */
+static int
+checkclnum(struct bootblock *boot, int fat, cl_t cl, cl_t *next)
+{
+       if (*next >= (CLUST_RSRVD&boot->ClustMask))
+               *next |= ~boot->ClustMask;
+       if (*next == CLUST_FREE) {
+               boot->NumFree++;
+               return FSOK;
+       }
+       if (*next == CLUST_BAD) {
+               boot->NumBad++;
+               return FSOK;
+       }
+       if (*next < CLUST_FIRST
+           || (*next >= boot->NumClusters && *next < CLUST_EOFS)) {
+               pwarn("Cluster %u in FAT %d continues with %s cluster number %u\n",
+                     cl, fat,
+                     *next < CLUST_RSRVD ? "out of range" : "reserved",
+                     *next&boot->ClustMask);
+               if (ask(1, "Truncate")) {
+                       *next = CLUST_EOF;
+                       return FSFATMOD;
+               }
+               return FSERROR;
+       }
+       return FSOK;
+}
+
+/*
+ * Read a FAT from disk. Returns 1 if successful, 0 otherwise.
+ */
+static int
+_readfat(int fs, struct bootblock *boot, int no, u_char **buffer)
+{
+       off_t off;
+
+        printf("Attempting to allocate %u KB for FAT\n",
+                (boot->FATsecs * boot->BytesPerSec) / 1024);
+
+       *buffer = malloc(boot->FATsecs * boot->BytesPerSec);
+       if (*buffer == NULL) {
+               perror("No space for FAT");
+               return 0;
+       }
+
+       off = boot->ResSectors + no * boot->FATsecs;
+       off *= boot->BytesPerSec;
+
+       if (lseek(fs, off, SEEK_SET) != off) {
+               perror("Unable to read FAT");
+               goto err;
+       }
+
+       if (read(fs, *buffer, boot->FATsecs * boot->BytesPerSec)
+           != boot->FATsecs * boot->BytesPerSec) {
+               perror("Unable to read FAT");
+               goto err;
+       }
+
+       return 1;
+
+    err:
+       free(*buffer);
+       return 0;
+}
+
+/*
+ * Read a FAT and decode it into internal format
+ */
+int
+readfat(int fs, struct bootblock *boot, int no, struct fatEntry **fp)
+{
+       struct fatEntry *fat;
+       u_char *buffer, *p;
+       cl_t cl;
+       int ret = FSOK;
+
+       boot->NumFree = boot->NumBad = 0;
+
+       if (!_readfat(fs, boot, no, &buffer))
+               return FSFATAL;
+
+       fat = calloc(boot->NumClusters, sizeof(struct fatEntry));
+       if (fat == NULL) {
+               perror("No space for FAT");
+               free(buffer);
+               return FSFATAL;
+       }
+
+       if (buffer[0] != boot->Media
+           || buffer[1] != 0xff || buffer[2] != 0xff
+           || (boot->ClustMask == CLUST16_MASK && buffer[3] != 0xff)
+           || (boot->ClustMask == CLUST32_MASK
+               && ((buffer[3]&0x0f) != 0x0f
+                   || buffer[4] != 0xff || buffer[5] != 0xff
+                   || buffer[6] != 0xff || (buffer[7]&0x0f) != 0x0f))) {
+
+               /* Windows 95 OSR2 (and possibly any later) changes
+                * the FAT signature to 0xXXffff7f for FAT16 and to
+                * 0xXXffff0fffffff07 for FAT32 upon boot, to know that the
+                * file system is dirty if it doesn't reboot cleanly.
+                * Check this special condition before errorring out.
+                */
+               if (buffer[0] == boot->Media && buffer[1] == 0xff
+                   && buffer[2] == 0xff
+                   && ((boot->ClustMask == CLUST16_MASK && buffer[3] == 0x7f)
+                       || (boot->ClustMask == CLUST32_MASK
+                           && buffer[3] == 0x0f && buffer[4] == 0xff
+                           && buffer[5] == 0xff && buffer[6] == 0xff
+                           && buffer[7] == 0x07)))
+                       ret |= FSDIRTY;
+               else {
+                       /* just some odd byte sequence in FAT */
+
+                       switch (boot->ClustMask) {
+                       case CLUST32_MASK:
+                               pwarn("%s (%02x%02x%02x%02x%02x%02x%02x%02x)\n",
+                                     "FAT starts with odd byte sequence",
+                                     buffer[0], buffer[1], buffer[2], buffer[3],
+                                     buffer[4], buffer[5], buffer[6], buffer[7]);
+                               break;
+                       case CLUST16_MASK:
+                               pwarn("%s (%02x%02x%02x%02x)\n",
+                                   "FAT starts with odd byte sequence",
+                                   buffer[0], buffer[1], buffer[2], buffer[3]);
+                               break;
+                       default:
+                               pwarn("%s (%02x%02x%02x)\n",
+                                   "FAT starts with odd byte sequence",
+                                   buffer[0], buffer[1], buffer[2]);
+                               break;
+                       }
+
+
+                       if (ask(1, "Correct"))
+                               ret |= FSFIXFAT;
+               }
+       }
+       switch (boot->ClustMask) {
+       case CLUST32_MASK:
+               p = buffer + 8;
+               break;
+       case CLUST16_MASK:
+               p = buffer + 4;
+               break;
+       default:
+               p = buffer + 3;
+               break;
+       }
+       for (cl = CLUST_FIRST; cl < boot->NumClusters;) {
+               switch (boot->ClustMask) {
+               case CLUST32_MASK:
+                       fat[cl].next = p[0] + (p[1] << 8)
+                                      + (p[2] << 16) + (p[3] << 24);
+                       fat[cl].next &= boot->ClustMask;
+                       ret |= checkclnum(boot, no, cl, &fat[cl].next);
+                       cl++;
+                       p += 4;
+                       break;
+               case CLUST16_MASK:
+                       fat[cl].next = p[0] + (p[1] << 8);
+                       ret |= checkclnum(boot, no, cl, &fat[cl].next);
+                       cl++;
+                       p += 2;
+                       break;
+               default:
+                       fat[cl].next = (p[0] + (p[1] << 8)) & 0x0fff;
+                       ret |= checkclnum(boot, no, cl, &fat[cl].next);
+                       cl++;
+                       if (cl >= boot->NumClusters)
+                               break;
+                       fat[cl].next = ((p[1] >> 4) + (p[2] << 4)) & 0x0fff;
+                       ret |= checkclnum(boot, no, cl, &fat[cl].next);
+                       cl++;
+                       p += 3;
+                       break;
+               }
+       }
+
+       free(buffer);
+       *fp = fat;
+       return ret;
+}
+
+/*
+ * Get type of reserved cluster
+ */
+char *
+rsrvdcltype(cl_t cl)
+{
+       if (cl == CLUST_FREE)
+               return "free";
+       if (cl < CLUST_BAD)
+               return "reserved";
+       if (cl > CLUST_BAD)
+               return "as EOF";
+       return "bad";
+}
+
+static int
+clustdiffer(cl_t cl, cl_t *cp1, cl_t *cp2, int fatnum)
+{
+       if (*cp1 == CLUST_FREE || *cp1 >= CLUST_RSRVD) {
+               if (*cp2 == CLUST_FREE || *cp2 >= CLUST_RSRVD) {
+                       if ((*cp1 != CLUST_FREE && *cp1 < CLUST_BAD
+                            && *cp2 != CLUST_FREE && *cp2 < CLUST_BAD)
+                           || (*cp1 > CLUST_BAD && *cp2 > CLUST_BAD)) {
+                               pwarn("Cluster %u is marked %s with different indicators\n",
+                                     cl, rsrvdcltype(*cp1));
+                               if (ask(1, "Fix")) {
+                                       *cp2 = *cp1;
+                                       return FSFATMOD;
+                               }
+                               return FSFATAL;
+                       }
+                       pwarn("Cluster %u is marked %s in FAT 0, %s in FAT %d\n",
+                             cl, rsrvdcltype(*cp1), rsrvdcltype(*cp2), fatnum);
+                       if (ask(1, "Use FAT 0's entry")) {
+                               *cp2 = *cp1;
+                               return FSFATMOD;
+                       }
+                       if (ask(1, "Use FAT %d's entry", fatnum)) {
+                               *cp1 = *cp2;
+                               return FSFATMOD;
+                       }
+                       return FSFATAL;
+               }
+               pwarn("Cluster %u is marked %s in FAT 0, but continues with cluster %u in FAT %d\n",
+                     cl, rsrvdcltype(*cp1), *cp2, fatnum);
+               if (ask(1, "Use continuation from FAT %d", fatnum)) {
+                       *cp1 = *cp2;
+                       return FSFATMOD;
+               }
+               if (ask(1, "Use mark from FAT 0")) {
+                       *cp2 = *cp1;
+                       return FSFATMOD;
+               }
+               return FSFATAL;
+       }
+       if (*cp2 == CLUST_FREE || *cp2 >= CLUST_RSRVD) {
+               pwarn("Cluster %u continues with cluster %u in FAT 0, but is marked %s in FAT %d\n",
+                     cl, *cp1, rsrvdcltype(*cp2), fatnum);
+               if (ask(1, "Use continuation from FAT 0")) {
+                       *cp2 = *cp1;
+                       return FSFATMOD;
+               }
+               if (ask(1, "Use mark from FAT %d", fatnum)) {
+                       *cp1 = *cp2;
+                       return FSFATMOD;
+               }
+               return FSERROR;
+       }
+       pwarn("Cluster %u continues with cluster %u in FAT 0, but with cluster %u in FAT %d\n",
+             cl, *cp1, *cp2, fatnum);
+       if (ask(1, "Use continuation from FAT 0")) {
+               *cp2 = *cp1;
+               return FSFATMOD;
+       }
+       if (ask(1, "Use continuation from FAT %d", fatnum)) {
+               *cp1 = *cp2;
+               return FSFATMOD;
+       }
+       return FSERROR;
+}
+
+/*
+ * Compare two FAT copies in memory. Resolve any conflicts and merge them
+ * into the first one.
+ */
+int
+comparefat(struct bootblock *boot, struct fatEntry *first,
+    struct fatEntry *second, int fatnum)
+{
+       cl_t cl;
+       int ret = FSOK;
+
+       for (cl = CLUST_FIRST; cl < boot->NumClusters; cl++)
+               if (first[cl].next != second[cl].next)
+                       ret |= clustdiffer(cl, &first[cl].next, &second[cl].next, fatnum);
+       return ret;
+}
+
+void
+clearchain(struct bootblock *boot, struct fatEntry *fat, cl_t head)
+{
+       cl_t p, q;
+
+       for (p = head; p >= CLUST_FIRST && p < boot->NumClusters; p = q) {
+               if (fat[p].head != head)
+                       break;
+               q = fat[p].next;
+               fat[p].next = fat[p].head = CLUST_FREE;
+               fat[p].length = 0;
+       }
+}
+
+int
+tryclear(struct bootblock *boot, struct fatEntry *fat, cl_t head, cl_t *trunc)
+{
+       if (ask(1, "Clear chain starting at %u", head)) {
+               clearchain(boot, fat, head);
+               return FSFATMOD;
+       } else if (ask(1, "Truncate")) {
+               *trunc = CLUST_EOF;
+               return FSFATMOD;
+       } else
+               return FSERROR;
+}
+
+/*
+ * Check a complete FAT in-memory for crosslinks
+ */
+int
+checkfat(struct bootblock *boot, struct fatEntry *fat)
+{
+       cl_t head, p, h, n, wdk;
+       u_int len;
+       int ret = 0;
+       int conf;
+
+       /*
+        * pass 1: figure out the cluster chains.
+        */
+       for (head = CLUST_FIRST; head < boot->NumClusters; head++) {
+               /* find next untravelled chain */
+               if (fat[head].head != 0         /* cluster already belongs to some chain */
+                   || fat[head].next == CLUST_FREE
+                   || fat[head].next == CLUST_BAD)
+                       continue;               /* skip it. */
+
+               /* follow the chain and mark all clusters on the way */
+               for (len = 0, p = head;
+                        p >= CLUST_FIRST && p < boot->NumClusters;
+                        p = fat[p].next) {
+                               /* we have to check the len, to avoid infinite loop */
+                               if (len > boot->NumClusters) {
+                                       printf("detect cluster chain loop: head %u for p %u\n", head, p);
+                                       break;
+                       }
+
+                       fat[p].head = head;
+                       len++;
+               }
+
+               /* the head record gets the length */
+               fat[head].length = fat[head].next == CLUST_FREE ? 0 : len;
+       }
+
+       /*
+        * pass 2: check for crosslinked chains (we couldn't do this in pass 1 because
+        * we didn't know the real start of the chain then - would have treated partial
+        * chains as interlinked with their main chain)
+        */
+       for (head = CLUST_FIRST; head < boot->NumClusters; head++) {
+               /* find next untravelled chain */
+               if (fat[head].head != head)
+                       continue;
+
+               /* follow the chain to its end (hopefully) */
+               /* also possible infinite loop, that's why I insert wdk counter */
+               for (p = head,wdk=boot->NumClusters;
+                    (n = fat[p].next) >= CLUST_FIRST && n < boot->NumClusters && wdk;
+                                p = n,wdk--) {
+                       if (fat[n].head != head)
+                               break;
+               }
+
+               if (n >= CLUST_EOFS)
+                       continue;
+
+               if (n == CLUST_FREE || n >= CLUST_RSRVD) {
+                       pwarn("Cluster chain starting at %u ends with cluster marked %s\n",
+                             head, rsrvdcltype(n));
+                       ret |= tryclear(boot, fat, head, &fat[p].next);
+                       continue;
+               }
+               if (n < CLUST_FIRST || n >= boot->NumClusters) {
+                       pwarn("Cluster chain starting at %u ends with cluster out of range (%u)\n",
+                             head, n);
+                       ret |= tryclear(boot, fat, head, &fat[p].next);
+                       continue;
+               }
+               pwarn("Cluster chains starting at %u and %u are linked at cluster %u\n",
+                     head, fat[n].head, n);
+               conf = tryclear(boot, fat, head, &fat[p].next);
+               if (ask(1, "Clear chain starting at %u", h = fat[n].head)) {
+                       if (conf == FSERROR) {
+                               /*
+                                * Transfer the common chain to the one not cleared above.
+                                */
+                               for (p = n;
+                                    p >= CLUST_FIRST && p < boot->NumClusters;
+                                    p = fat[p].next) {
+                                       if (h != fat[p].head) {
+                                               /*
+                                                * Have to reexamine this chain.
+                                                */
+                                               head--;
+                                               break;
+                                       }
+                                       fat[p].head = head;
+                               }
+                       }
+                       clearchain(boot, fat, h);
+                       conf |= FSFATMOD;
+               }
+               ret |= conf;
+       }
+
+       return ret;
+}
+
+/*
+ * Write out FATs encoding them from the internal format
+ */
+int
+writefat(int fs, struct bootblock *boot, struct fatEntry *fat, int correct_fat)
+{
+       u_char *buffer, *p;
+       cl_t cl;
+       int i;
+       u_int32_t fatsz;
+       off_t off;
+       int ret = FSOK;
+
+       buffer = malloc(fatsz = boot->FATsecs * boot->BytesPerSec);
+       if (buffer == NULL) {
+               perror("No space for FAT");
+               return FSFATAL;
+       }
+       memset(buffer, 0, fatsz);
+       boot->NumFree = 0;
+       p = buffer;
+       if (correct_fat) {
+               *p++ = (u_char)boot->Media;
+               *p++ = 0xff;
+               *p++ = 0xff;
+               switch (boot->ClustMask) {
+               case CLUST16_MASK:
+                       *p++ = 0xff;
+                       break;
+               case CLUST32_MASK:
+                       *p++ = 0x0f;
+                       *p++ = 0xff;
+                       *p++ = 0xff;
+                       *p++ = 0xff;
+                       *p++ = 0x0f;
+                       break;
+               }
+       } else {
+               /* use same FAT signature as the old FAT has */
+               int count;
+               u_char *old_fat;
+
+               switch (boot->ClustMask) {
+               case CLUST32_MASK:
+                       count = 8;
+                       break;
+               case CLUST16_MASK:
+                       count = 4;
+                       break;
+               default:
+                       count = 3;
+                       break;
+               }
+
+               if (!_readfat(fs, boot, boot->ValidFat >= 0 ? boot->ValidFat :0,
+                                        &old_fat)) {
+                       free(buffer);
+                       return FSFATAL;
+               }
+
+               memcpy(p, old_fat, count);
+               free(old_fat);
+               p += count;
+       }
+
+       for (cl = CLUST_FIRST; cl < boot->NumClusters; cl++) {
+               switch (boot->ClustMask) {
+               case CLUST32_MASK:
+                       if (fat[cl].next == CLUST_FREE)
+                               boot->NumFree++;
+                       *p++ = (u_char)fat[cl].next;
+                       *p++ = (u_char)(fat[cl].next >> 8);
+                       *p++ = (u_char)(fat[cl].next >> 16);
+                       *p &= 0xf0;
+                       *p++ |= (fat[cl].next >> 24)&0x0f;
+                       break;
+               case CLUST16_MASK:
+                       if (fat[cl].next == CLUST_FREE)
+                               boot->NumFree++;
+                       *p++ = (u_char)fat[cl].next;
+                       *p++ = (u_char)(fat[cl].next >> 8);
+                       break;
+               default:
+                       if (fat[cl].next == CLUST_FREE)
+                               boot->NumFree++;
+                       if (cl + 1 < boot->NumClusters
+                           && fat[cl + 1].next == CLUST_FREE)
+                               boot->NumFree++;
+                       *p++ = (u_char)fat[cl].next;
+                       *p++ = (u_char)((fat[cl].next >> 8) & 0xf)
+                              |(u_char)(fat[cl+1].next << 4);
+                       *p++ = (u_char)(fat[++cl].next >> 4);
+                       break;
+               }
+       }
+       for (i = 0; i < boot->FATs; i++) {
+               off = boot->ResSectors + i * boot->FATsecs;
+               off *= boot->BytesPerSec;
+               if (lseek(fs, off, SEEK_SET) != off
+                   || write(fs, buffer, fatsz) != fatsz) {
+                       perror("Unable to write FAT");
+                       ret = FSFATAL; /* Return immediately?           XXX */
+               }
+       }
+       free(buffer);
+       return ret;
+}
+
+/*
+ * Check a complete in-memory FAT for lost cluster chains
+ */
+int
+checklost(int dosfs, struct bootblock *boot, struct fatEntry *fat)
+{
+       cl_t head;
+       int mod = FSOK;
+       int ret;
+
+       for (head = CLUST_FIRST; head < boot->NumClusters; head++) {
+               /* find next untravelled chain */
+               if (fat[head].head != head
+                   || fat[head].next == CLUST_FREE
+                   || (fat[head].next >= CLUST_RSRVD
+                       && fat[head].next < CLUST_EOFS)
+                   || (fat[head].flags & FAT_USED))
+                       continue;
+
+               pwarn("Lost cluster chain at cluster %u\n%d Cluster(s) lost\n",
+                     head, fat[head].length);
+               mod |= ret = reconnect(dosfs, boot, fat, head);
+               if (mod & FSFATAL) {
+                       /* If the reconnect failed, then just clear the chain */
+                       pwarn("Error reconnecting chain - clearing\n");
+                       mod &= ~FSFATAL;
+                       clearchain(boot, fat, head);
+                       mod |= FSFATMOD;
+                       continue;
+               }
+               if (ret == FSERROR && ask(1, "Clear")) {
+                       clearchain(boot, fat, head);
+                       mod |= FSFATMOD;
+               }
+       }
+       finishlf();
+
+       if (boot->FSInfo) {
+               ret = 0;
+               if (boot->FSFree != boot->NumFree) {
+                       pwarn("Free space in FSInfo block (%d) not correct (%d)\n",
+                             boot->FSFree, boot->NumFree);
+                       if (ask(1, "Fix")) {
+                               boot->FSFree = boot->NumFree;
+                               ret = 1;
+                       }
+               }
+
+               if (boot->NumFree) {
+                       if ((boot->FSNext >= boot->NumClusters) || (fat[boot->FSNext].next != CLUST_FREE)) {
+                               pwarn("Next free cluster in FSInfo block (%u) not free\n",
+                                     boot->FSNext);
+                               if (ask(1, "Fix"))
+                                       for (head = CLUST_FIRST; head < boot->NumClusters; head++)
+                                               if (fat[head].next == CLUST_FREE) {
+                                                       boot->FSNext = head;
+                                                       ret = 1;
+                                                       break;
+                                               }
+                       }
+        }
+
+               if (boot->FSNext > boot->NumClusters  ) {
+                       pwarn("FSNext block (%d) not correct NumClusters (%d)\n",
+                                       boot->FSNext, boot->NumClusters);
+                       boot->FSNext=CLUST_FIRST; // boot->FSNext can have -1 value.
+           }
+
+               if (boot->NumFree && fat[boot->FSNext].next != CLUST_FREE) {
+                       pwarn("Next free cluster in FSInfo block (%u) not free\n",
+                                       boot->FSNext);
+                       if (ask(1, "Fix"))
+                               for (head = CLUST_FIRST; head < boot->NumClusters; head++)
+                                       if (fat[head].next == CLUST_FREE) {
+                                               boot->FSNext = head;
+                                               ret = 1;
+                                               break;
+                                       }
+           }
+
+               if (ret)
+                       mod |= writefsinfo(dosfs, boot);
+       }
+
+       return mod;
+}
diff --git a/src/fsck-msdos/fsutil.h b/src/fsck-msdos/fsutil.h
new file mode 100644 (file)
index 0000000..7acfdd6
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _FS_UTIL_H
+#define _FS_UTIL_H
+
+#define pwarn printf
+#define pfatal printf
+
+#endif
diff --git a/src/fsck-msdos/main.c b/src/fsck-msdos/main.c
new file mode 100644 (file)
index 0000000..9539d8f
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 1995 Wolfgang Solfrank
+ * Copyright (c) 1995 Martin Husemann
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Martin Husemann
+ *     and Wolfgang Solfrank.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdarg.h>
+
+#include "fsutil.h"
+#include "ext.h"
+
+int alwaysno;          /* assume "no" for all questions */
+int alwaysyes;         /* assume "yes" for all questions */
+int preen;             /* set when preening */
+int rdonly;            /* device is opened read only (supersedes above) */
+int skipclean;         /* skip clean file systems if preening */
+
+static void usage(void);
+
+static void
+usage(void)
+{
+
+       fprintf(stderr, "%s\n%s\n",
+           "usage: fsck_msdosfs -p [-f] filesystem ...",
+           "       fsck_msdosfs [-ny] filesystem ...");
+       exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+       int ret = 0, erg;
+       int ch;
+
+       skipclean = 1;
+       while ((ch = getopt(argc, argv, "CfFnpy")) != -1) {
+               switch (ch) {
+               case 'C': /* for fsck_ffs compatibility */
+                       break;
+               case 'f':
+                       skipclean = 0;
+                       break;
+               case 'F':
+                       /*
+                        * We can never run in the background.  We must exit
+                        * silently with a nonzero exit code so that fsck(8)
+                        * can probe our support for -F.  The exit code
+                        * doesn't really matter, but we use an unusual one
+                        * in case someone tries -F directly.  The -F flag
+                        * is intentionally left out of the usage message.
+                        */
+                       exit(5);
+               case 'n':
+                       alwaysno = 1;
+                       alwaysyes = preen = 0;
+                       break;
+               case 'y':
+                       alwaysyes = 1;
+                       alwaysno = preen = 0;
+                       break;
+
+               case 'p':
+                       preen = 1;
+                       alwaysyes = alwaysno = 0;
+                       break;
+
+               default:
+                       usage();
+                       break;
+               }
+       }
+       argc -= optind;
+       argv += optind;
+
+       if (!argc)
+               usage();
+
+       while (--argc >= 0) {
+//             setcdevname(*argv, preen);
+               erg = checkfilesys(*argv++);
+               if (erg > ret)
+                       ret = erg;
+       }
+
+       return ret;
+}
+
+
+/*VARARGS*/
+int
+ask(int def, const char *fmt, ...)
+{
+       va_list ap;
+
+       char prompt[256];
+       int c;
+
+       if (preen) {
+               if (rdonly)
+                       def = 0;
+               if (def)
+                       printf("FIXED\n");
+               return def;
+       }
+
+       va_start(ap, fmt);
+       vsnprintf(prompt, sizeof(prompt), fmt, ap);
+       if (alwaysyes || rdonly) {
+               printf("%s? %s\n", prompt, rdonly ? "no" : "yes");
+               return !rdonly;
+       }
+       do {
+               printf("%s? [yn] ", prompt);
+               fflush(stdout);
+               c = getchar();
+               while (c != '\n' && getchar() != '\n')
+                       if (feof(stdin))
+                               return 0;
+       } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
+       return c == 'y' || c == 'Y';
+}
diff --git a/src/gpio/buzzer.c b/src/gpio/buzzer.c
new file mode 100644 (file)
index 0000000..27e5777
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <limits.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/log.h"
+#include "gpio.h"
+
+#define GPIO_CHECK_PATH                "/sys/class/gpio/buzzer"
+#define GPIO_CHECK_STATUS      "/sys/class/gpio/buzzer/status"
+
+static int buzzer_init(void)
+{
+       static int type = GPIO_DEVICE_UNKNOWN;
+       int fd;
+
+       if (type != GPIO_DEVICE_UNKNOWN)
+               goto out;
+
+       fd = open(GPIO_CHECK_PATH, O_RDONLY);
+       if (fd == -1) {
+               _E("%s open error: %s", GPIO_CHECK_PATH, strerror(errno));
+               type = GPIO_DEVICE_NOT_EXIST;
+               goto out;
+       }
+       close(fd);
+       type = GPIO_DEVICE_EXIST;
+out:
+       return type;
+}
+
+static int buzzer_status(void)
+{
+       static int type = GPIO_DEVICE_UNKNOWN;
+       int val = GPIO_DEVICE_UNKNOWN;
+       int ret;
+       int fd;
+       char buf[2];
+
+       type = buzzer_init();
+       if (type != GPIO_DEVICE_EXIST)
+               goto out;
+
+       fd = open(GPIO_CHECK_STATUS, O_RDONLY);
+       if (fd == -1) {
+               _E("%s open error: %s", GPIO_CHECK_STATUS, strerror(errno));
+               goto out;
+       }
+
+       ret = read(fd, buf, 1);
+       close(fd);
+       if (ret != 1) {
+               _E("fail to get status %d", ret);
+               goto out;
+       }
+       buf[1] = '\0';
+       val = atoi(buf);
+       _I("device is (%d)", val);
+out:
+       return val;
+}
+
+static const struct gpio_device buzzer_gpio = {
+       .type   = GPIO_DEVICE_BUZZER,
+       .name   = "buzzer",
+       .init   = buzzer_init,
+       .status = buzzer_status,
+};
+
+static void __CONSTRUCTOR__ module_init(void)
+{
+       register_gpio_device(&buzzer_gpio);
+}
diff --git a/src/gpio/gpio.c b/src/gpio/gpio.c
new file mode 100644 (file)
index 0000000..eea1751
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdbool.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/list.h"
+#include "gpio.h"
+
+static dd_list *gpio_head;
+
+static const struct gpio_device default_gpio = {
+       .name = "default-gpio",
+};
+
+void register_gpio_device(const struct gpio_device *gpio)
+{
+       DD_LIST_APPEND(gpio_head, (void*)gpio);
+}
+
+void unregister_gpio_device(const struct gpio_device *gpio)
+{
+       DD_LIST_REMOVE(gpio_head, (void*)gpio);
+}
+
+int check_default_gpio_device(const struct gpio_device *gpio)
+{
+       return (gpio == &default_gpio);
+}
+
+const struct gpio_device *find_gpio_device(const char *name)
+{
+       dd_list *elem;
+       const struct gpio_device *gpio;
+
+       DD_LIST_FOREACH(gpio_head, elem, gpio) {
+               if (!strcmp(gpio->name, name))
+                       return gpio;
+       }
+
+       gpio = &default_gpio;
+       return gpio;
+}
+
+static DBusMessage *check_gpio_status(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       const struct gpio_device *gpio;
+       char *name;
+       int ret;
+       int status = GPIO_DEVICE_UNKNOWN;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               status = -EBADMSG;
+               goto out;
+       }
+
+       gpio = find_gpio_device(name);
+       if (check_default_gpio_device(gpio))
+               goto out;
+       status = gpio->status();
+               _D("%s %d", name, status);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &status);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "GetStatus",          "s", "i", check_gpio_status },
+};
+
+static void gpio_init(void *data)
+{
+       struct gpio_device *gpio;
+       dd_list *elem;
+       int ret;
+
+       DD_LIST_FOREACH(gpio_head, elem, gpio) {
+               gpio->init();
+               gpio->status();
+       }
+
+       ret = register_edbus_method(DEVICED_PATH_GPIO, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+const struct device_ops gpio_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "gpio",
+       .init     = gpio_init,
+};
+
+DEVICE_OPS_REGISTER(&gpio_device_ops)
diff --git a/src/gpio/gpio.h b/src/gpio/gpio.h
new file mode 100644 (file)
index 0000000..0dbe628
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __GPIO_HANDLER_H__
+#define __GPIO_HANDLER_H__
+
+#include <errno.h>
+#include "core/common.h"
+
+#define GPIO_DEVICE_CLOSED     0
+#define GPIO_DEVICE_OPENED     1
+
+enum gpio_device_check_type {
+       GPIO_DEVICE_UNKNOWN = -1,
+       GPIO_DEVICE_NOT_EXIST = 0,
+       GPIO_DEVICE_EXIST = 1,
+};
+enum gpio_device_type {
+       GPIO_DEVICE_HALL = 0,
+       GPIO_DEVICE_BUZZER,
+       GPIO_DEVICE_SIM,
+};
+
+struct gpio_device {
+       enum gpio_device_type type;
+       const char *name;
+       int (*init) (void);
+       int (*status) (void);
+};
+
+void register_gpio_device(const struct gpio_device *gpio);
+void unregister_gpio_device(const struct gpio_device *gpio);
+const struct gpio_device *find_gpio_device(const char *name);
+int check_default_gpio_device(const struct gpio_device *dev);
+
+#define NOT_SUPPORT_GPIO(gpio) \
+       ((check_default_gpio_device(gpio))? 1 : 0)
+
+#define FIND_GPIO_INT(gpio, name) do { \
+       if (!gpio) gpio = find_gpio_device(name); if(check_default_gpio_device(gpio)) return -ENODEV; \
+} while(0)
+
+#define FIND_GPIO_VOID(gpio, name) do { \
+       if (!gpio) gpio = find_gpio_device(name); if(check_default_gpio_device(gpio)) return; \
+} while(0)
+
+
+#endif /* __GPIO_HANDLER_H__ */
diff --git a/src/gpio/hall.c b/src/gpio/hall.c
new file mode 100644 (file)
index 0000000..5f9f26d
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <limits.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/log.h"
+#include "gpio.h"
+
+#define GPIO_CHECK_PATH                "/sys/class/flip/hall_ic"
+#define GPIO_CHECK_STATUS      "/sys/class/flip/hall_ic/cover_status"
+
+static int hall_init(void)
+{
+       static int type = GPIO_DEVICE_UNKNOWN;
+       int fd;
+
+       if (type != GPIO_DEVICE_UNKNOWN)
+               goto out;
+
+       fd = open(GPIO_CHECK_PATH, O_RDONLY);
+       if (fd == -1) {
+               _E("%s open error: %s", GPIO_CHECK_PATH, strerror(errno));
+               type = GPIO_DEVICE_NOT_EXIST;
+               goto out;
+       }
+       close(fd);
+       type = GPIO_DEVICE_EXIST;
+out:
+       return type;
+}
+
+static int hall_status(void)
+{
+       static int type = GPIO_DEVICE_UNKNOWN;
+       int val = GPIO_DEVICE_UNKNOWN;
+       int ret;
+       int fd;
+       char buf[2];
+
+       type = hall_init();
+       if (type != GPIO_DEVICE_EXIST)
+               goto out;
+
+       fd = open(GPIO_CHECK_STATUS, O_RDONLY);
+       if (fd == -1) {
+               _E("%s open error: %s", GPIO_CHECK_STATUS, strerror(errno));
+               goto out;
+       }
+
+       ret = read(fd, buf, 1);
+       close(fd);
+       if (ret != 1) {
+               _E("fail to get status %d", ret);
+               goto out;
+       }
+       buf[1] = '\0';
+       val = atoi(buf);
+       _I("device is (%d)", val);
+out:
+       return val;
+}
+
+static const struct gpio_device hall_gpio = {
+       .type   = GPIO_DEVICE_HALL,
+       .name   = "hall",
+       .init   = hall_init,
+       .status = hall_status,
+};
+
+static void __CONSTRUCTOR__ module_init(void)
+{
+       register_gpio_device(&hall_gpio);
+}
diff --git a/src/gpio/sim.c b/src/gpio/sim.c
new file mode 100644 (file)
index 0000000..69f0ee5
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <limits.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/log.h"
+#include "gpio.h"
+
+#define GPIO_CHECK_PATH                "/sys/class/gpio/sim"
+#define GPIO_CHECK_STATUS      "/sys/class/gpio/sim/status"
+
+static int sim_init(void)
+{
+       static int type = GPIO_DEVICE_UNKNOWN;
+       int fd;
+
+       if (type != GPIO_DEVICE_UNKNOWN)
+               goto out;
+
+       fd = open(GPIO_CHECK_PATH, O_RDONLY);
+       if (fd == -1) {
+               _E("%s open error: %s", GPIO_CHECK_PATH, strerror(errno));
+               type = GPIO_DEVICE_NOT_EXIST;
+               goto out;
+       }
+       close(fd);
+       type = GPIO_DEVICE_EXIST;
+out:
+       return type;
+}
+
+static int sim_status(void)
+{
+       static int type = GPIO_DEVICE_UNKNOWN;
+       int val = GPIO_DEVICE_UNKNOWN;
+       int ret;
+       int fd;
+       char buf[2];
+
+       type = sim_init();
+       if (type != GPIO_DEVICE_EXIST)
+               goto out;
+
+       fd = open(GPIO_CHECK_STATUS, O_RDONLY);
+       if (fd == -1) {
+               _E("%s open error: %s", GPIO_CHECK_STATUS, strerror(errno));
+               goto out;
+       }
+
+       ret = read(fd, buf, 1);
+       close(fd);
+       if (ret != 1) {
+               _E("fail to get status %d", ret);
+               goto out;
+       }
+       buf[1] = '\0';
+       val = atoi(buf);
+       _I("device is (%d)", val);
+out:
+       return val;
+}
+
+static const struct gpio_device sim_gpio = {
+       .type   = GPIO_DEVICE_SIM,
+       .name   = "sim",
+       .init   = sim_init,
+       .status = sim_status,
+};
+
+static void __CONSTRUCTOR__ module_init(void)
+{
+       register_gpio_device(&sim_gpio);
+}
index ef83327..67533c6 100644 (file)
@@ -31,7 +31,6 @@
 #include <Ecore.h>
 
 #include "core/log.h"
-#include "core/data.h"
 #include "core/common.h"
 #include "core/devices.h"
 #include "core/device-notifier.h"
 #include "hall-handler.h"
 
 #define SIGNAL_HALL_STATE      "ChangeState"
+#define HALL_PMQOS_TIME                1000 //ms
+enum hall_ic_init_type{
+       HALL_IC_NOT_READY = 0,
+       HALL_IC_INITIALIZED = 1,
+};
 
 static int hall_ic_status = HALL_IC_OPENED;
+static int hall_ic_initialized = HALL_IC_NOT_READY;
 
 static int hall_ic_get_status(void)
 {
+       int ret;
+       int val = HALL_IC_OPENED;
+
+       if (hall_ic_initialized == HALL_IC_INITIALIZED)
+               return hall_ic_status;
+
+       ret = device_get_property(DEVICE_TYPE_HALL, PROP_HALL_STATUS, &val);
+       if (ret == 0 && (val == HALL_IC_OPENED || val == HALL_IC_CLOSED))
+               hall_ic_status = val;
+
        return hall_ic_status;
 }
 
-static void hall_ic_chgdet_cb(struct main_data *ad)
+static void hall_ic_chgdet_cb(void)
 {
        int val = -1;
        int fd, r, ret;
@@ -69,7 +84,13 @@ static void hall_ic_chgdet_cb(struct main_data *ad)
 
        buf[1] = '\0';
 
-       hall_ic_status = atoi(buf);
+       hall_ic_initialized = HALL_IC_INITIALIZED;
+
+       val = atoi(buf);
+       if (val != HALL_IC_OPENED && val != HALL_IC_CLOSED)
+               val = HALL_IC_OPENED;
+       hall_ic_status = val;
+
        _I("cover is opened(%d)", hall_ic_status);
 
        device_notify(DEVICE_NOTIFIER_HALLIC_OPEN, (void *)hall_ic_status);
@@ -94,17 +115,6 @@ static void hall_ic_chgdet_cb(struct main_data *ad)
 
 }
 
-static int hall_action(int argc, char **argv)
-{
-       int i;
-       int pid;
-       int prop;
-
-       if (strncmp(argv[0], HALL_IC_NAME, strlen(HALL_IC_NAME)) == 0)
-               hall_ic_chgdet_cb(NULL);
-       return 0;
-}
-
 static void hall_edbus_signal_handler(void *data, DBusMessage *msg)
 {
        _D("hall_edbus_signal_handler occurs!!!");
@@ -114,17 +124,13 @@ static DBusMessage *edbus_getstatus_cb(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
        DBusMessage *reply;
-       int val, ret;
-
-       ret = device_get_property(DEVICE_TYPE_HALL, PROP_HALL_STATUS, &val);
-       if (ret >= 0)
-               ret = val;
-
-       _D("get hall status %d, %d", val, ret);
+       int val;
 
+       val = hall_ic_get_status();
+       _D("get hall status %d", val);
        reply = dbus_message_new_method_return(msg);
        dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &val);
        return reply;
 }
 
@@ -142,21 +148,26 @@ static void hall_ic_init(void *data)
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
 
-       register_action(PREDEF_HALL_IC, hall_action, NULL, NULL);
-
        register_edbus_signal_handler(DEVICED_PATH_HALL, DEVICED_INTERFACE_HALL,
                        SIGNAL_HALL_STATE,
                        hall_edbus_signal_handler);
+       val = hall_ic_get_status();
+       _D("get hall status %d", val);
+}
 
-       if (device_get_property(DEVICE_TYPE_HALL, PROP_HALL_STATUS, &val) >= 0)
-               hall_ic_status = val;
+static int hall_ic_execute(void *data)
+{
+       device_notify(DEVICE_NOTIFIER_PMQOS_HALL, (void*)HALL_PMQOS_TIME);
+       hall_ic_chgdet_cb();
+       return 0;
 }
 
 static const struct device_ops hall_device_ops = {
-       .priority       = DEVICE_PRIORITY_NORMAL,
-       .name           = HALL_IC_NAME,
-       .init           = hall_ic_init,
-       .status         = hall_ic_get_status,
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = HALL_IC_NAME,
+       .init     = hall_ic_init,
+       .status   = hall_ic_get_status,
+       .execute  = hall_ic_execute,
 };
 
 DEVICE_OPS_REGISTER(&hall_device_ops)
index 75760b3..058ec72 100644 (file)
@@ -28,6 +28,4 @@
 #define HALL_IC_PATH "/devices/virtual/"HALL_IC_SUBSYSTEM"/"HALL_IC_NAME
 #define HALL_IC_STATUS "/sys/class/"HALL_IC_SUBSYSTEM"/"HALL_IC_NAME"/cover_status"
 
-#define PREDEF_HALL_IC HALL_IC_NAME
-
 #endif //__HALL_HANDLER_H__
diff --git a/src/haptic/HW_touch_30ms_sharp.ivt b/src/haptic/HW_touch_30ms_sharp.ivt
deleted file mode 100755 (executable)
index 97c7978..0000000
Binary files a/src/haptic/HW_touch_30ms_sharp.ivt and /dev/null differ
diff --git a/src/haptic/README.standard b/src/haptic/README.standard
new file mode 100644 (file)
index 0000000..52cf000
--- /dev/null
@@ -0,0 +1,13 @@
+Standard Force Feedback Information
+
+1. Max effect id is 16.
+   It depends on force feedback driver.
+
+2. Do not increase effect id in case of repeated requests before previous effect finishs.
+   Standard Force Feedback does not reset the effect id on ff_set_effect function.
+   If the effect id is reseted as -1,
+   effect id will be increased until removing the effect from device by ioctl(EVIOCRMFF).
+   In this case Standard Force Feedback can not remove the previous effect id.
+
+3. Do not support to mix each effect.
+   If the request is occurred on the same time, it plays effect as per the last request.
index f0be7f7..46dfe5d 100644 (file)
@@ -90,6 +90,7 @@ static void release(void)
 }
 
 static const struct haptic_ops ext_ops = {
+       .type     = HAPTIC_EXTERNAL,
        .is_valid = is_valid,
        .load     = load,
        .release  = release,
diff --git a/src/haptic/haptic-micro.conf b/src/haptic/haptic-micro.conf
new file mode 100644 (file)
index 0000000..464c6b4
--- /dev/null
@@ -0,0 +1,15 @@
+[Haptic]
+# level
+#   how much does the vibration level to subdivide.
+#   The max value of vibration level fixed at 100.
+#   The min value of vibration level fixed at 0.
+level=3
+
+[level0]
+value=0
+
+[level1]
+value=80
+
+[level2]
+value=100
diff --git a/src/haptic/haptic-mobile.conf b/src/haptic/haptic-mobile.conf
new file mode 100644 (file)
index 0000000..84271f1
--- /dev/null
@@ -0,0 +1,24 @@
+[Haptic]
+# level
+#   how much does the vibration level to subdivide.
+#   The max value of vibration level fixed at 100.
+#   The min value of vibration level fixed at 0.
+level=6
+
+[level0]
+value=0
+
+[level1]
+value=20
+
+[level2]
+value=40
+
+[level3]
+value=60
+
+[level4]
+value=80
+
+[level5]
+value=100
index a211e41..d08ec85 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <stdbool.h>
 #include <dlfcn.h>
+#include <assert.h>
 #include <vconf.h>
 
 #include "core/log.h"
 #include "core/devices.h"
 #include "core/edbus-handler.h"
 #include "core/device-notifier.h"
+#include "core/config-parser.h"
+#include "powersaver/powersaver.h"
 #include "haptic.h"
 
 #ifndef DATADIR
 #define DATADIR                "/usr/share/deviced"
 #endif
 
+#define HAPTIC_CONF_PATH                       "/etc/deviced/haptic.conf"
+
 /* hardkey vibration variable */
-#define HARDKEY_VIB_RESOURCE           DATADIR"/HW_touch_30ms_sharp.ivt"
 #define HARDKEY_VIB_ITERATION          1
 #define HARDKEY_VIB_FEEDBACK           3
 #define HARDKEY_VIB_PRIORITY           2
+#define HARDKEY_VIB_DURATION           300
 #define HAPTIC_FEEDBACK_STEP           20
 
 /* power on, power off vibration variable */
 
 #define MAX_EFFECT_BUFFER                      (64*1024)
 
-#define RETRY_CNT                                      3
+#ifndef VCONFKEY_RECORDER_STATE
+#define VCONFKEY_RECORDER_STATE "memory/recorder/state"
+#define VCONFKEY_RECORDER_STATE_RECORDING      2
+#endif
 
 #define CHECK_VALID_OPS(ops, r)                ((ops) ? true : !(r = -ENODEV))
 
@@ -58,7 +66,16 @@ static int g_handle;
 /* haptic operation variable */
 static dd_list *h_head;
 static const struct haptic_plugin_ops *h_ops;
+static enum haptic_type h_type;
 static bool haptic_disabled;
+static int powersaver_on = 0;
+
+struct haptic_config {
+       int level;
+       int *level_arr;
+};
+
+static struct haptic_config haptic_conf;
 
 static int haptic_start(void);
 static int haptic_stop(void);
@@ -85,6 +102,7 @@ static int haptic_module_load(void)
                if (ops->is_valid && ops->is_valid()) {
                        if (ops->load)
                                h_ops = ops->load();
+                       h_type = ops->type;
                        break;
                }
        }
@@ -95,13 +113,32 @@ static int haptic_module_load(void)
        }
 
        /* solution bug
-          we do not use internal vibration except power off
-          but module does not stop vibrating, although called terminate function */
+        * we do not use internal vibration except power off.
+        * if the last handle is closed during the playing of vibration,
+        * solution makes unlimited vibration.
+        * so we need at least one handle. */
        haptic_internal_init();
 
        return 0;
 }
 
+static int convert_magnitude_by_conf(int level)
+{
+       int i, step;
+
+       assert(level >= 0 && level <= 100);
+
+       step = 100 / (haptic_conf.level-1);
+       for (i = 0; i < haptic_conf.level; ++i) {
+               if (level <= i*step) {
+                       _D("level changed : %d -> %d", level, haptic_conf.level_arr[i]);
+                       return haptic_conf.level_arr[i];
+               }
+       }
+
+       return -EINVAL;
+}
+
 static DBusMessage *edbus_get_count(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
@@ -128,8 +165,12 @@ static DBusMessage *edbus_open_device(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessage *reply;
        int index, handle, ret;
 
-       if (!CHECK_VALID_OPS(h_ops, ret))
-               goto exit;
+       /* Load haptic module before booting done */
+       if (!CHECK_VALID_OPS(h_ops, ret)) {
+               ret = haptic_module_load();
+               if (ret < 0)
+                       goto exit;
+       }
 
        if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID)) {
                ret = -EINVAL;
@@ -176,15 +217,13 @@ static DBusMessage *edbus_vibrate_monotone(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessageIter iter;
        DBusMessage *reply;
        unsigned int handle;
-       int duration, level, priority, e_handle, ret;
+       int duration, level, priority, e_handle, ret = 0;
 
        if (!CHECK_VALID_OPS(h_ops, ret))
                goto exit;
 
-       if (haptic_disabled) {
-               ret = -EACCES;
+       if (haptic_disabled)
                goto exit;
-       }
 
        if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
                                DBUS_TYPE_INT32, &duration,
@@ -194,6 +233,13 @@ static DBusMessage *edbus_vibrate_monotone(E_DBus_Object *obj, DBusMessage *msg)
                goto exit;
        }
 
+       /* convert as per conf value */
+       level = convert_magnitude_by_conf(level);
+       if (level < 0) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
        ret = h_ops->vibrate_monotone(handle, duration, level, priority, &e_handle);
        if (ret >= 0)
                ret = e_handle;
@@ -212,15 +258,13 @@ static DBusMessage *edbus_vibrate_buffer(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessage *reply;
        unsigned int handle;
        unsigned char *data;
-       int size, iteration, level, priority, e_handle, ret;
+       int size, iteration, level, priority, e_handle, ret = 0;
 
        if (!CHECK_VALID_OPS(h_ops, ret))
                goto exit;
 
-       if (haptic_disabled) {
-               ret = -EACCES;
+       if (haptic_disabled)
                goto exit;
-       }
 
        if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
                                DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size,
@@ -231,6 +275,13 @@ static DBusMessage *edbus_vibrate_buffer(E_DBus_Object *obj, DBusMessage *msg)
                goto exit;
        }
 
+       /* convert as per conf value */
+       level = convert_magnitude_by_conf(level);
+       if (level < 0) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
        ret = h_ops->vibrate_buffer(handle, data, iteration, level, priority, &e_handle);
        if (ret >= 0)
                ret = e_handle;
@@ -247,15 +298,13 @@ static DBusMessage *edbus_stop_device(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessageIter iter;
        DBusMessage *reply;
        unsigned int handle;
-       int ret;
+       int ret = 0;
 
        if (!CHECK_VALID_OPS(h_ops, ret))
                goto exit;
 
-       if (haptic_disabled) {
-               ret = -EACCES;
+       if (haptic_disabled)
                goto exit;
-       }
 
        if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, DBUS_TYPE_INVALID)) {
                ret = -EINVAL;
@@ -456,25 +505,24 @@ static int haptic_internal_exit(void)
        return h_ops->close_device(g_handle);
 }
 
-static int haptic_booting_done_cb(void *data)
-{
-       return haptic_module_load();
-}
-
 static int haptic_hardkey_changed_cb(void *data)
 {
-       int size, level, status, e_handle, ret, cnt = RETRY_CNT;
+       int size, level, status, e_handle, ret;
        unsigned char *buf;
 
-       while (!CHECK_VALID_OPS(h_ops, ret) && cnt--) {
-               haptic_module_load();
-               if (!cnt)
+       if (!CHECK_VALID_OPS(h_ops, ret)) {
+               ret = haptic_module_load();
+               if (ret < 0)
                        return ret;
        }
 
        if (!g_handle)
                haptic_internal_init();
 
+       /* if haptic is stopped, do not play vibration */
+       if (haptic_disabled || powersaver_on)
+               return 0;
+
        if (vconf_get_bool(VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL, &status) < 0) {
                _E("fail to get VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL");
                status = 1;
@@ -484,32 +532,27 @@ static int haptic_hardkey_changed_cb(void *data)
        if (!status)
                return 0;
 
-       buf = convert_file_to_buffer(HARDKEY_VIB_RESOURCE, &size);
-       if (!buf)
-               return -1;
-
        ret = vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &level);
        if (ret < 0) {
                _E("fail to get VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT");
                level = HARDKEY_VIB_FEEDBACK;
        }
 
-       ret = h_ops->vibrate_buffer(g_handle, buf, HARDKEY_VIB_ITERATION,
+       ret = h_ops->vibrate_monotone(g_handle, HARDKEY_VIB_DURATION,
                        level*HAPTIC_FEEDBACK_STEP, HARDKEY_VIB_PRIORITY, &e_handle);
        if (ret < 0)
                _E("fail to vibrate buffer : %d", ret);
 
-       free(buf);
        return ret;
 }
 
 static int haptic_poweroff_cb(void *data)
 {
-       int e_handle, ret, cnt = RETRY_CNT;
+       int e_handle, ret;
 
-       while (!CHECK_VALID_OPS(h_ops, ret) && cnt--) {
-               haptic_module_load();
-               if (!cnt)
+       if (!CHECK_VALID_OPS(h_ops, ret)) {
+               ret = haptic_module_load();
+               if (ret < 0)
                        return ret;
        }
 
@@ -531,16 +574,100 @@ static int haptic_poweroff_cb(void *data)
 
 static int haptic_powersaver_cb(void *data)
 {
-       int powersaver_on = (int)data;
+       int mode = (int)data;
+
+       switch (mode) {
+       case POWERSAVER_OFF:
+               powersaver_on = false;
+               break;
+       case POWERSAVER_BASIC:
+       case POWERSAVER_ENHANCED:
+               powersaver_on = true;
+               break;
+       default:
+               return -EINVAL;
+       }
 
-       if (powersaver_on)
+       _I("changed powersaver %d", powersaver_on);
+       return 0;
+}
+
+static void sound_capturing_cb(keynode_t *key, void *data)
+{
+       int status;
+
+       status = vconf_keynode_get_int(key);
+
+       /* if sound capture is in use, this value is 1(true). */
+       if (status == VCONFKEY_RECORDER_STATE_RECORDING)
                haptic_stop();
        else
                haptic_start();
+}
+
+static int parse_section(struct parse_result *result, void *user_data, int index)
+{
+       struct haptic_config *conf = (struct haptic_config*)user_data;
+
+       assert(result);
+       assert(result->section && result->name && result->value);
+
+       if (MATCH(result->name, "level")) {
+               conf->level = atoi(result->value);
+               conf->level_arr = calloc(sizeof(int), conf->level);
+               if (!conf->level_arr) {
+                       _E("failed to allocate memory for level");
+                       return -errno;
+               }
+       } else if (MATCH(result->name, "value")) {
+               if (index < 0)
+                       return -EINVAL;
+               conf->level_arr[index] = atoi(result->value);
+       }
 
        return 0;
 }
 
+static int haptic_load_config(struct parse_result *result, void *user_data)
+{
+       struct haptic_config *conf = (struct haptic_config*)user_data;
+       char name[NAME_MAX];
+       int ret;
+       static int index = 0;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       /* Parsing 'Haptic' section */
+       if (MATCH(result->section, "Haptic")) {
+               ret = parse_section(result, user_data, -1);
+               if (ret < 0) {
+                       _E("failed to parse [Haptic] section : %d", ret);
+                       return ret;
+               }
+               goto out;
+       }
+
+       /* Parsing 'Level' section */
+       for (index = 0; index < conf->level; ++index) {
+               snprintf(name, sizeof(name), "level%d", index);
+               if (MATCH(result->section, name)) {
+                       ret = parse_section(result, user_data, index);
+                       if (ret < 0) {
+                               _E("failed to parse [level] section : %d", ret);
+                               return ret;
+                       }
+                       goto out;
+               }
+       }
+
+out:
+       return 0;
+}
+
 static const struct edbus_method edbus_methods[] = {
        { "GetCount",          NULL,   "i", edbus_get_count },
        { "OpenDevice",         "i",   "i", edbus_open_device },
@@ -559,16 +686,29 @@ static void haptic_init(void *data)
 {
        int r;
 
+       /* Load haptic module */
+       haptic_module_load();
+
+       /* get haptic data from configuration file */
+       r = config_parse(HAPTIC_CONF_PATH, haptic_load_config, &haptic_conf);
+       if (r < 0) {
+               _E("failed to load configuration file(%s) : %d", HAPTIC_CONF_PATH, r);
+               safe_free(haptic_conf.level_arr);
+       }
+
        /* init dbus interface */
        r = register_edbus_method(DEVICED_PATH_HAPTIC, edbus_methods, ARRAY_SIZE(edbus_methods));
        if (r < 0)
                _E("fail to init edbus method(%d)", r);
 
        /* register notifier for below each event */
-       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, haptic_booting_done_cb);
        register_notifier(DEVICE_NOTIFIER_TOUCH_HARDKEY, haptic_hardkey_changed_cb);
        register_notifier(DEVICE_NOTIFIER_POWEROFF_HAPTIC, haptic_poweroff_cb);
-       register_notifier(DEVICE_NOTIFIER_POWERSAVER, haptic_powersaver_cb);
+       register_notifier(DEVICE_NOTIFIER_PMQOS_ULTRAPOWERSAVING,
+           haptic_powersaver_cb);
+
+       /* add watch for sound capturing value */
+       vconf_notify_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb, NULL);
 }
 
 static void haptic_exit(void *data)
@@ -577,11 +717,17 @@ static void haptic_exit(void *data)
        dd_list *elem;
        int r;
 
+       /* remove watch */
+       vconf_ignore_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb);
+
        /* unregister notifier for below each event */
-       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, haptic_booting_done_cb);
        unregister_notifier(DEVICE_NOTIFIER_TOUCH_HARDKEY, haptic_hardkey_changed_cb);
        unregister_notifier(DEVICE_NOTIFIER_POWEROFF_HAPTIC, haptic_poweroff_cb);
-       unregister_notifier(DEVICE_NOTIFIER_POWERSAVER, haptic_powersaver_cb);
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS_ULTRAPOWERSAVING,
+           haptic_powersaver_cb);
+
+       /* release haptic data memory */
+       safe_free(haptic_conf.level_arr);
 
        if (!CHECK_VALID_OPS(h_ops, r))
                return;
index dfda5d3..01e9d97 100644 (file)
@@ -34,7 +34,13 @@ static void __DESTRUCTOR__ module_exit(void) \
        remove_haptic(dev);     \
 }
 
+enum haptic_type {
+       HAPTIC_STANDARD,
+       HAPTIC_EXTERNAL,
+};
+
 struct haptic_ops {
+       enum haptic_type type;
        bool (*is_valid)(void);
        const struct haptic_plugin_ops *(*load)(void);
        void (*release)(void);
index 35e0666..d217686 100644 (file)
@@ -31,9 +31,9 @@
 #include <Ecore.h>
 
 #include "core/log.h"
+#include "core/list.h"
 #include "haptic.h"
 
-#define DEFAULT_HAPTIC_HANDLE  0xFFFF
 #define MAX_MAGNITUDE                  0xFFFF
 #define PERIODIC_MAX_MAGNITUDE 0x7FFF  /* 0.5 * MAX_MAGNITUDE */
 
 #define LONG(x) ((x)/BITS_PER_LONG)
 #define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
 
-static struct ff_effect ff_effect;
-static char ff_path[PATH_MAX];
-static int ff_use_count;
+
+struct ff_info {
+       Ecore_Timer *timer;
+       struct ff_effect effect;
+};
+
 static int ff_fd;
-static Ecore_Timer *timer;
+static dd_list *ff_list;
+static char ff_path[PATH_MAX];
 
-static int ff_stop(int fd);
-static Eina_Bool timer_cb(void *data)
+/* for debug */
+static void print_list(void)
 {
-       /* stop previous vibration */
-       ff_stop(ff_fd);
-       _I("stop vibration by timer");
+       struct ff_info *temp;
+       dd_list *elem;
+       int i = 0;
 
-       return ECORE_CALLBACK_CANCEL;
+       DD_LIST_FOREACH(ff_list, elem, temp)
+               _D("[%d] %x", i++, temp);
 }
 
-static int register_timer(int ms)
+static bool check_valid_handle(struct ff_info *info)
 {
-       /* add new timer */
-       timer = ecore_timer_add(ms/1000.f, timer_cb, NULL);
-       if (!timer)
-               return -EPERM;
+       struct ff_info *temp;
+       dd_list *elem;
 
-       return 0;
+       DD_LIST_FOREACH(ff_list, elem, temp) {
+               if (temp == info)
+                       break;
+       }
+
+       if (!temp)
+               return false;
+       return true;
 }
 
-static int unregister_timer(void)
+static int ff_stop(int fd, struct ff_effect *effect);
+static Eina_Bool timer_cb(void *data)
 {
-       if (timer) {
-               ecore_timer_del(timer);
-               timer = NULL;
-       }
+       struct ff_info *info = (struct ff_info*)data;
 
-       return 0;
+       if (!info)
+               return ECORE_CALLBACK_CANCEL;
+
+       if (!check_valid_handle(info))
+               return ECORE_CALLBACK_CANCEL;
+
+       _I("stop vibration by timer : id(%d)", info->effect.id);
+
+       /* stop previous vibration */
+       ff_stop(ff_fd, &info->effect);
+
+       /* reset timer */
+       info->timer = NULL;
+
+       return ECORE_CALLBACK_CANCEL;
 }
 
-static int ff_find_device(char *path, int size)
+static int ff_find_device(void)
 {
        DIR *dir;
        struct dirent *dent;
@@ -138,85 +160,102 @@ static int ff_find_device(char *path, int size)
        return -1;
 }
 
-static int ff_play(int fd, int length, int level)
+static int ff_init_effect(struct ff_effect *effect)
+{
+       if (!effect)
+               return -EINVAL;
+
+       /* initialize member variables in effect struct */
+       effect->type = FF_PERIODIC;
+       effect->id = -1;
+       effect->u.periodic.waveform = FF_SQUARE;
+       effect->u.periodic.period = 0.1*0x100;  /* 0.1 second */
+       effect->u.periodic.magnitude = 0;       /* temporary value */
+       effect->u.periodic.offset = 0;
+       effect->u.periodic.phase = 0;
+       effect->direction = 0x4000;     /* Along X axis */
+       effect->u.periodic.envelope.attack_length = 0;
+       effect->u.periodic.envelope.attack_level = 0;
+       effect->u.periodic.envelope.fade_length = 0;
+       effect->u.periodic.envelope.fade_level = 0;
+       effect->trigger.button = 0;
+       effect->trigger.interval = 0;
+       effect->replay.length = 0;              /* temporary value */
+       effect->replay.delay = 0;
+
+       return 0;
+}
+
+static int ff_set_effect(struct ff_effect *effect, int length, int level)
 {
-       struct input_event play;
-       int r = 0;
        double magnitude;
 
-       if (fd < 0)
+       if (!effect)
                return -EINVAL;
 
-       /* unregister existing timer */
-       unregister_timer();
-
        magnitude = (double)level/HAPTIC_MODULE_FEEDBACK_MAX;
        magnitude *= PERIODIC_MAX_MAGNITUDE;
 
        _I("info : magnitude(%d) length(%d)", (int)magnitude, length);
 
-       /* Set member variables in effect struct */
-       ff_effect.type = FF_PERIODIC;
-       if (!ff_effect.id)
-               ff_effect.id = -1;
-       ff_effect.u.periodic.waveform = FF_SQUARE;
-       ff_effect.u.periodic.period = 0.1*0x100;        /* 0.1 second */
-       ff_effect.u.periodic.magnitude = (int)magnitude;
-       ff_effect.u.periodic.offset = 0;
-       ff_effect.u.periodic.phase = 0;
-       ff_effect.direction = 0x4000;   /* Along X axis */
-       ff_effect.u.periodic.envelope.attack_length = 0;
-       ff_effect.u.periodic.envelope.attack_level = 0;
-       ff_effect.u.periodic.envelope.fade_length = 0;
-       ff_effect.u.periodic.envelope.fade_level = 0;
-       ff_effect.trigger.button = 0;
-       ff_effect.trigger.interval = 0;
-       ff_effect.replay.length = length;
-       ff_effect.replay.delay = 0;
-
-       if (ioctl(fd, EVIOCSFF, &ff_effect) == -1) {
-               /* workaround: if effect is erased, try one more */
-               ff_effect.id = -1;
-               if (ioctl(fd, EVIOCSFF, &ff_effect) == -1)
-                       return -errno;
-       }
+       /* set member variables in effect struct */
+       effect->u.periodic.magnitude = (int)magnitude;
+       effect->replay.length = length;         /* length millisecond */
 
-       /* Play vibration*/
+       return 0;
+}
+
+static int ff_play(int fd, struct ff_effect *effect)
+{
+       struct input_event play;
+
+       if (fd < 0 || !effect)
+               return -EINVAL;
+
+       /* upload an effect */
+       if (ioctl(fd, EVIOCSFF, effect) == -1)
+               return -errno;
+
+       /* play vibration*/
        play.type = EV_FF;
-       play.code = ff_effect.id;
+       play.code = effect->id;
        play.value = 1; /* 1 : PLAY, 0 : STOP */
 
        if (write(fd, (const void*)&play, sizeof(play)) == -1)
                return -errno;
 
-       /* register timer */
-       register_timer(length);
-
        return 0;
 }
 
-static int ff_stop(int fd)
+static int ff_stop(int fd, struct ff_effect *effect)
 {
        struct input_event stop;
-       int r = 0;
 
        if (fd < 0)
                return -EINVAL;
 
        /* Stop vibration */
        stop.type = EV_FF;
-       stop.code = ff_effect.id;
-       stop.value = 0;
+       stop.code = effect->id;
+       stop.value = 0; /* 1 : PLAY, 0 : STOP */
 
        if (write(fd, (const void*)&stop, sizeof(stop)) == -1)
                return -errno;
 
+       /* removing an effect from the device */
+       if (ioctl(fd, EVIOCRMFF, effect->id) == -1)
+               return -errno;
+
+       /* reset effect id */
+       effect->id = -1;
+
        return 0;
 }
 
 /* START: Haptic Module APIs */
 static int get_device_count(int *count)
 {
+       /* suppose there is just one haptic device */
        if (count)
                *count = 1;
 
@@ -225,8 +264,17 @@ static int get_device_count(int *count)
 
 static int open_device(int device_index, int *device_handle)
 {
-       /* open ff driver */
-       if (ff_use_count == 0) {
+       struct ff_info *info;
+       int n;
+
+       if (!device_handle)
+               return -EINVAL;
+
+       /* if it is the first element */
+       n = DD_LIST_LENGTH(ff_list);
+       if (n == 0 && !ff_fd) {
+               _I("First element: open ff driver");
+               /* open ff driver */
                ff_fd = open(ff_path, O_RDWR);
                if (!ff_fd) {
                        _E("Failed to open %s : %s", ff_path, strerror(errno));
@@ -234,34 +282,56 @@ static int open_device(int device_index, int *device_handle)
                }
        }
 
-       /* Increase handle count */
-       ff_use_count++;
+       /* allocate memory */
+       info = calloc(sizeof(struct ff_info), 1);
+       if (!info) {
+               _E("Failed to allocate memory : %s", strerror(errno));
+               return -errno;
+       }
+
+       /* initialize ff_effect structure */
+       ff_init_effect(&info->effect);
 
-       if (device_handle)
-               *device_handle = DEFAULT_HAPTIC_HANDLE;
+       /* add info to local list */
+       DD_LIST_APPEND(ff_list, info);
 
+       *device_handle = (int)info;
        return 0;
 }
 
 static int close_device(int device_handle)
 {
-       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+       struct ff_info *info = (struct ff_info*)device_handle;
+       int r, n;
+
+       if (!info)
+               return -EINVAL;
+
+       if (!check_valid_handle(info))
                return -EINVAL;
 
-       if (ff_use_count == 0)
-               return -EPERM;
+       /* stop vibration */
+       r = ff_stop(ff_fd, &info->effect);
+       if (r < 0)
+               _I("already stopped or failed to stop effect : %d", r);
 
-       ff_stop(ff_fd);
+       /* unregister existing timer */
+       if (r >= 0 && info->timer) {
+               ecore_timer_del(info->timer);
+               info->timer = NULL;
+       }
 
-       /* Decrease handle count */
-       ff_use_count--;
+       /* remove info from local list */
+       DD_LIST_REMOVE(ff_list, info);
+       safe_free(info);
 
-       /* close ff driver */
-       if (ff_use_count == 0) {
-               /* Initialize effect structure */
-               memset(&ff_effect, 0, sizeof(ff_effect));
+       /* if it is the last element */
+       n = DD_LIST_LENGTH(ff_list);
+       if (n == 0 && ff_fd) {
+               _I("Last element: close ff driver");
+               /* close ff driver */
                close(ff_fd);
-               ff_fd = -1;
+               ff_fd = 0;
        }
 
        return 0;
@@ -269,41 +339,104 @@ static int close_device(int device_handle)
 
 static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
 {
-       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+       struct ff_info *info = (struct ff_info*)device_handle;
+       int ret;
+
+       if (!info)
+               return -EINVAL;
+
+       if (!check_valid_handle(info))
                return -EINVAL;
 
-       return ff_play(ff_fd, duration, feedback);
+       /* Zero(0) is the infinitely vibration value */
+       if (duration == HAPTIC_MODULE_DURATION_UNLIMITED)
+               duration = 0;
+
+       /* set effect as per arguments */
+       ret = ff_set_effect(&info->effect, duration, feedback);
+       if (ret < 0) {
+               _E("failed to set effect(duration:%d, feedback:%d) : %d",
+                               duration, feedback, ret);
+               return ret;
+       }
+
+       /* play effect as per arguments */
+       ret = ff_play(ff_fd, &info->effect);
+       if (ret < 0) {
+               _E("failed to play haptic effect(id:%d) : %d",
+                               info->effect.id, ret);
+               return ret;
+       }
+
+       /* unregister existing timer */
+       if (info->timer) {
+               ecore_timer_del(info->timer);
+               info->timer = NULL;
+       }
+
+       /* register timer */
+       if (duration) {
+               info->timer = ecore_timer_add(duration/1000.f, timer_cb, info);
+               if (!info->timer)
+                       _E("Failed to add timer callback");
+       }
+
+       _D("effect id : %d", info->effect.id);
+       if (effect_handle)
+               *effect_handle = info->effect.id;
+
+       return 0;
 }
 
 static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
 {
-       if (device_handle != DEFAULT_HAPTIC_HANDLE)
-               return -EINVAL;
-
        /* temporary code */
-       return ff_play(ff_fd, 300, feedback);
+       return vibrate_monotone(device_handle, 300, feedback, priority, effect_handle);
 }
 
 static int stop_device(int device_handle)
 {
-       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+       struct ff_info *info = (struct ff_info*)device_handle;
+       int r;
+
+       if (!info)
+               return -EINVAL;
+
+       if (!check_valid_handle(info))
                return -EINVAL;
 
-       return ff_stop(ff_fd);
+       /* stop effect */
+       r = ff_stop(ff_fd, &info->effect);
+       if (r < 0)
+               _E("failed to stop effect(id:%d) : %d", info->effect.id, r);
+
+       /* unregister existing timer */
+       if (r >= 0 && info->timer) {
+               ecore_timer_del(info->timer);
+               info->timer = NULL;
+       }
+
+       return 0;
 }
 
 static int get_device_state(int device_index, int *effect_state)
 {
-       int status;
+       struct ff_info *info;
+       dd_list *elem;
+       int n, status = false;
 
-       if (ff_effect.id != 0)
-               status = 1;
-       else
-               status = 0;
+       if (!effect_state)
+               return -EINVAL;
 
-       if (effect_state)
-               *effect_state = status;
+       /* suppose there is just one haptic device */
+       DD_LIST_FOREACH(ff_list, elem, info) {
+               if (info->effect.id >= 0) {
+                       status = true;
+                       break;
+               }
+       }
 
+       *effect_state = status;
        return 0;
 }
 
@@ -315,9 +448,6 @@ static int create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_mod
 
 static int get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
 {
-       if (device_handle != DEFAULT_HAPTIC_HANDLE)
-               return -EINVAL;
-
        _E("Not support feature");
        return -EACCES;
 }
@@ -346,11 +476,13 @@ static bool is_valid(void)
 {
        int ret;
 
-       ret = ff_find_device(ff_path, sizeof(ff_path));
-
-       if (ret < 0)
+       ret = ff_find_device();
+       if (ret < 0) {
+               _I("Do not support standard haptic device");
                return false;
+       }
 
+       _I("Support standard haptic device");
        return true;
 }
 
@@ -360,6 +492,7 @@ static const struct haptic_plugin_ops *load(void)
 }
 
 static const struct haptic_ops std_ops = {
+       .type     = HAPTIC_STANDARD,
        .is_valid = is_valid,
        .load     = load,
 };
diff --git a/src/hdmi-cec/cec.c b/src/hdmi-cec/cec.c
new file mode 100644 (file)
index 0000000..61475ab
--- /dev/null
@@ -0,0 +1,414 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <linux/input.h>
+#include <pthread.h>
+#include <poll.h>
+
+#include "core/common.h"
+#include "core/list.h"
+#include "core/udev.h"
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "libcec.h"
+
+#define CED_PATH               "/devices/soc/*.cec"
+
+struct cec_dev{
+       pthread_t cec_thread;
+       int             mCecFd;
+       int             mCecPaddr;
+       int             mCecLaddr;
+       int             mCecTvOnOff;
+       int             mCecRoutPaddr;
+};
+
+static struct cec_dev *cec_device = NULL;
+
+void send_CEConeTouchPlay(struct cec_dev *pdev)
+{
+       int size = 0;
+       unsigned char buffer[4];
+       unsigned char ldst = buffer[0] >> 4;
+       unsigned char opcode = buffer[1];
+       int laddr = pdev->mCecLaddr;
+       int paddr = pdev->mCecPaddr;
+
+       buffer[0] = 0x40;
+       buffer[1] = CEC_OPCODE_TEXT_VIEW_ON;
+       size = 2;
+       _I("Tx : [CEC_OPCODE_TEXT_VIEW_ON]");
+
+       if (CECSendMessage(buffer, size) != size)
+               _E("CECSendMessage() failed!!!");
+       usleep(500000);
+
+       buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+       buffer[1] = CEC_OPCODE_ACTIVE_SOURCE;
+       buffer[2] = (paddr >> 8) & 0xFF;
+       buffer[3] = paddr & 0xFF;
+       size = 4;
+       _I("Tx : [CEC_OPCODE_ACTIVE_SOURCE]");
+
+       if (CECSendMessage(buffer, size) != size)
+               _E("CECSendMessage() failed!!!");
+       usleep(500000);
+
+       buffer[0] = 0x40;
+       buffer[1] = CEC_OPCODE_IMAGE_VIEW_ON;
+       size = 2;
+       _I("Tx : [CEC_OPCODE_IMAGE_VIEW_ON]");
+
+       if (CECSendMessage(buffer, size) != size)
+               _E("CECSendMessage() failed!!!");
+       usleep(500000);
+
+       buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+       buffer[1] = CEC_OPCODE_ACTIVE_SOURCE;
+       buffer[2] = (paddr >> 8) & 0xFF;
+       buffer[3] = paddr & 0xFF;
+       size = 4;
+       _I("Tx : [CEC_OPCODE_ACTIVE_SOURCE]");
+
+       if (CECSendMessage(buffer, size) != size)
+               _E("CECSendMessage() failed!!!");
+       return;
+}
+
+static void handle_cec(struct cec_dev *pdev)
+{
+       unsigned char buffer[16];
+       int size;
+       unsigned char lsrc, ldst, opcode;
+       int Psrc;
+       int ceconoff = 0;
+
+       size = CECReceiveMessage(buffer, CEC_MAX_FRAME_SIZE, 1000);
+
+       /* no data available or ctrl-c */
+       if (!size) {
+               _E("fail");
+               return;
+       }
+       /* "Polling Message" */
+       if (size == 1) {
+               _E("fail");
+               return;
+       }
+
+       if (!pdev) {
+               _E("there is no cec handle");
+               return;
+       }
+       lsrc = buffer[0] >> 4;
+
+       /* ignore messages with src address == mCecLaddr */
+       if (lsrc == pdev->mCecLaddr) {
+               _E("fail %x %x", lsrc, pdev->mCecLaddr);
+               return;
+       }
+       opcode = buffer[1];
+
+       if (lsrc != CEC_MSG_BROADCAST && (opcode ==CEC_OPCODE_SET_STREAM_PATH)) {
+               Psrc = buffer[2] << 8 | buffer[3];
+               _I("Psrc = 0x%x, dev->Paddr= 0x%x", Psrc, pdev->mCecPaddr);
+               if (pdev->mCecPaddr != Psrc) {
+                       _I("### ignore message : 0x%x ", opcode);
+                       return;
+               }
+       }
+
+       if (opcode == CEC_OPCODE_ROUTING_CHANGE) {
+               Psrc = buffer[4] << 8 | buffer[5];
+               _I("Psrc = 0x%x, dev->Paddr= 0x%x", Psrc, pdev->mCecPaddr);
+               pdev->mCecRoutPaddr = Psrc;
+               _I("Opcode : 0x%x Routing addr 0x%x", opcode, pdev->mCecRoutPaddr);
+       }
+
+       if (CECIgnoreMessage(opcode, lsrc)) {
+               _E("### ignore message coming from address 15 (unregistered)");
+               return;
+       }
+
+       if (buffer[0] == CEC_MSG_BROADCAST) {
+               switch (opcode) {
+               case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
+               case CEC_OPCODE_GET_CEC_VERSION:
+                       _I("### ignore broadcast message : 0x%x ", opcode);
+                       return;
+               default:
+                       break;
+               }
+       }
+
+       if (!CECCheckMessageSize(opcode, size)) {
+               /*
+               * For some reason the TV sometimes sends messages that are too long
+               * Dropping these causes the connect process to fail, so for now we
+               * simply ignore the extra data and process the message as if it had
+               * the correct size
+               */
+               _I("### invalid message size: %d(opcode: 0x%x) ###", size, opcode);
+               return;
+       }
+
+       /* check if message broadcasted/directly addressed */
+       if (!CECCheckMessageMode(opcode, (buffer[0] & 0x0F) == CEC_MSG_BROADCAST ? 1 : 0)) {
+               _E("### invalid message mode (directly addressed/broadcast) ###");
+               return;
+       }
+
+       ldst = lsrc;
+
+       /* TODO: macros to extract src and dst logical addresses */
+       /* TODO: macros to extract opcode */
+
+       if (opcode == CEC_OPCODE_SET_STREAM_PATH)
+               ceconoff = 1;
+       size = CECProcessOpcode(buffer,pdev-> mCecLaddr, pdev->mCecPaddr,
+       pdev->mCecRoutPaddr);
+
+       if (size > 0) {
+               if (CECSendMessage(buffer, size) != size)
+                       _E("CECSendMessage() failed!!!");
+       }
+
+       if (ceconoff)
+               send_CEConeTouchPlay(pdev);
+}
+
+static void *hwc_cec_thread(void *data)
+{
+    struct cec_dev *pdev =
+            (struct cec_dev *)data;
+       struct pollfd fds;
+       fds.fd = pdev->mCecFd;
+       fds.events = POLLIN;
+
+       while (true) {
+               int err;
+               fds.fd = pdev->mCecFd;
+               if (fds.fd > 0)
+                       err = poll(&fds, 1, -1);
+
+               if (err > 0) {
+                       if (fds.revents & POLLIN) {
+                               handle_cec(pdev);
+                       }
+               }
+               else if (err == -1) {
+                       if (errno == EINTR)
+                               break;
+                       _E("error in cec thread: %s", strerror(errno));
+               }
+       }
+    return NULL;
+}
+
+static int check_cec(void)
+{
+       static int cec = -1;
+
+       if (cec != -1)
+               goto out;
+
+       if(access("/dev/cec0", F_OK) == 0)
+               cec = 1;
+       cec = 0;
+out:
+       return cec;
+}
+
+static void start_cec(struct cec_dev *pdev)
+{
+       unsigned char buffer[CEC_MAX_FRAME_SIZE];
+       int size;
+
+       if (!pdev) {
+               _E("there is no cec handle");
+               return;
+       }
+       pdev->mCecPaddr = 0x100B;//CEC_NOT_VALID_PHYSICAL_ADDRESS;
+
+       //get TV physical address
+       pdev->mCecLaddr = CECAllocLogicalAddress(pdev->mCecPaddr, CEC_DEVICE_PLAYER);
+       /* Request power state from TV */
+       buffer[0] = (pdev->mCecLaddr << 4);
+       buffer[1] = CEC_OPCODE_GIVE_DEVICE_POWER_STATUS;
+       size = 2;
+       if (CECSendMessage(buffer, size) != size)
+               _E("CECSendMessage(%#x) failed!!!", buffer[0]);
+       /* Wakeup Homekey at first connection */
+       CECReportKey(KEY_POWER);
+}
+
+static void open_cec(struct cec_dev *pdev)
+{
+       int ret;
+
+       if (pdev) {
+               _I("already initialized");
+               return;
+       }
+       pdev = (struct cec_dev *)malloc(sizeof(*pdev));
+       if (!pdev) {
+               _E("there is no cec handle");
+               return;
+       }
+       memset(pdev, 0, sizeof(*pdev));
+       pdev->mCecFd = CECOpen();
+       _I("cec is %d", pdev->mCecFd);
+       if (pdev->mCecFd > 0) {
+               ret = pthread_create(&pdev->cec_thread, NULL, hwc_cec_thread, pdev);
+               if (ret) {
+                       _E("failed to start cec thread: %s", strerror(ret));
+                       pdev->mCecFd = -1;
+                       CECClose();
+               } else {
+                       _I("run thread");
+                       start_cec(pdev);
+                       _I("start cec");
+                       init_input_key_fd();
+               }
+
+       }
+}
+
+static void close_cec(struct cec_dev *pdev)
+{
+       CECClose();
+
+       if (!pdev)
+               return;
+
+       _I("cec is %d", pdev->mCecFd);
+       pthread_kill(pdev->cec_thread, SIGTERM);
+       pthread_join(pdev->cec_thread, NULL);
+       pdev->mCecFd = -1;
+       free(pdev);
+}
+
+static void init_cec(struct cec_dev *pdev)
+{
+       if (pdev) {
+               _I("already initialized");
+               return;
+       }
+       pdev = (struct cec_dev *)malloc(sizeof(*pdev));
+       if (!pdev) {
+               _E("there is no cec handle");
+               return;
+       }
+       memset(pdev, 0, sizeof(*pdev)); 
+}
+
+static void cec_uevent_changed (struct udev_device *dev)
+{
+       const char *state = NULL;
+       const char *devpath = NULL;
+       const char *value = NULL;
+
+       int ret;
+       static int cradle;
+
+       devpath = udev_device_get_property_value(dev, "DEVNAME");
+       value = udev_device_get_property_value(dev, "HDMICEC");
+       _I("%s %s", devpath, value);
+}
+
+const static struct uevent_handler cec_uevent_handler[] = {
+       { "misc"       ,     cec_uevent_changed       ,    NULL    },
+};
+
+static DBusMessage *dbus_get_state(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "GetState"  ,  NULL, "i" ,  dbus_get_state },
+};
+
+static int cec_init_booting_done(void *data)
+{
+       int ret, i;
+
+       for (i = 0 ; i < ARRAY_SIZE(cec_uevent_handler) ; i++) {
+               ret = register_uevent_control(&cec_uevent_handler[i]);
+               if (ret < 0)
+                       _E("FAIL: reg_uevent_control()");
+       }
+       ret = register_edbus_method(DEVICED_PATH_HDMICEC, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       return 0;
+}
+
+static void hdmi_cec_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, cec_init_booting_done);
+       _I("open cec");
+       open_cec(cec_device);
+}
+
+static void hdmi_cec_exit(void *data)
+{
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(cec_uevent_handler) ; i++) {
+               unregister_uevent_control(&cec_uevent_handler[i]);
+       }
+}
+
+static int hdmi_cec_execute(void *data)
+{
+       int state = (int)data;
+/*
+       if (check_cec() == 0) {
+               _E("there is no cec");
+               return 0;
+       }
+*/
+       if (state) {
+               _I("start cec");
+               start_cec(cec_device);
+       } else
+               close_cec(cec_device);
+       return 0;
+}
+
+static const struct device_ops cec_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "hdmi-cec",
+       .init     = hdmi_cec_init,
+       .exit     = hdmi_cec_exit,
+       .execute = hdmi_cec_execute,
+};
+
+DEVICE_OPS_REGISTER(&cec_device_ops)
diff --git a/src/hdmi-cec/cec.h b/src/hdmi-cec/cec.h
new file mode 100644 (file)
index 0000000..fcb1383
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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 _LINUX_CEC_H_
+#define _LINUX_CEC_H_
+
+#define CEC_IOC_MAGIC        'c'
+
+/**
+ * CEC device request code to set logical address.
+ */
+#define CEC_IOC_SETLADDR               _IOW(CEC_IOC_MAGIC, 0, unsigned int)
+#define CEC_IOC_HANDLEKEY              _IOW(CEC_IOC_MAGIC, 1, unsigned int)
+
+int init_input_key_fd(void);
+#endif /* _LINUX_CEC_H_ */
diff --git a/src/hdmi-cec/libcec.c b/src/hdmi-cec/libcec.c
new file mode 100644 (file)
index 0000000..c2724a2
--- /dev/null
@@ -0,0 +1,738 @@
+/*
+ * Copyright@ Samsung Electronics Co. LTD
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <linux/input.h>
+#include <linux/uinput.h>
+#include <errno.h>
+/* drv. header */
+#include "cec.h"
+#include "libcec.h"
+#include "core/log.h"
+
+#define CEC_DEBUG 1
+
+#define CEC_KEY_RELEASED 0
+#define CEC_KEY_PRESSED 1
+/**
+ * @def CEC_DEVICE_NAME
+ * Defines simbolic name of the CEC device.
+ */
+#define CEC_DEVICE_NAME         "/dev/cec0"
+
+static struct {
+       enum CECDeviceType devtype;
+       unsigned char laddr;
+} laddresses[] = {
+       { CEC_DEVICE_RECODER, 1  },
+       { CEC_DEVICE_RECODER, 2  },
+       { CEC_DEVICE_TUNER,   3  },
+       { CEC_DEVICE_PLAYER,  4  },
+       { CEC_DEVICE_AUDIO,   5  },
+       { CEC_DEVICE_TUNER,   6  },
+       { CEC_DEVICE_TUNER,   7  },
+       { CEC_DEVICE_PLAYER,  8  },
+       { CEC_DEVICE_RECODER, 9  },
+       { CEC_DEVICE_TUNER,   10 },
+       { CEC_DEVICE_PLAYER,  11 },
+};
+
+static struct {
+       char *key_name;
+       unsigned char cec_id;
+       unsigned char opcode;
+       unsigned int ui_id;
+} supportkeys[] = {
+       {"Connect",     0x40,   CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_F6},
+       {"Connect",     0x40,   CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_F6},
+       {"Enter",       0x0,    CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_ENTER},
+       {"Enter",       0x0,    CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_ENTER},
+       {"Up",          0x1,    CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_UP},
+       {"Up",          0x1,    CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_UP},
+       {"Down",        0x2,    CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_DOWN},
+       {"Down",        0x2,    CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_DOWN},
+       {"Left",        0x3,    CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_LEFT},
+       {"Left",        0x3,    CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_LEFT},
+       {"Right",       0x4,    CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_RIGHT},
+       {"Right",       0x4,    CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_RIGHT},
+       {"Exit",        0xD,    CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_MENU},
+       {"Exit",        0xD,    CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_MENU},
+       {"Clear",       0x2C,   CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_BACK},
+       {"Clear",       0x2C,   CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_BACK},
+       {"Clear2",      0x91,   CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN,   KEY_BACK},/* samsung key*/
+       {"Play",        0x24,   CEC_OPCODE_PLAY,                        KEY_PLAY},
+       {"Play",        0x44,   CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_PLAY},
+       {"Play",        0x44,   CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_PLAY},
+       {"Stop",        0x3,    CEC_OPCODE_DECK_CONTROL,                KEY_STOP},
+       {"Stop",        0x45,   CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_STOP},
+       {"Stop",        0x45,   CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_STOP},
+       {"Pause",       0x25,   CEC_OPCODE_PLAY,                        KEY_PAUSECD},
+       {"Pause",       0x46,   CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_PAUSECD},
+       {"Pause",       0x46,   CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_PAUSECD},
+       {"Rewind",      0x48,   CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_REWIND},
+       {"Rewind",      0x48,   CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_REWIND},
+       {"FastForward", 0x49,   CEC_OPCODE_USER_CONTROL_PRESSED,        KEY_FASTFORWARD},
+       {"FastForward", 0x49,   CEC_OPCODE_USER_CONTROL_RELEASED,       KEY_FASTFORWARD},
+       {"TV Standby",  0x36,   CEC_OPCODE_STANDBY,                     KEY_HOMEPAGE},
+       {"TV Routing Change", 0x80, CEC_OPCODE_ROUTING_CHANGE,          KEY_HOMEPAGE},
+};
+
+static int CECSetLogicalAddr(unsigned int laddr);
+
+#ifdef CEC_DEBUG
+inline static void CECPrintFrame(unsigned char *buffer, unsigned int size);
+#endif
+
+static int fd = -1;
+static int key_fd = -1;
+/**
+ * Open device driver and assign CEC file descriptor.
+ *
+ * @return  If success to assign CEC file descriptor, return fd; otherwise, return -1.
+ */
+int CECOpen()
+{
+       if (fd != -1)
+               CECClose();
+
+       if ((fd = open(CEC_DEVICE_NAME, O_RDWR)) < 0) {
+               _E("Can't open %s!\n", CEC_DEVICE_NAME);
+               return -1;
+       }
+
+       return fd;
+}
+
+/**
+ * Close CEC file descriptor.
+ *
+ * @return  If success to close CEC file descriptor, return 1; otherwise, return 0.
+ */
+int CECClose()
+{
+       int res = 1;
+
+       if (fd != -1) {
+               if (close(fd) != 0) {
+                       _E("close() failed!\n");
+                       res = 0;
+               }
+               fd = -1;
+       }
+
+       return res;
+}
+
+/**
+ * Allocate logical address.
+ *
+ * @param paddr   [in] CEC device physical address.
+ * @param devtype [in] CEC device type.
+ *
+ * @return new logical address, or 0 if an error occured.
+ */
+int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype)
+{
+       unsigned char laddr = CEC_LADDR_UNREGISTERED;
+       int i = 0;
+
+       _I("physical %x type %d", paddr, devtype);
+       if (fd == -1) {
+               _E("open device first!\n");
+               return 0;
+       }
+
+       if (CECSetLogicalAddr(laddr) < 0) {
+               _E("CECSetLogicalAddr() failed!\n");
+               return 0;
+       }
+
+       if (paddr == CEC_NOT_VALID_PHYSICAL_ADDRESS)
+               return CEC_LADDR_UNREGISTERED;
+
+       /* send "Polling Message" */
+       while (i < sizeof(laddresses) / sizeof(laddresses[0])) {
+               if (laddresses[i].devtype == devtype) {
+                       unsigned char _laddr = laddresses[i].laddr;
+                       unsigned char message = ((_laddr << 4) | _laddr);
+                       if (CECSendMessage(&message, 1) != 1) {
+                               laddr = _laddr;
+                               _I("find logical address %x %d", laddresses[i].laddr, laddresses[i].devtype);
+                               break;
+                       }
+               }
+               i++;
+       }
+
+       if (laddr == CEC_LADDR_UNREGISTERED) {
+               _E("All LA addresses in use!!!\n");
+               return CEC_LADDR_UNREGISTERED;
+       }
+
+       if (CECSetLogicalAddr(laddr) < 0) {
+               _E("CECSetLogicalAddr() failed!\n");
+               return 0;
+       }
+
+       /* broadcast "Report Physical Address" */
+       unsigned char buffer[5];
+       buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+       buffer[1] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS;
+       buffer[2] = (paddr >> 8) & 0xFF;
+       buffer[3] = paddr & 0xFF;
+       buffer[4] = devtype;
+
+       if (CECSendMessage(buffer, 5) != 5) {
+               _E("CECSendMessage() failed!\n");
+               return 0;
+       }
+
+       return laddr;
+}
+
+/**
+ * Send CEC message.
+ *
+ * @param *buffer   [in] pointer to buffer address where message located.
+ * @param size      [in] message size.
+ *
+ * @return number of bytes written, or 0 if an error occured.
+ */
+int CECSendMessage(unsigned char *buffer, int size)
+{
+       if (fd == -1) {
+               _E("open device first!\n");
+               return 0;
+       }
+
+       if (size > CEC_MAX_FRAME_SIZE) {
+               _E("size should not exceed %d\n", CEC_MAX_FRAME_SIZE);
+               return 0;
+       }
+
+#if CEC_DEBUG
+       _I("CECSendMessage() : size(%d)", size);
+       CECPrintFrame(buffer, size);
+#else
+       _I("CEC send : 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X", 
+       buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7],
+       buffer[8], buffer[9], buffer[10], buffer[11], buffer[12], buffer[13], buffer[14], buffer[15] );
+#endif
+       return write(fd, buffer, size);
+}
+
+/**
+ * Receive CEC message.
+ *
+ * @param *buffer   [in] pointer to buffer address where message will be stored.
+ * @param size      [in] buffer size.
+ * @param timeout   [in] timeout in microseconds.
+ *
+ * @return number of bytes received, or 0 if an error occured.
+ */
+int CECReceiveMessage(unsigned char *buffer, int size, long timeout)
+{
+       int bytes = 0;
+       fd_set rfds;
+       struct timeval tv;
+       int retval;
+
+       if (fd == -1) {
+               _E("open device first!\n");
+               return 0;
+       }
+
+       tv.tv_sec = 0;
+       tv.tv_usec = timeout;
+
+       FD_ZERO(&rfds);
+       FD_SET(fd, &rfds);
+
+       retval = select(fd + 1, &rfds, NULL, NULL, &tv);
+
+       if (retval == -1) {
+               _E("fail");
+               return 0;
+       } else if (retval) {
+               bytes = read(fd, buffer, size);
+#if CEC_DEBUG
+               _I("CECReceiveMessage() : size(%d)", bytes);
+               if(bytes > 0)
+                       CECPrintFrame(buffer, bytes);
+#endif
+       }
+
+       return bytes;
+}
+
+/**
+ * Set CEC logical address.
+ *
+ * @return 1 if success, otherwise, return 0.
+ */
+int CECSetLogicalAddr(unsigned int laddr)
+{
+       if (ioctl(fd, CEC_IOC_SETLADDR, &laddr)) {
+               _E("ioctl(CEC_IOC_SETLA) failed!\n");
+               return 0;
+       }
+
+       return 1;
+}
+
+int init_input_key_fd(void)
+{
+       struct uinput_user_dev uidev;
+       int key_idx = sizeof(supportkeys)/sizeof(supportkeys[0]);
+
+       if (key_fd < 0) {
+               key_fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
+               if(key_fd < 0) {
+                       _E("open failed");
+                       return -1;
+               }
+               memset(&uidev, 0, sizeof(uidev));
+               snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "cec-input");
+               uidev.id.bustype = BUS_USB;
+               uidev.id.version = 1;
+               uidev.id.vendor = 1;
+               uidev.id.product = 1;
+               ioctl(key_fd, UI_SET_EVBIT, EV_KEY);
+
+               while (--key_idx >= 0) {
+                       if (CEC_OPCODE_USER_CONTROL_PRESSED == supportkeys[key_idx].opcode ||
+                           CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN == supportkeys[key_idx].opcode) {
+                               ioctl (key_fd, UI_SET_KEYBIT, supportkeys[key_idx].ui_id);
+                               _I("register key %s key(%d)",
+                                       supportkeys[key_idx].key_name,
+                                       supportkeys[key_idx].ui_id);
+                       }
+               }
+               write (key_fd, &uidev, sizeof(uidev)); 
+               ioctl(key_fd, UI_DEV_CREATE);
+       }
+       return 0;
+}
+
+static int input_key_event(unsigned char opcode, unsigned int key)
+{
+       struct input_event ev;
+       int ret;
+
+       if (opcode != CEC_OPCODE_USER_CONTROL_PRESSED &&
+           opcode != CEC_OPCODE_USER_CONTROL_RELEASED &&
+           opcode != CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN &&
+           opcode != CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP) {
+               _E("unregister key event opcode(0x%X) key(%d)", opcode, key);
+               return -1;      
+       }
+       memset(&ev, 0, sizeof(ev));
+       ev.type = EV_KEY;
+       ev.code = key;
+       if (opcode == CEC_OPCODE_USER_CONTROL_PRESSED ||
+           opcode == CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN)
+               ev.value = CEC_KEY_PRESSED;
+       else
+               ev.value = CEC_KEY_RELEASED;
+       ret = write(key_fd, &ev, sizeof(ev));
+       return ret;
+}
+
+/**
+ * report cec key.
+ *
+ * @return 1 if success, otherwise, return 0.
+ */
+int CECReportKey(unsigned int key)
+{
+       int key_idx = sizeof(supportkeys)/sizeof(supportkeys[0]);
+
+       while (--key_idx >= 0) {
+               if (key == supportkeys[key_idx].ui_id) {
+                       _I("%s %d", supportkeys[key_idx].key_name, key);
+                       break;
+               }
+       }
+//     if (ioctl(fd, CEC_IOC_HANDLEKEY, &key)) {
+               _E("ioctl(CEC_IOC_HANDLEKEY) failed!");
+               return 0;
+//     }
+
+       return 1;
+}
+
+#if CEC_DEBUG
+/**
+ * Print CEC frame.
+ */
+void CECPrintFrame(unsigned char *buffer, unsigned int size)
+{
+       if (size > 0) {
+               int i;
+               _I("fsize: %d ", size);
+               _I("frame: ");
+               for (i = 0; i < size; i++)
+                       _I("0x%02x ", buffer[i]);
+
+               _I("\n");
+       }
+}
+#endif
+
+/**
+ * Check CEC message.
+ *
+ * @param opcode   [in] pointer to buffer address where message will be stored.
+ * @param lsrc     [in] buffer size.
+ *
+ * @return 1 if message should be ignored, otherwise, return 0.
+ */
+//TODO: not finished
+int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc)
+{
+       int retval = 0;
+
+       /* if a message coming from address 15 (unregistered) */
+       if (lsrc == CEC_LADDR_UNREGISTERED) {
+               switch (opcode) {
+               case CEC_OPCODE_DECK_CONTROL:
+               case CEC_OPCODE_PLAY:
+                       retval = 1;
+               default:
+                       break;
+               }
+       }
+
+       return retval;
+}
+
+/**
+ * Check CEC message.
+ *
+ * @param opcode   [in] pointer to buffer address where message will be stored.
+ * @param size     [in] message size.
+ *
+ * @return 0 if message should be ignored, otherwise, return 1.
+ */
+//TODO: not finished
+int CECCheckMessageSize(unsigned char opcode, int size)
+{
+       int retval = 1;
+
+       switch (opcode) {
+       case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
+       case CEC_OPCODE_SET_SYSTEM_AUDIO_MODE:
+       case CEC_OPCODE_IMAGE_VIEW_ON:
+       case CEC_OPCODE_TEXT_VIEW_ON:
+               if (size != 2)
+                       retval = 0;
+               break;
+       case CEC_OPCODE_PLAY:
+       case CEC_OPCODE_DECK_CONTROL:
+       case CEC_OPCODE_SET_MENU_LANGUAGE:
+       case CEC_OPCODE_ACTIVE_SOURCE:
+       case CEC_OPCODE_ROUTING_INFORMATION:
+               if (size != 3)
+                       retval = 0;
+               break;
+       case CEC_OPCODE_SET_STREAM_PATH:
+               if (size != 4)
+                       retval = 0;
+               break;
+       case CEC_OPCODE_FEATURE_ABORT:
+       case CEC_OPCODE_DEVICE_VENDOR_ID:
+       case CEC_OPCODE_REPORT_PHYSICAL_ADDRESS:
+               if (size != 4)
+                       retval = 0;
+               break;
+       case CEC_OPCODE_ROUTING_CHANGE:
+               if (size != 6)
+                       retval = 0;
+               break;
+       /* CDC - 1.4 */
+       case 0xf8:
+               if (!(size > 5 && size <= 16))
+                       retval = 0;
+               break;
+       default:
+               break;
+       }
+
+       return retval;
+}
+
+/**
+ * Check CEC message.
+ *
+ * @param opcode    [in] pointer to buffer address where message will be stored.
+ * @param broadcast [in] broadcast/direct message.
+ *
+ * @return 0 if message should be ignored, otherwise, return 1.
+ */
+//TODO: not finished
+int CECCheckMessageMode(unsigned char opcode, int broadcast)
+{
+       int retval = 1;
+
+       switch (opcode) {
+       case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
+       case CEC_OPCODE_SET_MENU_LANGUAGE:
+       case CEC_OPCODE_ACTIVE_SOURCE:
+               if (!broadcast)
+                       retval = 0;
+               break;
+       case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
+       case CEC_OPCODE_DECK_CONTROL:
+       case CEC_OPCODE_PLAY:
+       case CEC_OPCODE_USER_CONTROL_PRESSED:
+       case CEC_OPCODE_FEATURE_ABORT:
+       case CEC_OPCODE_ABORT:
+               if (broadcast)
+                       retval = 0;
+               break;
+       default:
+               break;
+       }
+
+       return retval;
+}
+
+/**
+ * handle key message.
+ *
+ * @param opcode       [in] opcode.
+ * @param key          [in] received key
+ *
+ */
+void CECHandleKey(unsigned char opcode, unsigned char key)
+{
+       int ret;
+       int key_idx = sizeof(supportkeys)/sizeof(supportkeys[0]);
+
+       while (--key_idx >= 0) {
+               if (opcode == supportkeys[key_idx].opcode &&
+                   key == supportkeys[key_idx].cec_id)
+               break;
+       }
+
+       if (key_idx >= 0) {
+               /* key is valid */
+               _I("[CEC] %s(opcode 0x%X,key 0x%X(key code %d)",
+               supportkeys[key_idx].key_name, (int)opcode, (int)key, supportkeys[key_idx].ui_id);
+               ret = input_key_event(supportkeys[key_idx].opcode, supportkeys[key_idx].ui_id);
+               if (ret < 0)
+                       _E("ioctl(CEC_IOC_HANDLEKEY) failed! (fd %d %d: err[%s])", key_fd, ret, strerror(errno));
+       } else {
+               _E("[CEC] 0x%X 0x%X is not supported key\n", opcode, key);
+       }
+}
+
+/**
+ * process CEC OneTouchPlay
+ *
+ * OneTouchPlay is disabled at normal case
+ * Enable : "adb shell setprop persist.hdmi.onetouch_enabled 1"
+ * send Text View On
+ * send Active source
+ */
+void CECOneTouchPlay(unsigned char *buffer, int laddr, int paddr)
+{
+       int size = 0;
+       unsigned char ldst = buffer[0] >> 4;
+       unsigned char opcode = buffer[1];
+
+       buffer[0] = (laddr << 4) | ldst;
+       buffer[1] = CEC_OPCODE_TEXT_VIEW_ON;
+       size = 2;
+       _I("Tx : [CEC_OPCODE_TEXT_VIEW_ON]");
+
+       if (size > 0) {
+               if (CECSendMessage(buffer, size) != size)
+                       _E("CECSendMessage() failed!!!");
+       }
+       usleep(500000);
+
+       buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+       buffer[1] = CEC_OPCODE_ACTIVE_SOURCE;
+       buffer[2] = (paddr >> 8) & 0xFF;
+       buffer[3] = paddr & 0xFF;
+       size = 4;
+       _I("Tx : [CEC_OPCODE_ACTIVE_SOURCE]");
+       if (size > 0) {
+               if (CECSendMessage(buffer, size) != size)
+                       _E("CECSendMessage() failed!!!");
+       }
+}
+
+/**
+ * process CEC message.
+ *
+ * @param buffer    [in/out] pointer to buffer address where message will be stored.
+ * @param laddr                [in] logical address
+ * @param paddr                [in] physical address
+ *
+ * @return return size of CEC message to send.
+ */
+int CECProcessOpcode(unsigned char *buffer, int laddr, int paddr, int raddr)
+{
+       int size = 0;
+       unsigned char ldst = buffer[0] >> 4;
+       unsigned char opcode = buffer[1];
+
+       switch (opcode) {
+       case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
+               /* responce with "Report Physical Address" */
+               buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+               buffer[1] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS;
+               buffer[2] = (paddr >> 8) & 0xFF;
+               buffer[3] = paddr & 0xFF;
+               buffer[4] = CEC_DEVICE_PLAYER;
+               size = 5;
+               break;
+       case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
+               _I("[CEC_OPCODE_REQUEST_ACTIVE_SOURCE 0x%X]", opcode);
+               if( raddr != paddr ) {
+                       _I("Not Currently active source  r:0x0%x  p:0x0%x", raddr, paddr);
+                       break;
+               }
+               buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+               buffer[1] = CEC_OPCODE_ACTIVE_SOURCE;
+               buffer[2] = (paddr >> 8) & 0xFF;
+               buffer[3] = paddr & 0xFF;
+               size = 4;
+               _I("Tx : [CEC_OPCODE_ACTIVE_SOURCE 0x%X]", CEC_OPCODE_ACTIVE_SOURCE);
+               break;
+       case CEC_OPCODE_IMAGE_VIEW_ON:
+       case CEC_OPCODE_TEXT_VIEW_ON:
+               _I("[CEC_OPCODE_IMAGE_VIEW_ON 0x%X]", opcode);
+               buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+               buffer[1] = CEC_OPCODE_ACTIVE_SOURCE;
+               buffer[2] = (paddr >> 8) & 0xFF;
+               buffer[3] = paddr & 0xFF;
+               size = 4;
+               _I("Tx : [CEC_OPCODE_ACTIVE_SOURCE 0x%X]", CEC_OPCODE_ACTIVE_SOURCE);
+               break;
+       case CEC_OPCODE_SET_STREAM_PATH:  //11.2.2-3 test
+               _I("[CEC_OPCODE_SET_STREAM_PATH 0x%X]", opcode);
+               buffer[0] = (laddr << 4) | CEC_MSG_BROADCAST;
+               buffer[1] = CEC_OPCODE_ACTIVE_SOURCE;
+#if 1
+               buffer[2] = (paddr >> 8) & 0xFF;
+               buffer[3] = paddr & 0xFF;
+#endif
+               size = 4;
+               _I("Tx : [CEC_OPCODE_ACTIVE_SOURCE 0x%X]", CEC_OPCODE_ACTIVE_SOURCE);
+               CECReportKey(KEY_HOMEPAGE);
+               break;
+       case CEC_OPCODE_MENU_REQUEST:
+               _I("[CEC_OPCODE_MENU_REQUEST 0x%X]", opcode);
+               buffer[0] = (laddr << 4) | ldst;
+               buffer[1] = CEC_OPCODE_MENU_STATUS;
+               buffer[2] = 0x0;/*active*/
+               size = 3;
+               _I("Tx : [CEC_OPCODE_MENU_STATUS 0x%X]", CEC_OPCODE_MENU_STATUS);
+               break;
+       case CEC_OPCODE_GET_DEVICE_VENDOR_ID:
+               _I("[CEC_OPCODE_GET_DEVICE_VENDOR_ID 0x%X]", opcode);
+               buffer[0] = (laddr << 4) | ldst;
+               buffer[1] = CEC_OPCODE_DEVICE_VENDOR_ID;
+               buffer[2] = 0x00;
+               buffer[3] = 0x00;
+               buffer[4] = 0xF0;
+               size = 5;
+               _I("Tx : [CEC_OPCODE_GET_DEVICE_VENDOR_ID 0x%X]", CEC_OPCODE_DEVICE_VENDOR_ID);
+               break;
+       case CEC_OPCODE_VENDOR_COMMAND_WITH_ID:
+               _I("[CEC_OPCODE_VENDOR_COMMAND_WITH_ID 0x%X] : %2X%2X%2X", opcode,
+               buffer[2], buffer[3], buffer[4]);
+               break;
+               case CEC_OPCODE_GET_CEC_VERSION:
+               buffer[0] = (laddr << 4) | ldst;
+               buffer[1] = CEC_OPCODE_CEC_VERSION;
+               buffer[2] = 0x05;
+               size = 3;
+               _I("Tx : [CEC_OPCODE_CEC_VERSION 0x%X] : 0x%X", CEC_OPCODE_CEC_VERSION, buffer[2]);
+               break;
+       case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
+               _I("[CEC_OPCODE_GIVE_DEVICE_POWER_STATUS 0x%X]", opcode);
+               buffer[0] = (laddr << 4) | ldst;
+               buffer[1] = CEC_OPCODE_REPORT_POWER_STATUS;
+               buffer[2] = 0x0;
+               size = 3;
+               _I("Tx : [CEC_OPCODE_REPORT_POWER_STATUS 0x%X]", CEC_OPCODE_REPORT_POWER_STATUS);
+               break;
+       case CEC_OPCODE_REPORT_POWER_STATUS:
+               _I("[CEC_OPCODE_REPORT_POWER_STATUS 0x%X]", opcode);
+               CECOneTouchPlay(buffer, laddr, paddr);
+               break;
+       case CEC_OPCODE_STANDBY:
+               _I("CEC_OPCODE_STANDBY 0x%X", opcode);
+               CECHandleKey(opcode, buffer[1]);
+               break;
+       case CEC_OPCODE_ROUTING_CHANGE:
+               _I("CEC_OPCODE_ROUTING_CHANGE 0x%X r:0x0%x  p:0x0%x", opcode, raddr, paddr);
+               if(paddr != raddr) {
+                       CECHandleKey(opcode, buffer[1]);
+                       _I("CEC_OPCODE_ROUTING_CHANGE Send HomeKey");
+               }
+               break;
+       case CEC_OPCODE_GIVE_OSD_NAME:
+               _I("CEC_OPCODE_GIVE_OSD_NAME 0x%X", opcode);
+               buffer[0] = (laddr << 4) | ldst;
+               buffer[1] = CEC_OPCODE_SET_OSD_NAME;
+               buffer[2] = 'T';
+               buffer[3] = 'i';
+               buffer[4] = 'z';
+               buffer[5] = 'e';
+               buffer[6] = 'n';
+               buffer[7] = 'G';
+               buffer[8] = 'a';
+               buffer[9] = 't';
+               buffer[10] = 'e';
+               buffer[11] = 'w';
+               buffer[12] = 'a';
+               buffer[13] = 'y';
+               size = 14;
+               _I("Tx : [CEC_OPCODE_SET_OSD_NAME 0x%X]", CEC_OPCODE_SET_OSD_NAME);
+               break;
+       case CEC_OPCODE_USER_CONTROL_PRESSED:
+       case CEC_OPCODE_USER_CONTROL_RELEASED:
+       case CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN:
+       case CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP:
+       case CEC_OPCODE_DECK_CONTROL:
+       case CEC_OPCODE_PLAY:
+               CECHandleKey(opcode, buffer[2]);
+               break;
+       case CEC_OPCODE_ABORT:
+       case CEC_OPCODE_FEATURE_ABORT:
+       default:
+               /* send "Feature Abort" */
+               buffer[0] = (laddr << 4) | ldst;
+               buffer[1] = CEC_OPCODE_FEATURE_ABORT;
+               buffer[2] = CEC_OPCODE_ABORT;
+               buffer[3] = 0x04; // "refused"
+               size = 4;
+               break;
+       }
+
+       return size;
+}
diff --git a/src/hdmi-cec/libcec.h b/src/hdmi-cec/libcec.h
new file mode 100644 (file)
index 0000000..e199523
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright@ Samsung Electronics Co. LTD
+ *
+ * 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 _LIBCEC_H_
+#define _LIBCEC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Maximum CEC frame size */
+#define CEC_MAX_FRAME_SIZE                16
+/* Not valid CEC physical address */
+#define CEC_NOT_VALID_PHYSICAL_ADDRESS    0xFFFF
+
+/* CEC broadcast address (as destination address) */
+#define CEC_MSG_BROADCAST        0x0F
+/* CEC unregistered address (as initiator address) */
+#define CEC_LADDR_UNREGISTERED   0x0F
+
+/*
+ * CEC Messages
+ */
+
+/* @name Messages for the One Touch Play Feature */
+#define CEC_OPCODE_ACTIVE_SOURCE            0x82
+#define CEC_OPCODE_IMAGE_VIEW_ON            0x04
+#define CEC_OPCODE_TEXT_VIEW_ON             0x0D
+
+/* @name Messages for the Routing Control Feature */
+#define CEC_OPCODE_INACTIVE_SOURCE          0x9D
+#define CEC_OPCODE_REQUEST_ACTIVE_SOURCE    0x85
+#define CEC_OPCODE_ROUTING_CHANGE           0x80
+#define CEC_OPCODE_ROUTING_INFORMATION      0x81
+#define CEC_OPCODE_SET_STREAM_PATH          0x86
+
+/* @name Messages for the Standby Feature */
+#define CEC_OPCODE_STANDBY                  0x36
+
+/* @name Messages for the One Touch Record Feature */
+#define CEC_OPCODE_RECORD_OFF               0x0B
+#define CEC_OPCODE_RECORD_ON                0x09
+#define CEC_OPCODE_RECORD_STATUS            0x0A
+#define CEC_OPCODE_RECORD_TV_SCREEN         0x0F
+
+/* @name Messages for the Timer Programming Feature */
+#define CEC_OPCODE_CLEAR_ANALOGUE_TIMER     0x33
+#define CEC_OPCODE_CLEAR_DIGITAL_TIMER      0x99
+#define CEC_OPCODE_CLEAR_EXTERNAL_TIMER     0xA1
+#define CEC_OPCODE_SET_ANALOGUE_TIMER       0x34
+#define CEC_OPCODE_SET_DIGITAL_TIMER        0x97
+#define CEC_OPCODE_SET_EXTERNAL_TIMER       0xA2
+#define CEC_OPCODE_SET_TIMER_PROGRAM_TITLE  0x67
+#define CEC_OPCODE_TIMER_CLEARED_STATUS     0x43
+#define CEC_OPCODE_TIMER_STATUS             0x35
+
+/* @name Messages for the System Information Feature */
+#define CEC_OPCODE_CEC_VERSION              0x9E
+#define CEC_OPCODE_GET_CEC_VERSION          0x9F
+#define CEC_OPCODE_GIVE_PHYSICAL_ADDRESS    0x83
+#define CEC_OPCODE_GET_MENU_LANGUAGE        0x91
+//#define CEC_OPCODE_POLLING_MESSAGE
+#define CEC_OPCODE_REPORT_PHYSICAL_ADDRESS  0x84
+#define CEC_OPCODE_SET_MENU_LANGUAGE        0x32
+
+/* @name Messages for the Deck Control Feature */
+#define CEC_OPCODE_DECK_CONTROL             0x42
+#define CEC_OPCODE_DECK_STATUS              0x1B
+#define CEC_OPCODE_GIVE_DECK_STATUS         0x1A
+#define CEC_OPCODE_PLAY                     0x41
+
+/* @name Messages for the Tuner Control Feature */
+#define CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS 0x08
+#define CEC_OPCODE_SELECT_ANALOGUE_SERVICE  0x92
+#define CEC_OPCODE_SELECT_DIGITAL_SERVICE   0x93
+#define CEC_OPCODE_TUNER_DEVICE_STATUS      0x07
+#define CEC_OPCODE_TUNER_STEP_DECREMENT     0x06
+#define CEC_OPCODE_TUNER_STEP_INCREMENT     0x05
+
+/* @name Messages for the Vendor Specific Commands Feature */
+#define CEC_OPCODE_DEVICE_VENDOR_ID         0x87
+#define CEC_OPCODE_GET_DEVICE_VENDOR_ID     0x8C
+#define CEC_OPCODE_VENDOR_COMMAND           0x89
+#define CEC_OPCODE_VENDOR_COMMAND_WITH_ID   0xA0
+#define CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN 0x8A
+#define CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP  0x8B
+
+/* @name Messages for the OSD Display Feature */
+#define CEC_OPCODE_SET_OSD_STRING           0x64
+
+/* @name Messages for the Device OSD Transfer Feature */
+#define CEC_OPCODE_GIVE_OSD_NAME            0x46
+#define CEC_OPCODE_SET_OSD_NAME             0x47
+
+/* @name Messages for the Device Menu Control Feature */
+#define CEC_OPCODE_MENU_REQUEST             0x8D
+#define CEC_OPCODE_MENU_STATUS              0x8E
+#define CEC_OPCODE_USER_CONTROL_PRESSED     0x44
+#define CEC_OPCODE_USER_CONTROL_RELEASED    0x45
+
+/* @name Messages for the Remote Control Passthrough Feature */
+
+/* @name Messages for the Power Status Feature */
+#define CEC_OPCODE_GIVE_DEVICE_POWER_STATUS 0x8F
+#define CEC_OPCODE_REPORT_POWER_STATUS      0x90
+
+/* @name Messages for General Protocol messages */
+#define CEC_OPCODE_FEATURE_ABORT            0x00
+#define CEC_OPCODE_ABORT                    0xFF
+
+/* @name Messages for the System Audio Control Feature */
+#define CEC_OPCODE_GIVE_AUDIO_STATUS        0x71
+#define CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7D
+#define CEC_OPCODE_REPORT_AUDIO_STATUS      0x7A
+#define CEC_OPCODE_SET_SYSTEM_AUDIO_MODE    0x72
+#define CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST 0x70
+#define CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS 0x7E
+
+/* @name Messages for the Audio Rate Control Feature */
+#define CEC_OPCODE_SET_AUDIO_RATE           0x9A
+
+/* @name CEC Operands */
+
+/* TODO: not finished */
+
+#define CEC_DECK_CONTROL_MODE_STOP      0x03
+#define CEC_PLAY_MODE_PLAY_FORWARD      0x24
+
+/*
+ * @enum CECDeviceType
+ * Type of CEC device
+ */
+enum CECDeviceType {
+    /* TV */
+    CEC_DEVICE_TV,
+    /* Recording Device */
+    CEC_DEVICE_RECODER,
+    /* Reserved */
+    CEC_RESERVED,
+    /* Tuner */
+    CEC_DEVICE_TUNER,
+    /* Playback Device */
+    CEC_DEVICE_PLAYER,
+    /* Audio System */
+    CEC_DEVICE_AUDIO,
+};
+
+int CECOpen();
+int CECClose();
+int CECAllocLogicalAddress(int paddr, enum CECDeviceType devtype);
+int CECSendMessage(unsigned char *buffer, int size);
+int CECReceiveMessage(unsigned char *buffer, int size, long timeout);
+
+int CECIgnoreMessage(unsigned char opcode, unsigned char lsrc);
+int CECCheckMessageSize(unsigned char opcode, int size);
+int CECCheckMessageMode(unsigned char opcode, int broadcast);
+int CECProcessOpcode(unsigned char *buffer, int laddr, int paddr, int raddr);
+int CECReportKey(unsigned int key);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBCEC_H_ */
diff --git a/src/icd/icd-integrity.c b/src/icd/icd-integrity.c
new file mode 100644 (file)
index 0000000..bf691e0
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include "sha2.h"
+#include "core/log.h"
+
+#define ICD_EXEC_PATH          "/usr/bin/icd"
+
+#define INTEGRITY_NOT_COMPROMISED      1
+#define INTEGRITY_COMPROMISED          0
+#define ERR_FILE_READ                  -1
+
+#define TZIC_IOC_MAGIC         0x9E
+#define TZIC_IOCTL_SET_FUSE_REQ        _IO(TZIC_IOC_MAGIC, 1)
+
+static int write_file(const char *path, const char *value)
+{
+       int fd, ret, len;
+
+       fd = open(path, O_WRONLY|O_CREAT, 0622);
+       if (fd < 0)
+               return -errno;
+
+       len = strlen(value);
+
+       do {
+               ret = write(fd, value, len);
+       } while (ret < 0 && errno == EINTR);
+
+       close(fd);
+
+       if (ret < 0)
+               return -errno;
+
+       return 0;
+}
+
+static int check_file_hash(const char *filename)
+{
+       int fd;
+       struct stat info;
+       int fsize = 0;
+       int result = INTEGRITY_COMPROMISED;
+       SECKM_SHA256_CTX ctx;
+       unsigned char digest[SECKM_SHA256_DIGEST_LENGTH];
+       unsigned char *input = 0;
+
+       /* icd digest */
+       unsigned char hashed[] =
+       "\x08\x01\x77\xd8\x5e\xdf\xa2\xe3\x9c\x34\xe7\xd6\xdd\x86\xae\x88\xeb\x19\x1b\xc9\xb6\xdd\x3d\xa2\x80\xd1\xaa\xf5\x1e\x29\x41\x14";
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               goto out_err;
+
+       if (fstat(fd, &info) < 0)
+               goto out;
+
+       fsize = info.st_size;
+
+       input = (unsigned char *)malloc(fsize);
+       if (!input)
+               goto out;
+
+       result = read(fd, input, fsize);
+       if (result != fsize) {
+               result = ERR_FILE_READ;
+               goto out;
+       }
+
+       SECKM_SHA256_Init((SECKM_SHA256_CTX*) &ctx);
+       SECKM_SHA256_Update((SECKM_SHA256_CTX*) &ctx, input, fsize);
+       SECKM_SHA256_Final((SECKM_SHA256_CTX*) &ctx, digest);
+
+       if ((memcmp(hashed, digest, SECKM_SHA256_DIGEST_LENGTH) == 0))
+               result = INTEGRITY_NOT_COMPROMISED;
+out:
+       close(fd);
+out_err:
+       /*
+        * FIXME: temporarily skip a tamper flag setting
+        * icd package not working
+        */
+#if 0
+       if (result != INTEGRITY_NOT_COMPROMISED) {
+               fd = open("/dev/tzic", O_RDWR);
+               if (fd > 0) {
+                       ioctl(fd, TZIC_IOCTL_SET_FUSE_REQ, &result);
+                       close(fd);
+               }
+       }
+#endif
+       if (input)
+               free(input);
+
+       return result;
+}
+
+void icd_check_integrity(void)
+{
+       int ret;
+       int check;
+
+       check = check_file_hash(ICD_EXEC_PATH);
+       if (check == INTEGRITY_NOT_COMPROMISED)
+               ret = write_file("/dev/icd", "1");
+       else
+               ret = write_file("/dev/icd", "0");
+       _I("icd status %d %d", check, ret);
+}
diff --git a/src/icd/icd-integrity.h b/src/icd/icd-integrity.h
new file mode 100644 (file)
index 0000000..024097d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 __ICD_INTEGRITY_H__
+#define __ICD_INTEGRITY_H__
+
+void icd_check_integrity(void);
+
+#endif //__ICD_INTEGRITY_H__
diff --git a/src/icd/icd.c b/src/icd/icd.c
new file mode 100644 (file)
index 0000000..573690d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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 <assert.h>
+#include <limits.h>
+#include <libudev.h>
+#include <Ecore.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/udev.h"
+
+#include "icd-integrity.h"
+
+static void icd_init(void *data)
+{
+       icd_check_integrity();
+}
+
+static void icd_exit(void *data)
+{
+}
+
+static const struct device_ops icd_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "icd",
+       .init     = icd_init,
+       .exit     = icd_exit,
+};
+
+DEVICE_OPS_REGISTER(&icd_device_ops)
diff --git a/src/icd/sha2.c b/src/icd/sha2.c
new file mode 100644 (file)
index 0000000..438064d
--- /dev/null
@@ -0,0 +1,406 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+/*
+ * FILE:        sha2.c
+ * AUTHOR:      Aaron D. Gifford <me@aarongifford.com>
+ *
+ * A licence was granted to the ASF by Aaron on 4 November 2003.
+ */
+#include <string.h>
+#include <unistd.h>
+#include "sha2.h"
+
+//#define UINT64_C(x) x##ULL
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SECKM_SHA256_SHORT_BLOCK_LENGTH       (SECKM_SHA256_BLOCK_LENGTH - 8)
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#define REVERSE32(w,x)  { \
+        sha2_word32 tmp = (w); \
+        tmp = (tmp >> 16) | (tmp << 16); \
+        (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#define REVERSE64(w,x)  { \
+        sha2_word64 tmp = (w); \
+        tmp = (tmp >> 32) | (tmp << 32); \
+        tmp = ((tmp & UINT64_C(0xff00ff00ff00ff00)) >> 8) | \
+              ((tmp & UINT64_C(0x00ff00ff00ff00ff)) << 8); \
+        (x) = ((tmp & UINT64_C(0xffff0000ffff0000)) >> 16) | \
+              ((tmp & UINT64_C(0x0000ffff0000ffff)) << 16); \
+}
+
+/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+typedef unsigned char   sha2_byte;         /* Exactly 1 byte */
+typedef uint32_t sha2_word32; /* Exactly 4 bytes */
+typedef uint64_t sha2_word64; /* Exactly 8 bytes */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n)  { \
+        (w)[0] += (sha2_word64)(n); \
+        if ((w)[0] < (n)) { \
+                (w)[1]++; \
+        } \
+}
+
+#define MEMSET_BZERO(p,l)       memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l)     memcpy((d), (s), (l))
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
+ *   S is a ROTATION) because the SHA-256/384/512 description document
+ *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
+ *   same "backwards" definition.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define R(b,x)          ((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define S32(b,x)        (((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x)        (((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-256: */
+#define Sigma0_256(x)   (S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
+#define Sigma1_256(x)   (S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
+#define sigma0_256(x)   (S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
+#define sigma1_256(x)   (S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x)   (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x)   (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x)   (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
+#define sigma1_512(x)   (S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
+
+/*** INTERNAL FUNCTION PROTOTYPES *************************************/
+/* NOTE: These should not be accessed directly from outside this
+ * library -- they are intended for private internal visibility/use
+ * only.
+ */
+void SECKM_SHA256_Transform(SECKM_SHA256_CTX*, const sha2_word32*);
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-256: */
+static const sha2_word32 K256[64] =
+{ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+        0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+        0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+        0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+        0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+        0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+        0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+        0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+        0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+        0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+        0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+        0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+        0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL };
+
+/* Initial hash value H for SHA-256: */
+static const sha2_word32 SECKM_SHA256_initial_hash_value[8] =
+{ 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL,
+        0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL };
+
+/*** SHA-256: *********************************************************/
+void SECKM_SHA256_Init(SECKM_SHA256_CTX* context)
+{
+    if (context == (SECKM_SHA256_CTX*) 0)
+    {
+        return;
+    }
+    MEMCPY_BCOPY(context->state, SECKM_SHA256_initial_hash_value, SECKM_SHA256_DIGEST_LENGTH);
+    MEMSET_BZERO(context->buffer, SECKM_SHA256_BLOCK_LENGTH);
+    context->bitcount = 0;
+}
+
+void SECKM_SHA256_Transform(SECKM_SHA256_CTX* context, const sha2_word32* data)
+{
+    sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
+    sha2_word32 T1, T2, *W256;
+    int j;
+
+    W256 = (sha2_word32*) context->buffer;
+
+    /* Initialize registers with the prev. intermediate value */
+    a = context->state[0];
+    b = context->state[1];
+    c = context->state[2];
+    d = context->state[3];
+    e = context->state[4];
+    f = context->state[5];
+    g = context->state[6];
+    h = context->state[7];
+
+    j = 0;
+    do
+    {
+        /* Copy data while converting to host byte order */
+        REVERSE32(*data++,W256[j]);
+        /* Apply the SHA-256 compression function to update a..h */
+        T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+        T2 = Sigma0_256(a) + Maj(a, b, c);
+        h = g;
+        g = f;
+        f = e;
+        e = d + T1;
+        d = c;
+        c = b;
+        b = a;
+        a = T1 + T2;
+
+        j++;
+    } while (j < 16);
+
+    do
+    {
+        /* Part of the message block expansion: */
+        s0 = W256[(j + 1) & 0x0f];
+        s0 = sigma0_256(s0);
+        s1 = W256[(j + 14) & 0x0f];
+        s1 = sigma1_256(s1);
+
+        /* Apply the SHA-256 compression function to update a..h */
+        T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j & 0x0f] += s1
+                + W256[(j + 9) & 0x0f] + s0);
+        T2 = Sigma0_256(a) + Maj(a, b, c);
+        h = g;
+        g = f;
+        f = e;
+        e = d + T1;
+        d = c;
+        c = b;
+        b = a;
+        a = T1 + T2;
+
+        j++;
+    } while (j < 64);
+
+    /* Compute the current intermediate hash value */
+    context->state[0] += a;
+    context->state[1] += b;
+    context->state[2] += c;
+    context->state[3] += d;
+    context->state[4] += e;
+    context->state[5] += f;
+    context->state[6] += g;
+    context->state[7] += h;
+
+    /* Clean up */
+    a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+void SECKM_SHA256_Update(SECKM_SHA256_CTX* context, const sha2_byte *data, size_t len)
+{
+    unsigned int freespace, usedspace;
+
+    if (len == 0)
+    {
+        /* Calling with no data is valid - we do nothing */
+        return;
+    }
+
+    /* Sanity check: */
+    if (context == (SECKM_SHA256_CTX*) 0 || data == (sha2_byte*) 0)
+        return;
+
+    usedspace = (unsigned int) ((context->bitcount >> 3) % SECKM_SHA256_BLOCK_LENGTH);
+    if (usedspace > 0)
+    {
+        /* Calculate how much free space is available in the buffer */
+        freespace = SECKM_SHA256_BLOCK_LENGTH - usedspace;
+
+        if (len >= freespace)
+        {
+            /* Fill the buffer completely and process it */
+            MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+            context->bitcount += freespace << 3;
+            len -= freespace;
+            data += freespace;
+            SECKM_SHA256_Transform(context, (sha2_word32*) context->buffer);
+        }
+        else
+        {
+            /* The buffer is not yet full */
+            MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+            context->bitcount += len << 3;
+            /* Clean up: */
+            usedspace = freespace = 0;
+            return;
+        }
+    }
+    while (len >= SECKM_SHA256_BLOCK_LENGTH)
+    {
+        /* Process as many complete blocks as we can */
+        SECKM_SHA256_Transform(context, (sha2_word32*) data);
+        context->bitcount += SECKM_SHA256_BLOCK_LENGTH << 3;
+        len -= SECKM_SHA256_BLOCK_LENGTH;
+        data += SECKM_SHA256_BLOCK_LENGTH;
+    }
+    if (len > 0)
+    {
+        /* There's left-overs, so save 'em */
+        MEMCPY_BCOPY(context->buffer, data, len);
+        context->bitcount += len << 3;
+    }
+    /* Clean up: */
+    usedspace = freespace = 0;
+}
+
+void SECKM_SHA256_Final(SECKM_SHA256_CTX* context, sha2_byte digest[])
+{
+    sha2_word32 *d = (sha2_word32*) digest;
+    unsigned int usedspace;
+
+    /* Sanity check: */
+    if (context == (SECKM_SHA256_CTX*) 0)
+        return;
+
+    /* If no digest buffer is passed, we don't bother doing this: */
+    if (digest != (sha2_byte*) 0)
+    {
+        usedspace = (unsigned int) ((context->bitcount >> 3)
+                % SECKM_SHA256_BLOCK_LENGTH);
+        /* Convert FROM host byte order */
+        REVERSE64(context->bitcount,context->bitcount);
+
+        if (usedspace > 0)
+        {
+            /* Begin padding with a 1 bit: */
+            context->buffer[usedspace++] = 0x80;
+
+            if (usedspace <= SECKM_SHA256_SHORT_BLOCK_LENGTH)
+            {
+                /* Set-up for the last transform: */
+                MEMSET_BZERO(&context->buffer[usedspace], SECKM_SHA256_SHORT_BLOCK_LENGTH - usedspace);
+            }
+            else
+            {
+                if (usedspace < SECKM_SHA256_BLOCK_LENGTH)
+                {
+                    MEMSET_BZERO(&context->buffer[usedspace], SECKM_SHA256_BLOCK_LENGTH - usedspace);
+                }
+                /* Do second-to-last transform: */
+                SECKM_SHA256_Transform(context, (sha2_word32*) context->buffer);
+
+                /* And set-up for the last transform: */
+                MEMSET_BZERO(context->buffer, SECKM_SHA256_SHORT_BLOCK_LENGTH);
+            }
+        }
+        else
+        {
+            /* Set-up for the last transform: */
+            MEMSET_BZERO(context->buffer, SECKM_SHA256_SHORT_BLOCK_LENGTH);
+
+            /* Begin padding with a 1 bit: */
+            *context->buffer = 0x80;
+        }
+        /* Set the bit count: */
+        *(sha2_word64*) &context->buffer[SECKM_SHA256_SHORT_BLOCK_LENGTH]
+                = context->bitcount;
+
+        /* Final transform: */
+        SECKM_SHA256_Transform(context, (sha2_word32*) context->buffer);
+
+        {
+            /* Convert TO host byte order */
+            int j;
+            for (j = 0; j < 8; j++)
+            {
+                REVERSE32(context->state[j],context->state[j]);
+                *d++ = context->state[j];
+            }
+        }
+    }
+
+    /* Clean up state data: */
+    MEMSET_BZERO(context, sizeof(*context));
+    usedspace = 0;
+}
+
+#ifdef FIPS_MODE
+
+struct sha_testvec {
+       unsigned char *plaintext;
+       unsigned char *digest;
+       unsigned char psize;
+};
+
+/*
+ * SHA256 test vectors from from NIST
+ */
+#define SHA256_TEST_VECTORS    1
+
+static struct sha_testvec SHA256_tv[] = {
+       {
+               .plaintext = (unsigned char *) "abc",
+               .psize  = 3,
+               .digest = (unsigned char *)
+                         "\xba\x78\x16\xbf\x8f\x01\xcf\xea"
+                         "\x41\x41\x40\xde\x5d\xae\x22\x23"
+                         "\xb0\x03\x61\xa3\x96\x17\x7a\x9c"
+                         "\xb4\x10\xff\x61\xf2\x00\x15\xad",
+       },
+       {
+               .plaintext = "\x3b\xc4\x10\xe5\xef\x25\xb2\xea\x5b\xb0\xe5\x15\xc9\xd6\x64\x07\xe9\xd6\x82\x96\xc6\xe1\xbd\x14\xf9\x7b\x95\xd4\x1c\x24\x9f\xeb\x82\x38\xd5\x34\x25\x14\x30\x97\xe0\x7a\x79\x8a\xdf\x37\x5c\xd7\x53\x02\xbe\xa0\x6a\xa8\x50\xa1\x7e\x66\x64\xb6\x8d\x96",
+               .psize  = 62,
+               .digest = "\x56\x4a\x57\xf4\xda\xa0\xcb\x7d\x2e\xef\x3d\x4c\x2e\xb1\xed\x29\xfd\xb6\xe9\xe8\x8e\x35\x62\x3c\x0e\x30\x8c\xb9\x10\xa8\x7d\xce",
+       },
+       {
+               .plaintext = "\xef\x1a\x07\x28\x77\x22\x4d\x78\x67\xf8\x1c\x57\x21\x01\x92\x80\x46\xf3\xdf\x6f\x32\x44\xef\x74\xc5\xe3\x4a\x07\x69\x25\x38\x5b\x50\x02\x28\x36\xfe\x81\x52\xff\x08\x71\x9c\x19\x1b\x5a\xba\x6f\x3f\xb3\x9a\x50\x5d\x55\xff\x7e\xff\x30\x6c\x81\x58\x3d\x43",
+               .psize  = 63,
+               .digest = "\x69\x16\xf3\x45\xa6\x92\x0c\xc3\x13\xa8\xbe\xc7\x63\x55\x4c\x64\xbb\xbc\x78\x28\x07\xae\x4c\x78\x1f\xda\x6e\x48\xcd\x1c\x49\x1a",
+       },
+       {
+               .plaintext = "\xc3\x11\xf1\x64\x83\xb3\xad\x91\x21\xa9\x99\xa3\xa5\x2f\x12\x58\x63\x96\x33\x2f\x73\xea\xeb\x28\x62\xd3\x53\xcb\x27\xb9\x3f\x6b\x59\x2b\x14\xac\x9f\x82\xd9\x43\x67\xc1\x90\xfd\xdb\xc0\xc6\x03\x10\x8a\x69\x5c\x81\x03\xda\xb3\xbd\xce\x43\x5b\x5c\x6d\x2b\x90",
+               .psize  = 64,
+               .digest = "\xa1\xf3\x34\xef\x0e\x59\x88\x90\x65\x48\x0d\xdf\x16\x47\x8f\xd3\xdf\xc3\x0f\xea\x33\xe7\x80\x92\xfe\x1e\x08\x85\x0b\xed\xb9\xea",
+       },
+};
+
+/* Self Tests SHA256; Please refer to test_vectors.h for the data structures and test vectors used
+ * Returns:
+ *    0 - all tests passed
+ *    1...SHA256_TEST_VECTORS - error (and corresponding test vector number, 1-based)
+ */
+int SECKM_SHA2_selftest (void) {
+       int        i;
+    SECKM_SHA256_CTX ctx;
+    unsigned char output[SECKM_SHA256_DIGEST_LENGTH];
+
+       for (i = 0; i < SHA256_TEST_VECTORS; i++ ) {
+        SECKM_SHA256_Init(&ctx);
+        SECKM_SHA256_Update(&ctx, SHA256_tv[i].plaintext, SHA256_tv[i].psize);
+        SECKM_SHA256_Final(&ctx, output);
+
+               if (memcmp(output, SHA256_tv[i].digest, SECKM_SHA256_DIGEST_LENGTH)) {
+                        LOG_KM ("SHA2 Selftest failed: %d\n", i+1);
+                       return i+1;
+                }
+       }
+       return 0;
+}
+
+#endif /* FIPS_MODE */
diff --git a/src/icd/sha2.h b/src/icd/sha2.h
new file mode 100644 (file)
index 0000000..d902daa
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+/*
+ * FILE:        sha2.h
+ * AUTHOR:      Aaron D. Gifford <me@aarongifford.com>
+ *
+ * A licence was granted to the ASF by Aaron on 4 November 2003.
+ */
+
+#ifndef __SHA2_H__
+#define __SHA2_H__
+
+#include <stdint.h>
+
+/*** SHA-256 Various Length Definitions ***********************/
+#define SECKM_SHA256_BLOCK_LENGTH             64
+#define SECKM_SHA256_DIGEST_LENGTH            32
+#define SECKM_SHA256_DIGEST_STRING_LENGTH     (SECKM_SHA256_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256 Context Structures *******************************/
+typedef struct _SECKM_SHA256_CTX {
+        uint32_t    state[8];
+        uint64_t    bitcount;
+        unsigned char      buffer[SECKM_SHA256_BLOCK_LENGTH];
+} SECKM_SHA256_CTX;
+
+
+/*** SHA-256 Function Prototypes ******************************/
+void SECKM_SHA256_Init(SECKM_SHA256_CTX *);
+void SECKM_SHA256_Update(SECKM_SHA256_CTX *, const unsigned char *, size_t);
+void SECKM_SHA256_Final(SECKM_SHA256_CTX *, unsigned char [SECKM_SHA256_DIGEST_LENGTH]);
+
+#endif /* __SHA2_H__ */
+
+
diff --git a/src/led/conf.c b/src/led/conf.c
new file mode 100644 (file)
index 0000000..b109b1b
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <errno.h>
+#include <assert.h>
+
+#include "deviced/dd-led.h"
+#include "core/log.h"
+#include "core/list.h"
+#include "core/config-parser.h"
+#include "conf.h"
+
+#define LED_CONF       "/etc/deviced/led.conf"
+#define LED_STR                "led"
+
+static const char* led_str[] = {
+       [LED_OFF] = "Off",
+       [LED_LOW_BATTERY] = "Low battery",
+       [LED_CHARGING] = "Charging",
+       [LED_FULLY_CHARGED] = "Fully charged",
+       [LED_CHARGING_ERROR] = "Charging error",
+       [LED_MISSED_NOTI] = "Missed noti",
+       [LED_VOICE_RECORDING] = "Voice recording",
+       [LED_REMOTE_CONTROLLER] = "Remote controller",
+       [LED_AIR_WAKEUP] = "Air Wakeup",
+       [LED_POWER_OFF] = "Power off",
+       [LED_CUSTOM] = "Custom",
+};
+
+static dd_list *led_head;
+
+static int get_selected_lcd_mode(const char *value)
+{
+       int lcd = 0;
+
+       assert(value);
+
+       if (strstr(value, "on"))
+               lcd |= DURING_LCD_ON;
+       if (strstr(value, "off"))
+               lcd |= DURING_LCD_OFF;
+
+       return lcd;
+}
+
+static int parse_scenario(struct parse_result *result, void *user_data)
+{
+       dd_list *head = (dd_list*)led_head;
+       struct led_mode *led;
+       int index;
+
+       for (index = 0; index < LED_MODE_MAX; ++index) {
+               if (MATCH(result->section, led_str[index]))
+                       break;
+       }
+
+       if (index == LED_MODE_MAX) {
+               _E("No matched valid scenario : %s", result->section);
+               return -EINVAL;
+       }
+
+       /* search for matched led_data */
+       led = find_led_data(index);
+       /* If there is no matched data */
+       if (!led) {
+               /* allocate led_data memory */
+               led = (struct led_mode*)calloc(1, sizeof(struct led_mode));
+               if (!led) {
+                       _E("out of memory : %s", strerror(errno));
+                       return -errno;
+               }
+
+               /* set default value */
+               led->mode = index;
+               led->state = 0;
+               led->data.wave = false;
+               led->data.lcd = DURING_LCD_OFF;
+               led->data.duration = -1;
+
+               /* Add to list */
+               DD_LIST_APPEND(led_head, led);
+       }
+
+       /* parse the result data */
+       if (MATCH(result->name, "priority"))
+               led->data.priority = atoi(result->value);
+       else if (MATCH(result->name, "on"))
+               led->data.on = atoi(result->value);
+       else if (MATCH(result->name, "off"))
+               led->data.off = atoi(result->value);
+       else if (MATCH(result->name, "color"))
+               led->data.color = (unsigned int)strtoul(result->value, NULL, 16);
+       else if (MATCH(result->name, "wave"))
+               led->data.wave = (!strcmp(result->value, "on") ? true : false);
+       else if (MATCH(result->name, "lcd"))
+               led->data.lcd = get_selected_lcd_mode(result->value);
+       else if (MATCH(result->name, "duration"))
+               led->data.duration = atoi(result->value);
+
+       return 0;
+}
+
+static int led_load_config(struct parse_result *result, void *user_data)
+{
+       int ret;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       /* Parsing 'LED' section */
+       if (MATCH(result->section, "LED"))
+               return 0;
+
+       /* Parsing 'Scenario' section */
+       ret = parse_scenario(result, user_data);
+       if (ret < 0) {
+               _E("failed to parse %s section", result->section);
+               return ret;
+       }
+
+       return 0;
+}
+
+int get_led_data(void)
+{
+       int ret;
+
+       /* get configuration file */
+       ret = config_parse(LED_CONF, led_load_config, led_head);
+       if (ret < 0) {
+               _E("failed to load configuration file(%s) : %d", LED_CONF, ret);
+               release_led_data();
+               return ret;
+       }
+
+       /* for debug */
+       print_all_data();
+
+       return 0;
+}
+
+void release_led_data(void)
+{
+       dd_list *l;
+       struct led_mode *node;
+
+       DD_LIST_FOREACH(led_head, l, node) {
+               _D("node name : %d", node->mode);
+               DD_LIST_REMOVE(led_head, node);
+               free(node);
+       }
+}
+
+struct led_mode *find_led_data(int mode)
+{
+       dd_list *l;
+       struct led_mode *node;
+
+       DD_LIST_FOREACH(led_head, l, node) {
+               if (node->mode == mode)
+                       return node;
+       }
+
+       return NULL;
+}
+
+struct led_mode *get_valid_led_data(int lcd_state)
+{
+       dd_list *l;
+       struct led_mode *node;
+       struct led_mode *cur = NULL;
+       int pr = 3;
+
+       DD_LIST_FOREACH(led_head, l, node) {
+               if (!node->state)
+                       continue;
+
+               if (!(node->data.lcd & lcd_state))
+                       continue;
+
+               if (node->data.priority <= pr) {
+                       pr = node->data.priority;
+                       cur = node;
+               }
+       }
+
+       return cur;
+}
+
+void print_all_data(void)
+{
+       dd_list *l;
+       struct led_mode *node;
+
+       _D("Mode State priority   on  off    color lcd wave");
+       DD_LIST_FOREACH(led_head, l, node) {
+               _D("%4d %5d %8d %4d %4d %x %4d %4d",
+                               node->mode, node->state, node->data.priority,
+                               node->data.on, node->data.off, node->data.color,
+                               node->data.lcd, node->data.wave);
+       }
+}
similarity index 80%
rename from src/led/xml.h
rename to src/led/conf.h
index a85375b..37efdd2 100644 (file)
  */
 
 
-#ifndef __XML_H__
-#define __XML_H__
+#ifndef __CONF_H__
+#define __CONF_H__
+
+enum {
+       DURING_LCD_ON = 0x1,
+       DURING_LCD_OFF = 0x2,
+       DURING_BOTH = DURING_LCD_ON | DURING_LCD_OFF,
+};
 
 struct led_mode {
        int mode;
@@ -29,13 +35,15 @@ struct led_mode {
                int off;
                unsigned int color;
                int wave;
+               int lcd;
+               int duration;
        } data;
 };
 
 int get_led_data(void);
 void release_led_data(void);
 struct led_mode *find_led_data(int mode);
-struct led_mode *get_valid_led_data(void);
+struct led_mode *get_valid_led_data(int lcd_state);
 void print_all_data(void);
 
 #endif
diff --git a/src/led/led.conf b/src/led/led.conf
new file mode 100644 (file)
index 0000000..f6967be
--- /dev/null
@@ -0,0 +1,100 @@
+[LED]
+
+###############################
+### LED Indicator Scenarios ###
+###############################
+# priority
+#   0 : the highest
+#   1 : middle (default value)
+#   2 : the lowest
+#   3 : just for Off state
+# on
+#   On time (ms)
+# off
+#   Off time (ms)
+#   If on/off value is zero,
+#   it means led always turns on until app turns off.
+# color
+#   FFRRGGBB
+#   First 2 digits are alpah information
+# lcd
+#   on : turn on during lcd on state
+#   off : turn on during lcd off state (default value)
+#   These value is separated by comma.
+# wave
+#   on : play with wave pattern
+#   off : play with no pattern (default value)
+# duration
+#   the duration of patterns
+#   -1 : infinitly (default value)
+
+[Off]
+priority=3
+on=0
+off=0
+color=FF000000
+lcd=on,off
+
+[Low battery]
+priority=2
+on=500
+off=5000
+color=FFFF0000
+
+[Charging]
+priority=2
+on=0
+off=0
+color=FFFF0000
+
+[Fully charged]
+priority=2
+on=0
+off=0
+color=FF00FF00
+
+[Charging error]
+priority=0
+on=500
+off=500
+color=FFFF0000
+
+[Missed noti]
+priority=1
+on=500
+off=5000
+color=FF0000FF
+
+[Voice recording]
+priority=1
+on=500
+off=500
+color=FF0000FF
+
+[Remote controller]
+priority=1
+on=0
+off=0
+color=FF0000FF
+lcd=on
+
+[Air Wakeup]
+priority=1
+on=1000
+off=0
+color=FF0000FF
+lcd=on
+duration=1
+
+[Power off]
+priority=0
+on=0
+off=0
+color=FF0000FF
+wave=on
+
+[Custom]
+priority=1
+on=500
+off=5000
+color=FF0000FF
index be01dfc..950437c 100644 (file)
@@ -25,7 +25,6 @@
 #include <vconf.h>
 
 #include "deviced/dd-led.h"
-#include "xml.h"
 #include "core/log.h"
 #include "core/common.h"
 #include "core/edbus-handler.h"
@@ -33,6 +32,7 @@
 #include "core/device-notifier.h"
 #include "core/device-handler.h"
 #include "display/core.h"
+#include "conf.h"
 
 #define BOOT_ANIMATION_FINISHED                1
 
@@ -53,17 +53,32 @@ enum {
        LED_CUSTOM_DEFAULT = (LED_CUSTOM_DUTY_ON),
 };
 
-static bool charging_key;
-static bool lowbat_key;
+static int charging_key;
+static int lowbat_key;
 static bool charging_state;
 static bool lowbat_state;
 static bool full_state;
 static bool badbat_state;
 static bool ovp_state;
-static bool rgb_blocked = false;
+static int rgb_blocked = false;
 static bool rgb_dumpmode = false;
 static Ecore_Timer *dumpmode_timer = NULL;
 static enum state_t lcd_state = S_NORMAL;
+static Ecore_Timer *reset_timer;
+
+static int rgb_start(enum device_flags flags)
+{
+       _I("rgbled device will be started");
+       rgb_blocked = false;
+       return 0;
+}
+
+static int rgb_stop(enum device_flags flags)
+{
+       _I("rgbled device will be stopped");
+       rgb_blocked = true;
+       return 0;
+}
 
 static int led_prop(int mode, int on, int off, unsigned int color)
 {
@@ -94,8 +109,8 @@ static int led_prop(int mode, int on, int off, unsigned int color)
                break;
        }
 
-       _D("changed mode(%d) : on(%d), off(%d), color(%x)",
-                       mode, led->data.on, led->data.off, led->data.color);
+       _D("changed mode(%d) : state(%d), on(%d), off(%d), color(%x)",
+                       mode, led->state, led->data.on, led->data.off, led->data.color);
        return 0;
 }
 
@@ -150,9 +165,11 @@ static unsigned int led_blend(unsigned int before)
        return COMBINE_RGB(red, grn, blu);
 }
 
+static Eina_Bool timer_reset_cb(void *data);
 static int led_mode_to_device(struct led_mode *led)
 {
        int val, color;
+       double time;
 
        if (led == NULL)
                return 0;
@@ -163,6 +180,16 @@ static int led_mode_to_device(struct led_mode *led)
        if (rgb_blocked && led->mode != LED_POWER_OFF && led->mode != LED_OFF)
                return 0;
 
+       if (led->data.duration > 0) {
+               time = ((led->data.on + led->data.off) * led->data.duration) / 1000.f;
+               if (reset_timer)
+                       ecore_timer_del(reset_timer);
+               reset_timer = ecore_timer_add(time, timer_reset_cb, led);
+               if (!reset_timer)
+                       _E("failed to add reset timer");
+               _D("add reset timer (mode:%d, %lfs)", led->mode, time);
+       }
+
        val = LED_VALUE(led->data.on, led->data.off);
        color = led_blend(led->data.color);
 
@@ -175,10 +202,32 @@ static int led_mode_to_device(struct led_mode *led)
        return 0;
 }
 
+static Eina_Bool timer_reset_cb(void *data)
+{
+       struct led_mode *led = (struct led_mode*)data;
+
+       if (!led)
+               return ECORE_CALLBACK_CANCEL;
+
+       led->state = false;
+       _D("reset timer (mode:%d)", led->mode);
+
+       /* turn off previous setting */
+       led = find_led_data(LED_OFF);
+       led_mode_to_device(led);
+
+       led = get_valid_led_data(lcd_state);
+       /* preventing duplicated requests */
+       if (led && led->mode != LED_OFF)
+               led_mode_to_device(led);
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
 static int led_display_changed_cb(void *data)
 {
        struct led_mode *led = NULL;
-       int val;
+       int state;
 
        /* store last display condition */
        lcd_state = (enum state_t)data;
@@ -188,11 +237,22 @@ static int led_display_changed_cb(void *data)
                return 0;
 
        if (lcd_state == S_LCDOFF)
-               led = get_valid_led_data();
+               state = DURING_LCD_OFF;
        else if (lcd_state == S_NORMAL || lcd_state == S_LCDDIM)
-               led = find_led_data(LED_OFF);
+               state = DURING_LCD_ON;
+       else
+               return 0;
+
+       /* turn off previous setting */
+       led = find_led_data(LED_OFF);
+       led_mode_to_device(led);
+
+       led = get_valid_led_data(state);
+       /* preventing duplicated requests */
+       if (led && led->mode != LED_OFF)
+               led_mode_to_device(led);
 
-       return led_mode_to_device(led);
+       return 0;
 }
 
 static int led_charging_changed_cb(void *data)
@@ -340,6 +400,17 @@ static void led_vconf_blocking_cb(keynode_t *key, void *data)
        _I("rgbled blocking mode %s", (rgb_blocked ? "started" : "stopped"));
 }
 
+static void led_vconf_psmode_cb(keynode_t *key, void *data)
+{
+       int psmode;
+
+       psmode = vconf_keynode_get_int(key);
+       if (psmode == SETTING_PSMODE_EMERGENCY)
+               rgb_stop(NORMAL_MODE);
+       else
+               rgb_start(NORMAL_MODE);
+}
+
 static DBusMessage *edbus_playcustom(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
@@ -381,6 +452,20 @@ static DBusMessage *edbus_stopcustom(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessageIter iter;
        DBusMessage *reply;
        int val, ret;
+       bool state;
+
+       ret = get_led_mode_state(LED_CUSTOM, &state);
+       if (ret < 0) {
+               _E("failed to get led mode state : %d", ret);
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (!state) {
+               _E("not play custom led");
+               ret = -EPERM;
+               goto error;
+       }
 
        /* reset default value */
        ret = led_mode(LED_CUSTOM, false);
@@ -388,6 +473,7 @@ static DBusMessage *edbus_stopcustom(E_DBus_Object *obj, DBusMessage *msg)
 
        _D("stop custom %d", ret);
 
+error:
        reply = dbus_message_new_method_return(msg);
        dbus_message_iter_init_append(reply, &iter);
        dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
@@ -424,6 +510,15 @@ static DBusMessage *edbus_set_mode(E_DBus_Object *obj, DBusMessage *msg)
        ret = led_mode(mode, val);
        ret = led_prop(mode, on, off, color);
 
+       /* If lcd prop has a during_lcd_on bit,
+          it should turn on/off during lcd on state */
+       led = find_led_data(mode);
+       if (led && (led->data.lcd & DURING_LCD_ON) &&
+           (lcd_state == S_NORMAL || lcd_state == S_LCDDIM)) {
+               led = get_valid_led_data(DURING_LCD_ON);
+               led_mode_to_device(led);
+       }
+
        /* Exception case :
           in case of display off condition,
           who requests missed noti event, it should change the device value */
@@ -526,7 +621,7 @@ static const struct edbus_method edbus_methods[] = {
 
 static void rgb_init(void *data)
 {
-       int ta_connected, boot;
+       int ta_connected, boot, psmode;
        int ret;
        struct led_mode *led;
 
@@ -538,6 +633,9 @@ static void rgb_init(void *data)
        /* get led mode data from xml */
        get_led_data();
 
+       /* LED_OFF state must be always true */
+       led_mode(LED_OFF, true);
+
        /* verify booting or restart */
        ret = vconf_get_int(VCONFKEY_BOOT_ANIMATION_FINISHED, &boot);
        if (ret != 0)
@@ -567,11 +665,11 @@ next:
        register_notifier(DEVICE_NOTIFIER_BATTERY_OVP, led_battery_ovp_changed_cb);
 
        /* initialize vconf value */
-       vconf_get_bool(VCONFKEY_SETAPPL_LED_INDICATOR_CHARGING, (int*)&charging_key);
-       vconf_get_bool(VCONFKEY_SETAPPL_LED_INDICATOR_LOW_BATT, (int*)&lowbat_key);
+       vconf_get_bool(VCONFKEY_SETAPPL_LED_INDICATOR_CHARGING, &charging_key);
+       vconf_get_bool(VCONFKEY_SETAPPL_LED_INDICATOR_LOW_BATT, &lowbat_key);
 
        /* initialize led indicator blocking value */
-       vconf_get_bool(VCONFKEY_SETAPPL_BLOCKINGMODE_LED_INDICATOR, (int*)&rgb_blocked);
+       vconf_get_bool(VCONFKEY_SETAPPL_BLOCKINGMODE_LED_INDICATOR, &rgb_blocked);
 
        /* register vconf callback */
        vconf_notify_key_changed(VCONFKEY_SETAPPL_LED_INDICATOR_CHARGING,
@@ -583,6 +681,14 @@ next:
        vconf_notify_key_changed(VCONFKEY_SETAPPL_BLOCKINGMODE_LED_INDICATOR,
                        led_vconf_blocking_cb, NULL);
 
+       /* check power saving state */
+       vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &psmode);
+       if (psmode == SETTING_PSMODE_EMERGENCY)
+               rgb_stop(NORMAL_MODE);
+
+       /* register power saving callback */
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, led_vconf_psmode_cb, NULL);
+
        ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &ta_connected);
        if (!ret && ta_connected)
                led_charging_changed_cb((void*)ta_connected);
@@ -602,6 +708,9 @@ static void rgb_exit(void *data)
        vconf_ignore_key_changed(VCONFKEY_SETAPPL_BLOCKINGMODE_LED_INDICATOR,
                        led_vconf_blocking_cb);
 
+       /* unregister power saving callback */
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE, led_vconf_psmode_cb);
+
        /* unregister notifier for each event */
        unregister_notifier(DEVICE_NOTIFIER_LCD, led_display_changed_cb);
        unregister_notifier(DEVICE_NOTIFIER_BATTERY_CHARGING, led_charging_changed_cb);
@@ -619,20 +728,6 @@ static void rgb_exit(void *data)
        release_led_data();
 }
 
-static int rgb_start(void)
-{
-       _I("rgbled device will be started");
-       rgb_blocked = false;
-       return 0;
-}
-
-static int rgb_stop(void)
-{
-       _I("rgbled device will be stopped");
-       rgb_blocked = true;
-       return 0;
-}
-
 static const struct device_ops rgbled_device_ops = {
        .priority = DEVICE_PRIORITY_NORMAL,
        .name     = "rgbled",
diff --git a/src/led/xml.c b/src/led/xml.c
deleted file mode 100644 (file)
index 66a3b8d..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 <errno.h>
-#include <assert.h>
-#include <libxml/parser.h>
-
-#include "deviced/dd-led.h"
-#include "xml.h"
-#include "core/log.h"
-#include "core/list.h"
-
-#ifndef DATADIR
-#define DATADIR "/usr/share/deviced"
-#endif
-
-#define LED_XML                DATADIR"/led.xml"
-#define LED_STR                "led"
-
-static const char* led_str[] = {
-       [LED_OFF] = "off",
-       [LED_LOW_BATTERY] = "low battery",
-       [LED_CHARGING] = "charging",
-       [LED_FULLY_CHARGED] = "fully charged",
-       [LED_CHARGING_ERROR] = "charging error",
-       [LED_MISSED_NOTI] = "missed noti",
-       [LED_VOICE_RECORDING] = "voice recording",
-       [LED_POWER_OFF] = "power off",
-       [LED_CUSTOM] = "custom",
-};
-
-static dd_list *led_head;
-
-static xmlDocPtr xml_open(const char *xml)
-{
-       xmlDocPtr doc;
-
-       doc = xmlReadFile(xml, NULL, 0);
-       if (doc == NULL) {
-               _E("xmlReadFile fail");
-               return NULL;
-       }
-
-       return doc;
-}
-
-static void xml_close(xmlDocPtr doc)
-{
-       xmlFreeDoc(doc);
-}
-
-static xmlNodePtr xml_find(xmlDocPtr doc, const xmlChar* expr)
-{
-       xmlNodePtr root;
-       xmlNodePtr cur;
-       xmlChar *key;
-
-       assert(doc);
-       assert(expr);
-
-       root = xmlDocGetRootElement(doc);
-       if (root == NULL) {
-               _E("xmlDocGetRootElement fail");
-               return NULL;
-       }
-
-       for (cur = root->children; cur != NULL; cur = cur->next) {
-               if (xmlStrcmp(cur->name, (const xmlChar*)LED_STR))
-                       continue;
-
-               key = xmlGetProp(cur, (const xmlChar*)"label");
-               if (key && !xmlStrcmp(key, expr)) {
-                       _D("%s", key);
-                       xmlFree(key);
-                       return cur;
-               }
-       }
-
-       return NULL;
-}
-
-static struct led_mode *xml_parse(xmlDocPtr doc, xmlNodePtr cur)
-{
-       xmlNodePtr node;
-       xmlNodePtr attr;
-       struct led_mode *led;
-       xmlChar *key;
-       int i = 0;
-
-       assert(doc);
-       assert(cur);
-
-       led = (struct led_mode*)malloc(sizeof(struct led_mode));
-       if (led == NULL) {
-               _E("out of memory");
-               return NULL;
-       }
-
-       for (node = cur->children; node != NULL; node = node->next) {
-               if (node->type != XML_ELEMENT_NODE)
-                       continue;
-
-               if (!xmlStrcmp(node->name, "priority")) {
-                       key = xmlNodeListGetString(doc, node->children, 1);
-                       if (!key)
-                               continue;
-                       led->data.priority = atoi(key);
-                       xmlFree(key);
-               } else if (!xmlStrcmp(node->name, "data")) {
-                       key = xmlGetProp(node, (const xmlChar*)"on");
-                       if (!key)
-                               continue;
-                       led->data.on = atoi(key);
-                       xmlFree(key);
-
-                       key = xmlGetProp(node, (const xmlChar*)"off");
-                       if (!key)
-                               continue;
-                       led->data.off = atoi(key);
-                       xmlFree(key);
-
-                       key = xmlGetProp(node, (const xmlChar*)"color");
-                       if (!key)
-                               continue;
-                       led->data.color = (unsigned int)strtoul(key, NULL, 16);
-                       xmlFree(key);
-
-                       key = xmlGetProp(node, (const xmlChar*)"wave");
-                       if (!key || xmlStrcmp(key, "on"))
-                               led->data.wave = false;
-                       else
-                               led->data.wave = true;
-                       xmlFree(key);
-               }
-       }
-
-       _D("priority : %d, on : %d, off : %d, color : %x, wave : %d",
-                       led->data.priority, led->data.on, led->data.off,
-                       led->data.color, led->data.wave);
-       return led;
-}
-
-int get_led_data(void)
-{
-       xmlDocPtr doc;
-       xmlNodePtr cur;
-       struct led_mode *led;
-       int i;
-       int r;
-
-       doc = xml_open(LED_XML);
-       if (doc == NULL) {
-               _E("xml_open(%s) fail", LED_XML);
-               errno = EPERM;
-               return -1;
-       }
-
-       for (i = 0; i < LED_MODE_MAX; ++i) {
-               cur = xml_find(doc, (const xmlChar*)led_str[i]);
-               if (cur == NULL) {
-                       _E("xml_find(%s) fail", led_str[i]);
-                       break;
-               }
-
-               led = xml_parse(doc, cur);
-               if (led == NULL) {
-                       _E("xml_parse fail");
-                       break;
-               }
-
-               led->mode = i;
-               led->state = 0;
-               DD_LIST_APPEND(led_head, led);
-       }
-
-       xml_close(doc);
-       return 0;
-}
-
-void release_led_data(void)
-{
-       dd_list *l;
-       struct led_mode *node;
-
-       DD_LIST_FOREACH(led_head, l, node) {
-               _D("node name : %d", node->mode);
-               DD_LIST_REMOVE(led_head, node);         
-               free(node);
-       }
-}
-
-struct led_mode *find_led_data(int mode)
-{
-       dd_list *l;
-       struct led_mode *node;
-
-       DD_LIST_FOREACH(led_head, l, node) {
-               if (node->mode == mode)
-                       return node;
-       }
-
-       return NULL;
-}
-
-struct led_mode *get_valid_led_data(void)
-{
-       dd_list *l;
-       struct led_mode *node;
-       struct led_mode *cur = NULL;
-       int pr = 2;
-
-       DD_LIST_FOREACH(led_head, l, node) {
-               if (!node->state)
-                       continue;
-               if (node->data.priority <= pr) {
-                       pr = node->data.priority;
-                       cur = node;
-               }
-       }
-
-       return cur;
-}
-
-void print_all_data(void)
-{
-       dd_list *l;
-       struct led_mode *node;
-
-       _D("Mode State priority   on  off    color wave");
-       DD_LIST_FOREACH(led_head, l, node) {
-               _D("%4d %5d %8d %4d %4d %x %4d",
-                               node->mode, node->state, node->data.priority,
-                               node->data.on, node->data.off, node->data.color, node->data.wave);
-       }
-}
index fc6a787..d333f38 100755 (executable)
@@ -5,6 +5,7 @@ SET(LIBDEVICED_SRCS
        battery.c
        control.c
        display.c
+       dbus.c
        haptic.c
        led.c
        mmc.c
@@ -22,6 +23,7 @@ pkg_check_modules(libpkgs REQUIRED
        vconf
        dlog
        dbus-1
+       dbus-glib-1
        edbus)
 
 FOREACH(flag ${libpkgs_CFLAGS})
@@ -30,7 +32,7 @@ ENDFOREACH(flag)
 
 # libdeviced
 ADD_LIBRARY(${PROJECT_NAME} SHARED ${LIBDEVICED_SRCS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${libpkgs_LDFLAGS} shared)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${libpkgs_LDFLAGS})
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
 # CMake Policy (CMP0002)
 # The logical name of executable and library targes
diff --git a/src/libdeviced/dbus.c b/src/libdeviced/dbus.c
new file mode 100644 (file)
index 0000000..b204635
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <errno.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "common.h"
+#include "log.h"
+#include "dbus.h"
+
+/* -1 is a default timeout value, it's converted to 25*1000 internally. */
+#define DBUS_REPLY_TIMEOUT     (-1)
+
+struct pending_call_data {
+       dbus_pending_cb func;
+       void *data;
+};
+
+int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
+{
+       char *ch;
+       int i;
+       int int_type;
+       dbus_bool_t bool_type;
+       uint64_t int64_type;
+       DBusMessageIter arr;
+       struct dbus_byte *byte;
+
+       if (!sig || !param)
+               return 0;
+
+       for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
+               switch (*ch) {
+               case 'b':
+                       bool_type = (atoi(param[i])) ? TRUE:FALSE;
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &bool_type);
+                       break;
+               case 'i':
+                       int_type = atoi(param[i]);
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
+                       break;
+               case 'u':
+                       int_type = strtoul(param[i], NULL, 10);
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
+                       break;
+               case 't':
+                       int64_type = atoll(param[i]);
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
+                       break;
+               case 's':
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &param[i]);
+                       break;
+               case 'a':
+                       ++i, ++ch;
+                       switch (*ch) {
+                       case 'y':
+                               dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr);
+                               byte = (struct dbus_byte*)param[i];
+                               dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &(byte->data), byte->size);
+                               dbus_message_iter_close_container(iter, &arr);
+                               break;
+                       default:
+                               break;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+DBusMessage *dbus_method_sync_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[])
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       DBusError err;
+       int r;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return NULL;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return NULL;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       r = append_variant(&iter, sig, param);
+       if (r < 0) {
+               _E("append_variant error(%d) %s %s:%s-%s",
+                       r, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return NULL;
+       }
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
+       if (!reply) {
+               _E("dbus_connection_send error(No reply) %s %s:%s-%s",
+                       dest, path, interface, method);
+       }
+
+       if (dbus_error_is_set(&err)) {
+               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               reply = NULL;
+       }
+
+       dbus_message_unref(msg);
+       return reply;
+}
+
+int dbus_method_sync(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[])
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       DBusError err;
+       int ret, result;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return -EPERM;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return -EBADMSG;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       ret = append_variant(&iter, sig, param);
+       if (ret < 0) {
+               _E("append_variant error(%d) %s %s:%s-%s",
+                       ret, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return ret;
+       }
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
+       dbus_message_unref(msg);
+       if (!reply) {
+               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               return -ECOMM;
+       }
+
+       ret = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+       dbus_message_unref(reply);
+       if (!ret) {
+               _E("no message : [%s:%s] %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               return -ENOMSG;
+       }
+
+       return result;
+}
+
+int dbus_method_async(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[])
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       int ret;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return -EPERM;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return -EBADMSG;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       ret = append_variant(&iter, sig, param);
+       if (ret < 0) {
+               _E("append_variant error(%d) %s %s:%s-%s",
+                       ret, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return ret;
+       }
+
+       ret = dbus_connection_send(conn, msg, NULL);
+       dbus_message_unref(msg);
+       if (ret != TRUE) {
+               _E("dbus_connection_send error(%s %s:%s-%s)",
+                       dest, path, interface, method);
+               return -ECOMM;
+       }
+
+       return 0;
+}
+
+static void cb_pending(DBusPendingCall *pending, void *user_data)
+{
+       DBusMessage *msg;
+       DBusError err;
+       struct pending_call_data *data = user_data;
+       int ret;
+
+       ret = dbus_pending_call_get_completed(pending);
+       if (!ret) {
+               _I("dbus_pending_call_get_completed() fail");
+               dbus_pending_call_unref(pending);
+               return;
+       }
+
+       dbus_error_init(&err);
+       msg = dbus_pending_call_steal_reply(pending);
+       if (!msg) {
+               _E("no message : [%s:%s]", err.name, err.message);
+
+               if (data->func) {
+                       dbus_set_error(&err, "org.tizen.system.deviced.NoReply",
+                                       "There was no reply to this method call");
+                       data->func(data->data, NULL, &err);
+                       dbus_error_free(&err);
+               }
+               return;
+       }
+
+       ret = dbus_set_error_from_message(&err, msg);
+       if (ret) {
+               _E("error msg : [%s:%s]", err.name, err.message);
+
+               if (data->func)
+                       data->func(data->data, NULL, &err);
+               dbus_error_free(&err);
+       } else {
+               if (data->func)
+                       data->func(data->data, msg, &err);
+       }
+
+       dbus_message_unref(msg);
+       dbus_pending_call_unref(pending);
+}
+
+int dbus_method_async_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data)
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusPendingCall *pending = NULL;
+       struct pending_call_data *pdata;
+       int ret;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return -EPERM;
+       }
+
+       /* this function should be invoked to receive dbus messages
+        * does nothing if it's already been done */
+       dbus_connection_setup_with_g_main(conn, NULL);
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return -EBADMSG;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       ret = append_variant(&iter, sig, param);
+       if (ret < 0) {
+               _E("append_variant error(%d)%s %s:%s-%s",
+                       ret, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return ret;
+       }
+
+       ret = dbus_connection_send_with_reply(conn, msg, &pending, timeout);
+       if (!ret) {
+               dbus_message_unref(msg);
+               _E("dbus_connection_send error(%s %s:%s-%s)",
+                       dest, path, interface, method);
+               return -ECOMM;
+       }
+
+       dbus_message_unref(msg);
+
+       if (cb && pending) {
+               pdata = malloc(sizeof(struct pending_call_data));
+               if (!pdata)
+                       return -ENOMEM;
+
+               pdata->func = cb;
+               pdata->data = data;
+
+               ret = dbus_pending_call_set_notify(pending, cb_pending, pdata, free);
+               if (!ret) {
+                       free(pdata);
+                       dbus_pending_call_cancel(pending);
+                       return -ECOMM;
+               }
+       }
+
+       return 0;
+}
+
+static void __CONSTRUCTOR__ dbus_init(void)
+{
+       dbus_threads_init_default();
+}
index 3ae6746..da3faf0 100755 (executable)
 
 #define PREDEF_DUMP_LOG                        "dump_log"
 #define PREDEF_DELETE_DUMP             "delete_dump"
-#define PREDEF_FLIGHT_MODE             "flightmode"
-#define PREDEF_LED_CMD                 "ledcmd"
-#define PREDEF_LED_BRT                 "ledbrt"
-#define PREDEF_LED_MODE                "ledmode"
+#define FLIGHT_MODE            "flightmode"
 
 #define ALARM_BUS_NAME         "com.samsung.alarm.manager"
 #define ALARM_PATH_NAME                "/com/samsung/alarm/manager"
@@ -151,6 +148,45 @@ static int noti_send(struct sysnoti *msg)
        return result;
 }
 
+static int dbus_flightmode_handler(char* type, char *buf)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[3];
+       int ret, val;
+
+       pa[0] = type;
+       pa[1] = "1";
+       pa[2] = buf;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER,
+                       pa[0], "sis", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_POWER, pa[0], val);
+       return val;
+}
+
+API int deviced_change_flightmode(int mode)
+{
+       char buf[255];
+       snprintf(buf, sizeof(buf), "%d", mode);
+       return dbus_flightmode_handler(FLIGHT_MODE, buf);
+}
+
 API int deviced_call_predef_action(const char *type, int num, ...)
 {
        struct sysnoti *msg;
index 3cb19a6..46b6dbb 100644 (file)
@@ -85,11 +85,16 @@ API int deviced_get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
        char buf[PATH_MAX + 1];
        char *filename;
 
+       if (cmdline == NULL) {
+               errno = EINVAL;
+               return -EINVAL;
+       }
+
        snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
        fd = open(buf, O_RDONLY);
        if (fd < 0) {
                errno = ESRCH;
-               return -1;
+               return -ESRCH;
        }
 
        ret = read(fd, buf, PATH_MAX);
@@ -104,7 +109,7 @@ API int deviced_get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
 
        if (cmdline_size < strlen(filename) + 1) {
                errno = EOVERFLOW;
-               return -1;
+               return -EOVERFLOW;
        }
 
        strncpy(cmdline, filename, cmdline_size - 1);
index 70daf48..0601371 100644 (file)
@@ -477,6 +477,12 @@ API int display_set_color_blind(int enable, struct blind_color_info *info)
        char *arr[4];
        int ret, ret_val;
 
+       if (!info)
+               return -EINVAL;
+
+       if (!!enable != enable)
+               return -EINVAL;
+
        snprintf(str_enable, sizeof(str_enable), "%d", enable);
        arr[0] = str_enable;
        snprintf(str_red, sizeof(str_red), "%llu", BLIND_COLOR(info->RrCr, info->RgCg, info->RbCb));
@@ -607,9 +613,6 @@ API int display_lock_state(unsigned int s_bits, unsigned int flag,
                p = STR_NULL;
        pa[2] = p;
 
-       if (timeout < 0)
-               return -EINVAL;
-
        snprintf(str_timeout, sizeof(str_timeout), "%d", timeout);
        pa[3] = str_timeout;
 
index 86c23a7..8fcfe76 100644 (file)
@@ -116,6 +116,10 @@ API int led_set_brightness_with_noti(int val, bool enable)
 
 API int led_set_ir_command(char *value)
 {
+       if (value == NULL) {
+               return -EINVAL;
+       }
+
        DBusError err;
        DBusMessage *msg;
        char *arr[1];
index 73f1a1e..f2c60e7 100644 (file)
 
 #define ODE_MOUNT_STATE 1
 
+#define FORMAT_TIMEOUT (120*1000)
+
 API int mmc_secure_mount(const char *mount_point)
 {
+       if (mount_point == NULL) {
+               return -EINVAL;
+       }
+
        char *arr[1];
        arr[0] = (char *)mount_point;
        return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_MMC,
@@ -44,6 +50,10 @@ API int mmc_secure_mount(const char *mount_point)
 
 API int mmc_secure_unmount(const char *mount_point)
 {
+       if (mount_point == NULL) {
+               return -EINVAL;
+       }
+
        char *arr[1];
        arr[0] = (char *)mount_point;
        return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_MMC,
@@ -207,5 +217,5 @@ API int deviced_format_mmc(struct mmc_contents *mmc_data, int option)
                        DEVICED_PATH_MMC,
                        DEVICED_INTERFACE_MMC,
                        METHOD_REQUEST_FORMAT,
-                       "i", arr, format_cb, -1, data);
+                       "i", arr, format_cb, FORMAT_TIMEOUT, data);
 }
diff --git a/src/logd/CMakeLists.txt b/src/logd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a84b849
--- /dev/null
@@ -0,0 +1,10 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(PROJECT logd)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(INCLUDEDIR ${PREFIX}/include)
+SET(LIBDIR ${PREFIX}/lib)
+SET(VERSION ${LOGD_VERSION})
+
+############### SUBDIRS ##########################
+ADD_SUBDIRECTORY(src)
diff --git a/src/logd/src/CMakeLists.txt b/src/logd/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5e78a93
--- /dev/null
@@ -0,0 +1,29 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(LIB_LOGD "logd")
+SET(LIB_LOGD_DB "logd-db")
+############### SET FLAGS ########################
+SET(COMMON_FLAGS "-DVERSION=\"${VERSION}\" -Wall -Werror -Wextra -Wno-unused-parameter -Wunused-macros -Wformat=2 -Wshadow -Wstrict-overflow=1 -g -fvisibility=hidden -fPIC -Wl,-lrt")
+
+#SET(COMMON_FLAGS "${COMMON_FLAGS} -DUSE_TASKSTATS")
+
+SET(CMAKE_C_FLAGS "-std=gnu99 ${COMMON_FLAGS}")
+SET(CMAKE_CXX_FLAGS "-std=gnu++0x ${COMMON_FLAGS}")
+
+IF ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
+       SET(DEBUG_ENABLED 1)
+       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gdwarf-4 -O0")
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -gdwarf-4 -O0")
+       SET(CMAKE_VERBOSE_MAKEFILE ON)
+ENDIF()
+
+############### INCLUDE ##########################
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/logd/src/liblogd)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/logd/src/liblogd-db)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/logd/src/shared)
+
+############### SUBDIRS ##########################
+ADD_SUBDIRECTORY(shared)
+ADD_SUBDIRECTORY(battery)
+ADD_SUBDIRECTORY(liblogd-db)
+ADD_SUBDIRECTORY(liblogd)
diff --git a/src/logd/src/battery/CMakeLists.txt b/src/logd/src/battery/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5394e9e
--- /dev/null
@@ -0,0 +1,35 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(logd_battery)
+
+SET(BATTERY_CALIBRATION_SOURCES
+       calibration.c)
+
+SET(POWER_MONITOR_SOURCES
+       power-monitor.cpp)
+
+############### SET FLAGS ########################
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(logd_battery_pkgs REQUIRED vconf libsystemd-journal)
+
+FOREACH(flag ${logd_battery_pkgs_LDFLAGS})
+       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${logd_battery_pkgs_CFLAGS})
+       SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lrt -std=c++0x")
+
+############### TARGET ###########################
+ADD_EXECUTABLE(${PROJECT_NAME}_calibration ${BATTERY_CALIBRATION_SOURCES})
+ADD_EXECUTABLE(logd_power_monitor ${POWER_MONITOR_SOURCES})
+TARGET_LINK_LIBRARIES(logd_power_monitor ${LIB_LOGD_DB} ${LIB_LOGD})
+
+############### INSTALL ##########################
+INSTALL(TARGETS ${PROJECT_NAME}_calibration
+       DESTINATION bin)
+INSTALL(TARGETS logd_power_monitor
+       DESTINATION bin)
diff --git a/src/logd/src/battery/calibration.c b/src/logd/src/battery/calibration.c
new file mode 100644 (file)
index 0000000..1d3bf44
--- /dev/null
@@ -0,0 +1,222 @@
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <vconf.h>
+
+#include "macro.h"
+
+static int default_timeout = 10;
+
+struct calibration_test {
+       const char *description;
+       int (*func)(void *);
+       void *param;
+       int consumption;
+};
+
+static int run_test_battery(int timeout);
+static int (*run_test)(int) = run_test_battery;
+
+static int system_cmd(const char *cmd, char *const args[])
+{
+       pid_t pid = fork();
+
+
+       if (pid == 0) {
+               if (execv(cmd, args) < 0) {
+                       perror("execv: ");
+               }
+       } else if (pid == -1) {
+               fprintf(stderr, "Can't run \"%s\"\n", cmd);
+               return -errno;
+       } else {
+               wait(NULL);
+       }
+
+       return 0;
+}
+
+static int current_battery_level(void)
+{
+       const char *cmd = "/bin/cat /sys/class/power_supply/battery/uevent |\
+/bin/grep POWER_SUPPLY_CAPACITY_RAW | /usr/bin/cut -d '=' -f 2";
+       FILE *fp = NULL;
+       int level;
+
+       fp = popen(cmd, "r");
+       if (fp == NULL) {
+               fprintf(stderr, "Can't obtain battery level\n");
+               return -errno;
+       }
+
+       if (fscanf(fp, "%d", &level) <= 0) {
+               fprintf(stderr, "Can't read power supply\n");
+               fclose(fp);
+               return -EIO;
+       }
+
+       fclose(fp);
+
+       return level;
+}
+
+static int power_supply(void)
+{
+       FILE *fp = NULL;
+       int ps;
+
+       /* TODO: move hardware depended settings to config file */
+       fp = fopen("/sys/class/power_supply/max17047-fuelgauge/current_avg", "r");
+       if (fp == NULL) {
+               fprintf(stderr, "Can't open current_now\n");
+               return -errno;
+       }
+
+       if (fscanf(fp, "%d", &ps) <= 0) {
+               fprintf(stderr, "Can't read power supply\n");
+               fclose(fp);
+               return -EIO;
+       }
+       fclose(fp);
+
+       return -ps;
+}
+
+static int write_number(const char *file, int number)
+{
+       FILE *fp = NULL;
+
+       fp = fopen(file, "w");
+       if (fp == NULL) {
+               fprintf(stderr, "Can't open current_now\n");
+               return -errno;
+       }
+
+       fprintf(fp, "%d", number);
+       fclose(fp);
+
+       return 0;
+}
+
+static int run_test_battery(int timeout)
+{
+       int level1 = current_battery_level();
+       sleep(timeout);
+       int level2 = current_battery_level();
+
+       return level1 - level2;
+}
+
+static int run_test_power_supply(int timeout)
+{
+       sleep(timeout);
+
+       return power_supply();
+}
+
+/* display */
+static void set_brightness(int value)
+{
+       write_number("/sys/class/backlight/s6d6aa1-bl/brightness", value);
+}
+
+static void display_on(void)
+{
+       char cmd[] = "/usr/bin/xset";
+       char *const args[] = { cmd, "dpms", "force", "on", NULL };
+       system_cmd(cmd, args);
+}
+
+static void display_off(void)
+{
+       char cmd[] = "/usr/bin/xset";
+       char *const args[] = { cmd, "dpms", "force", "off", NULL };
+       system_cmd(cmd, args);
+}
+
+static int run_display_test(void *brightness)
+{
+       int consumption = 0;
+       display_on();
+       set_brightness((int)brightness);
+       consumption = run_test(default_timeout);
+       display_off();
+
+       return consumption;
+}
+
+/* default */
+static int run_default_test(void *user_data)
+{
+       display_off();
+
+       return run_test(default_timeout);
+}
+
+/* wi-fi */
+static int wifi_on(void)
+{
+       char cmd[] = "/usr/bin/wifi-qs";
+       char *const args[] = { cmd, NULL };
+       system_cmd(cmd, args);
+       sleep(10);
+
+       return 0;
+}
+
+static int run_wifi_test(void *user_data)
+{
+       if (wifi_on() < 0)
+               return -1;
+
+       return run_test(default_timeout);
+}
+
+/* gps */
+static int run_gps_test(void *user_data)
+{
+       vconf_set_int(VCONFKEY_LOCATION_ENABLED, 1);
+       int consumption = run_test(default_timeout);
+       vconf_set_int(VCONFKEY_LOCATION_ENABLED, 0);
+       return consumption;
+}
+
+int main(int argc, char *argv[])
+{
+       struct calibration_test tests[] = {
+               {"default", run_default_test, NULL, 0},
+               {"display 1", run_display_test, (void*)1, 0},
+               {"display 20", run_display_test, (void*)20, 0},
+               {"display 40", run_display_test, (void*)40, 0},
+               {"display 60", run_display_test, (void*)60, 0},
+               {"display 80", run_display_test, (void*)80, 0},
+               {"display 100", run_display_test, (void*)100, 0},
+               {"gps", run_gps_test, NULL, 0},
+               {"wifi", run_wifi_test, NULL, 0},
+       };
+
+       for (int i = 1; i < argc; ++i) {
+               if (strcmp(argv[i], "-p") == 0) {
+                       run_test = run_test_power_supply;
+                       default_timeout = 30;
+               }
+       }
+       signal(SIGHUP, SIG_IGN);
+       printf("timeout = %d\n", default_timeout);
+
+       for (size_t i = 0; i < ARRAY_SIZE(tests); ++i) {
+               tests[i].consumption = tests[i].func(tests[i].param);
+               if (tests[i].consumption >= 0) {
+                       printf("%s: %d %.2f\n", tests[i].description, tests[i].consumption,
+                                (float)tests[i].consumption / tests[0].consumption);
+               } else {
+                       fprintf(stderr, "Can't run \"%s\" test\n", tests[i].description);
+               }
+       }
+
+       return 0;
+}
diff --git a/src/logd/src/battery/power-monitor.cpp b/src/logd/src/battery/power-monitor.cpp
new file mode 100644 (file)
index 0000000..9862d39
--- /dev/null
@@ -0,0 +1,87 @@
+#include <algorithm>
+#include <logd.h>
+#include <logd-db.h>
+#include <iostream>
+#include <map>
+#include <string>
+#include <stdlib.h>
+#include <vector>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+using namespace std;
+
+static uint64_t getTimeUSec()
+{
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts);
+       return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
+}
+
+struct Stat {
+       string appid;
+       float totalCons; /* uAh */
+       float currentCons; /* mA */
+};
+
+static vector<Stat> newStat;
+static map<string, Stat> oldStat;
+
+static enum logd_db_query proc_stat_cb(const struct logd_proc_stat *proc_stat, void *user_data)
+{
+       Stat stat;
+
+       stat.totalCons = proc_stat->stime_power_cons + proc_stat->utime_power_cons;
+       stat.appid = proc_stat->application;
+       newStat.push_back(stat);
+
+
+       return LOGD_DB_QUERY_CONTINUE;
+}
+
+int main(int argc, char **argv)
+{
+       float totalCurrent = 0;
+       float total = 0;
+       uint64_t lastTime = 0;
+
+       while (1) {
+               uint64_t curTime = getTimeUSec();
+               newStat.clear();
+               logd_foreach_proc_stat(&proc_stat_cb, NULL);
+               totalCurrent = total = 0;
+
+               for (auto it = newStat.begin(); it != newStat.end(); ++it) {
+                       it->currentCons = 0;
+                       if (oldStat.count(it->appid)) {
+                               total += it->totalCons;
+                               it->currentCons =
+                                       (it->totalCons - oldStat[it->appid].totalCons) * 3.6 /
+                                       (curTime - lastTime) * 1000;
+                               totalCurrent += it->currentCons;
+                       }
+               }
+               oldStat.clear();
+               lastTime = curTime;
+
+               sort(newStat.begin(), newStat.end(),
+                       [] (Stat lhs, Stat rhs)
+                       {
+                               return lhs.currentCons > rhs.currentCons;
+                       });
+
+
+               printf("%-50.50s %15s %15s\n", "Application", "power cons, uah", "current, mA");
+               auto it = newStat.begin();
+               for (size_t i = 0; i < newStat.size(); ++i, ++it) {
+                       if (i < 20 && totalCurrent)
+                               printf("%-50.50s %15.2f %15.2f (%.2f%%)\n", it->appid.c_str(),
+                                       it->totalCons, it->currentCons, it->currentCons / totalCurrent * 100);
+                       oldStat[it->appid] = *it;
+               }
+               printf("\n%-50.50s %15.2f  %15.4f\n", "Total", total, totalCurrent);
+               sleep(1);
+               printf("\033[2J\033[1;1H");
+       }
+}
diff --git a/src/logd/src/liblogd-db/CMakeLists.txt b/src/logd/src/liblogd-db/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1bc7f40
--- /dev/null
@@ -0,0 +1,44 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(PC_NAME ${LIB_LOGD_DB})
+SET(PC_REQUIRED "sqlite3")
+SET(PC_PROVIDED_LIBS "-l${LIB_LOGD_DB}")
+SET(PC_CFLAGS -I\${includedir}/${LIB_LOGD_DB})
+
+CONFIGURE_FILE(
+       lib${LIB_LOGD_DB}.pc.in
+       lib${LIB_LOGD_DB}.pc
+       @ONLY
+)
+
+SET(LIB_SOURCE
+       db.c
+       devices.c
+       events.c
+       proc-stat.c
+       padvisor.c)
+
+############### SET FLAGS ########################
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(liblogd_db_pkgs REQUIRED sqlite3 libsystemd-journal dlog)
+
+FOREACH(flag ${liblogd_db_pkgs_LDFLAGS})
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${liblogd_db_pkgs_CFLAGS})
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+############### TARGET ###########################
+ADD_LIBRARY(${LIB_LOGD_DB} SHARED ${LIB_SOURCE})
+TARGET_LINK_LIBRARIES(${LIB_LOGD_DB} socket-helper systemd-journal)
+
+############### INSTALL ##########################
+INSTALL(TARGETS ${LIB_LOGD_DB} DESTINATION lib)
+INSTALL(FILES logd-db.h DESTINATION include/${LIB_LOGD_DB})
+INSTALL(FILES padvisor.h DESTINATION include/${LIB_LOGD_DB})
+INSTALL(FILES lib${LIB_LOGD_DB}.pc DESTINATION lib/pkgconfig)
+
+############### SUBDIRS ##########################
+ADD_SUBDIRECTORY(tests)
diff --git a/src/logd/src/liblogd-db/db.c b/src/logd/src/liblogd-db/db.c
new file mode 100644 (file)
index 0000000..5517a13
--- /dev/null
@@ -0,0 +1,47 @@
+#include <sqlite3.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "devices.h"
+#include "events.h"
+#include "logd-db.h"
+#include "macro.h"
+#include "padvisor.h"
+#include "proc-stat.h"
+
+static sqlite3 *db = 0;
+static char *db_file_path = "/opt/dbspace/.logd.db";
+
+__attribute__ ((constructor))
+static int db_init(void)
+{
+       DB_CHECK(sqlite3_open(db_file_path, &db));
+
+       devices_init();
+       events_init();
+       padvisor_init();
+       proc_stat_init();
+
+
+       return 0;
+}
+
+__attribute__ ((destructor))
+static int db_finalize(void)
+{
+       devices_finalize();
+       events_finalize();
+       padvisor_finalize();
+       proc_stat_finalize();
+
+       sqlite3_close(db);
+
+       return 0;
+}
+
+sqlite3 *logd_get_db(void)
+{
+       return db;
+}
diff --git a/src/logd/src/liblogd-db/db.h b/src/logd/src/liblogd-db/db.h
new file mode 100644 (file)
index 0000000..1af41d5
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef _LOGD_DB_H_
+#define _LOGD_DB_H_
+
+#include <sqlite3.h>
+#include <stdint.h>
+
+#include "core/log.h"
+#include "logd.h"
+#include "logd-db.h"
+#include "padvisor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_SQL_SIZE 1000
+
+
+#define PREPARE_STMT(stmt, sql)                                                \
+       do {                                                            \
+               if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL)        \
+                       != SQLITE_OK) {                                 \
+                       _E("Can't prepare statement");                  \
+                       stmt = 0;                                       \
+                       return -1;                                      \
+               }                                                       \
+       } while (0);
+
+#define FINALIZE_STMT(stmt)                                            \
+       do {                                                            \
+               if (sqlite3_finalize(stmt) != SQLITE_OK) {              \
+                       _E("Can't finalize prepared statement: %s",     \
+                          sqlite3_errmsg(db));                         \
+                       return -1;                                      \
+               }                                                       \
+               stmt = 0;                                               \
+       } while (0);
+
+#define DB_CHECK(ret)                                                  \
+       do {                                                            \
+               if (ret != SQLITE_OK) {                                 \
+                       _E("data base error: %s", sqlite3_errmsg(db));  \
+                       sqlite3_close(db);                              \
+                       return -1;                                      \
+               }                                                       \
+       } while (0);
+
+sqlite3 *logd_get_db(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_DB_H_ */
diff --git a/src/logd/src/liblogd-db/devices.c b/src/logd/src/liblogd-db/devices.c
new file mode 100644 (file)
index 0000000..b31f957
--- /dev/null
@@ -0,0 +1,391 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "core/log.h"
+#include "db.h"
+#include "devices.h"
+#include "macro.h"
+#include "socket-helper.h"
+
+#define STORE_POWER_CONS_SQL "INSERT INTO device_working_time \
+(time_stamp, device, time) VALUES(?, ?, ?); "
+
+#define STORE_POWER_MODE_SQL "INSERT INTO power_mode \
+(time_stamp, old_mode_number, new_mode_number, duration, battery_level_change) \
+VALUES (?, ?, ?, ?, ?); "
+
+#define LOAD_POWER_MODE_STAT_SQL "SELECT * FROM power_mode WHERE \
+old_mode_number=? order by id DESC;"
+
+#define MIN_BATTERY_LEVEL 0
+#define MAX_BATTERY_LEVEL 10000
+
+static int device_state[LOGD_OBJECT_MAX] = { 0, };
+
+static sqlite3 *db;
+static sqlite3_stmt *store_power_cons_stmt;
+static sqlite3_stmt *store_power_mode_stmt;
+static sqlite3_stmt *load_power_mode_stat_stmt;
+
+int devices_init(void)
+{
+       db = logd_get_db();
+
+       PREPARE_STMT(store_power_cons_stmt, STORE_POWER_CONS_SQL);
+       PREPARE_STMT(store_power_mode_stmt, STORE_POWER_MODE_SQL);
+       PREPARE_STMT(load_power_mode_stat_stmt, LOAD_POWER_MODE_STAT_SQL);
+
+       return 0;
+}
+
+int devices_finalize(void)
+{
+       FINALIZE_STMT(store_power_cons_stmt);
+       FINALIZE_STMT(store_power_mode_stmt);
+       FINALIZE_STMT(load_power_mode_stat_stmt);
+
+       return 0;
+}
+
+int logd_store_device_wt(uint64_t time_stamp, enum logd_object device, time_t _time)
+{
+       DB_CHECK(sqlite3_reset(store_power_cons_stmt));
+       DB_CHECK(sqlite3_bind_int64(store_power_cons_stmt, 1, time_stamp));
+       DB_CHECK(sqlite3_bind_int(store_power_cons_stmt, 2, device));
+       DB_CHECK(sqlite3_bind_int(store_power_cons_stmt, 3, _time));
+
+       if (sqlite3_step(store_power_cons_stmt) != SQLITE_DONE) {
+               _E("Can't store device workingtime: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       return 0;
+}
+
+API int store_devices_workingtime(enum logd_object device, int state)
+{
+       static time_t last_time = 0;
+       time_t current_time = time(NULL);
+
+       if (last_time) {
+               for (size_t i = 0; i < ARRAY_SIZE(device_state); ++i) {
+                       if (device_state[i])
+                               logd_store_device_wt(current_time, i, current_time - last_time);
+               }
+       }
+
+       device_state[device] = state;
+       last_time = current_time;
+
+       return 0;
+}
+
+API int logd_foreach_devices_stat(enum logd_db_query (*cb)
+        (const struct logd_device_stat *, void *), void *user_data)
+{
+       int sock;
+       int count;
+       int i;
+       int ret = 0;
+       struct logd_device_stat dev_stat;
+       enum logd_socket_req_type req_type = LOGD_DEV_STAT_REQ;
+
+       if ((sock = connect_to_logd_socket()) < 0) {
+               _E("Failed connect_to_logd_socket");
+               return sock;
+       }
+
+       if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
+               ret = -errno;
+               _E("can't write to socket");
+               goto out;
+       }
+
+       if (read_from_socket(sock, &count, sizeof(count)) != sizeof(count)) {
+               ret = -errno;
+               _E("can't read from socket");
+               goto out;
+       }
+
+       for (i = 0; i < count; ++i) {
+               if (read_from_socket(sock, &dev_stat, sizeof(dev_stat)) != sizeof(dev_stat)) {
+                       ret = -errno;
+                       _E("can't read from socket");
+                       goto out;
+               }
+               if (cb(&dev_stat, user_data) == LOGD_DB_QUERY_STOP)
+                       break;
+       }
+out:
+       close(sock);
+
+       return ret;
+}
+
+API int logd_get_estimate_battery_lifetime(int **estimate_times)
+{
+       int sock;
+       int ret = 0;
+       enum logd_socket_req_type req_type = LOGD_EST_TIME_REQ;
+       int i;
+
+       (*estimate_times) = (int*)calloc(LOGD_POWER_MODE_MAX, sizeof(int));
+       if (!(*estimate_times)) {
+               _E("can't alloc memory");
+               return -ENOMEM;
+       }
+
+       if ((sock = connect_to_logd_socket()) < 0) {
+               _E("Failed connect_to_logd_socket");
+               free((*estimate_times));
+               return sock;
+       }
+
+       if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
+               ret = -errno;
+               _E("can't write to socket");
+               free((*estimate_times));
+               goto out;
+       }
+
+       for (i = 0; i < LOGD_POWER_MODE_MAX; ++i) {
+               int est_time;
+
+               if (read_from_socket(sock, &est_time, sizeof(est_time)) != sizeof(est_time)) {
+                       ret = -errno;
+                       _E("can't read from socket");
+                       free((*estimate_times));
+                        goto out;
+               }
+               (*estimate_times)[i] = est_time;
+       }
+
+out:
+       close(sock);
+       return ret;
+
+}
+
+API struct logd_battery_info* logd_get_battery_info(void)
+{
+       int sock;
+       int count;
+       int i;
+       enum logd_socket_req_type req_type = LOGD_BATTERY_LVL_REQ;
+
+       struct logd_battery_info *info = NULL;
+
+       if ((sock = connect_to_logd_socket()) < 0) {
+               _E("Failed connect_to_logd_socket");
+               return NULL;
+       }
+
+       if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
+               _E("can't write to socket");
+               goto err;
+       }
+
+       if (read_from_socket(sock, &count, sizeof(count)) != sizeof(count)) {
+               _E("can't read from socket");
+               goto err;
+       }
+
+       if (count <= 0) {
+               _E("wrong count value");
+               goto err;
+       }
+
+       info = (struct logd_battery_info*) calloc(1, sizeof(struct logd_battery_info));
+       info->n = count;
+       info->levels = (struct logd_battery_level*)
+               malloc(sizeof(struct logd_battery_level) * count);
+
+       for (i = 0; i < count; ++i) {
+               if (read_from_socket(
+                       sock, info->levels + i, sizeof(struct logd_battery_level)) !=
+                               sizeof(struct logd_battery_level)) {
+                       _E("can't read from socket");
+                       goto err;
+               }
+       }
+
+       close(sock);
+
+       return info;
+
+err:
+       close(sock);
+       logd_free_battery_info(info);
+       return NULL;
+}
+
+API int logd_seek_battery_level(struct logd_battery_info *info, int level)
+{
+       int i;
+
+       if (level < MIN_BATTERY_LEVEL || level > MAX_BATTERY_LEVEL
+               || info == NULL)
+               return -EINVAL;
+
+       for (i = info->n - 1; i >= 0; --i) {
+               if (info->levels[i].level == level)
+                       return i;
+       }
+
+       return 0;
+}
+
+API void logd_free_battery_info(struct logd_battery_info *info)
+{
+       if (!info)
+               return;
+
+       if (info->levels)
+               free(info->levels);
+       free(info);
+}
+
+API float logd_battery_level_at(const struct logd_battery_info *info, time_t date)
+{
+       int i;
+       struct logd_battery_level *bl = NULL;
+
+       if (!info || !info->levels)
+               return -EINVAL;
+
+       if (date < info->levels[0].date) {
+               _E("logd_battery_info not contains info at %ld", date);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < info->n; ++i) {
+               bl = &info->levels[i];
+
+               if (i == info->n - 1)
+                       break;
+               if (date >= bl->date && date < info->levels[i + 1].date)
+                       break;
+       }
+
+       return bl->level + (date - bl->date) * bl->k;
+}
+
+API float logd_battery_charging_speed_at(const struct logd_battery_info *info, time_t date)
+{
+       int i;
+
+       if (!info || !info->levels)
+               return -EINVAL;
+
+       if (date < info->levels[0].date) {
+               _E("logd_battery_info not contains info at %ld", date);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < info->n - 1; ++i) {
+               if (date >= info->levels[i].date && date < info->levels[i + 1].date)
+                       break;
+       }
+       if (i != 0 && i == info->n - 1)
+               --i;
+
+       return info->levels[i].k;
+}
+
+API int get_current_battery_level()
+{
+       int ret = -EIO;
+       const  char *level_file = "/sys/class/power_supply/battery/capacity";
+       int level = 0;
+       FILE *fp = fopen(level_file, "r");
+
+       if (!fp) {
+               ret = -errno;
+               _E("can't open %s", level_file);
+               return ret;
+       }
+       errno = 0;
+       if (fscanf(fp, "%d", &level) != 1) {
+               if (errno)
+                       ret = -errno;
+               _E("Can't read battery level");
+               fclose(fp);
+               return ret;
+       }
+
+       fclose(fp);
+       return level > MAX_BATTERY_LEVEL ? MAX_BATTERY_LEVEL : level;
+}
+
+API float* load_discharging_speed(int long_period)
+{
+       float *result = NULL;
+       int i;
+
+       if (sqlite3_reset(load_power_mode_stat_stmt) != SQLITE_OK) {
+               _E("sqlite3_reset failed");
+               return NULL;
+       }
+
+       result = (float*)calloc(LOGD_POWER_MODE_MAX, sizeof(float));
+       if (!result)
+               return NULL;
+
+       for (i = 0; i < LOGD_POWER_MODE_MAX; ++i) {
+               int total_duration = 0;
+               float total_battery_level_change = 0;
+
+               if (sqlite3_reset(load_power_mode_stat_stmt) != SQLITE_OK) {
+                       _E("load_power_mode_stat_stmt reset error");
+                       free(result);
+                       return NULL;
+               }
+
+               if (sqlite3_bind_int(load_power_mode_stat_stmt, 1, i) != SQLITE_OK) {
+                       _E("load_power_mode_stat_stmt bind error");
+                       free(result);
+                       return NULL;
+               }
+
+               while (sqlite3_step(load_power_mode_stat_stmt) == SQLITE_ROW) {
+                       int duration = sqlite3_column_int(load_power_mode_stat_stmt, 3);
+                       int battery_level_change = sqlite3_column_int(load_power_mode_stat_stmt, 4);
+
+                       if (total_duration + duration > long_period) {
+                               total_battery_level_change +=
+                                       ((float)(long_period - total_duration)) / duration * battery_level_change;
+                               total_duration = long_period;
+                               break;
+                       }
+                       total_duration += duration;
+                       total_battery_level_change += battery_level_change;
+               }
+               if (total_duration < long_period || total_battery_level_change == 0)
+                       result[i] = -1;
+               else
+                       result[i] = total_duration / total_battery_level_change;
+       }
+
+       return result;
+}
+
+
+API int store_new_power_mode(time_t time_stamp, enum logd_power_mode old_mode,
+       enum logd_power_mode new_mode, time_t duration, int battery_level_change)
+{
+       DB_CHECK(sqlite3_reset(store_power_mode_stmt));
+       DB_CHECK(sqlite3_bind_int64(store_power_mode_stmt, 1, time_stamp));
+       DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 2, old_mode));
+       DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 3, new_mode));
+       DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 4, duration));
+       DB_CHECK(sqlite3_bind_int(store_power_mode_stmt, 5, battery_level_change));
+
+       if (sqlite3_step(store_power_mode_stmt) != SQLITE_DONE) {
+               _E("Can't store power mode: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/src/logd/src/liblogd-db/devices.h b/src/logd/src/liblogd-db/devices.h
new file mode 100644 (file)
index 0000000..4a898a3
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _LOGD_DEVICES_H_
+#define _LOGD_DEVICES_H_
+
+#include "logd.h"
+#include "logd-db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int devices_init(void);
+int devices_finalize(void);
+int store_devices_workingtime(enum logd_object device, int state);
+int get_current_battery_level(void);
+int store_new_power_mode(time_t time_stamp, enum logd_power_mode old_mode,
+       enum logd_power_mode new_mode, time_t duration, int battery_level_change);
+float* load_discharging_speed(int long_period);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_DEVICES_H_ */
+
diff --git a/src/logd/src/liblogd-db/events.c b/src/logd/src/liblogd-db/events.c
new file mode 100644 (file)
index 0000000..7d90aa7
--- /dev/null
@@ -0,0 +1,278 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "events.h"
+#include "macro.h"
+
+#define LOAD_APPS_SQL "SELECT * FROM applications;"
+#define STORE_APP_SQL "INSERT INTO applications (name) VALUES (?);"
+#define STORE_EVENT_SQL "INSERT INTO events\
+       (object, action, time_stamp, app_id, info) VALUES (?, ?, ?, ?, ?);"
+#define LOAD_EVENTS_SQL "SELECT E.object, E.action, E.time_stamp, A.name, E.info\
+       FROM applications A, events E                                   \
+       WHERE E.app_id=A.id"
+#define DEL_OLD_EVENTS_SQL "DELETE FROM events WHERE time_stamp < ?"
+
+
+#define LOAD_EVENTS_ALL "SELECT E.object, E.action, E.time_stamp, A.name, E.info\
+       FROM applications A, events E\
+       WHERE E.app_id=A.id"
+#define AND " AND"
+#define OR " OR"
+#define TIMESTAMP_LT " (time_stamp < %lld)"
+#define TIMESTAMP_GT " (time_stamp > %lld)"
+#define BY_OBJECT " (object = %d)"
+#define BY_ACTION " (action = %d)"
+#define EXTRA (32)
+
+#define QUERY_BASE_STR_LEN sizeof(LOAD_EVENTS_ALL)
+#define QUERY_ADD_STR_TIME_LEN sizeof(TIMESTAMP_LT) + sizeof(AND) \
+       + sizeof(TIMESTAMP_GT) + EXTRA
+#define QUERY_ADD_STR_LEN_MAX sizeof(BY_OBJECT) + sizeof(AND) + EXTRA
+
+static sqlite3 *db;
+
+static sqlite3_stmt *load_apps_stmt;
+static sqlite3_stmt *store_app_stmt;
+static sqlite3_stmt *store_event_stmt;
+static sqlite3_stmt *load_events_stmt;
+static sqlite3_stmt *del_old_events_stmt;
+
+int events_init(void)
+{
+       db = logd_get_db();
+
+       PREPARE_STMT(load_apps_stmt, LOAD_APPS_SQL);
+       PREPARE_STMT(store_app_stmt, STORE_APP_SQL);
+       PREPARE_STMT(store_event_stmt, STORE_EVENT_SQL);
+       PREPARE_STMT(load_events_stmt, LOAD_EVENTS_SQL);
+       PREPARE_STMT(del_old_events_stmt, DEL_OLD_EVENTS_SQL);
+
+       return 0;
+}
+
+int events_finalize(void)
+{
+       FINALIZE_STMT(load_apps_stmt);
+       FINALIZE_STMT(store_app_stmt);
+       FINALIZE_STMT(store_event_stmt);
+       FINALIZE_STMT(load_events_stmt);
+       FINALIZE_STMT(del_old_events_stmt);
+
+       return 0;
+}
+
+API int logd_store_app(const char *app)
+{
+       DB_CHECK(sqlite3_reset(store_app_stmt));
+       DB_CHECK(sqlite3_bind_text(store_app_stmt, 1, app, -1, SQLITE_STATIC));
+       if (sqlite3_step(store_app_stmt) != SQLITE_DONE) {
+               _E("Failed to record to applications table: %s",
+                  sqlite3_errmsg(db));
+               return -1;
+       }
+
+       return 0;
+}
+
+API int logd_load_apps(enum logd_db_query (*cb) (int, const char *, void *),
+               void *user_data)
+{
+       const char *app = NULL;
+       int id;
+
+       while (sqlite3_step(load_apps_stmt) == SQLITE_ROW) {
+               app = (const char *)sqlite3_column_text(load_apps_stmt, 0);
+               id = sqlite3_column_int(load_apps_stmt, 1);
+               if (!cb(id, app, user_data))
+                       break;
+       }
+
+       return 0;
+}
+
+API int logd_store_event(int event_type, uint64_t _time, int app_id,
+                  const char *message)
+{
+       DB_CHECK(sqlite3_reset(store_event_stmt));
+       DB_CHECK(sqlite3_bind_int(store_event_stmt, 1, event_type & 0xffff));
+       DB_CHECK(sqlite3_bind_int(store_event_stmt, 2, event_type >> 16));
+       DB_CHECK(sqlite3_bind_int64(store_event_stmt, 3, _time));
+       DB_CHECK(sqlite3_bind_int(store_event_stmt, 4, app_id));
+       DB_CHECK(sqlite3_bind_text(store_event_stmt, 5, message, -1,
+                SQLITE_STATIC));
+
+       if (sqlite3_step(store_event_stmt) != SQLITE_DONE) {
+               _E("Failed to record to events table: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       return 0;
+}
+
+API int logd_load_events(enum logd_db_query (*cb)(const struct logd_event_info *, void *),
+       sqlite3_stmt *stmt, void *user_data)
+{
+       struct logd_event_info event;
+       int ret = 0;
+
+       stmt = stmt ? stmt : load_events_stmt;
+
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               event.object = sqlite3_column_int(stmt, 0);
+               event.action = sqlite3_column_int(stmt, 1);
+               event.time = sqlite3_column_int64(stmt, 2);
+
+               event.application =
+                       strdup((char *)sqlite3_column_text(stmt, 3));
+               event.message =
+                       strdup((char *)sqlite3_column_text(stmt, 4));
+
+               ret = cb(&event, user_data);
+               free(event.message);
+               free(event.application);
+               if (ret != LOGD_DB_QUERY_CONTINUE)
+                       break;
+       }
+
+       return 0;
+}
+
+
+API int delete_old_events(uint64_t min_time)
+{
+       DB_CHECK(sqlite3_reset(del_old_events_stmt));
+       DB_CHECK(sqlite3_bind_int64(del_old_events_stmt, 1, min_time));
+
+       if (sqlite3_step(del_old_events_stmt) != SQLITE_DONE) {
+               _E("Failed to remove old events: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+
+       return 0;
+}
+
+API int logd_foreach_events(const struct logd_events_filter *filter,
+       enum logd_db_query (*cb)(const struct logd_event_info *, void *),
+       void *user_data)
+{
+       char *buf, *qbuf;
+       int idx, omidx, amidx, ret, len, firstskip;
+       sqlite3_stmt *stmt;
+
+       if (filter == NULL) {
+               len = QUERY_BASE_STR_LEN;
+
+               buf = (char *)malloc(len);
+               if (!buf) {
+                       ret = -ENOMEM;
+                       goto out_finish;
+               }
+               len -= snprintf(buf, len, LOAD_EVENTS_ALL);
+               if (len < 0) {
+                       ret = len;
+                       goto out_free;
+               }
+
+       } else {
+               omidx = 0;
+               for (idx = 0; idx < LOGD_OBJECT_MAX; idx++) {
+                       if (filter->objects_mask[idx] == 1)
+                               omidx++;
+               }
+               amidx = 0;
+               for (idx = 0; idx < LOGD_ACTION_MAX; idx++) {
+                       if (filter->actions_mask[idx] == 1)
+                               amidx++;
+               }
+
+               len = QUERY_BASE_STR_LEN + sizeof(AND) +
+                       QUERY_ADD_STR_TIME_LEN +
+                       (omidx * QUERY_ADD_STR_LEN_MAX) +
+                       (amidx * QUERY_ADD_STR_LEN_MAX);
+
+               buf = (char *)malloc(len);
+               if (!buf) {
+                       ret = -ENOMEM;
+                       goto out_finish;
+               }
+               len -= snprintf(buf, len, LOAD_EVENTS_ALL);
+               if (len < 0) {
+                       ret = len;
+                       goto out_free;
+               }
+
+               if (filter->from) {
+                       strcat(buf, AND);
+                       ret = asprintf(&qbuf, TIMESTAMP_GT, filter->from);
+                       if (ret <=0)
+                               goto out_free;
+                       strcat(buf, qbuf);
+                       free(qbuf);
+               }
+
+               if (filter->to) {
+                       strcat(buf, AND);
+                       ret = asprintf(&qbuf, TIMESTAMP_LT, filter->to);
+                       if (ret <=0)
+                               goto out_free;
+                       strcat(buf, qbuf);
+                       free(qbuf);
+               }
+
+               if (omidx) {
+                       strcat(buf, AND);
+                       strcat(buf, " (");
+                       firstskip = 0;
+                       for (idx = 0; idx < LOGD_OBJECT_MAX; idx++) {
+                               if (filter->objects_mask[idx] == 1) {
+                                       if (firstskip != 0)
+                                               strcat(buf, OR);
+                                       else
+                                               firstskip = 1;
+                                       ret = asprintf(&qbuf, BY_OBJECT, idx);
+                                       if (ret <= 0)
+                                               goto out_free;
+                                       strncat(buf, qbuf, ret);
+                                       free(qbuf);
+                               }
+                       }
+                       strcat(buf, ")");
+               }
+               if (amidx) {
+                       strcat(buf, AND);
+                       strcat(buf, " (");
+                       firstskip = 0;
+                       for (idx = 0; idx < LOGD_ACTION_MAX; idx++) {
+                               if (filter->actions_mask[idx] == 1) {
+                                       if (firstskip != 0)
+                                               strcat(buf, OR);
+                                       else
+                                               firstskip = 1;
+                                       ret = asprintf(&qbuf, BY_ACTION, idx);
+                                       if (ret <= 0)
+                                               goto out_free;
+                                       strncat(buf, qbuf, ret);
+                                       free(qbuf);
+                               }
+                       }
+                       strcat(buf, ")");
+               }
+       }
+
+       PREPARE_STMT(stmt, buf);
+       free(buf);
+       ret = logd_load_events(cb, stmt, user_data);
+       FINALIZE_STMT(stmt);
+
+       return ret;
+
+out_free:
+       free(buf);
+out_finish:
+       return ret;
+}
diff --git a/src/logd/src/liblogd-db/events.h b/src/logd/src/liblogd-db/events.h
new file mode 100644 (file)
index 0000000..9fe7bab
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _LOGD_EVENTS_H_
+#define _LOGD_EVENTS_H_
+
+#include <sqlite3.h>
+
+#include "logd-db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int events_init(void);
+int events_finalize(void);
+int logd_store_app(const char *app);
+int logd_load_apps(enum logd_db_query (*cb) (int, const char *, void *),
+               void *user_data);
+int logd_store_event(int event_type, uint64_t _time, int app_id,
+                  const char *message);
+int logd_load_events(enum logd_db_query (*cb)(const struct logd_event_info *, void *),
+       sqlite3_stmt *stmt, void *user_data);
+int delete_old_events(uint64_t min_time);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_EVENTS_H_ */
diff --git a/src/logd/src/liblogd-db/liblogd-db.pc.in b/src/logd/src/liblogd-db/liblogd-db.pc.in
new file mode 100644 (file)
index 0000000..06da144
--- /dev/null
@@ -0,0 +1,8 @@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_PROVIDED_LIBS@
+Cflags: @PC_CFLAGS@
diff --git a/src/logd/src/liblogd-db/logd-db.h b/src/logd/src/liblogd-db/logd-db.h
new file mode 100644 (file)
index 0000000..661b45d
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * logd
+ *
+ * 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.
+ */
+
+/**
+ * @file logd-db.h
+ *
+ * @desc Contains API to get information about event and processes statistics.
+ */
+
+#ifndef _LOGD_LOGD_DATA_H_
+#define _LOGD_LOGD_DATA_H_
+
+#include <logd.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum logd_socket_req_type {
+       LOGD_UNKNOWN_REQ,
+       LOGD_PROC_STAT_REQ,
+       LOGD_DEV_STAT_REQ,
+       LOGD_BATTERY_LVL_REQ,
+       LOGD_EST_TIME_REQ,
+};
+
+struct logd_device_stat {
+       /** Device identifier */
+       enum logd_object type;
+       /** total power consumed by device in uAh */
+       float power_cons;
+       /** current power consumption in mA */
+       float cur_power_cons;
+};
+
+struct logd_event_info {
+       /** Object - 1st parameter in <CODE>logd_event</CODE> function*/
+       enum logd_object object;
+       /** Action - 2nd parameter in <CODE>logd_event</CODE> function*/
+       enum logd_action action;
+       /** Time when event was created */
+       uint64_t time;
+       /** Full path to application that created event */
+       char *application;
+       /** Message of event. 3rd parameter in <CODE>logd_event</CODE> function */
+       char *message;
+};
+
+struct logd_proc_stat {
+       /**
+        * Full path to application. If it starts from '[' then it's
+        * kernel thread
+        */
+       char *application;
+       uint64_t utime; /** User CPU time in msec */
+       uint64_t stime; /** System CPU time in msec */
+       float utime_power_cons, stime_power_cons;
+       int is_active; /* application is running now */
+       /*
+        * Persentage from CPU time of all applications.
+        * persentage = (utime + stime) / (all_app_utime + all_app_stime)
+        */
+       float percentage;
+};
+
+
+struct logd_events_filter {
+       /** Start process events from that time in unixtime format */
+       uint64_t from;
+       /** Process events till that time in unixtime format */
+       uint64_t to;
+       /**
+        * Mask that describes what events process. If you want to load only
+        * event whete action is <CODE>LOGD_WIFI</CODE> or
+        * <CODE>LOGD_DISPLAY</CODE> you must assign:
+        * @code
+        * filter.actions_mask[LOGD_WIFI] = 1;
+        * filter.actions_mask[LOGD_DISPLAY] = 1;
+        * @endcode
+        */
+       int actions_mask[LOGD_ACTION_MAX];
+       /** Is's like <CODE>actions_mask</CODE> but for object */
+       int objects_mask[LOGD_OBJECT_MAX];
+};
+
+enum logd_db_query {
+       LOGD_DB_QUERY_STOP,
+       LOGD_DB_QUERY_CONTINUE,
+};
+
+/**
+ * Through events that database contains.
+ *
+ * @param filter give ability to clarify parameters of events that you want
+ * to process. If NULL then process all event from database.
+ * @param cb pointer to function that will call for each event.
+ * @param user_data any data that must be given to <CODE>cb</CODE>. May be NULL.
+ *
+ * @return On succes, 0. On error, negative value.
+ *
+ * Example usage:
+ * @code
+ * enum logd_db_query cb(const struct logd_event_info *event, void *user_data)
+ * {
+ *     struct tm st;
+ *     time_t time_sec;
+ *     char timestr[200];
+ *
+ *     time_sec = event->time;
+ *     localtime_r(&time_sec, &st);
+ *     strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &st);
+ *     printf("%s %s %s\n", event->application, timestr, event->message);
+ *
+ *     return LOGD_DB_QUERY_CONTINUE;
+ * }
+ *
+ * logd_foreach_events(&filter, &cb, NULL);
+ * @endcode
+ */
+int logd_foreach_events(const struct logd_events_filter *filter,
+       enum logd_db_query (*cb)(const struct logd_event_info *, void *), void *user_data);
+
+/**
+ * Through precess statistics. Statistics counted start from logd_grabber
+ * started (usually starts from target's switch on).
+ *
+ * @param cb pointer to function that will call for each process.
+ * @param user_data any data that must be given to <CODE>cb</CODE>. May be NULL.
+ *
+ * @return On succes, 0. On error, negative value.
+ *
+ * Example usage like <CODE>logd_foreach_events</CODE>.
+ */
+int logd_foreach_proc_stat(enum logd_db_query (*cb) (const struct logd_proc_stat *, void *),
+       void *user_data);
+
+/**
+ * Through devices statistics.
+ *
+ * @param cb pointer to function that will call for each device.
+ * (Now implemented only for backlight - display.
+ * @param user_data any data that must be given to <CODE>cb</CODE>. May be NULL.
+ *
+ * @return On succes, 0. On error, negative value.
+ *
+ * Example usage like <CODE>logd_foreach_events</CODE>.
+ */
+int logd_foreach_devices_stat(enum logd_db_query (*cb)
+        (const struct logd_device_stat *, void *), void *user_data);
+
+
+struct logd_battery_level {
+       time_t date;
+       int level;
+       float k; /** Speed of charging (may be negative) */
+};
+
+struct logd_battery_info {
+       struct logd_battery_level *levels;
+       int n;
+};
+
+/**
+ * Return information about battery level. Returned object can be provided in
+ * logd_battery_level_at to get battery level at exact time.
+ *
+ * @return On success <CODE>struct logd_battery_info</CODE> object. On error, NULL.
+ * Returned object must be released by <CODE>logd_free_battery_info</CODE>.
+ */
+struct logd_battery_info* logd_get_battery_info(void);
+
+/**
+ * Release memory used by <CODE>info</CODE>.
+ *
+ * @param info relased object.
+ */
+void logd_free_battery_info(struct logd_battery_info *info);
+
+/**
+ * Return index when info->levels[index].level == level.
+ *
+ * @param info object returned by <CODE>logd_get_battery_info</CODE>.
+ * @param level the battery level index of what you want to find.
+ *
+ * @return index of info->levels. Great then 0 if the level was found,
+ * 0 if not found, less then 0 in error case. Max level is 10000 - 100%.
+ */
+int logd_seek_battery_level(struct logd_battery_info *info, int level);
+
+/**
+ * Provide battery level at certain time. Max level is 10000 - 100%.
+ *
+ * @param info object returned by <CODE>logd_get_battery_info</CODE>.
+ * @param date battery level at that time will be returned.
+ *
+ * @return battery level in percentage.
+ */
+float logd_battery_level_at(const struct logd_battery_info *info, time_t date);
+
+/**
+ * Provide battery charging/discharging speed at certain time.
+ *
+ * @param info object returned by <CODE>logd_get_battery_info</CODE>.
+ * @param date battery charging speed at that time will be returned.
+ *
+ * @return battery charging/discharging (if value is negative) in persents/sec.
+ */
+float logd_battery_charging_speed_at(const struct logd_battery_info *info, time_t date);
+
+/**
+ * Provide info about estimate remaining battery lifetime for each
+ * available power mode from <CODE>logd_power_mode</CODE>.
+ *
+ * @param estimate_times pointer to int pointer that will cantains
+ * estimate time for all power modes. It has to be released by
+ * <CODE>free</CODE> if functions terminated successfully.
+ *
+ * @return On succes, 0. On error, negative value.
+ *
+ * Example usage:
+ * @code
+ * int *estimate_times = NULL;
+ * if (logd_get_estimate_battery_lifetime(&estimate_times) < 0) {
+ *     puts("error");
+ *     return -1;
+ * }
+ * for (int i = 0; i < LOGD_POWER_MODE_MAX; ++i)
+ *     printf("%d\n", estimate_times[i]);
+ * free(estimate_times);
+ * @endcode
+ */
+int logd_get_estimate_battery_lifetime(int **estimate_times);
+
+/**
+ * Provide information about energy efficiency for all launched applications.
+ * power_efficiency = power_cons / time * 3600 (how much energy will used
+ * in a hour by that application. More is worse.
+ *
+ * @param cb a callback that will called for all applications. It receive
+ * three parameters: path to the binary, energy efficiency for that binary
+ * and any user data (see next parameter). Power efficiency can be computed
+ * only when the application has running long enough (more then 2 hour in
+ * the current realization). If it's less then 2 hours then efficiency will
+ * be less then 0.
+ *
+ * @param user_data any data that will be given to <CODE>cb</CODE>. May be NULL.
+ *
+ * @return On succes, 0. On error, negative value.
+ */
+int logd_foreach_apps_energy_efficiency(enum logd_db_query (*cb)
+       (const char *application, float efficiency, void *user_data), void *user_data);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_LOGD_DATA_H_ */
diff --git a/src/logd/src/liblogd-db/padvisor.c b/src/logd/src/liblogd-db/padvisor.c
new file mode 100644 (file)
index 0000000..4a1a531
--- /dev/null
@@ -0,0 +1,242 @@
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdio.h>
+#include <sqlite3.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "padvisor.h"
+#include "db.h"
+#include "devices.h"
+#include "macro.h"
+
+static sqlite3_stmt *load_mostused_apps_stmt;
+static sqlite3_stmt *get_enabled_devices_stmt;
+static sqlite3_stmt *load_dev_working_time_stmt;
+
+static sqlite3 *db;
+
+struct logd_device_ratio {
+       enum logd_object device;
+       float coefficient;
+};
+
+static struct logd_device_ratio ratio[] = {
+       /* HW devices */
+       {LOGD_ACCELEROMETER, 0},
+       {LOGD_BAROMETER, 0},
+       {LOGD_BT, 0.22},
+       {LOGD_DISPLAY, 1.86}, /* brightness 80% */
+       {LOGD_GEOMAGNETIC, 0},
+       {LOGD_GPS, 0.54},
+       {LOGD_GYROSCOPE, 0},
+       {LOGD_LIGHT, 0},
+       {LOGD_NFC, 0},
+       {LOGD_PROXIMITY, 0},
+       {LOGD_THERMOMETER, 0},
+       {LOGD_WIFI, 0.11},
+       {LOGD_MMC, 0},
+       /* Battery */
+       {LOGD_BATTERY_SOC, 0},
+       {LOGD_CHARGER, 0},
+       /* Apps */
+       {LOGD_FOREGRD_APP, 0},
+       /* Function */
+       {LOGD_AUTOROTATE, 0},
+       {LOGD_MOTION, 0},
+       {LOGD_POWER_MODE, 0},
+};
+
+STATIC_ASSERT(sizeof(ratio)/sizeof(ratio[0]) == LOGD_OBJECT_MAX, number_of_ratio_\
+elements_must_be_equal_LOGD_OBJECT_MAX);
+
+#define GET_ENABLED_DEVICES_SQL "SELECT object, MAX(time_stamp) \
+FROM events GROUP BY object HAVING action!=%d"
+
+#define LOAD_DEV_WORKING_TIME_SQL "SELECT device, SUM(time) AS time \
+FROM device_working_time WHERE time_stamp>=? AND time_stamp<=? \
+GROUP BY device"
+
+int padvisor_init()
+{
+       int ret;
+       char *get_enabled_devices;
+
+       db = logd_get_db();
+
+       ret = asprintf(&get_enabled_devices, GET_ENABLED_DEVICES_SQL, LOGD_OFF);
+       if (ret == -1) {
+               fprintf(stderr, "Cannot create statement\n");
+               return -errno;
+       }
+
+       PREPARE_STMT(load_dev_working_time_stmt, LOAD_DEV_WORKING_TIME_SQL);
+       PREPARE_STMT(get_enabled_devices_stmt, get_enabled_devices);
+
+       free(get_enabled_devices);
+
+       return 0;
+}
+
+int padvisor_finalize()
+{
+       FINALIZE_STMT(load_dev_working_time_stmt);
+       FINALIZE_STMT(load_mostused_apps_stmt);
+       FINALIZE_STMT(get_enabled_devices_stmt);
+
+       return 0;
+}
+
+static int compare_device_power_cons(const void *dev1, const void *dev2)
+{
+       float coeff1 = ratio[((struct logd_idle_device*)dev1)->device].coefficient;
+       float coeff2 = ratio[((struct logd_idle_device*)dev2)->device].coefficient;
+
+       if (coeff1 < coeff2)
+               return 1;
+       else if (coeff1 > coeff2)
+               return -1;
+
+       return 0;
+}
+
+static enum logd_db_query mostused_apps_cb(const struct logd_proc_stat *proc_stat, void *user_data)
+{
+       static int i = 0;
+       struct logd_power_advisor *lpa = (struct logd_power_advisor*) user_data;
+
+       lpa->procs[i].application = strdup(proc_stat->application);
+       lpa->procs[i].utime = proc_stat->utime;
+       lpa->procs[i].stime = proc_stat->stime;
+       lpa->procs[i].utime_power_cons = proc_stat->utime_power_cons;
+       lpa->procs[i].stime_power_cons = proc_stat->stime_power_cons;
+       lpa->proc_stat_used_num++;
+
+       if (++i < LOGD_ADVISOR_MAX)
+               return LOGD_DB_QUERY_CONTINUE;
+
+       i = 0;
+       return LOGD_DB_QUERY_STOP;
+}
+
+API struct logd_power_advisor *logd_get_power_advisor(void)
+{
+       int i;
+       int ret;
+       struct logd_power_advisor *lpa;
+       int total_power_cons = 0;
+
+       lpa = calloc(1, sizeof(struct logd_power_advisor));
+       if (lpa == NULL) {
+               _E("Can't calloc logd_power_advisor");
+               return NULL;
+       }
+
+       for (i = 0; i < LOGD_ADVISOR_MAX; i++) {
+               if (sqlite3_step(get_enabled_devices_stmt) != SQLITE_ROW) {
+                       break;
+               }
+
+               lpa->idle_devices[i].device =
+                       sqlite3_column_int(get_enabled_devices_stmt, 0);
+               lpa->idle_devices[i].idle_time =
+                       sqlite3_column_int64(get_enabled_devices_stmt, 1);
+               lpa->idle_devices_used_num++;
+       }
+       qsort(lpa->idle_devices, lpa->idle_devices_used_num,
+               sizeof(struct logd_idle_device), compare_device_power_cons);
+
+       ret = sqlite3_reset(get_enabled_devices_stmt);
+       if (ret != SQLITE_OK) {
+               _E("cannot reset statement: %s", sqlite3_errmsg(db));
+               free(lpa);
+               return NULL;
+       }
+
+       logd_foreach_proc_stat(&mostused_apps_cb, lpa);
+
+       for (i = 0; i < lpa->proc_stat_used_num; i++) {
+               total_power_cons += lpa->procs[i].utime_power_cons + lpa->procs[i].stime_power_cons;
+       }
+
+       for (i = 0; i < lpa->proc_stat_used_num; ++i)
+               lpa->procs[i].percentage =
+                       (float)(lpa->procs[i].utime_power_cons + lpa->procs[i].stime_power_cons) /
+                               total_power_cons;
+
+       return lpa;
+}
+
+API void logd_free_power_advisor(struct logd_power_advisor *lpa)
+{
+       int i;
+
+       if (!lpa)
+               return;
+
+       for (i = 0; i < lpa->proc_stat_used_num; i++) {
+               free(lpa->procs[i].application);
+       }
+
+       free(lpa);
+}
+
+API struct device_power_consumption *
+logd_get_device_power_cons(time_t from, time_t to)
+{
+       struct device_power_consumption *pcons;
+       float scaled_time = 0;
+
+       if (sqlite3_bind_int(load_dev_working_time_stmt, 1, from) !=
+               SQLITE_OK) {
+               _E("Can't bind argument: %s", sqlite3_errmsg(db));
+               return NULL;
+       }
+       if (sqlite3_bind_int(load_dev_working_time_stmt, 2, to) !=
+               SQLITE_OK) {
+               _E("Can't bind argument: %s", sqlite3_errmsg(db));
+               return NULL;
+       }
+
+       pcons = calloc(1, sizeof(struct device_power_consumption));
+       if (!pcons) {
+               _E("Can't calloc device_power_consumption");
+               return NULL;
+       }
+
+       while (sqlite3_step(load_dev_working_time_stmt) == SQLITE_ROW)
+       {
+               int devid = sqlite3_column_int(load_dev_working_time_stmt, 0);
+               int dev_time = sqlite3_column_int(load_dev_working_time_stmt, 1);
+
+               if (devid < 0 || LOGD_OBJECT_MAX <= devid) {
+                       _E("wrong device id: %d", devid);
+                       free(pcons);
+                       return NULL;
+               }
+               pcons->device_cons[devid].time = dev_time;
+               pcons->total_time += dev_time;
+               scaled_time += ratio[devid].coefficient * dev_time;
+       }
+
+       if (pcons->total_time) {
+               for (int i = 0; i < LOGD_OBJECT_MAX; ++i) {
+                       pcons->device_cons[i].percentage = ratio[i].coefficient *
+                               pcons->device_cons[i].time / scaled_time;
+               }
+       }
+       if (sqlite3_reset(load_dev_working_time_stmt) != SQLITE_OK) {
+               _E("Can't reset statement: %s", sqlite3_errmsg(db));
+               free(pcons);
+               return NULL;
+       }
+
+       return pcons;
+}
+
+API void logd_free_device_power_cons(struct device_power_consumption *pcons)
+{
+       if (pcons)
+               free(pcons);
+}
+
diff --git a/src/logd/src/liblogd-db/padvisor.h b/src/logd/src/liblogd-db/padvisor.h
new file mode 100644 (file)
index 0000000..907a0ae
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * logd
+ *
+ * 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.
+ */
+
+/**
+ * @file padvisor.h
+ *
+ * @desc Contains API that can help to manage devices/processec for.decrease
+ * power consumption.
+ */
+
+#ifndef _LOGD_PADVISER_H_
+#define _LOGD_PADVISER_H_
+
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "logd-db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum { LOGD_ADVISOR_MAX = 32 };
+
+struct logd_idle_device {
+       uint64_t idle_time; /** Time when device was swithed on */
+       enum logd_object device; /** Device identifier */
+};
+
+struct logd_power_advisor {
+       /** Array of enabled devices */
+       struct logd_idle_device idle_devices[LOGD_ADVISOR_MAX];
+       /** Top <CODE>LOGD_ADVISOR_MAX</CODE> most power cunsuming application */
+       struct logd_proc_stat procs[LOGD_ADVISOR_MAX];
+       /** Count of devices in <CODE>idle_devices</CODE> */
+       int idle_devices_used_num;
+       /** Count of processes in <CODE>procs</CODE> */
+       int proc_stat_used_num;
+};
+
+struct logd_power_consumption {
+       enum logd_object device; /** Device identifier */
+       /** Persentage from all devices power consumption */
+       float percentage;
+       /** Time in sec when device was enabled */
+       int time;
+};
+
+struct device_power_consumption {
+       /** Array of all devices with theirs power consumption */
+       struct logd_power_consumption device_cons[LOGD_OBJECT_MAX];
+       /** Sum of all logd_power_consumption::time from device_cons in sec */
+       int total_time;
+};
+
+/* please, not use that function in your application, it isn't public API */
+int padvisor_init(void);
+int padvisor_finalize(void);
+
+/* next functions are public API */
+
+/**
+ * Return information about devices and processes.
+ *
+ * @return On success, pointer to <CODE>logd_power_advisor</CODE> struct.
+ * Returned pointer must be released by <CODE>logd_free_power_advisor</CODE>.
+ * On error, NULL.
+ */
+struct logd_power_advisor *logd_get_power_advisor(void);
+/**
+ * Release <CODE>logd_power_advisor</CODE> struct returned by
+ * <CODE>logd_get_power_advisor</CODE>.
+ * @param lpa pointer that must be free.
+ */
+void logd_free_power_advisor(struct logd_power_advisor *lpa);
+
+/**
+ * Return information about devices power consumption for given period.
+ *
+ * @param from Count power consumption from that time in unixtime format.
+ * @param to Count power consumption till that time in unixtime format.
+ * @return On success, pointer to <CODE>device_power_consumption</CODE> struct.
+ * Returned pointer must be released by <CODE>logd_free_device_power_cons</CODE>.
+ * On error, NULL.
+ */
+struct device_power_consumption *
+logd_get_device_power_cons(time_t from, time_t to);
+/**
+ * Release <CODE>device_power_consumption</CODE> struct returned by
+ * <CODE>logd_get_device_power_cons</CODE>.
+ * @param pcons pointer that must be free.
+ */
+void logd_free_device_power_cons(struct device_power_consumption* pcons);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_PADVISER_H_ */
diff --git a/src/logd/src/liblogd-db/proc-stat.c b/src/logd/src/liblogd-db/proc-stat.c
new file mode 100644 (file)
index 0000000..33670ee
--- /dev/null
@@ -0,0 +1,212 @@
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+#include "proc-stat.h"
+#include "macro.h"
+#include "socket-helper.h"
+
+#define UPDATE_PROC_STAT_SQL "REPLACE INTO proc_power_cons \
+       (appid, power_cons, duration, day) VALUES(?, ?, ?, ?)"
+#define LOAD_PROC_STAT_SQL "SELECT * FROM proc_power_cons WHERE day=?"
+#define DELETE_OLD_POWER_CONS "DELETE FROM proc_power_cons WHERE day=?"
+
+static sqlite3 *db;
+static sqlite3_stmt *update_proc_stat_stmt;
+static sqlite3_stmt *load_proc_stat_stmt;
+static sqlite3_stmt *delete_old_power_cons_stmt;
+
+API int proc_stat_init(void)
+{
+       db = logd_get_db();
+
+       PREPARE_STMT(update_proc_stat_stmt, UPDATE_PROC_STAT_SQL);
+       PREPARE_STMT(load_proc_stat_stmt, LOAD_PROC_STAT_SQL);
+       PREPARE_STMT(delete_old_power_cons_stmt, DELETE_OLD_POWER_CONS);
+
+       return 0;
+}
+
+API int proc_stat_finalize(void)
+{
+       FINALIZE_STMT(load_proc_stat_stmt);
+       FINALIZE_STMT(update_proc_stat_stmt);
+       FINALIZE_STMT(delete_old_power_cons_stmt);
+
+       return 0;
+}
+
+API int foreach_proc_power_cons(enum logd_db_query (*cb)
+       (const struct proc_power_cons *pc, void *user_data), int day, void *user_data)
+{
+       enum logd_db_query res;
+
+       DB_CHECK(sqlite3_reset(load_proc_stat_stmt));
+       DB_CHECK(sqlite3_bind_int(load_proc_stat_stmt, 1, day));
+       while (sqlite3_step(load_proc_stat_stmt) == SQLITE_ROW) {
+               struct proc_power_cons pc;
+
+               pc.appid = strdup((const char*)
+                       sqlite3_column_text(load_proc_stat_stmt, 0));
+               if (!pc.appid) {
+                       _E("strdup failed");
+                       return -ENOMEM;
+               }
+               pc.power_cons = sqlite3_column_int64(load_proc_stat_stmt, 1);
+               pc.duration = sqlite3_column_int(load_proc_stat_stmt, 2);
+               res = cb(&pc, user_data);
+               free((void*)pc.appid);
+               if (res == LOGD_DB_QUERY_STOP)
+                       break;
+       }
+
+       return 0;
+}
+
+
+API int logd_foreach_apps_energy_efficiency(enum logd_db_query (*cb)
+       (const char *application, float efficiency, void *user_data), void *user_data)
+{
+       enum logd_db_query res;
+
+       DB_CHECK(sqlite3_reset(load_proc_stat_stmt));
+       while (sqlite3_step(load_proc_stat_stmt) == SQLITE_ROW) {
+               struct proc_power_cons pc;
+               float efficiency = -1;
+
+               pc.appid = strdup((const char*)
+                       sqlite3_column_text(load_proc_stat_stmt, 0));
+               if (!pc.appid) {
+                       _E("strdup failed");
+                       return -ENOMEM;
+               }
+               pc.power_cons = sqlite3_column_int64(load_proc_stat_stmt, 1);
+               pc.duration = sqlite3_column_int(load_proc_stat_stmt, 2);
+               if (pc.duration >= 2 * 60 * 60) /* 2 hours */
+                       efficiency = ((float)pc.power_cons) / pc.duration;
+               res = cb(pc.appid, efficiency * 60 * 60, user_data);
+               free((void*)pc.appid);
+               if (res == LOGD_DB_QUERY_STOP)
+                       break;
+       }
+
+       return 0;
+}
+
+
+API int update_proc_power_cons(struct proc_power_cons *pc, int day)
+{
+       DB_CHECK(sqlite3_reset(update_proc_stat_stmt));
+       DB_CHECK(sqlite3_bind_text(update_proc_stat_stmt, 1, pc->appid, -1,
+               SQLITE_STATIC));
+       DB_CHECK(sqlite3_bind_int64(update_proc_stat_stmt, 2, pc->power_cons));
+       DB_CHECK(sqlite3_bind_int(update_proc_stat_stmt, 3, pc->duration));
+       DB_CHECK(sqlite3_bind_int(update_proc_stat_stmt, 4, day));
+
+       if (sqlite3_step(update_proc_stat_stmt) != SQLITE_DONE) {
+               _E("Failed to record to proc_stat table");
+               return -1;
+       }
+
+       return 0;
+}
+
+API int logd_foreach_proc_stat(enum logd_db_query (*cb)
+       (const struct logd_proc_stat *, void *), void *user_data)
+{
+       int ret = 0;
+       int count;
+       int sock;
+       struct logd_proc_stat proc_stat;
+       enum logd_socket_req_type req_type = LOGD_PROC_STAT_REQ;
+
+       if ((sock = connect_to_logd_socket()) < 0) {
+               return sock;
+       }
+
+       if (write(sock, &req_type, sizeof(req_type)) != sizeof(req_type)) {
+               ret = -errno;
+               _E("Can'r write req_type");
+               goto out;
+       }
+
+       if (read_from_socket(sock, &count, sizeof(count)) != sizeof(count)) {
+               ret = -errno;
+               _E("Can't read count");
+               goto out;
+       }
+
+       for (int i = 0; i < count; ++i) {
+               int length;
+               char buf[FILENAME_MAX] = { 0, };
+               if (read_from_socket(sock, &length, sizeof(length)) != sizeof(length)) {
+                       ret = -errno;
+                       _E("Can't read len");
+                       goto out;
+               }
+
+               if (read_from_socket(sock, buf, length) != length) {
+                       ret = -errno;
+                       _E("recv failed");
+                       goto out;
+               }
+               proc_stat.application = strdup(buf);
+               if (read_from_socket(sock, &proc_stat.utime, sizeof(proc_stat.utime)) !=
+                       sizeof(proc_stat.utime)) {
+                       ret = -errno;
+                       _E("recv failed");
+                       goto out;
+               }
+
+               if (read_from_socket(sock, &proc_stat.stime, sizeof(proc_stat.stime)) !=
+                       sizeof(proc_stat.stime)) {
+                       ret = -errno;
+                       _E("recv failed");
+               }
+
+               if (read_from_socket(sock, &proc_stat.utime_power_cons, sizeof(proc_stat.utime_power_cons)) !=
+                       sizeof(proc_stat.utime_power_cons)) {
+                       ret = -errno;
+                       _E("recv failed");
+                       goto out;
+               }
+
+               if (read_from_socket(sock, &proc_stat.stime_power_cons, sizeof(proc_stat.stime_power_cons)) !=
+                       sizeof(proc_stat.stime_power_cons)) {
+                       ret = -errno;
+                       _E("recv failed");
+                       goto out;
+               }
+
+               if (read_from_socket(sock, &proc_stat.is_active, sizeof(proc_stat.is_active)) !=
+                       sizeof(proc_stat.is_active)) {
+                       ret = -errno;
+                       _E("recv failed");
+                       goto out;
+               }
+
+               ret = cb(&proc_stat, user_data);
+               free(proc_stat.application);
+               if (ret == LOGD_DB_QUERY_STOP) {
+                       break;
+               }
+       }
+
+out:
+       close(sock);
+       return ret;
+}
+
+API int delete_old_power_cons(int day)
+{
+       DB_CHECK(sqlite3_reset(delete_old_power_cons_stmt));
+       DB_CHECK(sqlite3_bind_int(delete_old_power_cons_stmt, 1, day));
+
+       if (sqlite3_step(delete_old_power_cons_stmt) != SQLITE_DONE) {
+               _E("Failed to record to proc_stat table");
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/src/logd/src/liblogd-db/proc-stat.h b/src/logd/src/liblogd-db/proc-stat.h
new file mode 100644 (file)
index 0000000..de66b47
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _LOGD_PROC_STAT_H_
+#define _LOGD_PROC_STAT_H_
+
+#include "logd.h"
+#include "logd-db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct proc_power_cons {
+       const char *appid;
+       uint64_t power_cons;
+       int duration;
+};
+
+int proc_stat_init(void);
+int proc_stat_finalize(void);
+
+int foreach_proc_power_cons(enum logd_db_query (*cb)
+       (const struct proc_power_cons *pc, void *user_data), int day, void *user_data);
+
+int update_proc_power_cons(struct proc_power_cons *pc, int day);
+int delete_old_power_cons(int day);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_PROC_STAT_H_ */
diff --git a/src/logd/src/liblogd-db/tests/CMakeLists.txt b/src/logd/src/liblogd-db/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..53642df
--- /dev/null
@@ -0,0 +1,11 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+############### TARGET ###########################
+ADD_EXECUTABLE(logd_foreach_test foreach-test.c)
+ADD_EXECUTABLE(logd_padvisor_test padvisor-test.c)
+TARGET_LINK_LIBRARIES(logd_foreach_test ${LIB_LOGD_DB} ${LIB_LOGD})
+TARGET_LINK_LIBRARIES(logd_padvisor_test ${LIB_LOGD_DB} ${LIB_LOGD})
+
+############### INSTALL ##########################
+INSTALL(TARGETS logd_foreach_test DESTINATION bin)
+INSTALL(TARGETS logd_padvisor_test DESTINATION bin)
diff --git a/src/logd/src/liblogd-db/tests/foreach-test.c b/src/logd/src/liblogd-db/tests/foreach-test.c
new file mode 100644 (file)
index 0000000..6c36e29
--- /dev/null
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <logd-db.h>
+#include "macro.h"
+
+enum logd_db_query cb(const struct logd_event_info *event, void *user_data)
+{
+       struct tm st;
+       time_t time_sec;
+       char timestr[200];
+
+       time_sec = event->time;
+       localtime_r(&time_sec, &st);
+       strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &st);
+       printf("%s %s %s\n", event->application, timestr, event->message);
+
+       return LOGD_DB_QUERY_CONTINUE;
+}
+
+enum logd_db_query proc_stat_cb(const struct logd_proc_stat *proc_stat, void *user_data)
+{
+       if (proc_stat->utime_power_cons + proc_stat->stime_power_cons == 0)
+               return LOGD_DB_QUERY_STOP;
+
+       printf("%-50.50s %10f %d\n", proc_stat->application,
+               proc_stat->utime_power_cons + proc_stat->stime_power_cons, proc_stat->is_active);
+
+       return LOGD_DB_QUERY_CONTINUE;
+}
+
+enum logd_db_query dev_stat_cb(const struct logd_device_stat *dev_stat, void *user_data)
+{
+       printf("device %d\t%f\t%f\n", dev_stat->type, dev_stat->power_cons,
+               dev_stat->cur_power_cons);
+
+       return LOGD_DB_QUERY_CONTINUE;
+}
+
+enum logd_db_query energy_efficiency_cb(const char *application,
+       float efficiency, void *user_data)
+{
+       printf("%s %f\n", application, efficiency);
+
+       return LOGD_DB_QUERY_CONTINUE;
+}
+
+int main()
+{
+       struct logd_events_filter filter;
+       struct logd_battery_info *info;
+       int *est_time = NULL;
+       int i;
+
+       memset(&filter, 0, sizeof(filter));
+       filter.from = 0;
+       filter.to = 2500000000U;
+       if (logd_foreach_events(&filter, &cb, NULL) < 0)
+               puts("logd_foreach_events failed");
+
+       filter.objects_mask[LOGD_BATTERY_SOC] = 1;
+       printf("by object %d\n", LOGD_BATTERY_SOC);
+       if (logd_foreach_events(&filter, &cb, NULL) < 0)
+               puts("logd_foreach_events failed");
+
+       filter.objects_mask[LOGD_CHARGER] = 1;
+       printf("by object %d\n", LOGD_CHARGER);
+       if (logd_foreach_events(&filter, &cb, NULL) < 0)
+               puts("logd_foreach_events failed");
+
+       printf("by action %d\n", LOGD_ON);
+       filter.actions_mask[LOGD_ON] = 1;
+       if (logd_foreach_events(&filter, &cb, NULL) < 0)
+               puts("logd_foreach_events failed");
+
+       printf("by action %d\n", LOGD_STOP);
+       filter.actions_mask[LOGD_STOP] = 1;
+       if (logd_foreach_events(&filter, &cb, NULL) < 0)
+               puts("logd_foreach_events failed");
+
+       printf("all of db\n");
+       if (logd_foreach_events(NULL, &cb, NULL) < 0)
+               puts("logd_foreach_events failed");
+
+       printf("\n\n%-50.50s %10s %10s\n", "Application", "power cons, uah", "is active");
+       if (logd_foreach_proc_stat(&proc_stat_cb, NULL) < 0)
+               puts("logd_foreach_proc_stat failed");
+
+       if (logd_foreach_devices_stat(&dev_stat_cb, NULL) < 0)
+               puts("logd_foreach_devices_stat failed");
+
+       if ((info = logd_get_battery_info()) == NULL) {
+               puts("logd_get_battery_info failed");
+       } else {
+               for (i = 0; i < info->n; ++i)
+                       printf("date %ld  level %d  k %f\n", info->levels[i].date,
+                               info->levels[i].level, info->levels[i].k);
+               printf("level = %f\n", logd_battery_level_at(info, time(NULL) - 5));
+               printf("index when battery capacity was equal 100%% %d\n",
+                       logd_seek_battery_level(info, 10000));
+       }
+
+       logd_foreach_apps_energy_efficiency(energy_efficiency_cb, NULL);
+
+       if (logd_get_estimate_battery_lifetime(&est_time) == 0) {
+               for (i = 0; i < LOGD_POWER_MODE_MAX; ++i)
+                       printf("%d\n", est_time[i]);
+               free(est_time);
+       } else {
+               puts("logd_get_estimate_battery_lifetime failed");
+       }
+
+       return 0;
+}
diff --git a/src/logd/src/liblogd-db/tests/padvisor-test.c b/src/logd/src/liblogd-db/tests/padvisor-test.c
new file mode 100644 (file)
index 0000000..098ab57
--- /dev/null
@@ -0,0 +1,46 @@
+#include <db.h>
+#include <errno.h>
+#include <macro.h>
+#include <padvisor.h>
+
+int main(void)
+{
+       struct logd_power_advisor *lpa = NULL;
+       struct device_power_consumption *dpc =
+               logd_get_device_power_cons(1, 2000000000);
+
+       if (!dpc) {
+               puts("logd_get_device_power_cons failed");
+               return -errno;
+       }
+
+       puts("Device id  | Working time  | persent");
+       for (int i = 0; i < LOGD_OBJECT_MAX; ++i) {
+               printf("%9d  | %12d  | %.4f\n", i, dpc->device_cons[i].time,
+                       dpc->device_cons[i].percentage * 100);
+       }
+       logd_free_device_power_cons(dpc);
+
+
+       lpa = logd_get_power_advisor();
+       if (lpa != NULL) {
+               for (int i = 0; i < lpa->idle_devices_used_num; i++) {
+                       printf("device - %d, time - %lld\n",
+                               lpa->idle_devices[i].device,
+                               lpa->idle_devices[i].idle_time);
+               }
+               for (int i = 0; i < lpa->proc_stat_used_num; i++) {
+                       printf("application - %s, percentage - %.2f, power cons(uAh) - %f  utime - %lld, stime - %lld\n",
+                               lpa->procs[i].application, lpa->procs[i].percentage * 100,
+                               lpa->procs[i].utime_power_cons + lpa->procs[i].stime_power_cons,
+                               lpa->procs[i].utime, lpa->procs[i].stime);
+               }
+       } else {
+               printf("logd_get_power_advisor() returned NULL\n");
+               return -errno;
+       }
+
+       logd_free_power_advisor(lpa);
+
+       return 0;
+}
diff --git a/src/logd/src/liblogd/CMakeLists.txt b/src/logd/src/liblogd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0ab715b
--- /dev/null
@@ -0,0 +1,39 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(PC_NAME ${LIB_LOGD})
+SET(PC_REQUIRED "libsystemd-journal")
+SET(PC_PROVIDED_LIBS "-l${LIB_LOGD}")
+SET(PC_CFLAGS -I\${includedir}/${LIB_LOGD})
+
+CONFIGURE_FILE(
+       liblogd.pc.in
+       liblogd.pc
+       @ONLY
+)
+
+SET(LIB_SOURCE
+       logd.c)
+
+############### SET FLAGS ########################
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(liblogd_pkgs REQUIRED libsystemd-journal dlog)
+
+FOREACH(flag ${liblogd_pkgs_LDFLAGS})
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${liblogd_pkgs_CFLAGS})
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+############### TARGET ###########################
+ADD_LIBRARY(${LIB_LOGD} SHARED ${LIB_SOURCE})
+TARGET_LINK_LIBRARIES(${LIB_LOGD} systemd-journal)
+
+############### INSTALL ##########################
+INSTALL(TARGETS ${LIB_LOGD} DESTINATION lib)
+INSTALL(FILES logd.h DESTINATION include/${LIB_LOGD})
+INSTALL(FILES lib${LIB_LOGD}.pc DESTINATION lib/pkgconfig)
+
+############### SUBDIRS ##########################
+ADD_SUBDIRECTORY(tests)
diff --git a/src/logd/src/liblogd/liblogd.pc.in b/src/logd/src/liblogd/liblogd.pc.in
new file mode 100644 (file)
index 0000000..06da144
--- /dev/null
@@ -0,0 +1,8 @@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_PROVIDED_LIBS@
+Cflags: @PC_CFLAGS@
diff --git a/src/logd/src/liblogd/logd.c b/src/logd/src/liblogd/logd.c
new file mode 100644 (file)
index 0000000..a5798d0
--- /dev/null
@@ -0,0 +1,90 @@
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <systemd/sd-journal.h>
+#include "core/log.h"
+#include "logd.h"
+#include "macro.h"
+
+#define ADD_ACTION_STR(action, str) [action]=str
+
+#define GET_ACTION_STR(table, action) table[action]
+/*
+ * If you want add action,
+ * you must add string of each action
+ * using ADD_ACTION_STR macro.
+ */
+static const char *action_string[LOGD_ACTION_MAX] = {
+       ADD_ACTION_STR(LOGD_NONE_ACTION, "none"),
+       ADD_ACTION_STR(LOGD_ON, "on"),
+       ADD_ACTION_STR(LOGD_START, "start"),
+       ADD_ACTION_STR(LOGD_CONTINUE, "continue"),
+       ADD_ACTION_STR(LOGD_STOP, "stop"),
+       ADD_ACTION_STR(LOGD_OFF, "off"),
+       ADD_ACTION_STR(LOGD_CHANGED, "changed"),
+};
+
+static const char *get_value(enum logd_object object,
+        enum logd_action action, ...)
+{
+       char *text = NULL;
+       va_list vl;
+
+       va_start(vl, action);
+
+       switch (object | LOGD_SHIFT_ACTION(action)) {
+       case LOGD_BATTERY_SOC | LOGD_SHIFT_ACTION(LOGD_CHANGED):
+       case LOGD_DISPLAY | LOGD_SHIFT_ACTION(LOGD_CHANGED):
+       case LOGD_POWER_MODE | LOGD_SHIFT_ACTION(LOGD_CHANGED):
+               if (vasprintf(&text, "%d", vl) < 0)
+                       goto error;
+               break;
+       case LOGD_FOREGRD_APP | LOGD_SHIFT_ACTION(LOGD_CHANGED):
+               if (vasprintf(&text, "%s", vl) < 0)
+                       goto error;
+               break;
+       default:
+               /*
+                * we already have defined the string of each action
+                * as it is initialized.
+                * we check avaliable of action and object here.
+                * GET_ACTION_STR will return the string
+                * which is proper of action.
+                */
+               if (action < LOGD_ACTION_MAX && object < LOGD_OBJECT_MAX) {
+                       text = strdup(GET_ACTION_STR(action_string, action));
+                       break;
+               }
+               _E("invalid logd_object or logd_action: %d, %d", object, action);
+               goto error;
+       }
+       va_end(vl);
+       return text;
+
+error:
+       va_end(vl);
+       return NULL;
+}
+
+API int logd_event(enum logd_object object, enum logd_action action, ...)
+{
+       va_list vl;
+       const char *message = NULL;
+       int ret;
+
+       va_start(vl, action);
+       message = get_value(object, action);
+       if (!message) {
+               va_end(vl);
+               return LOGD_ERROR_INVALID_PARAM;
+       }
+       va_end(vl);
+
+       ret = sd_journal_send("LOGD_EVENT_TYPE=%d",
+       object | LOGD_SHIFT_ACTION(action), "MESSAGE=%s", message, NULL);
+       free((void *) message);
+
+       return ret < 0 ? LOGD_ERROR_SDJOURNAL : LOGD_ERROR_OK;
+}
diff --git a/src/logd/src/liblogd/logd.h b/src/logd/src/liblogd/logd.h
new file mode 100644 (file)
index 0000000..1302eaa
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * logd
+ *
+ * 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.
+ */
+
+/**
+ * @file logd.h
+ *
+ * @desc Contains API to create logd events.
+ */
+
+#ifndef _LOGD_ACTIVITY_LOGGING_H_
+#define _LOGD_ACTIVITY_LOGGING_H_
+
+#include <stdint.h>
+
+#define LOGD_SHIFT_ACTION(action) ((action) << 16)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum logd_object {
+       /* HW devices */
+       LOGD_ACCELEROMETER,
+       LOGD_BAROMETER,
+       LOGD_BT,
+       LOGD_DISPLAY,
+       LOGD_GEOMAGNETIC,
+       LOGD_GPS,
+       LOGD_GYROSCOPE,
+       LOGD_LIGHT,
+       LOGD_NFC,
+       LOGD_PROXIMITY,
+       LOGD_THERMOMETER,
+       LOGD_WIFI,
+       LOGD_MMC,
+       /* Battery */
+       LOGD_BATTERY_SOC,
+       LOGD_CHARGER,
+       /* Apps */
+       LOGD_FOREGRD_APP,
+       /* Function */
+       LOGD_AUTOROTATE,
+       LOGD_MOTION,
+       LOGD_POWER_MODE,
+       /* Users */
+
+       LOGD_OBJECT_MAX,
+};
+
+enum logd_action {
+       LOGD_NONE_ACTION,
+       LOGD_ON,
+       LOGD_START,
+       LOGD_CONTINUE,
+       LOGD_STOP,
+       LOGD_OFF,
+       LOGD_CHANGED,
+       LOGD_ACTION_MAX,
+};
+
+/**
+ * enum logd_power_mode must be 3rd parameter
+ * for LOGD_POWER_MODE | LOGD_CHANGED event
+ */
+enum logd_power_mode {
+       LOGD_POWER_MODE_NORMAL,
+       LOGD_POWER_MODE_POWERFUL,
+       LOGD_POWER_MODE_EMERGENCY,
+       LOGD_POWER_MODE_MAX, /* it's fake power mode, don't use it */
+       LOGD_POWER_MODE_CHARGED, /* it's fake power mode, don't use it */
+};
+
+enum logd_error {
+       LOGD_ERROR_OK,
+       LOGD_ERROR_INVALID_PARAM,
+       LOGD_ERROR_SDJOURNAL
+};
+
+/**
+ * Create new logd event, that will be sent to logd_grabber and stored in DB.
+ *
+ * @param object Object that was changed.
+ * @param action Type of event that occured with object.
+ * @param ... Message that clarify event's parameter. Required not for all
+ * event type. It can be <CODE>int</CODE> or <CODE>char*</CODE> depends on
+ * <CODE>object</CODE> and <CODE>action</CODE>.
+ * object=LOGD_BATTERY_SOC and action=LOGD_CHANGED, data=[battary level] (int)
+ * object=LOGD_DISPLAY and action=LOGD_CHANGED, data=[brigthness level] (int)
+ * object=LOGD_FOREGRD_APP and action=LOGD_CHANGED, data=[new foregraund appl] (char*)
+ * @return On success, LOGD_ERROR_OK. On error, other value from
+ * <CODE>enum logd_error</CODE>
+ *
+ * Example usage:
+ * @code
+ * logd_event(LOGD_WIFI, LOGD_ON);
+ * logd_event(LOGD_FOREGRD_APP, LOGD_CHANGED, "browser");
+ * @endcode
+ */
+int logd_event(enum logd_object object, enum logd_action action, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_ACTIVITY_LOGGING_H_ */
diff --git a/src/logd/src/liblogd/tests/CMakeLists.txt b/src/logd/src/liblogd/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5260956
--- /dev/null
@@ -0,0 +1,8 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+############### TARGET ###########################
+ADD_EXECUTABLE(store-event-test store-event-test.c)
+TARGET_LINK_LIBRARIES(store-event-test ${LIB_LOGD})
+
+############### INSTALL ##########################
+INSTALL(TARGETS store-event-test DESTINATION bin)
diff --git a/src/logd/src/liblogd/tests/store-event-test.c b/src/logd/src/liblogd/tests/store-event-test.c
new file mode 100644 (file)
index 0000000..e36ec5c
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "core/log.h"
+#include "logd.h"
+
+int main(int argc, char **argv)
+{
+       logd_event(LOGD_POWER_MODE, LOGD_CHANGED, 2);
+/*     logd_event(LOGD_DISPLAY, LOGD_CHANGED, argc == 2 ? atoi(argv[1]) : 51);
+       logd_event(LOGD_WIFI, LOGD_ON);
+       logd_event(LOGD_FOREGRD_APP, LOGD_CHANGED, "browser");*/
+       logd_event(LOGD_BATTERY_SOC, LOGD_CHANGED, 90);
+       sleep(1);
+       logd_event(LOGD_BATTERY_SOC, LOGD_CHANGED, 80);
+       sleep(2);
+       logd_event(LOGD_BATTERY_SOC, LOGD_CHANGED, 70);
+       sleep(3);
+       return 0;
+}
+
diff --git a/src/logd/src/shared/CMakeLists.txt b/src/logd/src/shared/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c6a6221
--- /dev/null
@@ -0,0 +1,21 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+############### SET FLAGS ########################
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(shared_pkgs REQUIRED dlog)
+
+FOREACH(flag ${shared_pkgs_LDFLAGS})
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${shared_pkgs_CFLAGS})
+       SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+############### TARGET ###########################
+ADD_LIBRARY(netlink STATIC netlink.c)
+ADD_LIBRARY(task-stats STATIC task-stats.c)
+ADD_LIBRARY(proc-events STATIC proc-events.c)
+ADD_LIBRARY(socket-helper STATIC socket-helper.c)
+
+TARGET_LINK_LIBRARIES(task-stats netlink)
diff --git a/src/logd/src/shared/logd-taskstats.h b/src/logd/src/shared/logd-taskstats.h
new file mode 100644 (file)
index 0000000..8584e2c
--- /dev/null
@@ -0,0 +1,82 @@
+/* taskstats.h - exporting per-task statistics
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ *           (C) Balbir Singh,   IBM Corp. 2006
+ *           (C) Jay Lan,        SGI, 2006
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+/*
+ * This header was generated from a Linux kernel header
+ * "include/linux/taskstats.h", to make information necessary for userspace to
+ * call into the kernel available to logd. It contains only constants,
+ * structures, and macros generated from the original header, and thus,
+ * contains no copyrightable information.
+*/
+/*
+ * Modification: Unused variable is changed to padding variable in taskstats
+ * and removed unused enum variable about TASKSTATS.
+ * Feb. 02th 2014
+ */
+
+
+#ifndef _LINUX_TASKSTATS_H
+#define _LINUX_TASKSTATS_H
+
+#include <linux/types.h>
+
+#define TS_COMM_LEN            32
+
+struct taskstats {
+       __u16   version;
+       __u32   ac_exitcode;
+       __u8    ac_flag;
+       __u8    ac_nice;
+       __u64   cpu_count __attribute__((aligned(8)));
+       __u64   cpu_delay_total;
+       __u64   blkio_count;
+       __u64   blkio_delay_total;
+       __u64   swapin_count;
+       __u64   swapin_delay_total;
+       __u64   cpu_run_real_total;
+       __u64   cpu_run_virtual_total;
+       char    ac_comm[TS_COMM_LEN];
+       __u8    ac_sched __attribute__((aligned(8)));
+       __u8    ac_pad[3];
+       __u32   ac_uid __attribute__((aligned(8)));
+       __u32   ac_gid;
+       __u32   ac_pid;
+       __u32   ac_ppid;
+       __u32   ac_btime;
+       __u64   ac_etime __attribute__((aligned(8)));
+       __u64   ac_utime;
+       __u64   ac_stime;
+       __u64   ac_utime_power_cons;
+       __u64   ac_stime_power_cons;
+       __u64   extra_pad[20];
+};
+
+enum {
+       TASKSTATS_CMD_GET = 1,
+};
+
+enum {
+       TASKSTATS_TYPE_STATS = 3,
+       TASKSTATS_TYPE_AGGR_PID = 4,
+};
+
+enum {
+       TASKSTATS_CMD_ATTR_UNSPEC = 0,
+       TASKSTATS_CMD_ATTR_PID = 1,
+       TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 3,
+};
+
+#define TASKSTATS_GENL_NAME    "TASKSTATS"
+
+#endif
diff --git a/src/logd/src/shared/macro.h b/src/logd/src/shared/macro.h
new file mode 100644 (file)
index 0000000..ac59a93
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _LOGD_MACRO_H_
+#define _LOGD_MACRO_H_
+
+#include <time.h>
+#include "core/common.h"
+
+#define USEC_PER_SEC 1000000ull
+#define SEC_PER_DAY 86400
+#define DAYS_PER_WEEK 7
+#define time_after(a, b) ((int64_t)(b) - (int64_t)(a) < 0)
+#define time_after_eq(a, b) ((int64_t)(b) - (int64_t)(a) <= 0)
+
+//#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+#define STRINGIZE(x) #x
+#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
+
+#define API __attribute__ ((visibility ("default")))
+
+#define STATIC_ASSERT(CONDITION,MESSAGE) typedef char static_assert_\
+##MESSAGE[(CONDITION)?0:-1]
+
+#define CHECK_RET(ret, func_name)                                      \
+       do {                                                            \
+               if (ret < 0) {                                          \
+                       _E(func_name" failed: error code %d", ret);     \
+                       return ret;                                     \
+               }                                                       \
+       } while (0);
+
+__attribute__ ((unused)) static time_t getSecTime()
+{
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts);
+       return ts.tv_sec;
+}
+
+#endif /* _LOGD_MACRO_H_ */
diff --git a/src/logd/src/shared/netlink.c b/src/logd/src/shared/netlink.c
new file mode 100644 (file)
index 0000000..ec2d63b
--- /dev/null
@@ -0,0 +1,132 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "core/log.h"
+#include "netlink.h"
+
+int create_netlink_socket(int protocol, int groups, int pid)
+{
+       int sock;
+       int flags;
+       struct sockaddr_nl local;
+       int buf_size = 1024*1024;
+
+       sock = socket(AF_NETLINK, SOCK_RAW, protocol);
+       if (sock < 0) {
+               int ret = -errno;
+               _E("socket failed: %s", strerror(errno));
+               return ret;
+       }
+       if ((flags = fcntl(sock, F_GETFL, 0)) < 0) {
+               int ret = -errno;
+               _E("fcntl failed");
+               close(sock);
+               return ret;
+       }
+
+       if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) != 0) {
+               int ret = -errno;
+               _E("fcntl failed: %s", strerror(errno));
+               close(sock);
+               return ret;
+       }
+       if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&buf_size, sizeof(buf_size)) < 0)
+               return -1;
+
+       if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size)) < 0)
+               return -1;
+
+       bzero(&local, sizeof(struct sockaddr_nl));
+       local.nl_family = AF_NETLINK;
+       local.nl_groups = groups;
+       local.nl_pid = pid;
+
+       if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0) {
+               int ret = -errno;
+               _E("bind failed: %s", strerror(errno));
+               close(sock);
+               return ret;
+       }
+
+       return sock;
+}
+
+int send_cmd(int sock, unsigned short family_id, pid_t pid, __u8 cmd,
+        unsigned short nl_type, void *nl_data, int nl_len)
+{
+       struct nlattr *attr;
+       struct sockaddr_nl addr;
+       int ret = 0;
+       int len;
+       char *buffer;
+
+       struct msgtemplate message;
+
+       message.g.cmd = cmd;
+       message.g.version = 1;
+       message.n.nlmsg_flags = NLM_F_REQUEST;
+       message.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
+       message.n.nlmsg_pid = pid;
+       message.n.nlmsg_seq = 0;
+       message.n.nlmsg_type = family_id;
+
+       attr = (struct nlattr *) GENLMSG_DATA(&message);
+       attr->nla_type = nl_type;
+       attr->nla_len = nl_len + 1 + NLA_HDRLEN;
+
+       memcpy(NLA_DATA(attr), nl_data, nl_len);
+       message.n.nlmsg_len += NLMSG_ALIGN(attr->nla_len);
+
+       buffer = (char *) &message;
+       len = message.n.nlmsg_len;
+       memset(&addr, 0, sizeof(addr));
+       addr.nl_family = AF_NETLINK;
+
+       for (; ret < len; buffer += ret, len -= ret) {
+               ret = sendto(sock, buffer, len, 0, (struct sockaddr *) &addr,
+                       sizeof(addr));
+               if (ret < 0 && errno != EAGAIN)
+                       return -errno;
+       }
+
+       return 0;
+}
+
+int get_family_id(int sock, const char *name)
+{
+       struct {
+               struct nlmsghdr n;
+               struct genlmsghdr g;
+               char buf[256];
+       } ans;
+
+       struct nlattr *na;
+       int id = 0, rc;
+       int rep_len;
+
+       rc = send_cmd(sock, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
+                       CTRL_ATTR_FAMILY_NAME, (void *)name, strlen(name) + 1);
+       if (rc < 0) {
+               _E("send_cmd error");
+               return rc;
+       }
+
+       rep_len = recv(sock, &ans, sizeof(ans), 0);
+       if (rep_len < 0 || ans.n.nlmsg_type == NLMSG_ERROR ||
+           !NLMSG_OK((&ans.n), (unsigned int)rep_len)) {
+               _E("recv error");
+               return -errno;
+       }
+
+       na = (struct nlattr *) GENLMSG_DATA(&ans);
+       na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
+
+       if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
+               id = *(__u16 *) NLA_DATA(na);
+       }
+
+       return id;
+}
diff --git a/src/logd/src/shared/netlink.h b/src/logd/src/shared/netlink.h
new file mode 100644 (file)
index 0000000..550763f
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef _LOGD_NETLINK_H_
+#define _LOGD_NETLINK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <linux/genetlink.h>
+/* TODO: replace "logd-taskstats.h" on " <linux/taskstats.h>
+ * if the build system will contains kernel-headers from tizen.
+ * Now it's necessary due to build system using 2.6.36 kernel and
+ * struct taskstats not contains ac_stime_power_cons, ac_utime_power_cons
+ * variables.
+ */
+#include "logd-taskstats.h"
+#include <linux/netlink.h>
+
+#define GENLMSG_DATA(glh)      ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
+#define GENLMSG_PAYLOAD(glh)   (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
+#define NLA_DATA(na)           ((void *)((char*)(na) + NLA_HDRLEN))
+#define NLA_PAYLOAD(len)       (len - NLA_HDRLEN)
+
+#define MAX_MSG_SIZE           1024
+
+struct msgtemplate {
+       struct nlmsghdr n;
+       struct genlmsghdr g;
+       char buf[MAX_MSG_SIZE];
+};
+
+int create_netlink_socket(int protocol, int groups, int pid);
+int send_cmd(int sock, unsigned short family_id, pid_t pid, __u8 cmd,
+        unsigned short nl_type, void *nl_data, int nl_len);
+int get_family_id(int sock, const char *n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_NETLINK_H_ */
diff --git a/src/logd/src/shared/proc-events.c b/src/logd/src/shared/proc-events.c
new file mode 100644 (file)
index 0000000..9ee8772
--- /dev/null
@@ -0,0 +1,60 @@
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "core/log.h"
+#include "proc-events.h"
+#include "netlink.h"
+
+int subscribe_on_proc_events(int sock)
+{
+       struct {
+               struct nlmsghdr n;
+               struct __attribute__ ((__packed__)) {
+                       struct cn_msg cn_msg;
+                       enum proc_cn_mcast_op cn_mcast;
+               };
+       } msg;
+
+       bzero(&msg, sizeof(msg));
+       msg.n.nlmsg_len = sizeof(msg);
+       msg.n.nlmsg_pid = getpid();
+       msg.n.nlmsg_type = NLMSG_DONE;
+
+       msg.cn_msg.id.idx = CN_IDX_PROC;
+       msg.cn_msg.id.val = CN_VAL_PROC;
+       msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);
+       msg.cn_mcast = PROC_CN_MCAST_LISTEN;
+
+       if (send(sock, &msg, sizeof(msg), 0) < 0) {
+               _E("send failed");
+               return -errno;
+       }
+
+       return 0;
+}
+
+
+int process_proc_event_answer(int sock,
+       int (*process_cb)(struct proc_event *e, void *user_data), void *user_data)
+{
+       int rc;
+       struct {
+               struct nlmsghdr nl_hdr;
+               struct __attribute__ ((__packed__)) {
+                       struct cn_msg cn_msg;
+                       struct proc_event event;
+               };
+       } msg;
+
+       rc = recv(sock, &msg, sizeof(msg), 0);
+       if (rc < 0 && errno != EAGAIN) {
+               _E("recv failed");
+               return -errno;
+       }
+
+       if (rc > 0)
+               process_cb(&msg.event, user_data);
+
+       return 0;
+}
diff --git a/src/logd/src/shared/proc-events.h b/src/logd/src/shared/proc-events.h
new file mode 100644 (file)
index 0000000..8ee176c
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _LOGD_PROC_EVENTS_H_
+#define _LOGD_PROC_EVENTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/connector.h>
+#include <linux/cn_proc.h>
+
+int subscribe_on_proc_events(int sock);
+int process_proc_event_answer(int sock,
+       int (*process_cb)(struct proc_event *e, void *user_data), void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_PROC_EVENTS_H_ */
diff --git a/src/logd/src/shared/socket-helper.c b/src/logd/src/shared/socket-helper.c
new file mode 100644 (file)
index 0000000..43f6027
--- /dev/null
@@ -0,0 +1,102 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "core/log.h"
+#include "socket-helper.h"
+
+int create_logd_socket()
+{
+       int ret = 0;
+       struct sockaddr_un saun;
+       int old_umask = umask(~(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
+       struct group *group_entry = NULL;
+       int len, sock;
+
+       if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+               ret = -errno;
+               _E("Failed to create socket");
+               return ret;
+       }
+
+       saun.sun_family = AF_UNIX;
+       strcpy(saun.sun_path, LOGD_SOCKET_PATH);
+       unlink(LOGD_SOCKET_PATH);
+
+       len = sizeof(saun.sun_family) + sizeof(saun.sun_path);
+       if (bind(sock, (const struct sockaddr*)&saun, len) < 0) {
+               ret = -errno;
+               _E("Failed bind socket");
+               goto err;
+       }
+       umask(old_umask);
+
+       group_entry = getgrnam("app");
+       if (group_entry == NULL) {
+               ret = -errno;
+               _E("can't find app group id");
+               goto err;
+       }
+       if (chown(LOGD_SOCKET_PATH, -1, group_entry->gr_gid) < 0) {
+               ret = -errno;
+               _E("can't change group");
+               goto err;
+       }
+
+       if (listen(sock, 5) < 0) {
+               ret = -errno;
+               _E("Failed listen socket");
+               goto err;
+       }
+
+       return sock;
+err:
+       close(sock);
+       return ret;
+}
+
+int connect_to_logd_socket()
+{
+       struct sockaddr_un saun;
+       int len, ret;
+       int sock;
+
+       if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+               ret = -errno;
+               _E("Failed to create socket");
+               return ret;
+       }
+       saun.sun_family = AF_UNIX;
+       strcpy(saun.sun_path, LOGD_SOCKET_PATH);
+
+       len = sizeof(saun.sun_family) + sizeof(saun.sun_path);
+       if (connect(sock, (const struct sockaddr*)&saun, len) < 0) {
+               ret = -errno;
+               _E("Failed connect");
+               close(sock);
+               return ret;
+       }
+
+       return sock;
+}
+
+int read_from_socket(int sock, void *buf, int size)
+{
+       int i = 0;
+       int ret;
+
+       while (i < size) {
+               ret = recv(sock, buf + i, size - i, 0);
+               if (ret > 0) {
+                       i += ret;
+               } else if (errno != EAGAIN)
+                       return -errno;
+
+       }
+       return i;
+}
diff --git a/src/logd/src/shared/socket-helper.h b/src/logd/src/shared/socket-helper.h
new file mode 100644 (file)
index 0000000..d9bcc88
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _LOGD_SOCKET_HELPER_H_
+#define _LOGD_SOCKET_HELPER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOGD_SOCKET_PATH "/tmp/logd.socket"
+
+int create_logd_socket();
+int connect_to_logd_socket();
+int read_from_socket(int sock, void *buf, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_PROC_STAT_H_ */
diff --git a/src/logd/src/shared/task-stats.c b/src/logd/src/shared/task-stats.c
new file mode 100644 (file)
index 0000000..4bf88e9
--- /dev/null
@@ -0,0 +1,124 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "core/log.h"
+#include "task-stats.h"
+
+static short taskstats_family_id = 0;
+
+int reg_task_stats_cpu_mask(int sock, const char *cpu_mask)
+{
+       char buf[80] = { 0, };
+       int rc;
+       pid_t self_pid = 0;
+
+       if (taskstats_family_id == 0) {
+               taskstats_family_id = get_family_id(sock, TASKSTATS_GENL_NAME);
+               if (taskstats_family_id < 0) {
+                       _E("get_family_id taskstats failed");
+                       return taskstats_family_id;
+               }
+       }
+
+       strcpy(buf, cpu_mask);
+       self_pid = getpid();
+       rc = send_cmd(sock, taskstats_family_id, self_pid, TASKSTATS_CMD_GET,
+               TASKSTATS_CMD_ATTR_REGISTER_CPUMASK, &buf, sizeof(buf));
+       if (rc < 0) {
+               _E("TASKSTATS_CMD_ATTR_REGISTER_CPUMASK failed");
+               return rc;
+       }
+
+       return sock;
+}
+
+
+int request_stat_by_pid(int sock, pid_t pid)
+{
+       pid_t self_pid = 0;
+
+       if (taskstats_family_id == 0) {
+               taskstats_family_id = get_family_id(sock, TASKSTATS_GENL_NAME);
+               if (taskstats_family_id < 0) {
+                       _E("get_family_id taskstats failed");
+                       return taskstats_family_id;
+               }
+       }
+       self_pid = getpid();
+
+       return send_cmd(sock, taskstats_family_id, self_pid, TASKSTATS_CMD_GET,
+               TASKSTATS_CMD_ATTR_PID, &pid, sizeof(__u32));
+}
+
+
+int process_task_stats_answer(int sock,
+       int (*process_cb)(struct taskstats *t, void *user_data), void *user_data)
+{
+       int repl_len = 0;
+       int len = 0, offset = 0;
+       struct msgtemplate msg;
+       char *buff = (char *)&msg;
+       struct nlattr *na;
+       int aggr_len;
+
+       errno = 0;
+       do {
+               len = recv(sock, buff + offset, sizeof(msg) - offset, 0);
+               if (len < 0 && errno != EAGAIN) {
+                       int ret = -errno;
+                       _E("recv failed");
+                       return ret;
+               }
+               if (len > 0)
+                       offset += len;
+       } while (errno == EAGAIN);
+
+       if (msg.n.nlmsg_type == NLMSG_OVERRUN) {
+               _E("unexpected netlink message");
+               return -1;
+       }
+
+       if (msg.n.nlmsg_type == NLMSG_ERROR ||
+               !NLMSG_OK((&msg.n), (unsigned int)offset)) {
+               struct nlmsgerr *err = NLMSG_DATA(&msg);
+               return err->error;
+       }
+
+       repl_len = GENLMSG_PAYLOAD(&msg.n);
+       na = (struct nlattr *) GENLMSG_DATA(&msg);
+       len = 0;
+
+       while (len < repl_len) {
+               len += NLA_ALIGN(na->nla_len);
+
+               switch (na->nla_type) {
+               case TASKSTATS_TYPE_AGGR_PID:
+                       aggr_len = NLA_PAYLOAD(na->nla_len);
+                       offset = 0;
+
+                       na = (struct nlattr *) NLA_DATA(na);
+                       while (offset < aggr_len) {
+                               switch (na->nla_type) {
+                               case TASKSTATS_TYPE_STATS:
+                                       if (process_cb((struct taskstats *) NLA_DATA(na),
+                                               user_data) < 0) {
+                                               _E("process_cb failed");
+                                       }
+                                       break;
+                               default:
+                                       break;
+                               }
+                               offset += NLA_ALIGN(na->nla_len);
+                               na = (struct nlattr *) ((char *) na + offset);
+                       }
+                       break;
+               default:
+                       break;
+               }
+               na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
+       }
+
+       return 0;
+}
diff --git a/src/logd/src/shared/task-stats.h b/src/logd/src/shared/task-stats.h
new file mode 100644 (file)
index 0000000..0e69443
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _LOGD_TASK_STATS_H_
+#define _LOGD_TASK_STATS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "netlink.h"
+
+int reg_task_stats_cpu_mask(int sock, const char *cpu_mask);
+int process_task_stats_answer(int sock,
+       int (*process_cb)(struct taskstats *t, void *user_data), void *user_data);
+int request_stat_by_pid(int sock, pid_t pid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGD_TASKSTATS_H_ */
diff --git a/src/logd_grabber/battery.c b/src/logd_grabber/battery.c
new file mode 100644 (file)
index 0000000..8aa1f1a
--- /dev/null
@@ -0,0 +1,355 @@
+#include <Eina.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <vconf.h>
+
+#include "core/log.h"
+#include "battery.h"
+#include "config.h"
+#include "devices.h"
+#include "logd.h"
+#include "logd-db.h"
+#include "logd-grabber.h"
+#include "macro.h"
+
+static const char *vconf_power_mode_path = "db/setting/psmode";
+static int min_term_predict_lifetime;
+static time_t last_pm_time;
+static int last_pm_level;
+static enum logd_power_mode curr_power_mode;
+
+static Eina_List *battery_check_points = NULL;
+
+static int on_charge()
+{
+       const char *charge_status_file = "/sys/class/power_supply/battery/status";
+       FILE *fp;
+       int ret;
+       char *buf;
+
+       fp = fopen(charge_status_file, "r");
+       if (!fp) {
+               ret = -errno;
+               _E("fopen failed: %s", strerror(errno));
+               return ret;
+       }
+
+       errno = 0;
+       if (fscanf(fp, "%ms", &buf) < 0) {
+               ret = -errno;
+               _E("fscanf failed: %s", strerror(errno));
+               goto out;
+       }
+
+       if (strcmp(buf, "Charging"))
+               ret = 1;
+       else
+               ret = 0;
+       free(buf);
+out:
+       if (fclose(fp) < 0) {
+               _E("fopen failed: %s", strerror(errno));
+       }
+
+       return ret;
+}
+
+static void power_mode_changed_cb(keynode_t *key, void *data)
+{
+       int new_power_mode = (enum logd_power_mode)vconf_keynode_get_int(key);
+
+       if (logd_event(LOGD_POWER_MODE, LOGD_CHANGED, new_power_mode) !=
+               LOGD_ERROR_OK) {
+               _E("logd_event failed");
+       }
+}
+
+int battery_init()
+{
+       last_pm_time = getSecTime();
+       last_pm_level = get_current_battery_level();
+       struct logd_battery_level *b;
+       int is_on_charge;
+       int ret;
+
+       min_term_predict_lifetime = config_get_int("min_term_predict_lifetime", 10800, NULL);
+
+       if (last_pm_level < 0) {
+               _E("get_current_battery_level failed, level set as 0");
+       }
+
+       b = (struct logd_battery_level*) calloc(1, sizeof(struct logd_battery_level));
+       if (!b) {
+               ret = -errno;
+               _E("calloc failed: %s", strerror(errno));
+               return ret;
+       }
+
+       b->date = last_pm_time;
+       b->level = last_pm_level;
+
+       battery_check_points = eina_list_append(battery_check_points, b);
+       if (eina_error_get()) {
+               _E("eina_list_append failed: %s", eina_error_msg_get(eina_error_get()));
+               free(b);
+               return -ENOMEM;
+       }
+
+       is_on_charge = on_charge();
+       if (is_on_charge < 0) {
+               _E("on_charge failed");
+               return is_on_charge;
+       } else if (is_on_charge > 0) {
+               curr_power_mode = LOGD_POWER_MODE_CHARGED;
+       } else {
+               if (vconf_get_int(vconf_power_mode_path, (int*)&curr_power_mode) < 0) {
+                       _E("vconf_get_int failed: %s. Current power mode set as 0",
+                               vconf_power_mode_path);
+               }
+       }
+
+       if (vconf_notify_key_changed(vconf_power_mode_path,
+               power_mode_changed_cb, NULL) < 0) {
+               _E("vconf_notify_key_changed failed: %s", vconf_power_mode_path);
+       }
+
+       return 0;
+}
+
+int battery_level_changed_event_handler(struct logd_grabber_event *event)
+{
+       struct logd_battery_level *b;
+       struct logd_battery_level *last_point;
+       int ret;
+       int level = get_current_battery_level();
+       Eina_List *last_point_list = eina_list_last(battery_check_points);
+       time_t monotonic_time = getSecTime();
+
+       if (level < 0) {
+               _E("get_current_battery_level failed");
+               return level;
+       }
+
+       last_point = (struct logd_battery_level*)eina_list_data_get(last_point_list);
+       if (level == last_point->level)
+               return 0;
+       if (monotonic_time != last_point->date)
+               last_point->k = (float)(level - last_point->level) /
+                       (monotonic_time - last_point->date);
+       else
+               last_point->k = level - last_point->level;
+
+
+       b = (struct logd_battery_level*) calloc(1, sizeof(struct logd_battery_level));
+       if (!b) {
+               ret = -errno;
+               _E("calloc failed: %s", strerror(errno));
+               return ret;
+       }
+
+       b->date = monotonic_time;
+       b->level = level;
+
+       battery_check_points = eina_list_append(battery_check_points, b);
+       if (eina_error_get()) {
+               _E("eina_list_append failed: %s", eina_error_msg_get(eina_error_get()));
+               free(b);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+int battery_charger_event_handler(struct logd_grabber_event *event)
+{
+       Eina_List *last_point_list = eina_list_last(battery_check_points);
+       struct logd_battery_level *last_point;
+       time_t monotonic_time = getSecTime();
+       time_t time_diff = monotonic_time - last_pm_time;
+       int level_diff;
+       enum logd_power_mode new_power_mode;
+
+       last_point = (struct logd_battery_level*)eina_list_data_get(last_point_list);
+       level_diff = last_pm_level - last_point->level;
+
+       if (event->action == LOGD_ON)
+               new_power_mode = LOGD_POWER_MODE_CHARGED;
+       else if (event->action == LOGD_OFF) {
+               if (vconf_get_int(vconf_power_mode_path, (int*)&new_power_mode) < 0) {
+                       _E("vconf_get_int failed");
+               }
+
+               store_new_power_mode(event->date, curr_power_mode, new_power_mode,
+                       time_diff, level_diff);
+               curr_power_mode = new_power_mode;
+               last_pm_time = monotonic_time;
+               last_pm_level = last_point->level;
+       }
+
+       return 0;
+}
+
+int battery_power_mode_changed_event_handler(struct logd_grabber_event *event)
+{
+       Eina_List *last_point_list = eina_list_last(battery_check_points);
+       struct logd_battery_level *last_point;
+       enum logd_power_mode new_power_mode;
+       time_t time_diff;
+       int level_diff;
+       int ret;
+       time_t monotonic_time = getSecTime();
+
+       time_diff = monotonic_time - last_pm_time;
+       last_point = (struct logd_battery_level*)eina_list_data_get(last_point_list);
+       level_diff = last_pm_level - last_point->level;
+       new_power_mode = (enum logd_power_mode) atoi(event->message);
+
+       ret = store_new_power_mode(event->date, curr_power_mode, new_power_mode,
+               time_diff, level_diff);
+       if (ret < 0) {
+               _E("store_new_power_mode failed");
+               return ret;
+       }
+
+       curr_power_mode = new_power_mode;
+       last_pm_time = monotonic_time;
+       last_pm_level = last_point->level;
+
+       return 0;
+}
+
+int battery_level_at(time_t date)
+{
+       Eina_List *l;
+       struct logd_battery_level *data;
+       struct logd_battery_level *nearest = NULL;
+       time_t diff = INT_MAX;
+
+       EINA_LIST_FOREACH(battery_check_points, l, data) {
+               int d = date - data->date;
+
+               if (d < diff && d >= 0) {
+                       nearest = data;
+                       diff = d;
+               }
+       }
+
+       if (!nearest) {
+               _E("have no enough data to return battery level at %d", date);
+               return -1;
+       }
+
+       return (nearest->k * (date - nearest->date) + nearest->level);
+}
+
+int battery_send_check_points(int socket)
+{
+       Eina_List *l;
+       void *data;
+       int ret;
+       int count;
+
+       count = eina_list_count(battery_check_points);
+       if (write(socket, &count, sizeof(count)) != sizeof(count)) {
+               ret = -errno;
+               _E("write failed: %s", strerror(errno));
+               return ret;
+       }
+
+
+       EINA_LIST_FOREACH(battery_check_points, l, data) {
+               if (write(socket, data, sizeof(struct logd_battery_level)) !=
+                       sizeof(struct logd_battery_level)) {
+                       ret = -errno;
+                       _E("write failed: %s", strerror(errno));
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+int battery_send_estimate_lifetime(int socket)
+{
+       int est_time[LOGD_POWER_MODE_MAX];
+       float curr_speed = -1;
+       float *avg_discharge_speed = NULL;
+       struct logd_battery_level *last_point = NULL;
+       struct logd_battery_level *pre_last_point = NULL;
+       int points_number;
+       int level;
+       int ret;
+       int i;
+
+       points_number = eina_list_count(battery_check_points);
+       last_point = (struct logd_battery_level*)
+               eina_list_nth(battery_check_points, points_number - 1);
+       if (points_number > 1)
+               pre_last_point = (struct logd_battery_level*)
+                       eina_list_nth(battery_check_points, points_number - 2);
+
+       for (i = 0; i < LOGD_POWER_MODE_MAX; ++i)
+               est_time[i] = -1;
+
+       avg_discharge_speed = load_discharging_speed(min_term_predict_lifetime);
+       if (!avg_discharge_speed) {
+               _E("load_discharging_speed failed");
+               goto send;
+       }
+
+       level = last_point->level;
+
+       if (points_number > 2 && curr_power_mode != LOGD_POWER_MODE_CHARGED &&
+               last_point->level < pre_last_point->level) {
+               curr_speed = -pre_last_point->k;
+       }
+
+       if (curr_speed > 0) {
+               for (i = 0; i < LOGD_POWER_MODE_MAX; ++i) {
+                       est_time[i] = level / curr_speed;
+                       if (avg_discharge_speed[curr_power_mode] > 0 && avg_discharge_speed[i] > 0)
+                               est_time[i] *= avg_discharge_speed[i] /
+                                       avg_discharge_speed[curr_power_mode];
+
+                       est_time[i] -= getSecTime() - last_point->date;
+                       if (est_time[i] < 0)
+                               est_time[i] = 0;
+               }
+       } else {
+               for (i = 0; i < LOGD_POWER_MODE_MAX; ++i) {
+                       if (avg_discharge_speed[i] > 0)
+                               est_time[i] = level * avg_discharge_speed[i];
+               }
+       }
+
+       free(avg_discharge_speed);
+
+send:
+       for (i = 0; i < LOGD_POWER_MODE_MAX; ++i) {
+               if (write(socket, &est_time[i], sizeof(est_time[i])) !=
+                       sizeof(est_time[i])) {
+                       ret = -errno;
+                       _E("write failed: %s", strerror(errno));
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+int battery_exit()
+{
+       Eina_List *l;
+       void *data;
+
+       if (battery_check_points) {
+               EINA_LIST_FOREACH(battery_check_points, l, data)
+                       free(data);
+               eina_list_free(battery_check_points);
+       }
+
+       return 0;
+}
diff --git a/src/logd_grabber/battery.h b/src/logd_grabber/battery.h
new file mode 100644 (file)
index 0000000..06e66d8
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __BATTERY_H__
+#define __BATTERY_H__
+
+#include <time.h>
+
+#include "event.h"
+#include "logd-grabber.h"
+
+int battery_init();
+int battery_level_at(time_t date);
+int battery_send_estimate_lifetime(int socket);
+int battery_send_check_points(int socket);
+int battery_exit();
+
+int battery_level_changed_event_handler(struct logd_grabber_event *event);
+int battery_charger_event_handler(struct logd_grabber_event *event);
+int battery_power_mode_changed_event_handler(struct logd_grabber_event *event);
+
+#endif /* __BATTERY_H__ */
diff --git a/src/logd_grabber/config.c b/src/logd_grabber/config.c
new file mode 100644 (file)
index 0000000..5d00e7e
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ *  deviced
+ *
+ * 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 <Eina.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "core/log.h"
+
+static Eina_Hash *vars;
+static const char *path = "/etc/deviced/logd-grabber.conf";
+
+static int is_correct(char ch)
+{
+       if (ch >= '0' && ch <= '9')
+               return 1;
+       if (ch >='a' && ch <= 'z')
+               return 1;
+       if (ch >='A' && ch <= 'Z')
+               return 1;
+       if (ch == '_' || ch == '.')
+               return 1;
+
+       return 0;
+}
+
+static int split(char *str, char **key, char **value)
+{
+       char *ptr = NULL;
+       char *_key;
+       char *_value;
+
+       _key = NULL;
+       _value = strchr(str, '=');
+       if (!_value) {
+               _E("Wrong variable declaration: \"%s\". "
+                       "Must be like \"key = value\"\n", str);
+               return -EINVAL;
+       }
+       ptr = str;
+       while (*str == ' ') ++str;
+       while (ptr < _value) {
+               if (!is_correct(*ptr)) {
+                       if (*ptr == ' ') {
+                               _key = ptr;
+                               while (*ptr == ' ' && ptr != _value)
+                                       ++ptr;
+                               if (ptr != _value) {
+                                       _E("Expected '=' before '%c' at %d\n",
+                                               *ptr, ptr - str);
+                               }
+                       } else if (ptr != _value) {
+                               _E("wrong char '%c' at %d\n", *ptr, ptr - str);
+                               return -EINVAL;
+                       }
+               }
+               ++ptr;
+       }
+       if (!_key)
+               _key = _value;
+       ptr = _key;
+       *key = (char*) calloc(1, ptr - str + 1);
+       strncpy(*key, str, ptr - str);
+
+       ptr = _value + 1;
+       while (*ptr == ' ') ++ptr;
+       if (*ptr == 0) {
+               _E("expected char symbol at %d", ptr - str);
+               free(*key);
+               return -EINVAL;
+       }
+
+       _value = ptr;
+
+       while (*ptr != 0) {
+               if (!is_correct(*ptr)) {
+                       _E("wrong char '%c' at %d\n", *ptr, ptr - str);
+                       free(*key);
+                       return -EINVAL;
+               }
+               ++ptr;
+       }
+
+       ptr = _value;
+       *value = (char*) calloc(1, strlen(str) - (ptr - str) + 1);
+       strncpy(*value, str + (ptr - str) , strlen(str) - (ptr - str));
+
+       return 0;
+}
+
+int config_init(void)
+{
+       FILE *fp = NULL;
+       char *key;
+       char *value;
+       char buf[100];
+
+       vars = eina_hash_string_superfast_new(free);
+
+       fp = fopen(path, "r");
+       if (!fp) {
+               perror("fopen: ");
+               return -errno;
+       }
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               if (buf[strlen(buf) - 1] == '\n')
+                       buf[strlen(buf) - 1] = 0;
+               if (split(buf, &key, &value) < 0) {
+                       _E("split failed");
+                       if (fclose(fp) < 0) {
+                               _E("fclose failed: %s", strerror(errno));
+                       }
+                       return -EINVAL;
+               }
+               if (eina_hash_add(vars, key, value) != EINA_FALSE) {
+                       _I("%s = %s added\n", key, value);
+               }
+       }
+       if (fclose(fp) < 0) {
+               int ret = -errno;
+               _E("fclose failed: %s", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+const char *config_get_string(const char *key, const char *def_value, int *error_code)
+{
+       const char *value = eina_hash_find(vars, key);
+
+       if (error_code) {
+               if (!value) {
+                       _E("key %d not exist", key);
+                       *error_code = -1;
+                       value = def_value;
+               } else {
+                       *error_code = 0;
+               }
+       }
+
+       return value;
+}
+
+int config_get_int(const char *key, int def_value, int *error_code)
+{
+       const char *value = config_get_string(key, NULL, error_code);
+       int converted_value;
+
+       if (!value)
+               return def_value;
+       converted_value = atoi(value);
+
+       return converted_value;
+}
+
+float config_get_float(const char *key, float def_value, int *error_code)
+{
+       const char *value = config_get_string(key, NULL, error_code);
+       float converted_value;
+
+       if (!value)
+               return def_value;
+       converted_value = atof(value);
+
+       return converted_value;
+}
+
+double config_get_double(const char *key, double def_value, int *error_code)
+{
+       const char *value = config_get_string(key, NULL, error_code);
+       double converted_value;
+
+       if (!value)
+               return def_value;
+       converted_value = atof(value);
+
+       return converted_value;
+}
+
+int config_exit(void)
+{
+       eina_hash_free(vars);
+
+       return 0;
+}
diff --git a/src/logd_grabber/config.h b/src/logd_grabber/config.h
new file mode 100644 (file)
index 0000000..0f96867
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *  deviced
+ *
+ * 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 __CONFIG_H__
+#define __CONFIG_H__
+
+int config_init(void);
+const char *config_get_string(const char *key, const char *def_value, int *error_code);
+int config_get_int(const char *key, int def_value, int *error_code);
+float config_get_float(const char *key, float def_value, int *error_code);
+double config_get_double(const char *key, double def_value, int *error_code);
+int config_exit(void);
+
+#endif /* __CONFIG_H__ */
diff --git a/src/logd_grabber/data/logd-grabber-micro.conf.in b/src/logd_grabber/data/logd-grabber-micro.conf.in
new file mode 100644 (file)
index 0000000..cf8dd15
--- /dev/null
@@ -0,0 +1,12 @@
+enable_grabber = no
+old_events_del_period = 1800
+proc_stat_store_period = 1800
+old_events_rotate_period = 604800
+power_const_per_uah = 3213253205
+backlight_a = 0.0000258471
+backlight_b = 0.0027898
+backlight_c = 1.36308
+backlight_k = 73.432
+min_term_predict_lifetime = 10800
+mmc_write_sectors_per_uah = 2820
+mmc_read_sectors_per_uah = 4708
diff --git a/src/logd_grabber/data/logd-grabber.conf.in b/src/logd_grabber/data/logd-grabber.conf.in
new file mode 100644 (file)
index 0000000..cf8dd15
--- /dev/null
@@ -0,0 +1,12 @@
+enable_grabber = no
+old_events_del_period = 1800
+proc_stat_store_period = 1800
+old_events_rotate_period = 604800
+power_const_per_uah = 3213253205
+backlight_a = 0.0000258471
+backlight_b = 0.0027898
+backlight_c = 1.36308
+backlight_k = 73.432
+min_term_predict_lifetime = 10800
+mmc_write_sectors_per_uah = 2820
+mmc_read_sectors_per_uah = 4708
diff --git a/src/logd_grabber/data/logd.sql b/src/logd_grabber/data/logd.sql
new file mode 100644 (file)
index 0000000..5300b90
--- /dev/null
@@ -0,0 +1,39 @@
+PRAGMA journal_mode = PERSIST;
+
+CREATE TABLE IF NOT EXISTS events (
+       object INT,
+       action INT,
+       time_stamp BIGINT,
+       app_id INT,
+       info TEXT,
+       id INTEGER PRIMARY KEY
+);
+
+CREATE TABLE IF NOT EXISTS applications (
+       name TEXT,
+       id INTEGER PRIMARY KEY
+);
+
+CREATE TABLE IF NOT EXISTS device_working_time (
+       time_stamp BIGINT,
+       device INT,
+       time INT,
+       id INTEGER PRIMARY KEY
+);
+
+CREATE TABLE IF NOT EXISTS power_mode (
+       time_stamp BIGINT,
+       old_mode_number INT,
+       new_mode_number INT,
+       duration INT,
+       battery_level_change INT,
+       id INTEGER PRIMARY KEY
+);
+
+CREATE TABLE IF NOT EXISTS proc_power_cons (
+       appid TEXT,
+       power_cons BIGINT,
+       duration INT,
+       day INT,
+       PRIMARY KEY(appid, day)
+);
diff --git a/src/logd_grabber/display.c b/src/logd_grabber/display.c
new file mode 100644 (file)
index 0000000..ce55fc6
--- /dev/null
@@ -0,0 +1,165 @@
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "core/log.h"
+#include "config.h"
+#include "display.h"
+#include "macro.h"
+
+static int curr_brightness;
+static int display_state;
+static float total_power_cons = 0;
+static time_t last_change_time;
+
+static int get_brightness_file(char *file)
+{
+       const char *brightness_dir = "/sys/class/backlight/";
+       struct dirent *entry = NULL;
+       DIR *dir = NULL;
+       int ret;
+       char buf[PATH_MAX];
+
+       dir = opendir(brightness_dir);
+       if (!dir) {
+               ret = -errno;
+               _E("opendir failed: %s", strerror(errno));
+               return ret;
+       }
+
+       do {
+               entry = readdir(dir);
+               if (!entry) {
+                       ret = -errno;
+                       _E("readdir failed: %s", strerror(errno));
+                       closedir(dir);
+                       return ret;
+               }
+       } while (entry->d_name[0] == '.');
+
+       ret = sprintf(file, "%s/%s/brightness", brightness_dir, entry->d_name);
+       if (ret < 0) {
+               ret = -errno;
+               _E("asprintf failed: %s", strerror(errno));
+               closedir(dir);
+               return ret;
+       }
+       ret = closedir(dir);
+       if (ret < 0) {
+               ret = -errno;
+               _E("closedir failed: %s", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static int read_curr_brightness()
+{
+       FILE *fp = NULL;
+       char file[PATH_MAX];
+       int brightness;
+       int ret;
+
+       ret = get_brightness_file(file);
+       if (ret < 0) {
+               _E("get_brightness_file failed");
+               return ret;
+       }
+
+       fp = fopen(file, "r");
+       if (!fp) {
+               ret = -errno;
+               _E("fopen failed: %s", strerror(errno));
+               return ret;
+       }
+
+       if (fscanf(fp, "%d", &brightness) != 1) {
+               ret = -errno;
+               fclose(fp);
+               _E("fscanf failed: %s", strerror(errno));
+               return ret;
+       }
+
+       if (fclose(fp) < 0) {
+               ret = -errno;
+               _E("close failed: %s", strerror(errno));
+               return ret;
+       }
+
+       return brightness;
+}
+
+float backlight_curr_power_cons()
+{
+       double a = config_get_double("backlight_a", 0, NULL);
+       double b = config_get_double("backlight_b", 0, NULL);
+       double c = config_get_double("backlight_c", 0, NULL);
+       double k = config_get_double("backlight_k", 0, NULL);
+
+       double x = curr_brightness;
+
+       if (!display_state)
+               return 0;
+       return a * x * x * x + b * x * x + c * x + k;
+}
+
+static void recalc_total_power_cons()
+{
+       float curr_power_cons = backlight_curr_power_cons();
+       time_t t = getSecTime();
+
+       total_power_cons +=
+               (curr_power_cons / 3600 * 1000) * (t - last_change_time);
+       last_change_time = t;
+}
+
+int display_init()
+{
+       display_state = 1; /* TODO: check it, may be neet to read it by vconf */
+       curr_brightness = read_curr_brightness();
+       if (curr_brightness < 0) {
+               _E("read_curr_brightness failed: curr_brightness set as 0");
+               curr_brightness = 0;
+       }
+       last_change_time = getSecTime();
+
+       return 0;
+}
+
+int brightness_change_event_handler(struct logd_grabber_event *event)
+{
+       recalc_total_power_cons();
+
+       curr_brightness = atoi(event->message);
+
+       return 0;
+}
+
+int display_on_off_event_handler(struct logd_grabber_event *event)
+{
+       recalc_total_power_cons();
+
+       if (event->action == LOGD_ON) {
+               display_state = 1;
+       } else if (event->action == LOGD_OFF) {
+               display_state = 0;
+       }
+
+       return 0;
+}
+
+float get_display_curr_power_cons()
+{
+       return backlight_curr_power_cons();
+}
+
+float get_display_total_power_cons()
+{
+       recalc_total_power_cons();
+
+       return total_power_cons;
+}
diff --git a/src/logd_grabber/display.h b/src/logd_grabber/display.h
new file mode 100644 (file)
index 0000000..5cd57df
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __DISPLAY_H__
+#define __DISPLAY_H__
+
+#include "logd-grabber.h"
+#include "event.h"
+
+int display_init();
+int brightness_change_event_handler(struct logd_grabber_event *event);
+int display_on_off_event_handler(struct logd_grabber_event *event);
+float get_display_curr_power_cons();
+float get_display_total_power_cons();
+
+#endif /* __DISPLAY_H__ */
diff --git a/src/logd_grabber/event.c b/src/logd_grabber/event.c
new file mode 100644 (file)
index 0000000..785e9cc
--- /dev/null
@@ -0,0 +1,210 @@
+#include <Eina.h>
+#include <string.h>
+#include "core/log.h"
+#include "battery.h"
+#include "display.h"
+#include "devices.h"
+#include "event.h"
+#include "events.h"
+#include "journal-reader.h"
+#include "macro.h"
+#include "nlproc-stat.h"
+
+static Eina_Hash *stored_appids;
+static Eina_Hash *event_handlers;
+
+static enum logd_db_query load_apps_cb(int id, const char *app, void *user_data)
+{
+       char *tmp;
+
+       if (!eina_hash_find(stored_appids, app)) {
+               tmp = strdup(app);
+               if (!tmp) {
+                       _E("strdup failed: %s", strerror(errno));
+                       return LOGD_DB_QUERY_CONTINUE;
+               }
+
+               if (eina_hash_add(stored_appids, tmp, (void*)id) == EINA_FALSE) {
+                       _E("eina_hash_set failed: %s", eina_error_msg_get(eina_error_get()));
+               }
+       }
+
+       return LOGD_DB_QUERY_CONTINUE;
+}
+
+int init_event_handlers(void)
+{
+       int key;
+
+       event_handlers = eina_hash_int32_new(NULL);
+       if (!event_handlers) {
+               _E("eina_hash_int32_new failed");
+               return -ENOMEM;
+       }
+
+       /* LOGD_DISPLAY | LOGD_CHANGED */
+       key = LOGD_DISPLAY | LOGD_SHIFT_ACTION(LOGD_CHANGED);
+       if (eina_hash_add(event_handlers,
+               &key, brightness_change_event_handler) == EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* LOGD_DISPLAY | LOGD_ON */
+       key = LOGD_DISPLAY | LOGD_SHIFT_ACTION(LOGD_ON);
+       if (eina_hash_add(event_handlers,
+               &key, display_on_off_event_handler) == EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* LOGD_DISPLAY | LOGD_OFF */
+       key = LOGD_DISPLAY | LOGD_SHIFT_ACTION(LOGD_OFF);
+       if (eina_hash_add(event_handlers,
+               &key, display_on_off_event_handler) == EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* LOGD_BATTERY_SOC | LOGD_CHANGED */
+       key = LOGD_BATTERY_SOC | LOGD_SHIFT_ACTION(LOGD_CHANGED);
+       if (eina_hash_add(event_handlers,
+               &key, battery_level_changed_event_handler) == EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* LOGD_CHARGER | LOGD_ON */
+       key = LOGD_CHARGER | LOGD_SHIFT_ACTION(LOGD_ON);
+       if (eina_hash_add(event_handlers,
+               &key, battery_charger_event_handler) == EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* LOGD_CHARGER | LOGD_OFF */
+       key = LOGD_CHARGER | LOGD_SHIFT_ACTION(LOGD_OFF);
+       if (eina_hash_add(event_handlers,
+               &key, battery_charger_event_handler) == EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* LOGD_POWER_MODE | LOGD_CHANGED */
+       key = LOGD_POWER_MODE | LOGD_SHIFT_ACTION(LOGD_CHANGED);
+       if (eina_hash_add(event_handlers,
+               &key, battery_power_mode_changed_event_handler) == EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+
+       return 0;
+}
+
+int event_init()
+{
+       int ret;
+
+       stored_appids = eina_hash_string_superfast_new(NULL);
+       if (!stored_appids) {
+               _E("eina_hash_string_superfast_new failed");
+               return -ENOMEM;
+       }
+
+       ret = logd_load_apps(load_apps_cb, NULL);
+       if (ret < 0) {
+               _E("logd_load_apps failed");
+               return ret;
+       }
+
+       ret = init_event_handlers();
+       if (ret < 0) {
+               _E("init_event_handlers failed");
+               return ret;
+       }
+
+       return 0;
+}
+
+int event_exit()
+{
+       if (event_handlers)
+               eina_hash_free(event_handlers);
+
+       if (stored_appids)
+               eina_hash_free(stored_appids);
+
+       return 0;
+}
+
+void free_event(struct logd_grabber_event *event)
+{
+       if (!event)
+               return;
+       if (event->application)
+               free((void*)event->application);
+       if (event->message)
+               free((void*)event->message);
+}
+
+int store_event(struct logd_grabber_event *event)
+{
+       int id;
+       int ret;
+
+       if (event->action == LOGD_ON || event->action == LOGD_OFF)
+               if (store_devices_workingtime(event->object, event->action) < 0)
+                       _E("store_devices_workingtime failed");
+       id = (int)eina_hash_find(stored_appids, event->application);
+       if (!id) {
+               if (logd_store_app(event->application) < 0) {
+                       _E("logd_store_app failed");
+               }
+
+               logd_load_apps(load_apps_cb, NULL);
+
+               id = (int)eina_hash_find(stored_appids, event->application);
+               if (!id) {
+                       _E("eina_hash_find failed");
+               }
+       }
+
+       ret = logd_store_event(event->type, event->date, id, event->message);
+       if (ret < 0) {
+               _E("logd_store_event failed");
+       }
+
+       return ret;
+}
+
+void event_socket_cb(void *user_data)
+{
+       struct logd_grabber_event event;
+       int ret;
+
+       ret = get_next_event(&event);
+       if (ret < 0) {
+               _E("get_next_event failed");
+               return;
+       } else if (ret == 0) {
+               event_handler_func func;
+
+               _D("object %d, action %d, message: %s\n", event.object,
+                       event.action, event.message);
+
+               func = (event_handler_func) eina_hash_find(event_handlers, &event.type);
+               if (!func) {
+                       free_event(&event);
+                       return;
+               }
+               if (func(&event) < 0) {
+                       _E("Event handle failed: object %d, action %d, message: %s\n",
+                               event.object, event.action, event.message);
+               }
+               if (store_event(&event) < 0) {
+                       _E("store_event failed");
+               }
+               free_event(&event);
+       }
+}
diff --git a/src/logd_grabber/event.h b/src/logd_grabber/event.h
new file mode 100644 (file)
index 0000000..63d2d52
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __EVENT_H__
+#define __EVENT_H__
+
+#include <Ecore.h>
+#include <Eina.h>
+#include "logd.h"
+
+struct logd_grabber_event {
+       const char *application;
+       int type;
+       enum logd_object object;
+       enum logd_action action;
+       time_t date;
+       const char *message;
+};
+
+typedef int (*event_handler_func)(const struct logd_grabber_event *);
+
+int event_exit();
+int event_init();
+int store_event(struct logd_grabber_event *event);
+void event_socket_cb(void *user_data);
+
+#endif /* __EVENT_H__ */
diff --git a/src/logd_grabber/journal-reader.c b/src/logd_grabber/journal-reader.c
new file mode 100644 (file)
index 0000000..a5ac063
--- /dev/null
@@ -0,0 +1,106 @@
+#include <stdlib.h>
+#include <string.h>
+#include <systemd/sd-journal.h>
+
+#include "core/log.h"
+#include "event.h"
+#include "journal-reader.h"
+#include "logd-grabber.h"
+#include "macro.h"
+
+#define GET_ACTION_FROM_EVENT_TYPE(eventType) ((eventType) >> 16)
+#define GET_OBJECT_FROM_EVENT_TYPE(eventType) ((eventType) & 0xffff)
+
+static sd_journal *journal;
+
+int jr_init(void)
+{
+       int ret = 0;
+
+       ret = sd_journal_open(&journal, SD_JOURNAL_LOCAL_ONLY);
+       CHECK_RET(ret, "sd_journal_open");
+
+       ret = sd_journal_add_match(journal, "CODE_FUNC=logd_event", 0);
+       CHECK_RET(ret, "sd_journal_add_match");
+
+       ret = sd_journal_seek_tail(journal);
+       CHECK_RET(ret, "sd_journal_seek_tail");
+
+       ret = sd_journal_previous(journal);
+       CHECK_RET(ret, "sd_journal_previous");
+
+       return 0;
+}
+
+int jr_exit(void)
+{
+       if (journal)
+               sd_journal_close(journal);
+
+       return 0;
+}
+
+int jr_get_socket(void)
+{
+       return sd_journal_get_fd(journal);
+}
+
+int get_next_event(struct logd_grabber_event *event)
+{
+       const char type_field[] = "LOGD_EVENT_TYPE";
+       const char message_field[] = "MESSAGE";
+       const char application_field[] = "SYSLOG_IDENTIFIER";
+       char *event_type;
+       char *event_message;
+       char *event_application;
+       int ret;
+
+       while (1) {
+               uint64_t event_date;
+               size_t len;
+
+               if (!sd_journal_next(journal)) {
+                       ret = sd_journal_process(journal);
+                       if (ret < 0) {
+                               _E("sd_journal_process failed");
+                               return ret;
+                       }
+
+                       return 1;
+               }
+               ret = sd_journal_get_realtime_usec(journal, &event_date);
+               CHECK_RET(ret, "sd_journal_get_realtime_usec");
+               event->date = event_date / USEC_PER_SEC;
+
+               ret = sd_journal_get_data(journal, type_field,
+                       (const void**)&event_type, &len);
+               CHECK_RET(ret, "sd_journal_get_data");
+
+               if (event_type) {
+                       event_type = strdup(event_type + sizeof(type_field));
+                       ret = sd_journal_get_data(journal, message_field,
+                               (const void**)&event_message, &len);
+                       if (event_message) {
+                               event_message = strdup(event_message +
+                                       sizeof(message_field));
+                       }
+
+                       ret = sd_journal_get_data(journal, application_field,
+                               (const void**)&event_application, &len);
+                       if (event_application) {
+                               event_application = strdup(event_application +
+                                       sizeof(application_field));
+                       }
+                       break;
+               }
+       }
+
+       event->application = event_application;
+       event->message = event_message;
+       event->type = atoi(event_type);
+       free(event_type);
+       event->object = GET_OBJECT_FROM_EVENT_TYPE(event->type);
+       event->action = GET_ACTION_FROM_EVENT_TYPE(event->type);
+
+       return 0;
+}
diff --git a/src/logd_grabber/journal-reader.h b/src/logd_grabber/journal-reader.h
new file mode 100644 (file)
index 0000000..39b51a3
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __JOURNAL_READER_H__
+#define __JOURNAL_READER_H__
+
+#include "logd-grabber.h"
+
+int jr_init(void);
+int jr_exit(void);
+int jr_get_socket(void);
+int get_next_event(struct logd_grabber_event *event);
+
+#endif /* __JOURNAL_READER_H__ */
diff --git a/src/logd_grabber/logd-grabber.c b/src/logd_grabber/logd-grabber.c
new file mode 100644 (file)
index 0000000..0ef0e9c
--- /dev/null
@@ -0,0 +1,534 @@
+#include <Ecore.h>
+#include <Eina.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+
+#include "battery.h"
+#include "config.h"
+#include "display.h"
+#include "event.h"
+#include "events.h"
+#include "journal-reader.h"
+#include "logd-db.h"
+#include "logd.h"
+#include "macro.h"
+#include "mmc.h"
+#include "nlproc-stat.h"
+#include "socket-helper.h"
+#include "task-stats.h"
+#include "timer.h"
+
+
+static int proc_stat_store_period;
+static int old_events_rotate_period;
+static int old_events_del_period;
+
+static Eina_Hash *sockets;
+struct socket_info {
+       void (*cb)(void *);
+       void *user_data;
+};
+
+static int api_socket;
+static Ecore_Thread *logd_thread;
+static struct timer *proc_stat_store_timer;
+static struct timer *old_event_del_timer;
+static struct timer *old_proc_power_cons_timer;
+
+static int send_devices_power_cons(int sock)
+{
+       size_t i;
+       int ret;
+       struct power_cons {
+               enum logd_object object;
+               float total;
+               float curr;
+       } devices_power_cons[2] = {{
+               LOGD_DISPLAY,
+               get_display_total_power_cons(),
+               get_display_curr_power_cons()
+       }, {
+               LOGD_MMC,
+               mmc_power_cons(),
+               0
+       }};
+       const size_t count = ARRAY_SIZE(devices_power_cons);
+
+       if (write(sock, &count, sizeof(count)) != sizeof(count)) {
+               ret = -errno;
+               _E("write failed: %s", strerror(errno));
+               return ret;
+       }
+
+       for (i = 0; i < count; ++i) {
+               if (write(sock, &devices_power_cons[i], sizeof(devices_power_cons[i])) !=
+                       sizeof(devices_power_cons[i])) {
+                       ret = -errno;
+                       _E("write failed: %s", strerror(errno));
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static void api_socket_cb(void *user_data)
+{
+       enum logd_socket_req_type req_type;
+       int ns;
+       int ret;
+
+       if ((ns = accept(api_socket, NULL, NULL)) < 0) {
+               _E("accept failed: %s", strerror(errno));
+               return;
+       }
+
+       ret = read(ns, (void*)&req_type, sizeof(req_type));
+       if (ret != sizeof(req_type)) {
+               _E("failed read API request type");
+               if (close(ns) < 0) {
+                       _E("close failed: %s", strerror(errno));
+               }
+               return;
+       }
+
+       if (req_type == LOGD_DEV_STAT_REQ) { /* devices power consumption */
+               if (send_devices_power_cons(ns) < 0) {
+                       _E("send_devices_power_cons failed");
+               }
+       } else if (req_type == LOGD_PROC_STAT_REQ) {
+               if (send_proc_stat(ns) < 0) {
+                       _E("send_proc_stat failed");
+               }
+       } else if (req_type == LOGD_EST_TIME_REQ) {
+               if (battery_send_estimate_lifetime(ns) < 0) {
+                       _E("battery_send_estimate_lifetime failed");
+               }
+       } else if (req_type == LOGD_BATTERY_LVL_REQ) {
+               if (battery_send_check_points(ns) < 0) {
+                       _E("battery_send_check_points failed");
+               }
+       }
+
+       if (close(ns) < 0) {
+               _E("close failed: %s", strerror(errno));
+       }
+}
+
+static void task_stat_socket_cb(void *user_data)
+{
+       process_task_stats_answer(get_task_stats_sock(), proc_terminated, NULL);
+}
+
+static void proc_events_socket_cb(void *user_data)
+{
+       process_proc_event_answer(get_proc_events_sock(), proc_forked, NULL);
+}
+
+static void proc_stat_store_timer_cb(void *user_data)
+{
+       if (nlproc_stat_store() < 0) {
+               _E("nlproc_stat_store failed");
+       }
+
+       _I("per-process statistics stored");
+}
+
+static void old_event_del_timer_cb(void *usr_data)
+{
+       time_t t = time(NULL);
+
+       if (t == (time_t) -1) {
+               _E("time failed: %s", strerror(errno));
+               return;
+       }
+
+       if (delete_old_events(t - old_events_rotate_period) < 0) {
+               _E("delete_old_events failed");
+       }
+
+       _I("old events deleted");
+}
+
+static int sec_till_new_day()
+{
+       struct tm *tm;
+       time_t t;
+
+       time(&t);
+       tm = localtime(&t);
+       if (tm == NULL) {
+               _E("localtime failed");
+               return SEC_PER_DAY;
+       }
+
+       return SEC_PER_DAY - (tm->tm_sec + tm->tm_min * 60 + tm->tm_hour * 3600);
+}
+
+static void old_proc_power_cons_timer_cb(void *user_data)
+{
+       int time_till_new_day = sec_till_new_day();
+       struct timer *timer = (struct timer *)user_data;
+
+       if (delete_old_proc() < 0) {
+               _E("delete_old_proc failed");
+       }
+       _I("old cpu power cons deleted");
+
+       update_timer_exp(timer, time_till_new_day <= 10 ?
+               SEC_PER_DAY - 10 + time_till_new_day : time_till_new_day);
+
+       return;
+}
+
+static int init_timers()
+{
+       int ret;
+       struct socket_info *socket_info;
+
+       /* Timers */
+       proc_stat_store_timer = create_timer(proc_stat_store_period,
+               proc_stat_store_timer_cb, NULL);
+       if (!proc_stat_store_timer) {
+               _E("ecore_timer_add failed");
+       } else {
+               socket_info = calloc(1, sizeof(struct socket_info));
+               if (!socket_info) {
+                       ret = -errno;
+                       _E("calloc failed: %s", strerror(errno));
+                       return ret;
+               }
+               socket_info->cb = (void(*)(void*))process_timer;
+               socket_info->user_data = proc_stat_store_timer;
+
+               if (eina_hash_add(sockets, (void*)&proc_stat_store_timer->fd, socket_info) ==
+                       EINA_FALSE) {
+                       _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+                       return -ENOMEM;
+               }
+       }
+
+
+       old_event_del_timer = create_timer(old_events_del_period,
+               old_event_del_timer_cb, NULL);
+       if (!old_event_del_timer) {
+               _E("ecore_timer_add failed");
+       } else {
+               socket_info = calloc(1, sizeof(struct socket_info));
+               if (!socket_info) {
+                       ret = -errno;
+                       _E("calloc failed: %s", strerror(errno));
+                       return ret;
+               }
+               socket_info->cb = (void(*)(void*))process_timer;
+               socket_info->user_data = old_event_del_timer;
+
+               if (eina_hash_add(sockets, (void*)&old_event_del_timer->fd, socket_info) ==
+                       EINA_FALSE) {
+                       _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+                       return -ENOMEM;
+               }
+       }
+
+
+       old_proc_power_cons_timer = create_timer(sec_till_new_day() - 10,
+               old_proc_power_cons_timer_cb, NULL);
+       if (!old_proc_power_cons_timer) {
+               _E("ecore_timer_add failed");
+       } else {
+               old_proc_power_cons_timer->user_data = old_proc_power_cons_timer;
+               socket_info = calloc(1, sizeof(struct socket_info));
+               if (!socket_info) {
+                       ret = -errno;
+                       _E("calloc failed: %s", strerror(errno));
+                       return ret;
+               }
+               socket_info->cb = (void(*)(void*))process_timer;
+               socket_info->user_data = old_proc_power_cons_timer;
+
+               if (eina_hash_add(sockets, (void*)&old_proc_power_cons_timer->fd, socket_info) ==
+                       EINA_FALSE) {
+                       _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+                       return -ENOMEM;
+               }
+       }
+
+       return 0;
+}
+
+void logd_event_loop(void *user_data, Ecore_Thread *th)
+{
+       int max_fd = 0;
+       fd_set set;
+       void *data;
+       Eina_Iterator *it;
+
+       if (init_timers() < 0)
+               _E("init_timers failed");
+
+       it = eina_hash_iterator_key_new(sockets);
+       while (eina_iterator_next(it, &data)) {
+               int fd = *(int*)data;
+               max_fd = max(max_fd, fd);
+       }
+       eina_iterator_free(it);
+
+       while (1) {
+               FD_ZERO(&set);
+               it = eina_hash_iterator_key_new(sockets);
+               while (!ecore_thread_check(th) && eina_iterator_next(it, &data)) {
+                       int fd = *(int*)data;
+                       FD_SET(fd, &set);
+               }
+               eina_iterator_free(it);
+
+               if (ecore_thread_check(th))
+                       break;
+
+               select(max_fd + 1, &set, NULL, NULL, NULL);
+
+               it = eina_hash_iterator_key_new(sockets);
+               while (!ecore_thread_check(th) && eina_iterator_next(it, &data)) {
+                       int fd = *(int*)data;
+                       struct socket_info *info;
+
+                       if (FD_ISSET(fd, &set)) {
+                               info = eina_hash_find(sockets, &fd);
+                               if (info) {
+                                       info->cb(info->user_data);
+                               } else {
+                                       _E("eina_hash_find failed: wrong fd");
+                               }
+                       }
+
+               }
+               eina_iterator_free(it);
+               if (ecore_thread_check(th))
+                       break;
+       }
+       _I("loop exited");
+}
+
+
+static int init_sockets()
+{
+       int ret;
+       int event_socket;
+       int task_stat_socket;
+       int proc_events_socket;
+       struct socket_info *socket_info;
+
+       sockets = eina_hash_pointer_new(free);
+       if (!sockets) {
+               _E("eina_hash_pointer_new failed");
+               return -ENOMEM;
+       }
+
+       /* event_socket */
+       ret = jr_init();
+       CHECK_RET(ret, "jr_init");
+       event_socket = jr_get_socket();
+       if (event_socket <= 0) {
+               _E("jr_get_socket returned wrong socket");
+               return -ENOTSOCK;
+       }
+
+       socket_info = calloc(1, sizeof(struct socket_info));
+       if (!socket_info) {
+               ret = -errno;
+               _E("calloc failed: %s", strerror(errno));
+               return ret;
+       }
+       socket_info->cb = event_socket_cb;
+
+       if (eina_hash_add(sockets, (void*)&event_socket, socket_info) ==
+               EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* API socket */
+       if ((api_socket = create_logd_socket()) < 0) {
+               _E("create_logd_socket failed");
+               return api_socket;
+       }
+
+       socket_info = calloc(1, sizeof(struct socket_info));
+       if (!socket_info) {
+               ret = -errno;
+               _E("calloc failed: %s", strerror(errno));
+               return ret;
+       }
+       socket_info->cb = api_socket_cb;
+
+       if (eina_hash_add(sockets, (void*)&api_socket, socket_info) ==
+               EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* Task stat socket */
+       task_stat_socket = get_task_stats_sock();
+
+       socket_info = calloc(1, sizeof(struct socket_info));
+       if (!socket_info) {
+               ret = -errno;
+               _E("calloc failed: %s", strerror(errno));
+               return ret;
+       }
+       socket_info->cb = task_stat_socket_cb;
+
+       if (eina_hash_add(sockets, (void*)&task_stat_socket, socket_info) ==
+               EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       /* Proc events socket */
+       proc_events_socket = get_proc_events_sock();
+
+       socket_info = calloc(1, sizeof(struct socket_info));
+       if (!socket_info) {
+               ret = -errno;
+               _E("calloc failed: %s", strerror(errno));
+               return ret;
+       }
+       socket_info->cb = proc_events_socket_cb;
+
+       if (eina_hash_add(sockets, (void*)&proc_events_socket, socket_info) ==
+               EINA_FALSE) {
+               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void logd_grabber_exit()
+{
+       int ret;
+
+       if (!proc_stat_store_timer)
+               delete_timer(proc_stat_store_timer);
+       if (!old_event_del_timer)
+               delete_timer(old_event_del_timer);
+       if (!old_proc_power_cons_timer)
+               delete_timer(old_proc_power_cons_timer);
+
+       if (sockets) {
+               eina_hash_free(sockets);
+               sockets = NULL;
+       }
+
+       ret = event_exit();
+       if (ret < 0) {
+               _E("event_exit failed");
+       }
+}
+
+void logd_loop_cancel(void *user_data, Ecore_Thread *th)
+{
+       _I("logd_loop_cancel called");
+       logd_grabber_exit();
+}
+
+static int logd_grabber_init()
+{
+       int ret = 0;
+       const char *enable;
+
+       tzset();
+
+       ret = config_init();
+       if (ret < 0) {
+               _E("config_init failed");
+               return ret;
+       }
+       enable = config_get_string("enable_grabber", "yes", NULL);
+       if (strncmp(enable, "yes", 3)) {
+               _I("disable logd_grabber");
+               return ret;
+       }
+
+       log_init();
+
+       proc_stat_store_period =
+               config_get_int("proc_stat_store_period", 30 * 60, NULL);
+       old_events_rotate_period =
+               config_get_int("old_events_rotate_period", 60 * 60 *24 * 7, NULL);
+       old_events_del_period =
+               config_get_int("old_events_del_period", 30 * 60, NULL);
+
+       ret = mmc_init();
+       if (ret < 0) {
+               _E("mmc_init failed");
+               return ret;
+       }
+
+       ret = display_init();
+       if (ret < 0) {
+               _E("display_init failed");
+               return ret;
+       }
+
+       ret = nlproc_stat_init();
+       if (ret < 0) {
+               _E("nlproc_stat_init failed");
+               return ret;
+       }
+
+       ret = battery_init();
+       if (ret < 0) {
+               _E("battery_init failed");
+               return ret;
+       }
+
+       ret = event_init();
+       if (ret < 0) {
+               _E("event_init failed");
+               return ret;
+       }
+
+       ret = init_sockets();
+       if (ret < 0) {
+               _E("init_sockets failed");
+               return ret;
+       }
+
+       logd_thread = ecore_thread_run(logd_event_loop,
+                       NULL, logd_loop_cancel, NULL);
+
+       return 0;
+}
+
+
+static void logd_init()
+{
+       if (logd_grabber_init() < 0)
+               _E("logd_grabber_init failed");
+}
+
+static void logd_exit()
+{
+       if (logd_thread && !ecore_thread_check(logd_thread)) {
+               ecore_thread_cancel(logd_thread);
+               logd_thread = NULL;
+       }
+}
+
+static const struct device_ops logd_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "logd",
+       .init     = logd_init,
+       .exit     = logd_exit,
+};
+
+DEVICE_OPS_REGISTER(&logd_device_ops)
diff --git a/src/logd_grabber/logd-grabber.h b/src/logd_grabber/logd-grabber.h
new file mode 100644 (file)
index 0000000..0a912d4
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __LOGD_GRABBER_H__
+#define __LOGD_GRABBER_H__
+
+#include <logd.h>
+#include <time.h>
+
+#endif /* __LOGD_GRABBER_H__ */
diff --git a/src/logd_grabber/mmc.c b/src/logd_grabber/mmc.c
new file mode 100644 (file)
index 0000000..e8c3897
--- /dev/null
@@ -0,0 +1,60 @@
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "core/log.h"
+#include "config.h"
+#include "mmc.h"
+
+static int mmc_write_sectors_per_uah;
+static int mmc_read_sectors_per_uah;
+
+static int get_number_sectors(uint64_t *_read, uint64_t *_written)
+{
+       const char *path = "/sys/block/mmcblk0/stat";
+       FILE *fp = NULL;
+       int ret;
+
+       fp = fopen(path, "r");
+       if (!fp) {
+               ret = -errno;
+               _E("fopen failed: %s", strerror(errno));
+               return ret;
+       }
+       if (fscanf(fp, "%*s %*s %lld %*s %*s %*s %lld", _read, _written) < 2) {
+               _E("Can't read number of sectors from %s", path);
+               fclose(fp);
+               return -1;
+       }
+
+       if (fclose(fp) < 0) {
+               ret = -errno;
+               _E("fclose failed: %s", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+int mmc_init()
+{
+       mmc_write_sectors_per_uah =
+               config_get_int("mmc_write_sectors_per_uah", 2820, NULL);
+       mmc_read_sectors_per_uah =
+               config_get_int("mmc_read_sectors_per_uah", 4708, NULL);
+
+       return 0;
+}
+
+float mmc_power_cons()
+{
+       uint64_t _read, _written;
+
+       if (get_number_sectors(&_read, &_written) < 0) {
+               _E("get_number_sectors failed");
+               return 0;
+       }
+
+       return _read / mmc_read_sectors_per_uah + _written / mmc_write_sectors_per_uah;
+}
diff --git a/src/logd_grabber/mmc.h b/src/logd_grabber/mmc.h
new file mode 100644 (file)
index 0000000..3d38b4c
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __MMC_H__
+#define __MMC_H__
+
+int mmc_init();
+float mmc_power_cons();
+
+#endif /* __MMC_H__ */
diff --git a/src/logd_grabber/nlproc-stat.c b/src/logd_grabber/nlproc-stat.c
new file mode 100644 (file)
index 0000000..e17ba58
--- /dev/null
@@ -0,0 +1,839 @@
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <dirent.h>
+#include <Eina.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "core/log.h"
+#include "config.h"
+#include "logd-db.h"
+#include "logd-taskstats.h"
+#include "macro.h"
+#include "nlproc-stat.h"
+#include "proc-events.h"
+#include "proc-stat.h"
+#include "task-stats.h"
+
+#define LOGD_INTERNAL_PID 3
+
+struct process_stat {
+       int64_t utime, stime;
+       float utime_power_cons, stime_power_cons;
+       int is_active;
+       time_t duration;
+};
+
+static uint64_t power_const_per_uah;
+
+static int task_stats_sock;
+static int update_task_stats_sock;
+static int proc_events_sock;
+
+static Eina_Hash *active_pids;
+static Eina_Hash *terminated_stats;
+static Eina_Hash *total_stats;
+
+static struct process_stat* find_or_create_statistic(Eina_Hash *table, const char *cmdline);
+static int proc_state_update(void);
+
+const char *kernel_threads_name = "[kernel_threads]";
+
+static int day_of_week()
+{
+       time_t curr_time;
+       int ret;
+       int day;
+       struct tm *curr_tm = NULL;
+
+       curr_time = time(NULL);
+       if (curr_time == ((time_t) -1)) {
+               _E("time failed: %s", strerror(errno));
+               return -EFAULT;
+       }
+       curr_tm = localtime(&curr_time);
+       if (curr_tm == NULL) {
+               ret = -errno;
+               _E("time failed: %s", strerror(errno));
+               return ret;
+       }
+
+       return curr_tm->tm_wday;
+}
+
+static Eina_Bool sub_active_from_term_cb(const Eina_Hash *hash, const void *key,
+       void *data, void *fdata)
+{
+       struct process_stat *statistic;
+       struct process_stat *active_statistic = (struct process_stat *)data;
+       char *cmdline = (char*)key;
+
+       statistic = find_or_create_statistic(terminated_stats, cmdline);
+       if (!statistic) {
+               _E("find_or_create_statistic failed");
+               return 1; /* continue to process */
+       }
+
+       statistic->utime -= active_statistic->utime;
+       statistic->stime -= active_statistic->stime;
+       statistic->utime_power_cons -= active_statistic->utime_power_cons;
+       statistic->stime_power_cons -= active_statistic->stime_power_cons;
+       statistic->duration -= active_statistic->duration;
+
+       return 1; /* continue to process */
+}
+
+
+int delete_old_proc()
+{
+       int next_day;
+       int ret;
+
+       _I("delete_old_proc start");
+
+       if (nlproc_stat_store() < 0)
+               _E("nlproc_stat_store failed");
+
+       /* Already stored into database, so have no reason to keep it */
+       eina_hash_free_buckets(terminated_stats);
+
+       if (!terminated_stats) {
+               ret = 0;
+               goto out;
+       }
+
+       /* we have to clear next day stat due to run this function at 23:59:50 */
+       next_day = (day_of_week() + 1) % DAYS_PER_WEEK; /* next day */
+       if (next_day < 0) {
+               _E("day_of_week failed");
+               ret = next_day;
+               goto out;
+       }
+
+       ret = delete_old_power_cons(next_day);
+       if (ret < 0) {
+               _E("delete_old_power_cons failed");
+               goto out;
+       }
+       /* It's need to avoid double counting the same data that was
+       already stored into db */
+       proc_state_update();
+       eina_hash_foreach(total_stats, sub_active_from_term_cb, NULL);
+       ret = 0;
+
+out:
+       return ret;
+}
+
+int get_task_stats_sock(void)
+{
+       return task_stats_sock;
+}
+
+int get_proc_events_sock(void)
+{
+       return proc_events_sock;
+}
+
+static int get_cpu_mask(char **mask)
+{
+       int cpus_number;
+       int ret;
+
+       errno = 0;
+       cpus_number = sysconf(_SC_NPROCESSORS_CONF);
+       if (errno != 0) {
+               ret = -errno;
+               _E("sysconf failed: %s", strerror(errno));
+               return ret;
+       }
+
+       if (asprintf(mask, "0-%d", cpus_number - 1) == -1) {
+               ret = -errno;
+               _E("asprintf failed: %s", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static int get_pids_from_proc(Eina_List **pids)
+{
+       struct dirent *entry = NULL;
+       DIR *dir = NULL;
+       int ret;
+
+       dir = opendir("/proc");
+       if (dir == NULL) {
+               ret = -errno;
+               _E("opendir failed: %s", strerror(errno));
+               return ret;
+       }
+
+       while ((entry = readdir(dir)) != NULL) {
+               const char *p = entry->d_name;
+               char buf[30] = { 0, };
+               FILE *fp = NULL;
+               char state;
+               pid_t pid;
+
+               while (isdigit(*p))
+                       ++p;
+               if (*p != 0)
+                       continue;
+
+               pid = atoi(entry->d_name);
+               sprintf(buf, "/proc/%d/stat", pid);
+               fp = fopen(buf, "r");
+               if (!fp) {
+                       _E("fopen failed %s: %s", buf, strerror(errno));
+                       continue;
+               }
+
+               ret = fscanf(fp, "%*s %*s %c", &state);
+               if (ret != 1) {
+                       _E("fscanf failed: %s", strerror(errno));
+               }
+
+               if (fclose(fp) != 0) {
+                       _E("fclose failed: %s", strerror(errno));
+               }
+
+               if (ret == 1 && state != 'Z') {
+                       *pids = eina_list_append(*pids, (void*)pid);
+                       if (eina_error_get()) {
+                               _E("eina_list_append failed: %s", eina_error_msg_get(eina_error_get()));
+                       }
+               }
+       }
+
+       if (closedir(dir) < 0) {
+               ret = -errno;
+               _E("closedir failed: %s", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static int get_cmdline_by_pid(pid_t pid, char *cmdline)
+{
+       FILE *fp;
+       char path[30];
+       char buf[PATH_MAX + 1] = { 0, }; /* "+1" for readlink */
+       int ret;
+
+       ret = snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
+       if (ret < 0 || ret == sizeof(buf)) {
+               _E("snprintf failed or output was truncated");
+               return ret;
+       }
+       fp = fopen(path, "r");
+       if (fp != NULL) {
+               if (fscanf(fp, "%s", buf) != 1) {
+                       buf[0] = '\0';
+               }
+               if (fclose(fp) != 0) {
+                       _E("fclose failed: %s", strerror(errno));
+               }
+               if (buf[0] == '/') {
+                       strcpy(cmdline, buf);
+                       return 0;
+               }
+       }
+
+       bzero(path, sizeof(path));
+       ret = snprintf(path, sizeof(path), "/proc/%d/exe", pid);
+       if (ret < 0 || ret == sizeof(path)) {
+               _E("snprintf failed or output was truncated");
+               return ret;
+       }
+
+       bzero(buf, sizeof(buf));
+       if (readlink(path, buf, sizeof(buf) - 1) < 0) {
+               ret = snprintf(path, sizeof(path), "/proc/%d/comm", pid);
+               if (ret < 0 || ret == sizeof(path)) {
+                       _E("snprintf failed or output was truncated");
+                       return ret;
+               }
+               if (access(path, R_OK) < 0) {
+                       ret = -errno;
+                       return ret;
+               }
+               strcpy(cmdline, kernel_threads_name);
+               return 0;
+       }
+
+       strcpy(cmdline, buf);
+
+       return 0;
+}
+
+static struct process_stat* find_or_create_statistic(Eina_Hash *table, const char *cmdline)
+{
+       struct process_stat* statistic =
+               eina_hash_find(table, cmdline);
+
+       if (!statistic) {
+               statistic = (struct process_stat *)
+                       calloc(1, sizeof(struct process_stat));
+               if (!statistic) {
+                       _E("calloc failed: %s", strerror(errno));
+                       return NULL;
+               }
+
+               if (eina_hash_add(table, cmdline,
+                       statistic) == EINA_FALSE) {
+                       _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+                       free((void*)cmdline);
+                       free(statistic);
+                       return NULL;
+               }
+       }
+
+       return statistic;
+}
+
+int proc_terminated(struct taskstats *t, void *user_data)
+{
+       pid_t pid = t->ac_pid;
+       uint64_t s_time = t->ac_stime;
+       uint64_t u_time = t->ac_utime;
+       float u_time_power_cons = (float)t->ac_utime_power_cons / power_const_per_uah;
+       float s_time_power_cons = (float)t->ac_stime_power_cons / power_const_per_uah;
+
+       if (t->ac_stime || t->ac_utime) {
+               struct process_stat *statistic;
+               const char *cmdline = eina_hash_find(active_pids, &pid);
+
+               if (!cmdline)
+                       return 0;
+               statistic = find_or_create_statistic(terminated_stats, cmdline);
+               if (!statistic) {
+                       _E("find_or_create_statistic failed");
+                       return -ENOMEM;
+               }
+
+               statistic->utime += u_time;
+               statistic->stime += s_time;
+               statistic->utime_power_cons += u_time_power_cons;
+               statistic->stime_power_cons += s_time_power_cons;
+               statistic->duration += t->ac_etime / USEC_PER_SEC;
+       }
+
+       return 0;
+}
+
+static enum logd_db_query load_stat_cb(const struct proc_power_cons *pc, void *user_data)
+{
+       struct process_stat *statistic;
+       if (!user_data) {
+               _E("Wrong hash table");
+               return LOGD_DB_QUERY_STOP;
+       }
+
+       statistic = find_or_create_statistic((Eina_Hash *)user_data, pc->appid);
+       if (!statistic) {
+               _E("find_or_create_statistic failed");
+               return -ENOMEM;
+       }
+
+       /* TODO: remove useless utime, stime - need only power consumption */
+       statistic->utime_power_cons += pc->power_cons;
+       statistic->duration += pc->duration;
+
+       return LOGD_DB_QUERY_CONTINUE;
+}
+
+int nlproc_stat_init(void)
+{
+       char *cpus_mask = NULL;
+       Eina_List *pids = NULL;
+       Eina_List *l;
+       int ret;
+       int day;
+       void *pid;
+
+       power_const_per_uah = config_get_int("power_const_per_uah", 3213253205ll, NULL);
+
+       task_stats_sock = create_netlink_socket(NETLINK_GENERIC, 0, 0);
+       if (task_stats_sock < 0) {
+               _E("create_netlink_sock failed (task_stats_sock)");
+               return task_stats_sock;
+       }
+
+       update_task_stats_sock = create_netlink_socket(NETLINK_GENERIC, 0, 0);
+       if (update_task_stats_sock < 0) {
+               _E("create_netlink_sock failed (update_task_stats_sock)");
+               return update_task_stats_sock;
+       }
+
+       ret = get_cpu_mask(&cpus_mask);
+       if (ret < 0) {
+               _E("get_cpu_mask failed");
+               return ret;
+       }
+
+       ret = reg_task_stats_cpu_mask(task_stats_sock, cpus_mask);
+       if (ret < 0) {
+               _E("reg_task_stats_cpu_mask failed");
+               return ret;
+       }
+       free(cpus_mask);
+       proc_events_sock = create_netlink_socket(NETLINK_CONNECTOR, CN_IDX_PROC, getpid());
+       if (proc_events_sock < 0) {
+               _E("create_netlink_sock failed (proc_events_sock)");
+               return proc_events_sock;
+       }
+
+       ret = subscribe_on_proc_events(proc_events_sock);
+       if (ret < 0) {
+               _E("subscribe_on_proc_events failed");
+               return ret;
+       }
+
+       ret = get_pids_from_proc(&pids);
+       if (ret < 0) {
+               _E("get_pids_from_proc failed");
+               return ret;
+       }
+
+       active_pids = eina_hash_int32_new(free);
+       if (!active_pids) {
+               _E("eina_hash_pointer_new failed");
+               return -ENOMEM;
+       }
+
+       EINA_LIST_FOREACH(pids, l, pid) {
+               char cmdline[PATH_MAX];
+               char *tmp;
+
+               ret = get_cmdline_by_pid((int)pid, cmdline);
+               if (ret < 0) {
+                       continue;
+               }
+
+               tmp = strdup(cmdline);
+               if (!tmp) {
+                       _E("strdup failed: %s", strerror(errno));
+                       continue;
+               }
+               if (eina_hash_add(active_pids, &pid, tmp) == EINA_FALSE) {
+                       _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+                       return -ENOMEM;
+               }
+       }
+
+       eina_list_free(pids);
+
+       terminated_stats = eina_hash_string_superfast_new(free);
+       if (!terminated_stats) {
+               _E("eina_hash_string_superfast_new failed");
+               return -ENOMEM;
+
+       }
+
+       day = day_of_week();
+       if (day < 0) {
+               _E("day_of_week failed");
+               day = 0;
+       }
+
+       total_stats = eina_hash_string_superfast_new(free);
+       if (!total_stats) {
+               _E("eina_hash_string_superfast_new failed");
+               return -ENOMEM;
+       }
+
+       /* ignore statistic before logd started */
+       proc_state_update();
+       eina_hash_foreach(total_stats, sub_active_from_term_cb, NULL);
+
+       if (foreach_proc_power_cons(load_stat_cb, day, terminated_stats) < 0)
+               _E("foreach_proc_power_cons failed");
+
+
+       return 0;
+}
+
+int proc_forked(struct proc_event *e, void *user_data)
+{
+       int pid;
+       char cmdline[PATH_MAX];
+       char *old_cmdline;
+       int ret;
+       char *tmp;
+
+       if (e->what == PROC_EVENT_FORK) {
+               pid = e->event_data.fork.child_pid;
+       } else if (e->what == PROC_EVENT_EXEC) {
+               pid = e->event_data.exec.process_pid;
+       } else if (e->what == PROC_EVENT_EXIT) {
+               pid = e->event_data.exit.process_pid;
+               if (eina_hash_find(active_pids, &pid)) {
+                       if (eina_hash_del(active_pids, &pid, NULL) == EINA_FALSE) {
+                               _E("eina_hash_del failed %d", pid);
+                               return -EINVAL;
+                       }
+               }
+               return 0;
+       } else
+               return 0;
+
+       ret = get_cmdline_by_pid(pid, cmdline);
+       if (ret < 0) {
+               return ret;
+       }
+
+       tmp = strdup(cmdline);
+       if (!tmp) {
+               _E("strdup failed: %s", strerror(errno));
+               return -ENOMEM;
+       }
+
+       old_cmdline = eina_hash_set(active_pids, &pid, tmp);
+       if (old_cmdline)
+               free(old_cmdline);
+       else if (eina_error_get()) {
+               _E("eina_hash_set failed: %s", eina_error_msg_get(eina_error_get()));
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+int add_active_proc(struct taskstats *t, void *user_data)
+{
+       const char *launchpad_cmdline = "/usr/bin/launchpad_preloading_preinitializing_daemon";
+       int ret;
+       pid_t pid = t->ac_pid;
+       uint64_t s_time = t->ac_stime;
+       uint64_t u_time = t->ac_utime;
+       float u_time_power_cons = (float)t->ac_utime_power_cons / power_const_per_uah;
+       float s_time_power_cons = (float)t->ac_stime_power_cons / power_const_per_uah;
+
+       if (t->ac_stime || t->ac_utime) {
+               char *cmdline = eina_hash_find(active_pids, &pid);
+               struct process_stat *statistic;
+               char buf[PATH_MAX];
+
+               if (!cmdline) {
+                       ret = get_cmdline_by_pid(pid, buf);
+                       if (ret < 0) {
+                               return ret;
+                       }
+                       cmdline = strdup(buf);
+                       if (!cmdline) {
+                               _E("strdup failed: %s", strerror(errno));
+                               return -ENOMEM;
+                       }
+
+                       if (eina_hash_add(active_pids, &pid, cmdline) == EINA_FALSE) {
+                               _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
+                               free((void*)cmdline);
+                               return -ENOMEM;
+                       }
+               } else {
+                       if (strcmp(cmdline, launchpad_cmdline) == 0) {
+                               char *old_cmdline = NULL;
+                               ret = get_cmdline_by_pid(pid, buf);
+                               if (ret < 0) {
+                                       return ret;
+                               }
+                               cmdline = strdup(buf);
+                               if (!cmdline) {
+                                       _E("strdup failed: %s", strerror(errno));
+                                       return -ENOMEM;
+                               }
+                               old_cmdline = eina_hash_modify(active_pids,
+                                       &pid, cmdline);
+                               if (!old_cmdline) {
+                                       _E("eina_hash_modify failed: %s", eina_error_msg_get(eina_error_get()));
+                                       return -EINVAL;
+                               }
+                               free(old_cmdline);
+                       }
+               }
+
+               statistic = find_or_create_statistic(total_stats, cmdline);
+               if (!statistic) {
+                       _E("find_or_create_statistic failed");
+                       return -ENOMEM;
+               }
+
+               statistic->utime += u_time;
+               statistic->stime += s_time;
+               statistic->utime_power_cons += u_time_power_cons;
+               statistic->stime_power_cons += s_time_power_cons;
+               statistic->duration += t->ac_etime / USEC_PER_SEC;
+               statistic->is_active = 1;
+       }
+
+       return 0;
+}
+
+static Eina_Bool update_total_stat_cb(const Eina_Hash *hash, const void *key,
+       void *data, void *fdata)
+{
+       struct process_stat *statistic;
+       struct process_stat *new_statistic = (struct process_stat *)data;
+       char *cmdline = (char*)key;
+
+       statistic = find_or_create_statistic(total_stats, cmdline);
+       if (!statistic) {
+               _E("find_or_create_statistic failed");
+               return 1; /* continue to process */
+       }
+
+       statistic->utime += new_statistic->utime;
+       statistic->stime += new_statistic->stime;
+       statistic->utime_power_cons += new_statistic->utime_power_cons;
+       statistic->stime_power_cons += new_statistic->stime_power_cons;
+       statistic->duration += new_statistic->duration;
+
+       return 1; /* continue to process */
+}
+
+Eina_Bool update_active_pids_cb(const Eina_Hash *hash, const void *key,
+       void *data, void *fdata)
+{
+       int pid = *(int*)key;
+       int ret;
+
+       ret = request_stat_by_pid(update_task_stats_sock, (int)pid);
+       if (ret < 0) {
+               _E("request_stat_by_pid failed (pid=%d)", (int)pid);
+               return 1; /* continue to process */
+       }
+       ret = process_task_stats_answer(update_task_stats_sock,
+               add_active_proc, NULL);
+       if (ret < 0) {
+               _E("process_task_stats_answer failed (pid=%d)", (int)pid);
+               return 1; /* continue to process */
+       }
+
+       return 1; /* continue to process */
+}
+
+static int proc_state_update(void)
+{
+       eina_hash_free_buckets(total_stats);
+
+       eina_hash_foreach(active_pids, update_active_pids_cb, NULL);
+       eina_hash_foreach(terminated_stats, update_total_stat_cb, NULL);
+
+       return 0;
+}
+
+static int send_one_stat(const struct logd_proc_stat *statistics, int sock)
+{
+       const char *cmdline = (const char *)statistics->application;
+       int len = strlen(cmdline);
+       int ret;
+
+       if (send(sock, (void*)&len, sizeof(len), 0) < 0) {
+               goto err;
+       }
+       if (send(sock, cmdline, len, 0) < 0) {
+               goto err;
+       }
+       if (send(sock, &statistics->utime, sizeof(statistics->utime), 0) < 0) {
+               goto err;
+       }
+       if (send(sock, &statistics->stime, sizeof(statistics->stime), 0) < 0) {
+               goto err;
+       }
+       if (send(sock, &statistics->utime_power_cons,
+               sizeof(statistics->utime_power_cons), 0) < 0) {
+               goto err;
+       }
+       if (send(sock, &statistics->stime_power_cons,
+               sizeof(statistics->stime_power_cons), 0) < 0) {
+               goto err;
+       }
+       if (send(sock, &statistics->is_active,
+               sizeof(statistics->is_active), 0) < 0) {
+               goto err;
+       }
+
+       return 0;
+err:
+       ret = -errno;
+       if (errno != EPIPE)
+               _E("send failed: %s", strerror(errno));
+       return ret;
+}
+
+static int sort_stat_cb(void *d1, void *d2)
+{
+       const struct logd_proc_stat *s1 = d1;
+       const struct logd_proc_stat *s2 = d2;
+
+       if(!d1) return(1);
+       if(!d2) return(-1);
+
+       if (s1->utime_power_cons + s1->stime_power_cons <
+               s2->utime_power_cons + s2->stime_power_cons)
+               return 1;
+       else if (s1->utime_power_cons + s1->stime_power_cons >
+               s2->utime_power_cons + s2->stime_power_cons)
+               return -1;
+       return 0;
+}
+
+int send_proc_stat(int sock)
+{
+       int count = eina_hash_population(total_stats);
+       int day = day_of_week();
+       Eina_List *sorted_stat = NULL;
+       Eina_List *l;
+       Eina_Iterator *it;
+       void *data;
+       int ret;
+       int i;
+
+       ret = proc_state_update();
+       if (ret < 0) {
+               _E("proc_stat_update failed");
+               return ret;
+       }
+
+       for (i = 0; i < DAYS_PER_WEEK; ++i) {
+               /* stat for current day stored in activ/terminated hash tables */
+               if (i == day)
+                       continue;
+               if (foreach_proc_power_cons(load_stat_cb, i, total_stats) < 0)
+                       _E("foreach_proc_power_cons failed");
+       }
+
+       it = eina_hash_iterator_tuple_new(total_stats);
+       if (!it) {
+               _E("eina_hash_iterator_tuple_new failed");
+               return -ENOMEM;
+       }
+
+       while (eina_iterator_next(it, &data)) {
+               Eina_Hash_Tuple *t = data;
+               char *cmdline = (char*)t->key;
+               const struct process_stat *statistic = t->data;
+               struct logd_proc_stat *ps =
+                       (struct logd_proc_stat*) malloc(sizeof(struct logd_proc_stat));
+
+               if (!ps) {
+                       ret = -ENOMEM;
+                       _E("malloc failed: %s", strerror(errno));
+                       goto out_free;
+               }
+               ps->application = cmdline;
+               ps->utime = statistic->utime;
+               ps->stime = statistic->stime;
+               ps->utime_power_cons = statistic->utime_power_cons;
+               ps->stime_power_cons = statistic->stime_power_cons;
+               ps->is_active = statistic->is_active;
+
+               sorted_stat = eina_list_sorted_insert(sorted_stat,
+                       EINA_COMPARE_CB(sort_stat_cb), ps);
+               if (eina_error_get()) {
+                       _E("eina_list_sorted_insert failed: %s", eina_error_msg_get(eina_error_get()));
+               }
+
+       }
+
+       if (send(sock, &count, sizeof(count), 0) < 0) {
+               ret = -errno;
+               _E("send failed: %s", strerror(errno));
+               goto out_free;
+       }
+
+       EINA_LIST_FOREACH(sorted_stat, l, data) {
+               ret = send_one_stat(data, sock);
+               if (ret < 0) {
+                       if (ret != -EPIPE)
+                               _E("send_one_stat failed");
+                       break;
+               }
+       }
+
+       EINA_LIST_FOREACH(sorted_stat, l, data) {
+               free(data);
+       }
+
+       eina_iterator_free(it);
+
+       eina_list_free(sorted_stat);
+
+       return 0;
+
+out_free:
+       if (sorted_stat) {
+               EINA_LIST_FOREACH(sorted_stat, l, data) {
+                       free(data);
+               }
+       }
+
+       if (it)
+               eina_iterator_free(it);
+
+       if (sorted_stat)
+               eina_list_free(sorted_stat);
+       return ret;
+}
+
+int nlproc_stat_store(void)
+{
+       Eina_Iterator *it;
+       void *data;
+       int ret;
+       int day;
+
+       _I("nlproc_stat_store start");
+
+       ret = proc_state_update();
+       if (ret < 0) {
+               _E("proc_state_update failed");
+               goto out;
+       }
+
+       it = eina_hash_iterator_tuple_new(total_stats);
+       if (!it) {
+               _E("eina_hash_iterator_tuple_new failed");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       day = day_of_week();
+       if (day < 0) {
+               _E("day_of_week failed");
+               day = 0;
+       }
+
+       while (eina_iterator_next(it, &data)) {
+               struct proc_power_cons pc;
+               Eina_Hash_Tuple *t = data;
+               const char *cmdline = t->key;
+               const struct process_stat *statistic = t->data;
+
+               pc.appid = cmdline;
+               pc.power_cons = statistic->stime_power_cons + statistic->utime_power_cons;
+               pc.duration = statistic->duration;
+
+               update_proc_power_cons(&pc, day);
+       }
+       eina_iterator_free(it);
+       ret = 0;
+
+out:
+       return ret;
+}
+
+int nlproc_stat_exit()
+{
+       if (active_pids)
+               eina_hash_free(active_pids);
+       /* TODO: free terminated keys */
+
+       return 0;
+}
diff --git a/src/logd_grabber/nlproc-stat.h b/src/logd_grabber/nlproc-stat.h
new file mode 100644 (file)
index 0000000..4f93286
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __NLPROC_STAT_H__
+#define __NLPROC_STAT_H__
+
+#include "logd-taskstats.h"
+#include "proc-events.h"
+
+int nlproc_stat_init(void);
+int get_task_stats_sock(void);
+int get_proc_events_sock(void);
+int nlproc_stat_exit(void);
+
+int proc_forked(struct proc_event *e, void *user_data);
+int proc_terminated(struct taskstats *t, void *user_data);
+
+int send_proc_stat(int socket);
+int nlproc_stat_store(void);
+int delete_old_proc();
+
+#endif /* __PROC_STAT_H__ */
diff --git a/src/logd_grabber/timer.c b/src/logd_grabber/timer.c
new file mode 100644 (file)
index 0000000..589523e
--- /dev/null
@@ -0,0 +1,84 @@
+#include <sys/timerfd.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/log.h"
+#include "timer.h"
+
+int update_timer_exp(struct timer *tm, int timeout)
+{
+       struct timespec now;
+       struct itimerspec new_value;
+
+       clock_gettime(CLOCK_REALTIME, &now);
+       new_value.it_value.tv_sec = now.tv_sec + timeout;
+       new_value.it_value.tv_nsec = now.tv_nsec;
+
+       new_value.it_interval.tv_sec = timeout;
+       new_value.it_interval.tv_nsec = 0;
+
+       if (timerfd_settime(tm->fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1) {
+               _E("timerfd_settime: %s", strerror(errno));
+               return -errno;
+       }
+
+       return 0;
+}
+
+struct timer* create_timer(int timeout, void(*cb)(void*), void *user_data)
+{
+       int ret;
+       struct timer *tm;
+
+       tm = malloc(sizeof(struct timer));
+       if (!tm) {
+               _E("malloc failed");
+               return NULL;
+       }
+
+       tm->cb = cb;
+       tm->user_data = user_data;
+       tm->fd = timerfd_create(CLOCK_REALTIME, 0);
+       if (tm->fd == -1) {
+               _E("timerfd_create failed: %s", strerror(errno));
+               free(tm);
+               return NULL;
+       }
+
+       tm->timeout = timeout;
+
+       ret = update_timer_exp(tm, timeout);
+       if (ret < 0) {
+               close(tm->fd);
+               free(tm);
+               _E("update_timer_exp failed");
+               return NULL;
+       }
+
+       return tm;
+}
+
+void process_timer(struct timer *tm)
+{
+       int s;
+       uint64_t exp;
+
+       if (!tm)
+               return;
+       s = read(tm->fd, &exp, sizeof(uint64_t));
+       tm->cb(tm->user_data);
+}
+
+void delete_timer(struct timer *tm)
+{
+       if (!tm)
+               return;
+
+       close(tm->fd);
+       free(tm);
+}
diff --git a/src/logd_grabber/timer.h b/src/logd_grabber/timer.h
new file mode 100644 (file)
index 0000000..3e8e58e
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+struct timer {
+       int fd;
+       int timeout;
+       void (*cb)(void*);
+       void *user_data;
+};
+
+struct timer* create_timer(int timeout, void(*cb)(void*), void *user_data);
+void process_timer(struct timer *tm);
+int update_timer_exp(struct timer *tm, int timeout);
+void delete_timer(struct timer *tm);
+
+#endif /* __TIMER_H__ */
+
diff --git a/src/mmc/exfat.c b/src/mmc/exfat.c
new file mode 100644 (file)
index 0000000..e954c3e
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <limits.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/common.h"
+#include "core/log.h"
+#include "mmc-handler.h"
+
+#define FS_EXFAT_NAME "EXFAT"
+
+#define FS_EXFAT_MOUNT_OPT     "uid=5000,gid=5000,dmask=0002,fmask=0002"
+
+static const char *exfat_arg[] = {
+       "/sbin/mkfs.exfat",
+       "-t", "exfat", "-s", "9", "-c", "8", "-b", "11", "-f", "1", "-l", "tizen", NULL, NULL,
+};
+
+static const char *exfat_check_arg[] = {
+       "/sbin/fsck.exfat",
+       "-f", "-R", NULL, NULL,
+};
+
+static struct fs_check exfat_info = {
+       FS_TYPE_EXFAT,
+       "exfat",
+};
+
+static bool exfat_match(const char *devpath)
+{
+       int fd, len, r;
+       int argc;
+       char buf[BUF_LEN];
+       char *tmpbuf;
+
+       argc = ARRAY_SIZE(exfat_check_arg);
+       exfat_check_arg[argc - 2] = devpath;
+
+       fd = open(devpath, O_RDONLY);
+       if (fd < 0) {
+               _E("failed to open fd(%s) : %s", devpath, strerror(errno));
+               return false;
+       }
+
+       /* check file system name */
+       len = sizeof(buf);
+       tmpbuf = buf;
+       while (len != 0 && (r = read(fd, tmpbuf, len)) != 0) {
+               if (r < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       goto error;
+               }
+               len -= r;
+               tmpbuf += r;
+       }
+
+       if (strncmp((buf + 3), FS_EXFAT_NAME, strlen(FS_EXFAT_NAME)))
+               goto error;
+
+       close(fd);
+       _I("MMC type : %s", exfat_info.name);
+       return true;
+
+error:
+       close(fd);
+       _E("failed to match with exfat(%s %s)", devpath, buf);
+       return false;
+}
+
+static int exfat_check(const char *devpath)
+{
+       int argc;
+       argc = ARRAY_SIZE(exfat_check_arg);
+       exfat_check_arg[argc - 2] = devpath;
+       return run_child(argc, exfat_check_arg);
+}
+
+static int exfat_mount(bool smack, const char *devpath, const char *mount_point)
+{
+       char options[NAME_MAX];
+       int r, retry = RETRY_COUNT;
+
+       if (smack)
+               snprintf(options, sizeof(options), "%s,%s", FS_EXFAT_MOUNT_OPT, SMACKFS_MOUNT_OPT);
+       else
+               snprintf(options, sizeof(options), "%s", FS_EXFAT_MOUNT_OPT);
+
+       do {
+               r = mount(devpath, mount_point, "exfat", 0, options);
+               if (!r) {
+                       _I("Mounted mmc card [exfat]");
+                       return 0;
+               }
+               usleep(100000);
+       } while (r < 0 && errno == ENOENT && retry-- > 0);
+
+       return -errno;
+}
+
+static int exfat_format(const char *devpath)
+{
+       int argc;
+       argc = ARRAY_SIZE(exfat_arg);
+       exfat_arg[argc - 2] = devpath;
+       return run_child(argc, exfat_arg);
+}
+
+static const struct mmc_fs_ops exfat_ops = {
+       .type = FS_TYPE_EXFAT,
+       .name = "exfat",
+       .match = exfat_match,
+       .check = exfat_check,
+       .mount = exfat_mount,
+       .format = exfat_format,
+};
+
+static void __CONSTRUCTOR__ module_init(void)
+{
+       add_fs(&exfat_ops);
+}
+/*
+static void __DESTRUCTOR__ module_exit(void)
+{
+       remove_fs(&exfat_ops);
+}
+*/
index 6253dac..1ff73e6 100644 (file)
@@ -33,7 +33,7 @@
 
 #define FS_EXT4_NAME   "ext4"
 
-#define FS_EXT4_SMACK_LABEL " /usr/bin/mmc-smack-label"
+#define FS_EXT4_SMACK_LABEL "/usr/bin/mmc-smack-label"
 
 struct popup_data {
        char *name;
@@ -81,12 +81,12 @@ static bool ext4_match(const char *devpath)
        if (r < 0)
                goto error;
 
-       _D("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
+       _I("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
        if (memcmp(buf, ext4_info.magic, ext4_info.magic_sz))
                goto error;
 
        close(fd);
-       _D("MMC type : %s", ext4_info.name);
+       _I("MMC type : %s", ext4_info.name);
        return true;
 
 error:
@@ -110,8 +110,6 @@ static int mmc_check_smack(const char *mount_point)
        snprintf(buf, sizeof(buf), "%s", mount_point);
        launch_evenif_exist(FS_EXT4_SMACK_LABEL, buf);
 
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
        if (mmc_popup_pid > 0) {
                _E("will be killed mmc-popup(%d)", mmc_popup_pid);
                kill(mmc_popup_pid, SIGTERM);
@@ -128,11 +126,9 @@ static int check_smack_popup(void)
 
        ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
        if (val == 1 || ret != 0) {
-               if (apps == NULL) {
-                       apps = find_device("apps");
-                       if (apps == NULL)
-                               return 0;
-               }
+
+               FIND_DEVICE_INT(apps, "apps");
+
                params = malloc(sizeof(struct popup_data));
                if (params == NULL) {
                        _E("Malloc failed");
@@ -155,13 +151,14 @@ static int ext4_mount(bool smack, const char *devpath, const char *mount_point)
        do {
                r = mount(devpath, mount_point, "ext4", 0, NULL);
                if (!r) {
-                       _D("Mounted mmc card [ext4]");
+                       _I("Mounted mmc card [ext4]");
                        if (smack) {
                                check_smack_popup();
                                mmc_check_smack(mount_point);
                        }
                        return 0;
                }
+               _I("mount fail : r = %d, err = %d", r, errno);
                usleep(100000);
        } while (r < 0 && errno == ENOENT && retry-- > 0);
 
index 5493a92..c501e40 100644 (file)
@@ -37,6 +37,7 @@
 #include "core/device-notifier.h"
 #include "core/common.h"
 #include "core/devices.h"
+#include "ode/ode.h"
 #include "mmc-handler.h"
 #include "config.h"
 #include "core/edbus-handler.h"
 
 #define ODE_MOUNT_STATE        1
 
+#define COMM_PKG_MGR_DBUS_SERVICE     "com.samsung.slp.pkgmgr"
+#define COMM_PKG_MGR_DBUS_PATH          "/com/samsung/slp/pkgmgr"
+#define COMM_PKG_MGR_DBUS_INTERFACE COMM_PKG_MGR_DBUS_SERVICE
+#define COMM_PKG_MGR_METHOD                "CreateExternalDirectory"
+
+#define SMACK_LABELING_TIME (0.5)
+
 enum unmount_operation {
        UNMOUNT_NORMAL = 0,
        UNMOUNT_FORCE,
@@ -101,6 +109,7 @@ static dd_list *fs_head;
 static char *mmc_curpath;
 static bool smack = false;
 static bool mmc_disabled = false;
+static Ecore_Timer *smack_timer = NULL;
 
 int __WEAK__ app2ext_unmount(void);
 
@@ -161,11 +170,8 @@ static void launch_syspopup(char *str)
        struct popup_data *params;
        static const struct device_ops *apps = NULL;
 
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return;
-       }
+       FIND_DEVICE_VOID(apps, "apps");
+
        params = malloc(sizeof(struct popup_data));
        if (params == NULL) {
                _E("Malloc failed");
@@ -279,7 +285,7 @@ int get_block_number(void)
 
                                        free(str_mmcblk_num);
                                        closedir(dp);
-                                       _D("%d", mmcblk_num);
+                                       _I("%d", mmcblk_num);
 
                                        snprintf(buf, 255, "/sys/block/%s/device/cid", dir->d_name);
 
@@ -356,7 +362,7 @@ static int get_mmc_size(const char *devpath)
        }
 
        nbytes = ullbytes/512;
-       _D("block size(64) : %d", nbytes);
+       _I("block size(64) : %d", nbytes);
        return nbytes;
 }
 
@@ -370,6 +376,43 @@ static int rw_mount(const char *szPath)
        return 0;
 }
 
+static void request_smack_broadcast(void)
+{
+       int ret;
+
+       ret = dbus_method_sync_timeout(COMM_PKG_MGR_DBUS_SERVICE,
+                       COMM_PKG_MGR_DBUS_PATH,
+                       COMM_PKG_MGR_DBUS_INTERFACE,
+                       COMM_PKG_MGR_METHOD,
+                       NULL, NULL, SMACK_LABELING_TIME*1000);
+       if (ret != 0)
+               _E("Failed to call dbus method (err: %d)", ret);
+}
+
+static Eina_Bool smack_timer_cb(void *data)
+{
+       if (smack_timer) {
+               ecore_timer_del(smack_timer);
+               smack_timer = NULL;
+       }
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
+       return EINA_FALSE;
+}
+
+void mmc_mount_done(void)
+{
+       request_smack_broadcast();
+       smack_timer = ecore_timer_add(SMACK_LABELING_TIME,
+                       smack_timer_cb, NULL);
+       if (smack_timer) {
+               _I("Wait to check");
+               return;
+       }
+       _E("Fail to add abnormal check timer");
+       smack_timer_cb(NULL);
+}
+
 static int mmc_mount(const char *devpath, const char *mount_point)
 {
        struct mmc_fs_ops *fs;
@@ -397,7 +440,7 @@ static int mmc_mount(const char *devpath, const char *mount_point)
        if (!fs)
                return -EINVAL;
 
-       _D("devpath : %s", devpath);
+       _I("devpath : %s", devpath);
        r = fs->check(devpath);
        if (r < 0)
                _E("failt to check devpath : %s", devpath);
@@ -420,10 +463,13 @@ static void *mount_start(void *arg)
        int r;
 
        devpath = data->devpath;
-
-       assert(devpath);
+       if (!devpath) {
+               r = -EINVAL;
+               goto error;
+       }
 
        /* clear previous filesystem */
+       ode_mmc_removed();
        mmc_check_and_unmount(MMC_MOUNT_POINT);
 
        /* check mount point */
@@ -438,19 +484,34 @@ static void *mount_start(void *arg)
        r = mmc_mount(devpath, MMC_MOUNT_POINT);
        if (r == -EROFS)
                launch_syspopup("mountrdonly");
+       /* Do not need to show error popup, if mmc is disabled */
+       else if (r == -EWOULDBLOCK)
+               goto error_without_popup;
        else if (r < 0)
                goto error;
 
        mmc_set_config(MAX_RATIO);
+       r = ode_mmc_inserted();
+       if (r < 0)
+               goto error_ode;
 
        free(devpath);
        free(data);
+
+       /* give a transmutable attribute to mount_point */
+       r = setxattr(MMC_MOUNT_POINT, "security.SMACK64TRANSMUTE", "TRUE", strlen("TRUE"), 0);
+       if (r < 0)
+               _E("setxattr error : %s", strerror(errno));
+
+       request_smack_broadcast();
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
        return 0;
 
 error:
        launch_syspopup("mounterr");
+
+error_without_popup:
        vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
 
@@ -458,6 +519,18 @@ error:
        free(data);
        _E("failed to mount device : %s", strerror(-r));
        return (void *)r;
+
+error_ode:
+       /* to ignore previous mount callbck func,
+          set a specific value(-1) to MMC_MOUNT key */
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, -1);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, -1);
+       r = ODE_MOUNT_STATE;
+
+       free(devpath);
+       free(data);
+       _I("you should mount with encryption");
+       return (void *)r;
 }
 
 static int mmc_unmount(int option, const char *mount_point)
@@ -469,6 +542,8 @@ static int mmc_unmount(int option, const char *mount_point)
        r = app2ext_unmount();
        if (r < 0)
                _I("Faild to unmount app2ext : %s", strerror(-r));
+       /* it must called before unmounting mmc */
+       ode_mmc_removed();
        r = mmc_check_and_unmount(mount_point);
        if (!r)
                return r;
@@ -512,6 +587,7 @@ static int mmc_unmount(int option, const char *mount_point)
                if (r < 0)
                        _I("Faild to unmount app2ext : %s", strerror(-r));
 
+               ode_mmc_removed();
                r = mmc_check_and_unmount(mount_point);
                if (!r)
                        break;
@@ -595,7 +671,7 @@ static int format(const char *devpath)
 
        for (retry = FORMAT_RETRY; retry > 0; --retry) {
                fs->check(devpath);
-               _D("format path : %s", path);
+               _I("format path : %s", path);
                r = fs->format(path);
                if (!r)
                        break;
@@ -691,6 +767,7 @@ static int mmc_removed(void)
        /* first, try to unmount app2ext */
        app2ext_unmount();
        /* unmount */
+       ode_mmc_removed();
        mmc_check_and_unmount((const char *)MMC_MOUNT_POINT);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
        free(mmc_curpath);
@@ -750,7 +827,7 @@ static DBusMessage *edbus_request_secure_mount(E_DBus_Object *obj, DBusMessage *
                }
        }
 
-       _D("mount path : %s", path);
+       _I("mount path : %s", path);
        ret = mmc_mount(mmc_curpath, path);
 
 error:
@@ -774,7 +851,7 @@ static DBusMessage *edbus_request_secure_unmount(E_DBus_Object *obj, DBusMessage
                goto error;
        }
 
-       _D("unmount path : %s", path);
+       _I("unmount path : %s", path);
        ret = mmc_unmount(UNMOUNT_NORMAL, path);
 
 error:
@@ -896,6 +973,68 @@ error:
        return reply;
 }
 
+static DBusMessage *edbus_request_insert(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *devpath;
+       int ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_STRING, &devpath, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EBADMSG;
+               goto error;
+       }
+
+       ret = mmc_inserted(devpath);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_request_remove(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = mmc_removed();
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_change_status(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int opt, ret;
+       char params[NAME_MAX];
+       struct mmc_data *pdata;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &opt, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EBADMSG;
+               goto error;
+       }
+       if (opt == VCONFKEY_SYSMAN_MMC_MOUNTED)
+               mmc_mount_done();
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
 int get_mmc_devpath(char devpath[])
 {
        if (mmc_disabled)
@@ -912,6 +1051,9 @@ static const struct edbus_method edbus_methods[] = {
        { "RequestMount",         NULL, "i", edbus_request_mount },
        { "RequestUnmount",        "i", "i", edbus_request_unmount },
        { "RequestFormat",         "i", "i", edbus_request_format },
+       { "RequestInsert",         "s", "i", edbus_request_insert },
+       { "RequestRemove",        NULL, "i", edbus_request_remove },
+       { "ChangeStatus",          "i", "i", edbus_change_status },
 };
 
 static int mmc_poweroff(void *data)
@@ -951,18 +1093,18 @@ static void mmc_exit(void *data)
        mmc_uevent_stop();
 }
 
-static int mmc_start(void)
+static int mmc_start(enum device_flags flags)
 {
        mmc_disabled = false;
-       _D("start");
+       _I("start");
        return 0;
 }
 
-static int mmc_stop(void)
+static int mmc_stop(enum device_flags flags)
 {
        mmc_disabled = true;
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
-       _D("stop");
+       _I("stop");
        return 0;
 }
 
index d1d9c91..89541a3 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <stdbool.h>
 
-#define SMACKFS_MOUNT_OPT      "smackfsroot=*,smackfsdef=*"
+#define SMACKFS_MOUNT_OPT      "smackfsroot=system::ext_storage,smackfsdef=system::ext_storage"
 #define MMC_MOUNT_POINT                "/opt/storage/sdcard"
 
 #define BUF_LEN                20
@@ -63,4 +63,6 @@ bool mmc_check_mounted(const char *mount_point);
 int mmc_uevent_start(void);
 int mmc_uevent_stop(void);
 int get_block_number(void);
+
+void mmc_mount_done(void);
 #endif /* __MMC_HANDLER_H__ */
index 1cab15d..a96e640 100644 (file)
@@ -32,8 +32,8 @@
 #define FS_VFAT_MOUNT_OPT      "uid=5000,gid=5000,dmask=0002,fmask=0002,iocharset=iso8859-1,utf8,shortname=mixed"
 
 static const char *vfat_arg[] = {
-       "/sbin/mkfs.vfat",
-       NULL, NULL,
+       "/usr/bin/newfs_msdos",
+       "-F", "32", "-O", "tizen", "-c", "8", NULL, NULL,
 };
 
 static const char *vfat_check_arg[] = {
@@ -94,7 +94,7 @@ static bool vfat_match(const char *devpath)
                return false;
        }
 
-       _D("MMC type : %s", vfat_info.name);
+       _I("MMC type : %s", vfat_info.name);
        return true;
 }
 
@@ -111,10 +111,10 @@ static int vfat_mount(bool smack, const char *devpath, const char *mount_point)
        do {
                r = mount(devpath, mount_point, "vfat", 0, options);
                if (!r) {
-                       _D("Mounted mmc card [vfat]");
+                       _I("Mounted mmc card [vfat]");
                        return 0;
                }
-               _D("mount fail : r = %d, err = %d", r, errno);
+               _I("mount fail : r = %d, err = %d", r, errno);
                usleep(100000);
        } while (r < 0 && errno == ENOENT && retry-- > 0);
 
@@ -145,7 +145,7 @@ static void __CONSTRUCTOR__ module_init(void)
 /*
 static void __DESTRUCTOR__ module_exit(void)
 {
-       _D("module exit");
+       _I("module exit");
        remove_fs(&vfat_ops);
 }
 */
diff --git a/src/newfs-msdos/CMakeLists.txt b/src/newfs-msdos/CMakeLists.txt
new file mode 100644 (file)
index 0000000..67688c4
--- /dev/null
@@ -0,0 +1,33 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(newfs_msdos C)
+
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_ENGINEER_MODE")
+    OPTION(USE_ENGINEER_MODE "Use Engineer mode" ON)
+ENDIF()
+
+SET(SRCS
+       newfs-msdos.c
+       )
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+IF(USE_ENGINEER_MODE)
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+ELSE()
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+ENDIF()
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+IF( $ENV{ARCH} MATCHES "arm" )
+       ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+ADD_DEFINITIONS("-DDEBUG")
+ADD_DEFINITIONS("-DTIZEN")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES LICENSE DESTINATION share/license RENAME ${PROJECT_NAME})
diff --git a/src/newfs-msdos/LICENSE b/src/newfs-msdos/LICENSE
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/newfs-msdos/newfs-msdos.c b/src/newfs-msdos/newfs-msdos.c
new file mode 100644 (file)
index 0000000..1a86f6d
--- /dev/null
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (c) 1998 Robert Nordier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+
+#ifndef TIZEN
+  #include <sys/fdcio.h>
+  #include <sys/disk.h>
+  #include <sys/disklabel.h>
+  #include <sys/mount.h>
+#else
+  #include <stdarg.h>
+  #include <linux/fs.h>
+  #include <linux/hdreg.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define MAXU16   0xffff        /* maximum unsigned 16-bit quantity */
+#define BPN      4             /* bits per nibble */
+#define NPB      2             /* nibbles per byte */
+
+#define DOSMAGIC  0xaa55       /* DOS magic number */
+#define MINBPS   512           /* minimum bytes per sector */
+#define MAXSPC   128           /* maximum sectors per cluster */
+#define MAXNFT   16            /* maximum number of FATs */
+#define DEFBLK   4096          /* default block size */
+#define DEFBLK16  2048         /* default block size FAT16 */
+#define DEFRDE   512           /* default root directory entries */
+#define RESFTE   2             /* reserved FAT entries */
+#define MINCLS12  1            /* minimum FAT12 clusters */
+#define MINCLS16  0x1000       /* minimum FAT16 clusters */
+#define MINCLS32  2            /* minimum FAT32 clusters */
+#define MAXCLS12  0xfed        /* maximum FAT12 clusters */
+#define MAXCLS16  0xfff5       /* maximum FAT16 clusters */
+#define MAXCLS32  0xffffff5    /* maximum FAT32 clusters */
+
+#define mincls(fat)  ((fat) == 12 ? MINCLS12 : \
+                     (fat) == 16 ? MINCLS16 :  \
+                                   MINCLS32)
+
+#define maxcls(fat)  ((fat) == 12 ? MAXCLS12 : \
+                     (fat) == 16 ? MAXCLS16 :  \
+                                   MAXCLS32)
+
+#define mk1(p, x)                              \
+    (p) = (u_int8_t)(x)
+
+#define mk2(p, x)                              \
+    (p)[0] = (u_int8_t)(x),                    \
+    (p)[1] = (u_int8_t)((x) >> 010)
+
+#define mk4(p, x)                              \
+    (p)[0] = (u_int8_t)(x),                    \
+    (p)[1] = (u_int8_t)((x) >> 010),           \
+    (p)[2] = (u_int8_t)((x) >> 020),           \
+    (p)[3] = (u_int8_t)((x) >> 030)
+
+#define argto1(arg, lo, msg)  argtou(arg, lo, 0xff, msg)
+#define argto2(arg, lo, msg)  argtou(arg, lo, 0xffff, msg)
+#define argto4(arg, lo, msg)  argtou(arg, lo, 0xffffffff, msg)
+#define argtox(arg, lo, msg)  argtou(arg, lo, UINT_MAX, msg)
+
+#define __unused       __attribute__((__unused__))
+
+struct bs {
+    u_int8_t jmp[3];           /* bootstrap entry point */
+    u_int8_t oem[8];           /* OEM name and version */
+};
+
+struct bsbpb {
+    u_int8_t bps[2];           /* bytes per sector */
+    u_int8_t spc;              /* sectors per cluster */
+    u_int8_t res[2];           /* reserved sectors */
+    u_int8_t nft;              /* number of FATs */
+    u_int8_t rde[2];           /* root directory entries */
+    u_int8_t sec[2];           /* total sectors */
+    u_int8_t mid;              /* media descriptor */
+    u_int8_t spf[2];           /* sectors per FAT */
+    u_int8_t spt[2];           /* sectors per track */
+    u_int8_t hds[2];           /* drive heads */
+    u_int8_t hid[4];           /* hidden sectors */
+    u_int8_t bsec[4];          /* big total sectors */
+};
+
+struct bsxbpb {
+    u_int8_t bspf[4];          /* big sectors per FAT */
+    u_int8_t xflg[2];          /* FAT control flags */
+    u_int8_t vers[2];          /* file system version */
+    u_int8_t rdcl[4];          /* root directory start cluster */
+    u_int8_t infs[2];          /* file system info sector */
+    u_int8_t bkbs[2];          /* backup boot sector */
+    u_int8_t rsvd[12];         /* reserved */
+};
+
+struct bsx {
+    u_int8_t drv;              /* drive number */
+    u_int8_t rsvd;             /* reserved */
+    u_int8_t sig;              /* extended boot signature */
+    u_int8_t volid[4];         /* volume ID number */
+    u_int8_t label[11];        /* volume label */
+    u_int8_t type[8];          /* file system type */
+};
+
+struct de {
+    u_int8_t namext[11];       /* name and extension */
+    u_int8_t attr;             /* attributes */
+    u_int8_t rsvd[10];         /* reserved */
+    u_int8_t time[2];          /* creation time */
+    u_int8_t date[2];          /* creation date */
+    u_int8_t clus[2];          /* starting cluster */
+    u_int8_t size[4];          /* size */
+};
+
+struct bpb {
+    u_int bps;                 /* bytes per sector */
+    u_int spc;                 /* sectors per cluster */
+    u_int res;                 /* reserved sectors */
+    u_int nft;                 /* number of FATs */
+    u_int rde;                 /* root directory entries */
+    u_int sec;                 /* total sectors */
+    u_int mid;                 /* media descriptor */
+    u_int spf;                 /* sectors per FAT */
+    u_int spt;                 /* sectors per track */
+    u_int hds;                 /* drive heads */
+    u_int hid;                 /* hidden sectors */
+    u_int bsec;                /* big total sectors */
+    u_int bspf;                /* big sectors per FAT */
+    u_int rdcl;                /* root directory start cluster */
+    u_int infs;                /* file system info sector */
+    u_int bkbs;                /* backup boot sector */
+};
+
+#define BPBGAP 0, 0, 0, 0, 0, 0
+
+static struct {
+    const char *name;
+    struct bpb bpb;
+} const stdfmt[] = {
+    {"160",  {512, 1, 1, 2,  64,  320, 0xfe, 1,  8, 1, BPBGAP}},
+    {"180",  {512, 1, 1, 2,  64,  360, 0xfc, 2,  9, 1, BPBGAP}},
+    {"320",  {512, 2, 1, 2, 112,  640, 0xff, 1,  8, 2, BPBGAP}},
+    {"360",  {512, 2, 1, 2, 112,  720, 0xfd, 2,  9, 2, BPBGAP}},
+    {"640",  {512, 2, 1, 2, 112, 1280, 0xfb, 2,  8, 2, BPBGAP}},    
+    {"720",  {512, 2, 1, 2, 112, 1440, 0xf9, 3,  9, 2, BPBGAP}},
+    {"1200", {512, 1, 1, 2, 224, 2400, 0xf9, 7, 15, 2, BPBGAP}},
+    {"1232", {1024,1, 1, 2, 192, 1232, 0xfe, 2,  8, 2, BPBGAP}},    
+    {"1440", {512, 1, 1, 2, 224, 2880, 0xf0, 9, 18, 2, BPBGAP}},
+    {"2880", {512, 2, 1, 2, 240, 5760, 0xf0, 9, 36, 2, BPBGAP}}
+};
+
+static const u_int8_t bootcode[] = {
+    0xfa,                      /* cli              */
+    0x31, 0xc0,                /* xor     ax,ax    */
+    0x8e, 0xd0,                /* mov     ss,ax    */
+    0xbc, 0x00, 0x7c,          /* mov     sp,7c00h */
+    0xfb,                      /* sti              */
+    0x8e, 0xd8,                /* mov     ds,ax    */
+    0xe8, 0x00, 0x00,          /* call    $ + 3    */
+    0x5e,                      /* pop     si       */
+    0x83, 0xc6, 0x19,          /* add     si,+19h  */
+    0xbb, 0x07, 0x00,          /* mov     bx,0007h */
+    0xfc,                      /* cld              */
+    0xac,                      /* lodsb            */
+    0x84, 0xc0,                /* test    al,al    */
+    0x74, 0x06,                /* jz      $ + 8    */
+    0xb4, 0x0e,                /* mov     ah,0eh   */
+    0xcd, 0x10,                /* int     10h      */
+    0xeb, 0xf5,                /* jmp     $ - 9    */
+    0x30, 0xe4,                /* xor     ah,ah    */
+    0xcd, 0x16,                /* int     16h      */
+    0xcd, 0x19,                /* int     19h      */
+    0x0d, 0x0a,
+    'N', 'o', 'n', '-', 's', 'y', 's', 't',
+    'e', 'm', ' ', 'd', 'i', 's', 'k',
+    0x0d, 0x0a,
+    'P', 'r', 'e', 's', 's', ' ', 'a', 'n',
+    'y', ' ', 'k', 'e', 'y', ' ', 't', 'o',
+    ' ', 'r', 'e', 'b', 'o', 'o', 't',
+    0x0d, 0x0a,
+    0
+};
+
+static void check_mounted(const char *, mode_t);
+static void getstdfmt(const char *, struct bpb *);
+static void getdiskinfo(int, const char *, const char *, int,
+                       struct bpb *);
+static void print_bpb(struct bpb *);
+static u_int ckgeom(const char *, u_int, const char *);
+static u_int argtou(const char *, u_int, u_int, const char *);
+static off_t argtooff(const char *, const char *);
+static int oklabel(const char *);
+static void mklabel(u_int8_t *, const char *);
+static void setstr(u_int8_t *, const char *, size_t);
+static void usage(void);
+
+/*
+ * Construct a FAT12, FAT16, or FAT32 file system.
+ */
+int main(int argc, char *argv[])
+{
+    static const char opts[] = "@:NB:C:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:u:";
+    const char *opt_B = NULL, *opt_L = NULL, *opt_O = NULL, *opt_f = NULL;
+    u_int opt_F = 0, opt_I = 0, opt_S = 0, opt_a = 0, opt_b = 0, opt_c = 0;
+    u_int opt_e = 0, opt_h = 0, opt_i = 0, opt_k = 0, opt_m = 0, opt_n = 0;
+    u_int opt_o = 0, opt_r = 0, opt_s = 0, opt_u = 0;
+    int opt_N = 0;
+    int Iflag = 0, mflag = 0, oflag = 0;
+    char buf[MAXPATHLEN];
+    struct stat sb;
+    struct timeval tv;
+    struct bpb bpb;
+    struct tm *tm;
+    struct bs *bs;
+    struct bsbpb *bsbpb;
+    struct bsxbpb *bsxbpb;
+    struct bsx *bsx;
+    struct de *de;
+    u_int8_t *img;
+    const char *fname, *dtype, *bname;
+    ssize_t n;
+    time_t now;
+    u_int fat, bss, rds, cls, dir, lsn, x, x1, x2;
+    int ch, fd, fd1;
+    off_t opt_create = 0, opt_ofs = 0;
+
+    while ((ch = getopt(argc, argv, opts)) != -1)
+       switch (ch) {
+       case '@':
+           opt_ofs = argtooff(optarg, "offset");
+           break;
+       case 'N':
+           opt_N = 1;
+           break;
+       case 'B':
+           opt_B = optarg;
+           break;
+       case 'C':
+           opt_create = argtooff(optarg, "create size");
+           break;
+       case 'F':
+           if (strcmp(optarg, "12") &&
+               strcmp(optarg, "16") &&
+               strcmp(optarg, "32"))
+               errx(1, "%s: bad FAT type", optarg);
+           opt_F = atoi(optarg);
+           break;
+       case 'I':
+           opt_I = argto4(optarg, 0, "volume ID");
+           Iflag = 1;
+           break;
+       case 'L':
+           if (!oklabel(optarg))
+               errx(1, "%s: bad volume label", optarg);
+           opt_L = optarg;
+           break;
+       case 'O':
+           if (strlen(optarg) > 8)
+               errx(1, "%s: bad OEM string", optarg);
+           opt_O = optarg;
+           break;
+       case 'S':
+           opt_S = argto2(optarg, 1, "bytes/sector");
+           break;
+       case 'a':
+           opt_a = argto4(optarg, 1, "sectors/FAT");
+           break;
+       case 'b':
+           opt_b = argtox(optarg, 1, "block size");
+           opt_c = 0;
+           break;
+       case 'c':
+           opt_c = argto1(optarg, 1, "sectors/cluster");
+           opt_b = 0;
+           break;
+       case 'e':
+           opt_e = argto2(optarg, 1, "directory entries");
+           break;
+       case 'f':
+           opt_f = optarg;
+           break;
+       case 'h':
+           opt_h = argto2(optarg, 1, "drive heads");
+           break;
+       case 'i':
+           opt_i = argto2(optarg, 1, "info sector");
+           break;
+       case 'k':
+           opt_k = argto2(optarg, 1, "backup sector");
+           break;
+       case 'm':
+           opt_m = argto1(optarg, 0, "media descriptor");
+           mflag = 1;
+           break;
+       case 'n':
+           opt_n = argto1(optarg, 1, "number of FATs");
+           break;
+       case 'o':
+           opt_o = argto4(optarg, 0, "hidden sectors");
+           oflag = 1;
+           break;
+       case 'r':
+           opt_r = argto2(optarg, 1, "reserved sectors");
+           break;
+       case 's':
+           opt_s = argto4(optarg, 1, "file system size");
+           break;
+       case 'u':
+           opt_u = argto2(optarg, 1, "sectors/track");
+           break;
+       default:
+           usage();
+       }
+    argc -= optind;
+    argv += optind;
+    if (argc < 1 || argc > 2)
+       usage();
+    fname = *argv++;
+    if (!opt_create && !strchr(fname, '/')) {
+       snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname);
+       if (!(fname = strdup(buf)))
+           err(1, "%s", buf);
+    }
+    dtype = *argv;
+    if (opt_create) {
+       if (opt_N)
+           errx(1, "create (-C) is incompatible with -N");
+       fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644);
+       if (fd == -1)
+           errx(1, "failed to create %s", fname);
+       if (ftruncate(fd, opt_create))
+           errx(1, "failed to initialize %jd bytes", (intmax_t)opt_create);
+    } else if ((fd = open(fname, opt_N ? O_RDONLY : O_RDWR)) == -1)
+       err(1, "%s", fname);
+    if (fstat(fd, &sb))
+       err(1, "%s", fname);
+    if (opt_create) {
+       if (!S_ISREG(sb.st_mode))
+           warnx("warning, %s is not a regular file", fname);
+    } else {
+       if (!S_ISCHR(sb.st_mode))
+           warnx("warning, %s is not a character device", fname);
+    }
+    if (!opt_N)
+       check_mounted(fname, sb.st_mode);
+    if (opt_ofs && opt_ofs != lseek(fd, opt_ofs, SEEK_SET))
+       errx(1, "cannot seek to %jd", (intmax_t)opt_ofs);
+    memset(&bpb, 0, sizeof(bpb));
+    if (opt_f) {
+       getstdfmt(opt_f, &bpb);
+       bpb.bsec = bpb.sec;
+       bpb.sec = 0;
+       bpb.bspf = bpb.spf;
+       bpb.spf = 0;
+    }
+    if (opt_h)
+       bpb.hds = opt_h;
+    if (opt_u)
+       bpb.spt = opt_u;
+    if (opt_S)
+       bpb.bps = opt_S;
+    if (opt_s)
+       bpb.bsec = opt_s;
+    if (oflag)
+       bpb.hid = opt_o;
+    if (!(opt_f || (opt_h && opt_u && opt_S && opt_s && oflag))) {
+       off_t delta;
+       getdiskinfo(fd, fname, dtype, oflag, &bpb);
+        if (opt_s) {
+            bpb.bsec = opt_s;
+        }
+       bpb.bsec -= (opt_ofs / bpb.bps);
+       delta = bpb.bsec % bpb.spt;
+       if (delta != 0) {
+           warnx("trim %d sectors from %d to adjust to a multiple of %d",
+               (int)delta, bpb.bsec, bpb.spt);
+           bpb.bsec -= delta;
+       }
+       if (bpb.spc == 0) {     /* set defaults */
+           if (bpb.bsec <= 6000)       /* about 3MB -> 512 bytes */
+               bpb.spc = 1;
+           else if (bpb.bsec <= (1<<17)) /* 64M -> 4k */
+               bpb.spc = 8;
+           else if (bpb.bsec <= (1<<19)) /* 256M -> 8k */
+               bpb.spc = 16;
+           else if (bpb.bsec <= (1<<22)) /* 2G -> 16k, some versions of windows
+                                            require a minimum of 65527 clusters */
+               bpb.spc = 32;
+           else
+               bpb.spc = 64;           /* otherwise 32k */
+       }
+    }
+    if (!powerof2(bpb.bps))
+       errx(1, "bytes/sector (%u) is not a power of 2", bpb.bps);
+    if (bpb.bps < MINBPS)
+       errx(1, "bytes/sector (%u) is too small; minimum is %u",
+            bpb.bps, MINBPS);
+    if (!(fat = opt_F)) {
+       if (opt_f)
+           fat = 12;
+       else if (!opt_e && (opt_i || opt_k))
+           fat = 32;
+    }
+    if ((fat == 32 && opt_e) || (fat != 32 && (opt_i || opt_k)))
+       errx(1, "-%c is not a legal FAT%s option",
+            fat == 32 ? 'e' : opt_i ? 'i' : 'k',
+            fat == 32 ? "32" : "12/16");
+    if (opt_f && fat == 32)
+       bpb.rde = 0;
+    if (opt_b) {
+       if (!powerof2(opt_b))
+           errx(1, "block size (%u) is not a power of 2", opt_b);
+       if (opt_b < bpb.bps)
+           errx(1, "block size (%u) is too small; minimum is %u",
+                opt_b, bpb.bps);
+       if (opt_b > bpb.bps * MAXSPC)
+           errx(1, "block size (%u) is too large; maximum is %u",
+                opt_b, bpb.bps * MAXSPC);
+       bpb.spc = opt_b / bpb.bps;
+    }
+    if (opt_c) {
+       if (!powerof2(opt_c))
+           errx(1, "sectors/cluster (%u) is not a power of 2", opt_c);
+       bpb.spc = opt_c;
+    }
+    if (opt_r)
+       bpb.res = opt_r;
+    if (opt_n) {
+       if (opt_n > MAXNFT)
+           errx(1, "number of FATs (%u) is too large; maximum is %u",
+                opt_n, MAXNFT);
+       bpb.nft = opt_n;
+    }
+    if (opt_e)
+       bpb.rde = opt_e;
+    if (mflag) {
+       if (opt_m < 0xf0)
+           errx(1, "illegal media descriptor (%#x)", opt_m);
+       bpb.mid = opt_m;
+    }
+    if (opt_a)
+       bpb.bspf = opt_a;
+    if (opt_i)
+       bpb.infs = opt_i;
+    if (opt_k)
+       bpb.bkbs = opt_k;
+    bss = 1;
+    bname = NULL;
+    fd1 = -1;
+    if (opt_B) {
+       bname = opt_B;
+       if (!strchr(bname, '/')) {
+           snprintf(buf, sizeof(buf), "/boot/%s", bname);
+           if (!(bname = strdup(buf)))
+               err(1, "%s", buf);
+       }
+       if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb))
+           err(1, "%s", bname);
+       if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bps ||
+           sb.st_size < bpb.bps || sb.st_size > bpb.bps * MAXU16)
+           errx(1, "%s: inappropriate file type or format", bname);
+       bss = sb.st_size / bpb.bps;
+    }
+    if (!bpb.nft)
+       bpb.nft = 2;
+    if (!fat) {
+       if (bpb.bsec < (bpb.res ? bpb.res : bss) +
+           howmany((RESFTE + (bpb.spc ? MINCLS16 : MAXCLS12 + 1)) *
+                   ((bpb.spc ? 16 : 12) / BPN), bpb.bps * NPB) *
+           bpb.nft +
+           howmany(bpb.rde ? bpb.rde : DEFRDE,
+                   bpb.bps / sizeof(struct de)) +
+           (bpb.spc ? MINCLS16 : MAXCLS12 + 1) *
+           (bpb.spc ? bpb.spc : howmany(DEFBLK, bpb.bps)))
+           fat = 12;
+       else if (bpb.rde || bpb.bsec <
+                (bpb.res ? bpb.res : bss) +
+                howmany((RESFTE + MAXCLS16) * 2, bpb.bps) * bpb.nft +
+                howmany(DEFRDE, bpb.bps / sizeof(struct de)) +
+                (MAXCLS16 + 1) *
+                (bpb.spc ? bpb.spc : howmany(8192, bpb.bps)))
+           fat = 16;
+       else
+           fat = 32;
+    }
+    x = bss;
+    if (fat == 32) {
+       if (!bpb.infs) {
+           if (x == MAXU16 || x == bpb.bkbs)
+               errx(1, "no room for info sector");
+           bpb.infs = x;
+       }
+       if (bpb.infs != MAXU16 && x <= bpb.infs)
+           x = bpb.infs + 1;
+       if (!bpb.bkbs) {
+           if (x == MAXU16)
+               errx(1, "no room for backup sector");
+           bpb.bkbs = x;
+       } else if (bpb.bkbs != MAXU16 && bpb.bkbs == bpb.infs)
+           errx(1, "backup sector would overwrite info sector");
+       if (bpb.bkbs != MAXU16 && x <= bpb.bkbs)
+           x = bpb.bkbs + 1;
+    }
+    if (!bpb.res)
+       bpb.res = fat == 32 ? MAX(x, MAX(16384 / bpb.bps, 4)) : x;
+    else if (bpb.res < x)
+       errx(1, "too few reserved sectors");
+    if (fat != 32 && !bpb.rde)
+       bpb.rde = DEFRDE;
+    rds = howmany(bpb.rde, bpb.bps / sizeof(struct de));
+    if (!bpb.spc)
+       for (bpb.spc = howmany(fat == 16 ? DEFBLK16 : DEFBLK, bpb.bps);
+            bpb.spc < MAXSPC &&
+            bpb.res +
+            howmany((RESFTE + maxcls(fat)) * (fat / BPN),
+                    bpb.bps * NPB) * bpb.nft +
+            rds +
+            (u_int64_t)(maxcls(fat) + 1) * bpb.spc <= bpb.bsec;
+            bpb.spc <<= 1);
+    if (fat != 32 && bpb.bspf > MAXU16)
+       errx(1, "too many sectors/FAT for FAT12/16");
+    x1 = bpb.res + rds;
+    x = bpb.bspf ? bpb.bspf : 1;
+    if (x1 + (u_int64_t)x * bpb.nft > bpb.bsec)
+       errx(1, "meta data exceeds file system size");
+    x1 += x * bpb.nft;
+    x = (u_int64_t)(bpb.bsec - x1) * bpb.bps * NPB /
+       (bpb.spc * bpb.bps * NPB + fat / BPN * bpb.nft);
+    x2 = howmany((RESFTE + MIN(x, maxcls(fat))) * (fat / BPN),
+                bpb.bps * NPB);
+    if (!bpb.bspf) {
+       bpb.bspf = x2;
+       x1 += (bpb.bspf - 1) * bpb.nft;
+    }
+    cls = (bpb.bsec - x1) / bpb.spc;
+    x = (u_int64_t)bpb.bspf * bpb.bps * NPB / (fat / BPN) - RESFTE;
+    if (cls > x)
+       cls = x;
+    if (bpb.bspf < x2)
+       warnx("warning: sectors/FAT limits file system to %u clusters",
+             cls);
+    if (cls < mincls(fat))
+       errx(1, "%u clusters too few clusters for FAT%u, need %u", cls, fat,
+           mincls(fat));
+    if (cls > maxcls(fat)) {
+       cls = maxcls(fat);
+       bpb.bsec = x1 + (cls + 1) * bpb.spc - 1;
+       warnx("warning: FAT type limits file system to %u sectors",
+             bpb.bsec);
+    }
+    printf("%s: %u sector%s in %u FAT%u cluster%s "
+          "(%u bytes/cluster)\n", fname, cls * bpb.spc,
+          cls * bpb.spc == 1 ? "" : "s", cls, fat,
+          cls == 1 ? "" : "s", bpb.bps * bpb.spc);
+    if (!bpb.mid)
+       bpb.mid = !bpb.hid ? 0xf0 : 0xf8;
+    if (fat == 32)
+       bpb.rdcl = RESFTE;
+    if (bpb.hid + bpb.bsec <= MAXU16) {
+       bpb.sec = bpb.bsec;
+       bpb.bsec = 0;
+    }
+    if (fat != 32) {
+       bpb.spf = bpb.bspf;
+       bpb.bspf = 0;
+    }
+    print_bpb(&bpb);
+    if (!opt_N) {
+       gettimeofday(&tv, NULL);
+       now = tv.tv_sec;
+       tm = localtime(&now);
+       if (!(img = malloc(bpb.bps)))
+           err(1, "%u", bpb.bps);
+       dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft;
+       for (lsn = 0; lsn < dir + (fat == 32 ? bpb.spc : rds); lsn++) {
+           x = lsn;
+           if (opt_B &&
+               fat == 32 && bpb.bkbs != MAXU16 &&
+               bss <= bpb.bkbs && x >= bpb.bkbs) {
+               x -= bpb.bkbs;
+               if (!x && lseek(fd1, opt_ofs, SEEK_SET))
+                   err(1, "%s", bname);
+           }
+           if (opt_B && x < bss) {
+               if ((n = read(fd1, img, bpb.bps)) == -1)
+                   err(1, "%s", bname);
+               if ((unsigned)n != bpb.bps)
+                   errx(1, "%s: can't read sector %u", bname, x);
+           } else
+               memset(img, 0, bpb.bps);
+           if (!lsn ||
+             (fat == 32 && bpb.bkbs != MAXU16 && lsn == bpb.bkbs)) {
+               x1 = sizeof(struct bs);
+               bsbpb = (struct bsbpb *)(img + x1);
+               mk2(bsbpb->bps, bpb.bps);
+               mk1(bsbpb->spc, bpb.spc);
+               mk2(bsbpb->res, bpb.res);
+               mk1(bsbpb->nft, bpb.nft);
+               mk2(bsbpb->rde, bpb.rde);
+               mk2(bsbpb->sec, bpb.sec);
+               mk1(bsbpb->mid, bpb.mid);
+               mk2(bsbpb->spf, bpb.spf);
+               mk2(bsbpb->spt, bpb.spt);
+               mk2(bsbpb->hds, bpb.hds);
+               mk4(bsbpb->hid, bpb.hid);
+               mk4(bsbpb->bsec, bpb.bsec);
+               x1 += sizeof(struct bsbpb);
+               if (fat == 32) {
+                   bsxbpb = (struct bsxbpb *)(img + x1);
+                   mk4(bsxbpb->bspf, bpb.bspf);
+                   mk2(bsxbpb->xflg, 0);
+                   mk2(bsxbpb->vers, 0);
+                   mk4(bsxbpb->rdcl, bpb.rdcl);
+                   mk2(bsxbpb->infs, bpb.infs);
+                   mk2(bsxbpb->bkbs, bpb.bkbs);
+                   x1 += sizeof(struct bsxbpb);
+               }
+               bsx = (struct bsx *)(img + x1);
+               mk1(bsx->sig, 0x29);
+               if (Iflag)
+                   x = opt_I;
+               else
+                   x = (((u_int)(1 + tm->tm_mon) << 8 |
+                         (u_int)tm->tm_mday) +
+                        ((u_int)tm->tm_sec << 8 |
+                         (u_int)(tv.tv_usec / 10))) << 16 |
+                       ((u_int)(1900 + tm->tm_year) +
+                        ((u_int)tm->tm_hour << 8 |
+                         (u_int)tm->tm_min));
+               mk4(bsx->volid, x);
+               mklabel(bsx->label, opt_L ? opt_L : "NO NAME");
+               sprintf(buf, "FAT%u", fat);
+               setstr(bsx->type, buf, sizeof(bsx->type));
+               if (!opt_B) {
+                   x1 += sizeof(struct bsx);
+                   bs = (struct bs *)img;
+                   mk1(bs->jmp[0], 0xeb);
+                   mk1(bs->jmp[1], x1 - 2);
+                   mk1(bs->jmp[2], 0x90);
+                   setstr(bs->oem, opt_O ? opt_O : "BSD  4.4",
+                          sizeof(bs->oem));
+                   memcpy(img + x1, bootcode, sizeof(bootcode));
+                   mk2(img + MINBPS - 2, DOSMAGIC);
+               }
+           } else if (fat == 32 && bpb.infs != MAXU16 &&
+                      (lsn == bpb.infs ||
+                       (bpb.bkbs != MAXU16 &&
+                        lsn == bpb.bkbs + bpb.infs))) {
+               mk4(img, 0x41615252);
+               mk4(img + MINBPS - 28, 0x61417272);
+               mk4(img + MINBPS - 24, 0xffffffff);
+               mk4(img + MINBPS - 20, bpb.rdcl);
+               mk2(img + MINBPS - 2, DOSMAGIC);
+           } else if (lsn >= bpb.res && lsn < dir &&
+                      !((lsn - bpb.res) %
+                        (bpb.spf ? bpb.spf : bpb.bspf))) {
+               mk1(img[0], bpb.mid);
+               for (x = 1; x < fat * (fat == 32 ? 3 : 2) / 8; x++)
+                   mk1(img[x], fat == 32 && x % 4 == 3 ? 0x0f : 0xff);
+           } else if (lsn == dir && opt_L) {
+               de = (struct de *)img;
+               mklabel(de->namext, opt_L);
+               mk1(de->attr, 050);
+               x = (u_int)tm->tm_hour << 11 |
+                   (u_int)tm->tm_min << 5 |
+                   (u_int)tm->tm_sec >> 1;
+               mk2(de->time, x);
+               x = (u_int)(tm->tm_year - 80) << 9 |
+                   (u_int)(tm->tm_mon + 1) << 5 |
+                   (u_int)tm->tm_mday;
+               mk2(de->date, x);
+           }
+           if ((n = write(fd, img, bpb.bps)) == -1)
+               err(1, "%s", fname);
+           if ((unsigned)n != bpb.bps) {
+               errx(1, "%s: can't write sector %u", fname, lsn);
+                exit(1);
+            }
+       }
+    }
+    return 0;
+}
+
+/*
+ * Exit with error if file system is mounted.
+ */
+static void
+check_mounted(const char *fname, mode_t mode)
+{
+#ifdef TIZEN
+    warnx("Skipping mount checks");
+#else
+    struct statfs *mp;
+    const char *s1, *s2;
+    size_t len;
+    int n, r;
+
+    if (!(n = getmntinfo(&mp, MNT_NOWAIT)))
+       err(1, "getmntinfo");
+    len = strlen(_PATH_DEV);
+    s1 = fname;
+    if (!strncmp(s1, _PATH_DEV, len))
+       s1 += len;
+    r = S_ISCHR(mode) && s1 != fname && *s1 == 'r';
+    for (; n--; mp++) {
+       s2 = mp->f_mntfromname;
+       if (!strncmp(s2, _PATH_DEV, len))
+           s2 += len;
+       if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) ||
+           !strcmp(s1, s2))
+           errx(1, "%s is mounted on %s", fname, mp->f_mntonname);
+    }
+#endif
+}
+
+/*
+ * Get a standard format.
+ */
+static void
+getstdfmt(const char *fmt, struct bpb *bpb)
+{
+    u_int x, i;
+
+    x = sizeof(stdfmt) / sizeof(stdfmt[0]);
+    for (i = 0; i < x && strcmp(fmt, stdfmt[i].name); i++);
+    if (i == x)
+       errx(1, "%s: unknown standard format", fmt);
+    *bpb = stdfmt[i].bpb;
+}
+
+/*
+ * Get disk slice, partition, and geometry information.
+ */
+
+#ifdef TIZEN
+static void
+getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
+           struct bpb *bpb)
+{
+    struct hd_geometry geom;
+
+    if (ioctl(fd, BLKSSZGET, &bpb->bps)) {
+        fprintf(stderr, "Error getting bytes / sector (%s)\n", strerror(errno));
+        exit(1);
+    }
+
+    ckgeom(fname, bpb->bps, "bytes/sector");
+
+    if (ioctl(fd, BLKGETSIZE, &bpb->bsec)) {
+        fprintf(stderr, "Error getting blocksize (%s)\n", strerror(errno));
+        exit(1);
+    }
+
+    if (ioctl(fd, HDIO_GETGEO, &geom)) {
+        fprintf(stderr, "Error getting gemoetry (%s) - trying sane values\n", strerror(errno));
+        geom.heads = 64;
+        geom.sectors = 63;
+    }
+
+    if (!geom.heads) {
+        printf("Bogus heads from kernel - setting sane value\n");
+        geom.heads = 64;
+    }
+
+    if (!geom.sectors) {
+        printf("Bogus sectors from kernel - setting sane value\n");
+        geom.sectors = 63;
+    }
+
+    bpb->spt = geom.sectors;
+    ckgeom(fname, bpb->spt, "sectors/track");
+
+    bpb->hds = geom.heads;
+    ckgeom(fname, bpb->hds, "drive heads");
+}
+
+#else
+
+static void
+getdiskinfo(int fd, const char *fname, const char *dtype, __unused int oflag,
+           struct bpb *bpb)
+{
+    struct disklabel *lp, dlp;
+    struct fd_type type;
+    off_t ms, hs = 0;
+
+    lp = NULL;
+
+    /* If the user specified a disk type, try to use that */
+    if (dtype != NULL) {
+       lp = getdiskbyname(dtype);
+    }
+
+    /* Maybe it's a floppy drive */
+    if (lp == NULL) {
+       if (ioctl(fd, DIOCGMEDIASIZE, &ms) == -1) {
+           struct stat st;
+
+           if (fstat(fd, &st))
+               err(1, "Cannot get disk size");
+           /* create a fake geometry for a file image */
+           ms = st.st_size;
+           dlp.d_secsize = 512;
+           dlp.d_nsectors = 63;
+           dlp.d_ntracks = 255;
+           dlp.d_secperunit = ms / dlp.d_secsize;
+           lp = &dlp;
+       } else if (ioctl(fd, FD_GTYPE, &type) != -1) {
+           dlp.d_secsize = 128 << type.secsize;
+           dlp.d_nsectors = type.sectrac;
+           dlp.d_ntracks = type.heads;
+           dlp.d_secperunit = ms / dlp.d_secsize;
+           lp = &dlp;
+       }
+    }
+
+    /* Maybe it's a fixed drive */
+    if (lp == NULL) {
+       if (ioctl(fd, DIOCGDINFO, &dlp) == -1) {
+           if (bpb->bps == 0 && ioctl(fd, DIOCGSECTORSIZE, &dlp.d_secsize) == -1)
+               errx(1, "Cannot get sector size, %s", strerror(errno));
+
+           /* XXX Should we use bpb->bps if it's set? */
+           dlp.d_secperunit = ms / dlp.d_secsize;
+
+           if (bpb->spt == 0 && ioctl(fd, DIOCGFWSECTORS, &dlp.d_nsectors) == -1) {
+               warnx("Cannot get number of sectors per track, %s", strerror(errno));
+               dlp.d_nsectors = 63;
+           }
+           if (bpb->hds == 0 && ioctl(fd, DIOCGFWHEADS, &dlp.d_ntracks) == -1) {
+               warnx("Cannot get number of heads, %s", strerror(errno));
+               if (dlp.d_secperunit <= 63*1*1024)
+                   dlp.d_ntracks = 1;
+               else if (dlp.d_secperunit <= 63*16*1024)
+                   dlp.d_ntracks = 16;
+               else
+                   dlp.d_ntracks = 255;
+           }
+       }
+
+       hs = (ms / dlp.d_secsize) - dlp.d_secperunit;
+       lp = &dlp;
+    }
+
+    if (bpb->bps == 0)
+       bpb->bps = ckgeom(fname, lp->d_secsize, "bytes/sector");
+    if (bpb->spt == 0)
+       bpb->spt = ckgeom(fname, lp->d_nsectors, "sectors/track");
+    if (bpb->hds == 0)
+       bpb->hds = ckgeom(fname, lp->d_ntracks, "drive heads");
+    if (bpb->bsec == 0)
+       bpb->bsec = lp->d_secperunit;
+    if (bpb->hid == 0)
+       bpb->hid = hs;
+}
+#endif
+
+/*
+ * Print out BPB values.
+ */
+static void
+print_bpb(struct bpb *bpb)
+{
+    printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res,
+          bpb->nft);
+    if (bpb->rde)
+       printf(" rde=%u", bpb->rde);
+    if (bpb->sec)
+       printf(" sec=%u", bpb->sec);
+    printf(" mid=%#x", bpb->mid);
+    if (bpb->spf)
+       printf(" spf=%u", bpb->spf);
+    printf(" spt=%u hds=%u hid=%u", bpb->spt, bpb->hds, bpb->hid);
+    if (bpb->bsec)
+       printf(" bsec=%u", bpb->bsec);
+    if (!bpb->spf) {
+       printf(" bspf=%u rdcl=%u", bpb->bspf, bpb->rdcl);
+       printf(" infs=");
+       printf(bpb->infs == MAXU16 ? "%#x" : "%u", bpb->infs);
+       printf(" bkbs=");
+       printf(bpb->bkbs == MAXU16 ? "%#x" : "%u", bpb->bkbs);
+    }
+    printf("\n");
+}
+
+/*
+ * Check a disk geometry value.
+ */
+static u_int
+ckgeom(const char *fname, u_int val, const char *msg)
+{
+    if (!val)
+       errx(1, "%s: no default %s", fname, msg);
+    if (val > MAXU16)
+       errx(1, "%s: illegal %s %d", fname, msg, val);
+    return val;
+}
+
+/*
+ * Convert and check a numeric option argument.
+ */
+static u_int
+argtou(const char *arg, u_int lo, u_int hi, const char *msg)
+{
+    char *s;
+    u_long x;
+
+    errno = 0;
+    x = strtoul(arg, &s, 0);
+    if (errno || !*arg || *s || x < lo || x > hi)
+       errx(1, "%s: bad %s", arg, msg);
+    return x;
+}
+
+/*
+ * Same for off_t, with optional skmgpP suffix
+ */
+static off_t
+argtooff(const char *arg, const char *msg)
+{
+    char *s;
+    off_t x;
+
+    x = strtoll(arg, &s, 0);
+    /* allow at most one extra char */
+    if (errno || x < 0 || (s[0] && s[1]) )
+       errx(1, "%s: bad %s", arg, msg);
+    if (*s) {  /* the extra char is the multiplier */
+       switch (*s) {
+       default:
+           errx(1, "%s: bad %s", arg, msg);
+           /* notreached */
+       
+       case 's':       /* sector */
+       case 'S':
+           x <<= 9;    /* times 512 */
+           break;
+
+       case 'k':       /* kilobyte */
+       case 'K':
+           x <<= 10;   /* times 1024 */
+           break;
+
+       case 'm':       /* megabyte */
+       case 'M':
+           x <<= 20;   /* times 1024*1024 */
+           break;
+
+       case 'g':       /* gigabyte */
+       case 'G':
+           x <<= 30;   /* times 1024*1024*1024 */
+           break;
+
+       case 'p':       /* partition start */
+       case 'P':       /* partition start */
+       case 'l':       /* partition length */
+       case 'L':       /* partition length */
+           errx(1, "%s: not supported yet %s", arg, msg);
+           /* notreached */
+       }
+    }
+    return x;
+}
+
+/*
+ * Check a volume label.
+ */
+static int
+oklabel(const char *src)
+{
+    int c, i;
+
+    for (i = 0; i <= 11; i++) {
+       c = (u_char)*src++;
+       if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c))
+           break;
+    }
+    return i && !c;
+}
+
+/*
+ * Make a volume label.
+ */
+static void
+mklabel(u_int8_t *dest, const char *src)
+{
+    int c, i;
+
+    for (i = 0; i < 11; i++) {
+       c = *src ? toupper(*src++) : ' ';
+       *dest++ = !i && c == '\xe5' ? 5 : c;
+    }
+}
+
+/*
+ * Copy string, padding with spaces.
+ */
+static void
+setstr(u_int8_t *dest, const char *src, size_t len)
+{
+    while (len--)
+       *dest++ = *src ? *src++ : ' ';
+}
+
+/*
+ * Print usage message.
+ */
+static void
+usage(void)
+{
+       fprintf(stderr,
+           "usage: newfs_msdos [ -options ] special [disktype]\n"
+           "where the options are:\n"
+           "\t-@ create file system at specified offset\n"                         
+           "\t-B get bootstrap from file\n"
+           "\t-C create image file with specified size\n"
+           "\t-F FAT type (12, 16, or 32)\n"
+           "\t-I volume ID\n"
+           "\t-L volume label\n"
+           "\t-N don't create file system: just print out parameters\n"
+           "\t-O OEM string\n"
+           "\t-S bytes/sector\n"
+           "\t-a sectors/FAT\n"
+           "\t-b block size\n"
+           "\t-c sectors/cluster\n"
+           "\t-e root directory entries\n"
+           "\t-f standard format\n"
+           "\t-h drive heads\n"
+           "\t-i file system info sector\n"
+           "\t-k backup boot sector\n"
+           "\t-m media descriptor\n"
+           "\t-n number of FATs\n"
+           "\t-o hidden sectors\n"
+           "\t-r reserved sectors\n"
+           "\t-s file system size (sectors)\n"
+           "\t-u sectors/track\n");
+       exit(1);
+}
diff --git a/src/ode/noti.c b/src/ode/noti.c
new file mode 100644 (file)
index 0000000..4a7227c
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 "core/log.h"
+#include "core/edbus-handler.h"
+#include "noti.h"
+
+#define METHOD_COMPLETE_NOTI_ON                "CompNotiOn"
+#define METHOD_PROGRESS_NOTI_ON                "ProgNotiOn"
+#define METHOD_PROGRESS_NOTI_OFF       "ProgNotiOff"
+#define METHOD_PROGRESS_NOTI_UPDATE    "ProgNotiUpdate"
+#define METHOD_ERROR_NOTI_ON           "ErrorNotiOn"
+#define METHOD_ERROR_NOTI_OFF          "ErrorNotiOff"
+
+#define RETRY_CNT      3
+
+static const char *ode_type_str[] = {
+       [ENCRYPT_TYPE] = "encrypt",
+       [DECRYPT_TYPE] = "decrypt",
+};
+
+static int progress_h;
+static int error_h;
+
+static int method_noti(const char *method, const char *sig, char *param[])
+{
+       int ret, retry = RETRY_CNT;
+
+       while (retry--) {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_ODE,
+                               POPUP_INTERFACE_ODE,
+                               method,
+                               sig, param);
+               if (ret > 0)
+                       break;
+       }
+
+       return ret;
+}
+
+int noti_progress_show(int type)
+{
+       char str_type[32];
+       char *arr[1];
+       int ret;
+
+       /* If ongoing noti already exists, delete the noti */
+       if (progress_h > 0)
+               noti_progress_clear();
+
+       /* If error noti already exists, delete the noti */
+       if (error_h > 0)
+               noti_error_clear();
+
+       snprintf(str_type, sizeof(str_type), "%s", ode_type_str[type]);
+       arr[0] = str_type;
+
+       ret = method_noti(METHOD_PROGRESS_NOTI_ON, "s", arr);
+       if (ret < 0)
+               return ret;
+
+       progress_h = ret;
+       _D("insert progress noti handle : %d", progress_h);
+       return 0;
+}
+
+int noti_progress_clear(void)
+{
+       char str_h[32];
+       char *arr[1];
+       int ret;
+
+       if (progress_h <= 0) {
+               _D("already ongoing noti clear");
+               return 0;
+       }
+
+       snprintf(str_h, sizeof(str_h), "%d", progress_h);
+       arr[0] = str_h;
+
+       ret = method_noti(METHOD_PROGRESS_NOTI_OFF, "i", arr);
+       if (ret != 0)
+               return ret;
+
+       _D("delete progress noti handle : %d", progress_h);
+       progress_h = 0;
+       return 0;
+}
+
+int noti_progress_update(int rate)
+{
+       char str_h[32];
+       char str_r[32];
+       char *arr[2];
+
+       if (progress_h <= 0) {
+               _E("need to create notification");
+               return -ENOENT;
+       }
+
+       if (rate < 0 || rate > 100) {
+               _E("Invalid parameter");
+               return -EINVAL;
+       }
+
+       snprintf(str_h, sizeof(str_h), "%d", progress_h);
+       arr[0] = str_h;
+       snprintf(str_r, sizeof(str_r), "%d", rate);
+       arr[1] = str_r;
+
+       return method_noti(METHOD_PROGRESS_NOTI_UPDATE, "ii", arr);
+}
+
+int noti_finish_show(int type)
+{
+       char str_type[32];
+       char *arr[1];
+       int ret;
+
+       snprintf(str_type, sizeof(str_type), "%s", ode_type_str[type]);
+       arr[0] = str_type;
+
+       return method_noti(METHOD_COMPLETE_NOTI_ON, "s", arr);
+}
+
+int noti_error_show(int type, int state, int val)
+{
+       char str_type[32], str_state[32], str_val[32];
+       char *arr[3];
+       int ret;
+
+       /* If ongoing noti already exists, delete the noti */
+       if (error_h > 0)
+               noti_error_clear();
+
+       snprintf(str_type, sizeof(str_type), "%s", ode_type_str[type]);
+       arr[0] = str_type;
+       snprintf(str_state, sizeof(str_state), "%d", state);
+       arr[1] = str_state;
+       snprintf(str_val, sizeof(str_val), "%d", val);
+       arr[2] = str_val;
+
+       ret = method_noti(METHOD_ERROR_NOTI_ON, "sii", arr);
+       if (ret < 0)
+               return ret;
+
+       error_h = ret;
+       _D("insert error noti handle : %d", error_h);
+       return 0;
+}
+
+int noti_error_clear(void)
+{
+       char str_h[32];
+       char *arr[1];
+       int ret;
+
+       if (error_h <= 0) {
+               _D("already ongoing noti clear");
+               return 0;
+       }
+
+       snprintf(str_h, sizeof(str_h), "%d", error_h);
+       arr[0] = str_h;
+
+       ret = method_noti(METHOD_ERROR_NOTI_OFF, "i", arr);
+       if (ret != 0)
+               return ret;
+
+       _D("delete error noti handle : %d", error_h);
+       error_h = 0;
+       return 0;
+}
similarity index 64%
rename from src/core/emulator.h
rename to src/ode/noti.h
index 71a5edf..145b62d 100644 (file)
  */
 
 
-#ifndef __EMULATOR_H__
-#define __EMULATOR_H__
+#ifndef __NOTI_H__
+#define __NOTI_H__
 
-#include "noti.h"
+enum ode_type {
+       ENCRYPT_TYPE,
+       DECRYPT_TYPE,
+};
 
-#ifdef MOBILE_EMULATOR
-static inline int emulator_add_callback(const char *noti,
-    void (*cb) (void *), void *data)
-{
-       return noti_add(noti, cb, data);
-}
-#else
-#define emulator_add_callback(a, b, c) do { } while (0)
-#endif
+enum ode_error_state {
+       NOT_ENOUGH_SPACE,
+       OPERATION_FAIL,
+};
+
+int noti_progress_show(int type);
+int noti_progress_clear(void);
+int noti_progress_update(int rate);
+int noti_finish_show(int type);
+int noti_error_show(int type, int state, int val);
+int noti_error_clear(void);
 
 #endif
diff --git a/src/ode/ode.c b/src/ode/ode.c
new file mode 100755 (executable)
index 0000000..8a61272
--- /dev/null
@@ -0,0 +1,529 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <stdlib.h>
+#include <vconf.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/mount.h>
+#include <errno.h>
+#include <mntent.h>
+
+#include "display/poll.h"
+#include "display/core.h"
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "core/common.h"
+#include "ode.h"
+#include "noti.h"
+#include "mmc/mmc-handler.h"
+
+#define SIGNAL_REQUEST_GENERAL_MOUNT           "RequestGeneralMount"
+#define SIGNAL_REQUEST_ODE_MOUNT                       "RequestOdeMount"
+#define SIGNAL_REQUEST_REMOVE_ERROR_NOTI       "RequestRemoveErrorNoti"
+#define SIGNAL_REMOVE_MMC                                      "RemoveMmc"
+
+#define VCONFKEY_ENCRYPT_NEEDED_SIZE           "db/sde/encrypt_size"
+
+#define ODE_CRYPT_META_FILE ".MetaEcfsFile"
+#define ODE_CRYPT_PROGRESS_FILE ".EncOngoing"
+#define ODE_VERIFY_ENC_KEY     "/opt/etc/edk_p_sd"
+
+#define PWLOCK_LAUNCH_NAME     "launch-app"
+#define PWLOCK_NAME            "pwlock"
+
+enum ode_progress_id {
+       ENCRYPT_START,
+       DECRYPT_START,
+       ENCRYPT_MOUNTED,
+       ODE_PROGRESS_MAX,
+};
+
+/* EN_DEV : Enable device policy
+ * DE_DEV : Disable device policy
+ * EN_MMC : Encrypted mmc
+ * DE_MMC : Decrypted mmc
+ * NO_MMC : no mmc
+ */
+enum ode_state {
+       ENCRYPTED_DEVICE_ENCRYPTED_MMC = 0,                     /* device policy ENABLE, mmc encryption ENABLE */
+       ENCRYPTED_DEVICE_DECRYPTED_MMC,
+       ENCRPYTED_DEVICE_NO_MMC,
+       DECRYPTED_DEVICE_ENCRYPTED_MMC,
+       DECRPYTED_DEVICE_DECRYPTED_MMC,
+       ENCRYPT_ONGOING,
+};
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static const char *ode_state_str[] = {
+       [ENCRYPTED_DEVICE_ENCRYPTED_MMC] = "ENCRYPTED_DEVICE_ENCRYPTED_MMC",
+       [ENCRYPTED_DEVICE_DECRYPTED_MMC] = "ENCRYPTED_DEVICE_DECRYPTED_MMC",
+       [ENCRPYTED_DEVICE_NO_MMC] = "ENCRPYTED_DEVICE_NO_MMC",
+       [DECRYPTED_DEVICE_ENCRYPTED_MMC] = "DECRYPTED_DEVICE_ENCRYPTED_MMC",
+       [DECRPYTED_DEVICE_DECRYPTED_MMC] = "DECRPYTED_DEVICE_DECRYPTED_MMC",
+       [ENCRYPT_ONGOING] = "ENCRYPT_OR_DECRYPT_ONGOING",
+};
+
+static int display_state = S_NORMAL;
+static int ode_display_changed(void *data)
+{
+       enum state_t state = (enum state_t)data;
+       char *str;
+       int rate;
+       if (display_state == S_LCDOFF && (state == S_NORMAL || state == S_LCDDIM)) {
+               str = vconf_get_str(VCONFKEY_SDE_ENCRYPT_PROGRESS);
+               if (str) {
+                       rate = atoi(str);
+                       if (rate >= 0 && rate <  100)
+                               noti_progress_update(rate);
+               }
+       }
+       display_state = state;
+       return 0;
+}
+
+static int ode_check_encrypt_sdcard()
+{
+       int ret = 0;
+       struct stat src_stat, enc_stat;
+       const char * cryptTempFile = ODE_CRYPT_META_FILE;
+       const char * cryptProgressFile = ODE_CRYPT_PROGRESS_FILE;
+       char *mMetaDataFile;
+
+       mMetaDataFile = malloc(strlen (MMC_MOUNT_POINT) + strlen (cryptTempFile) +2);
+       if (mMetaDataFile)
+       {
+               sprintf (mMetaDataFile, "%s%s%s", MMC_MOUNT_POINT, "/", cryptTempFile);
+               if (lstat (mMetaDataFile, &src_stat) < 0)
+                       if (errno == ENOENT)
+                               ret = -1;
+               free(mMetaDataFile);
+       }
+       if (!ret && lstat (ODE_VERIFY_ENC_KEY, &enc_stat) < 0)
+               if (errno == ENOENT)
+                       ret = -1;
+       _D("check sd card ecryption : %d", ret);
+       return ret;
+}
+
+static int ode_check_encrypt_progress()
+{
+       int ret = 0;
+       struct stat src_stat;
+       const char * cryptProgressFile = ODE_CRYPT_PROGRESS_FILE;
+       char *mMetaDataFile;
+
+       mMetaDataFile = malloc(strlen (MMC_MOUNT_POINT) + strlen (cryptProgressFile) +2);
+       if (mMetaDataFile)
+       {
+               sprintf (mMetaDataFile, "%s%s%s", MMC_MOUNT_POINT, "/", cryptProgressFile);
+               if (lstat (mMetaDataFile, &src_stat) == 0)
+                       ret = -1;
+               free(mMetaDataFile);
+       }
+       return ret;
+}
+
+static int ode_check_ecryptfs(char* path)
+{
+       int ret = false;
+       struct mntent* mnt;
+       const char* table = "/etc/mtab";
+       FILE* fp;
+       fp = setmntent(table, "r");
+       if (!fp)
+               return ret;
+       while (mnt=getmntent(fp)) {
+               if (!strcmp(mnt->mnt_type, "ecryptfs") && !strcmp(mnt->mnt_dir, path)) {
+                       ret = true;
+                       break;
+               }
+       }
+       endmntent(fp);
+       return ret;
+}
+
+static int ode_unmount_encrypt_sdcard(char* path)
+{
+       int result = 0;
+       if ( ode_check_ecryptfs(path)) {
+               if(umount2(path, MNT_DETACH) != 0) {
+                       if(umount2(path, MNT_EXPIRE) != 0) {
+                               _E("Unmount failed for drive %s err(%d %s)\n", path, errno, strerror(errno));
+                               if(errno == EAGAIN) {
+                                       SLOGE("Trying Unmount again\n");
+                                       if(umount2(path, MNT_EXPIRE) != 0) {
+                                               result = -1;
+                                               _E("Unmount failed for drive %s err(%d %s)\n", path, errno, strerror(errno));
+                                       }
+                               } else {
+                                       _E("Drive %s unmounted failed \n", path);
+                                       result = -1;
+                               }
+                       }
+               }
+               if (result == 0)
+                       _D("Drive %s unmounted successfully \n", path);
+       }
+       return result;
+}
+
+static void launch_syspopup(const char *option)
+{
+       int r;
+       char str[256];
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       snprintf(str, sizeof(str), "%s%s", "ode", option);
+
+       FIND_DEVICE_VOID(apps, "apps");
+
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return;
+       }
+       params->name = MMC_POPUP_NAME;
+       params->key = POPUP_KEY_CONTENT;
+       params->value = strdup(str);
+       apps->init((void *)params);
+       free(params);
+       return;
+}
+
+static int ode_check_error_state(void)
+{
+       char *str;
+       int type, state, val, r;
+
+       /* get progress value */
+       str = vconf_get_str(VCONFKEY_SDE_ENCRYPT_PROGRESS);
+       if (str) {
+               if (strcmp(str, "-1")) {        /* normal state */
+                       free(str);
+                       return 0;
+               } else                                          /* error state */
+                       free(str);
+       }
+
+       /* get memory size */
+       r = vconf_get_int(VCONFKEY_ENCRYPT_NEEDED_SIZE, &val);
+       /* get crypto state */
+       str = vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
+       if (r == 0 && val == 0) {
+               state = OPERATION_FAIL;
+               if (!strcmp(str, "encryption_start"))
+                       type = ENCRYPT_TYPE;
+               else
+                       type = DECRYPT_TYPE;
+       }
+       else {
+               state = NOT_ENOUGH_SPACE;
+               if (!strcmp(str, "unencrypted"))
+                       type = ENCRYPT_TYPE;
+               else
+                       type = DECRYPT_TYPE;
+       }
+
+       free(str);
+
+       /* get memory size */
+       r = vconf_get_int(VCONFKEY_ENCRYPT_NEEDED_SIZE, &val);
+       if (r == 0 && val == 0)
+               state = OPERATION_FAIL;
+       else
+               state = NOT_ENOUGH_SPACE;
+
+       noti_error_show(type, state, val);
+       return -EPERM;
+}
+
+int ode_judge_state(void)
+{
+       int dev, mmc_en;
+       int r;
+       char *en_state;
+
+       if (vconf_get_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, &dev) < 0) {
+               _E("fail to get ode policy vconf");
+               return -EPERM;
+       }
+
+       en_state = vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
+       if (en_state) {
+               if (ode_check_encrypt_progress() &&
+                           (!strcmp(en_state, "encryption_start")  || !strcmp(en_state, "decryption_start"))) {
+                       r = ENCRYPT_ONGOING;
+                       _I("ODE state : %s(%d)", ode_state_str[r], r);
+                       free(en_state);
+                       return r;
+               } else
+                       free(en_state);
+       }
+
+       mmc_en = ode_check_encrypt_sdcard();
+
+       /* although mmc does not exist, this api will return ENCRYPTED_DEVICE_DECRYPTED_MMC */
+       if (dev && mmc_en)
+               r = ENCRYPTED_DEVICE_DECRYPTED_MMC;
+       else if (dev && !mmc_en)
+               r = ENCRYPTED_DEVICE_ENCRYPTED_MMC;
+       else if (!dev && !mmc_en)
+               r = DECRYPTED_DEVICE_ENCRYPTED_MMC;
+       else
+               r = DECRPYTED_DEVICE_DECRYPTED_MMC;
+
+       _I("ODE state : %s(%d)", ode_state_str[r], r);
+       return r;
+}
+
+static void launch_pwlock(void)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       FIND_DEVICE_VOID(apps, "apps");
+
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return;
+       }
+       params->name = PWLOCK_LAUNCH_NAME;
+       params->key = PWLOCK_NAME;
+       apps->init((void *)params);
+       free(params);
+}
+
+int ode_launch_app(int state)
+{
+       switch (state) {
+       case ENCRYPTED_DEVICE_DECRYPTED_MMC: launch_syspopup("encrypt"); break;
+       case DECRYPTED_DEVICE_ENCRYPTED_MMC: launch_syspopup("decrypt"); break;
+       case ENCRYPTED_DEVICE_ENCRYPTED_MMC:
+       case ENCRYPT_ONGOING:
+               launch_pwlock();
+               break;
+       default: break;
+       }
+       return 0;
+}
+
+static void progress_start(void *value)
+{
+       pm_lock_internal(1, LCD_OFF, STAY_CUR_STATE, 0);
+       register_notifier(DEVICE_NOTIFIER_LCD, ode_display_changed);
+       noti_progress_show((int)value);
+       _D("progress start : type(%d)", (int)value);
+}
+
+static void progress_finish(int rate)
+{
+       char *str;
+       int ret;
+
+       pm_unlock_internal(1, LCD_OFF, PM_SLEEP_MARGIN);
+       unregister_notifier(DEVICE_NOTIFIER_LCD, ode_display_changed);
+       noti_progress_clear();
+       _D("progress finish");
+
+       /* in case of error state */
+       ret = ode_check_error_state();
+       if (ret < 0)
+               return;
+
+       /* when finished to encrypt or decrypt, update mount vconf in this time */
+       mmc_mount_done();
+
+       str = vconf_get_str(VCONFKEY_SDE_CRYPTO_STATE);
+       if (!strcmp(str, "encrypted")) {
+               noti_finish_show(ENCRYPT_TYPE);
+               vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, true);
+       }
+       else if (!strcmp(str, "unencrypted")) {
+               noti_finish_show(DECRYPT_TYPE);
+               vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, false);
+       }
+
+       free(str);
+}
+
+static void ode_mount(void *value)
+{
+       mmc_mount_done();
+       _D("set mount complete vconf");
+}
+
+static struct ode_progress_cb {
+       const char *str;
+       void (*func) (void *value);
+       void *value;
+} ode_progress[ODE_PROGRESS_MAX] = {
+       [ENCRYPT_START] = {"encryption_start", progress_start, (void*)ENCRYPT_TYPE},
+       [DECRYPT_START] = {"decryption_start", progress_start, (void*)DECRYPT_TYPE},
+       [ENCRYPT_MOUNTED] = {"mounted", ode_mount, NULL},
+};
+
+static void ode_crypto_state_cb(keynode_t *key, void* data)
+{
+       char *str;
+       int i;
+
+       str = vconf_keynode_get_str(key);
+       if (!str)
+               return;
+
+       for (i = 0; i < ODE_PROGRESS_MAX; ++i) {
+               if (!strcmp(str, ode_progress[i].str)) {
+                       if (ode_progress[i].func)
+                               ode_progress[i].func(ode_progress[i].value);
+                       break;
+               }
+       }
+}
+
+static void ode_crypto_progress_cb(keynode_t *key, void* data)
+{
+       char *str;
+       int rate;
+
+       str = vconf_keynode_get_str(key);
+       if (!str)
+               return;
+
+       rate = atoi(str);
+
+       if (display_state == S_NORMAL || display_state == S_LCDDIM)
+               noti_progress_update(rate);
+       _D("progress update : rate(%d)", rate);
+
+       if (rate == 100 || rate < 0)
+               progress_finish(rate);
+}
+
+static void ode_request_general_mount(void *data, DBusMessage *msg)
+{
+       mmc_mount_done();
+       vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, false);
+       _D("ode_request_general_mount occurs!!!");
+}
+
+static void ode_request_ode_mount(void *data, DBusMessage *msg)
+{
+       launch_pwlock();
+       vconf_set_bool(VCONFKEY_SETAPPL_MMC_ENCRYPTION_STATUS_BOOL, true);
+       _D("ode_request_ode_mount occurs!!!");
+}
+
+static void ode_request_remove_error_noti(void *data, DBusMessage *msg)
+{
+       if (noti_error_clear() < 0)
+               _E("Failed to remove error notification");
+}
+
+int ode_mmc_removed(void)
+{
+       int r;
+
+       r = ode_unmount_encrypt_sdcard(MMC_MOUNT_POINT);
+       if (r < 0)
+               _E("fail to sde_crypto_unmount");
+
+       /* delete error noti */
+       noti_error_clear();
+
+       /* send signal to syspopup for deleting a popup when removed mmc */
+       broadcast_edbus_signal(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
+                       SIGNAL_REMOVE_MMC, NULL, NULL);
+       return r;
+}
+
+int ode_mmc_inserted(void)
+{
+       int op;
+
+       op = ode_judge_state();
+       switch (op) {
+       case ENCRYPTED_DEVICE_ENCRYPTED_MMC:
+       case DECRYPTED_DEVICE_ENCRYPTED_MMC:
+               vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "encrypted");
+               break;
+       case ENCRYPT_ONGOING:
+               break;
+       default:
+               vconf_set_str(VCONFKEY_SDE_CRYPTO_STATE, "unencrypted");
+               break;
+       }
+
+       if (op != DECRPYTED_DEVICE_DECRYPTED_MMC) {
+               ode_launch_app(op);
+               return -1;
+       }
+
+       return 0;
+}
+
+static void ode_internal_init(void *data)
+{
+       /* init dbus interface */
+       register_edbus_signal_handler(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
+                       SIGNAL_REQUEST_GENERAL_MOUNT,
+                       ode_request_general_mount);
+       register_edbus_signal_handler(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
+                       SIGNAL_REQUEST_ODE_MOUNT,
+                       ode_request_ode_mount);
+       register_edbus_signal_handler(DEVICED_PATH_ODE, DEVICED_INTERFACE_ODE,
+                       SIGNAL_REQUEST_REMOVE_ERROR_NOTI,
+                       ode_request_remove_error_noti);
+
+
+       /* register vconf callback */
+       vconf_notify_key_changed(VCONFKEY_SDE_CRYPTO_STATE,
+                       ode_crypto_state_cb, NULL);
+       vconf_notify_key_changed(VCONFKEY_SDE_ENCRYPT_PROGRESS,
+                       ode_crypto_progress_cb, NULL);
+}
+
+static void ode_internal_exit(void *data)
+{
+       /* unregister vconf callback */
+       vconf_ignore_key_changed(VCONFKEY_SDE_CRYPTO_STATE,
+                       ode_crypto_state_cb);
+       vconf_ignore_key_changed(VCONFKEY_SDE_ENCRYPT_PROGRESS,
+                       ode_crypto_progress_cb);
+}
+
+static const struct device_ops ode_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "ode",
+       .init     = ode_internal_init,
+       .exit     = ode_internal_exit,
+};
+
+DEVICE_OPS_REGISTER(&ode_device_ops)
similarity index 81%
rename from src/core/core.h
rename to src/ode/ode.h
index 0ae3bbc..b57a523 100644 (file)
  */
 
 
-#ifndef __DD_CORE_H__
-#define __DD_CORE_H__
+#ifndef __ODE_H__
+#define __ODE_H__
 
-#include "data.h"
+int ode_mmc_inserted(void);
+int ode_mmc_removed(void);
 
-int core_action_run();
-int core_action_clear(int pid);
-
-#endif /* __DD_CORE_H__ */
+#endif
diff --git a/src/pass/pass-core.c b/src/pass/pass-core.c
new file mode 100644 (file)
index 0000000..63dcd10
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "pass.h"
+#include "pass-gov.h"
+#include "pass-hotplug.h"
+
+#include "core/device-notifier.h"
+#include "core/config-parser.h"
+
+#define PASS_CPU_STATS_MAX_COUNT       20
+
+/*
+ * is_enabled - Check the state of PASS governor
+ * @policy: instance of pass_policy structure
+ *
+ * Return true if the state of PASS is PASS_GOV_START
+ * Return false if the state of PASS is PASS_GOV_STOP
+ */
+static bool is_enabled(struct pass_policy *policy)
+{
+       if (!policy)
+               return false;
+
+       if (policy->gov_state != PASS_GOV_START)
+               return false;
+
+       return true;
+}
+
+/****************************************************************************
+ *                             PASS Notifier                                *
+ * - DEVICE_NOTIFIER_PMQOS                                                  *
+ * - DEVICE_NOTIFIER_BOOTING_DONE                                           *
+ ****************************************************************************/
+#define PASS_LOCK                      "Lock"
+#define PASS_UNLOCK                    "Unlock"
+
+static int pass_governor_change_level_scope(struct pass_policy *policy,
+                                           int min_level, int max_level);
+
+/*
+ * FIXME: Current notifier of deviced didn't pass separate user_data parameter
+ * on callback function. So, PASS must need global pass_policy instance. This
+ * code must be modified after changing deviced's notifier feature.
+ */
+static struct pass_policy *policy_pmqos;
+
+/*
+ * is_pmqos_enabled - Check state of whether to support PM_QOS for scenario
+ * @policy: instance of pass_policy structure
+ *
+ * Return true if the state of PM_QOS is supported
+ * Return false if the state of PM_QOS isn't supported
+ */
+static bool is_pmqos_enabled(struct pass_policy *policy)
+{
+       if (!policy)
+               return false;
+
+       if (!policy->scenario.list)
+               return false;
+
+       if (policy->scenario.state != PASS_ON)
+               return false;
+
+       return true;
+}
+
+/*
+ * is_scenario_locked - Check locked state of each scenario
+ * @policy: instance of pass_scenario structure
+ *
+ * Return true if scenario is locked and enabled
+ * Return false if scenario is unlocked or disabled
+ */
+
+static bool is_scenario_locked(struct pass_scenario *scn)
+{
+       if (!scn)
+               return false;
+
+       if (!scn->locked || scn->state != PASS_ON)
+               return false;
+
+       return true;
+}
+
+static enum pass_state is_pmqos_locked(char *data, char *name)
+{
+       char *unlock = NULL;
+
+       if (!data)
+               return PASS_OFF;
+
+       unlock = strstr(data, PASS_UNLOCK);
+       if (!unlock) {
+               /* Lock scenario */
+               strncpy(name, data, strlen(data) - strlen(PASS_LOCK));
+               return PASS_ON;
+       } else {
+               /* Unlock scenario */
+               strncpy(name, data, strlen(data) - strlen(PASS_UNLOCK));
+               return PASS_OFF;
+       }
+}
+
+static int find_scenario_index(struct pass_scenario_policy *scenario,
+                              char *name)
+{
+       int index;
+
+       for (index = 0; index < scenario->num_scenarios; index++)
+               if (MATCH(scenario->list[index].name, name))
+                       return index;
+
+       return -EINVAL;
+}
+
+/*
+ * pass_notifier_pmqos - Callback function of DEVICE_NOTIFIER_PMQOS notifier
+ * @data: the scenario name
+ */
+static int pass_notifier_pmqos(void *data)
+{
+       struct pass_policy *policy = policy_pmqos;
+       struct pass_scenario_policy *scenario = &policy->scenario;
+       struct pass_scenario *scn = NULL;
+       enum pass_state locked = PASS_UNUSED;
+       char name[PASS_NAME_LEN] = {""};
+       unsigned int cpufreq_min_level = 0;
+       unsigned int cpufreq_max_level = 0;
+       int count = 0;
+       int index = -1;
+       int i;
+
+       if (!is_enabled(policy))
+               return 0;
+
+       if (!is_pmqos_enabled(policy))
+               return 0;
+
+       /*
+        * Parse scenario name(data) whether to include 'Lock' or 'Unlock'
+        * string and divide correct scenario name.
+        */
+       locked = is_pmqos_locked(data, name);
+       index = find_scenario_index(scenario, name);
+       if (index < 0) {
+               _W("Unknown scenario (%s)\n", data);
+               return -EINVAL;
+       }
+       scn = &scenario->list[index];
+
+       /* Check the state of each scenario whether to support or not */
+       if (scn->state != PASS_ON) {
+               _W("cannot support '%s' scenario (support=%d)\n",
+                               name, scn->state);
+               return 0;
+       }
+
+       /*
+        * Compare locked state of scenario with
+        * if state is same as existing state
+        */
+       if (scn->locked == locked) {
+               _E("'%s' scenario is already %s\n",
+                               name, locked ? "Locked" : "Unlocked");
+               return 0;
+       }
+       scenario->list[index].locked = locked;
+
+       if (locked)
+               scenario->list[index].locked_time = get_time_ms();
+
+       /* Change scaling scope according to scenario's level */
+       for (i = 0; i < scenario->num_scenarios; i++) {
+               struct pass_scenario *scn = &scenario->list[i];
+
+               if (is_scenario_locked(scn)) {
+                       if (scn->cpufreq_min_level > cpufreq_min_level)
+                               cpufreq_min_level = scn->cpufreq_min_level;
+                       if (scn->cpufreq_max_level > cpufreq_max_level)
+                               cpufreq_max_level = scn->cpufreq_max_level;
+                       count++;
+               }
+
+               /*
+                * TODO: PASS have to control busfreq/gpufreq as same as cpufreq
+                */
+       }
+
+       /*
+        * Restore default min/max level if all scenarios hasn't locked state.
+        */
+       if (!is_scenario_locked(scn) && !count) {
+               cpufreq_min_level = policy->default_min_level;
+               cpufreq_max_level = policy->default_max_level;
+       }
+
+       if (locked) {
+               _I("Lock   '%s' scenario\n", name);
+       } else {
+               int64_t locked_time =
+                       get_time_ms() - scenario->list[index].locked_time;
+               scenario->list[index].locked_time = 0;
+
+               _I("UnLock '%s' scenario (%lldms)\n", name, locked_time);
+       }
+
+       pass_governor_change_level_scope(policy, cpufreq_min_level,
+                                        cpufreq_max_level);
+
+       /* TODO: PASS have to control busfreq/gpufreq as same as cpufreq. */
+
+       return 0;
+}
+
+/*
+ * pass_notifier_booting_done - Callback function of DEVICE_NOTIFIER_BOOTING_
+ *                              DONE notifier
+ * @data: NULL, this parameter isn't used
+ */
+static int pass_notifier_booting_done(void *data)
+{
+       if (!policy_pmqos)
+               return 0;
+
+       /* Start PASS governor if 'pass_support' in pass.conf is true */
+       if (policy_pmqos->state == PASS_ON && policy_pmqos->governor)
+               policy_pmqos->governor->update(policy_pmqos, PASS_GOV_START);
+
+       return 0;
+}
+
+/*
+ * pass_notifier_init - Register notifiers and init
+ * @policy: the instance of pass_policy structure
+ */
+static int pass_notifier_init(struct pass_policy *policy)
+{
+       /* Register DEVICE_NOTIFIER_PMQOS */
+       register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
+
+       /* Register DEVICE_NOTIFIER_BOOTING_DONE */
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+                         pass_notifier_booting_done);
+
+       /*
+        * FIXME: Current notifier of deviced didn't pass separate user_data
+        * parameter on callback function. So, PASS must need global pass_policy
+        * instance. This code must be modified after changing deviced's
+        * notifier feature.
+        */
+       policy_pmqos = policy;
+
+       return 0;
+}
+
+/*
+ * pass_notifier_exit - Un-register notifiers and exit
+ * @policy: the instance of pass_policy structure
+ */
+static int pass_notifier_exit(struct pass_policy *policy)
+{
+       /* Un-register DEVICE_NOTIFIER_PMQOS */
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
+
+       /* Un-Register DEVICE_NOTIFIER_BOOTING_DONE */
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+                           pass_notifier_booting_done);
+
+       return 0;
+}
+
+/*****************************************************************************
+ *                            PASS CPU Hotplug                               *
+ ****************************************************************************/
+
+/*
+ * pass_hotplug_set_online - Change the maximum number of online cpu
+ *
+ * @policy: the instance of struct pass_policy
+ * @max_online: the maximum number of online cpu
+ */
+static void pass_hotplug_set_online(struct pass_policy *policy,
+                                       unsigned int online)
+{
+       struct pass_table *table = policy->pass_table;
+       struct pass_hotplug *hotplug = policy->hotplug;
+       int num_online;
+       int i;
+
+       if (!hotplug || online == hotplug->online)
+               return;
+
+       if (online > hotplug->max_online)
+               online = hotplug->max_online;
+
+       if (online > hotplug->online)
+               num_online = online;
+       else
+               num_online = hotplug->online;
+
+       for (i = 0 ; i < policy->cpufreq.num_nr_cpus; i++) {
+               if (i < online)
+                       set_cpu_online(hotplug->sequence[i], PASS_CPU_UP);
+               else
+                       set_cpu_online(hotplug->sequence[i], PASS_CPU_DOWN);
+       }
+
+       /*
+       _I("- CPU %4s '%d->%d'Core\n",
+               (hotplug->online > online ? "DOWN" : "UP"),
+               hotplug->online, online);
+       */
+
+       hotplug->online = online;
+}
+
+/*
+ * pass_hotplug_stop - Stop PASS hotplug
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void pass_hotplug_stop(struct pass_policy *policy)
+{
+       struct pass_table *table = policy->pass_table;
+       int level = policy->max_level;
+
+       if (!policy->hotplug)
+               return;
+
+       policy->hotplug->online = table[level].limit_max_cpu;
+       policy->hotplug->max_online = policy->cpufreq.num_nr_cpus;
+}
+
+static int pass_hotplug_dummy_governor(struct pass_policy *policy)
+{
+       int level = policy->curr_level;
+
+       return policy->pass_table[level].limit_max_cpu;
+}
+
+/*
+ * Define PASS hotplug
+ *
+ * - Dummy hotplug
+ */
+static struct pass_hotplug pass_hotplug_dummy = {
+       .name           = "pass_hotplug_dummy",
+       .governor       = pass_hotplug_dummy_governor,
+};
+
+/*
+ * pass_get_governor - Return specific hotplug instance according to type
+ *
+ * @type: the type of PASS hotplug
+ */
+struct pass_hotplug* pass_get_hotplug(struct pass_policy *policy,
+                                       enum pass_gov_type type)
+{
+       switch (type) {
+       case PASS_GOV_STEP:
+       case PASS_GOV_RADIATION:
+               return &pass_hotplug_dummy;
+       default:
+               _E("Unknown hotplug type");
+               break;
+       };
+
+       return NULL;
+}
+
+/*****************************************************************************
+ *                              PASS governor                                *
+ ****************************************************************************/
+
+/*
+ * pass_governor_change_level - Change maximum cpu frequency and number of online cpu
+ *
+ * @policy: the instance of struct pass_policy
+ * @level: the pass level
+ */
+static int pass_governor_change_level(struct pass_policy *policy, int new_level)
+{
+       struct pass_table *table = policy->pass_table;
+       struct pass_hotplug *hotplug = policy->hotplug;
+       int curr_level = policy->curr_level;
+       int limit_max_freq;
+       int curr_max_freq;
+       int curr_min_freq;
+       int limit_max_cpu;
+       int online;
+       int i;
+
+       if (new_level > policy->max_level)
+               new_level = policy->max_level;
+
+       if (new_level < policy->min_level)
+               new_level = policy->min_level;
+
+       if (new_level == curr_level)
+               return 0;
+
+       /*
+        * Get maximum CPU frequency/the maximum number of online CPU
+        * according to PASS level.
+        */
+       limit_max_freq = table[new_level].limit_max_freq;
+       limit_max_cpu = table[new_level].limit_max_cpu;
+
+       policy->prev_level = policy->curr_level;
+       policy->curr_level = new_level;
+
+       /* Turn on/off CPUs according the maximum number of online CPU */
+       if (hotplug) {
+               if (hotplug->max_online != limit_max_cpu)
+                       hotplug->max_online = limit_max_cpu;
+
+               if (hotplug->governor)
+                       online = hotplug->governor(policy);
+               else
+                       online = 1;
+
+               curr_max_freq = get_cpufreq_scaling_max_freq();
+               curr_min_freq = get_cpufreq_scaling_min_freq();
+
+               set_cpufreq_scaling_min_freq(curr_max_freq);
+
+               pass_hotplug_set_online(policy, online);
+
+               set_cpufreq_scaling_min_freq(curr_min_freq);
+       }
+
+       /* Set maximum CPU frequency */
+       set_cpufreq_scaling_max_freq(limit_max_freq);
+
+       _I("Level %4s '%d->%d' : '%d'Hz/'%d'Core\n",
+               (curr_level > new_level ? "DOWN" : "UP"),
+               curr_level, new_level, limit_max_freq, limit_max_cpu);
+
+       return 0;
+};
+
+/*
+ * pass_governor_change_level_scope - Change the scope of cpufreq scaling
+ *
+ * @policy: the instance of struct pass_policy
+ * @min_level: the minimum level of cpufreq scaling
+ * @max_level: the maximum level of cpufreq scaling
+ */
+static int pass_governor_change_level_scope(struct pass_policy *policy,
+                                           int min_level, int max_level)
+{
+       if (!policy)
+               return -EINVAL;
+
+       if (min_level > max_level) {
+               _E("min_level(%d) have to be smaller than max_level(%d)\n",
+                                               min_level, max_level);
+               return -EINVAL;
+       }
+
+       if (min_level == policy->min_level
+               && max_level == policy->max_level)
+               return 0;
+
+       /* Change minimum/maximum level of cpufreq scaling */
+       policy->min_level = min_level;
+       policy->max_level = max_level;
+
+       pass_governor_change_level(policy, policy->curr_level);
+
+       return 0;
+}
+
+/*
+ * pass_calculate_busy_cpu - Count a number of busy cpu among NR_CPUS by using
+ *                          runnable_avg_sum/runnable_avg_period
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void pass_calculate_busy_cpu(struct pass_policy *policy)
+{
+       struct pass_cpu_stats *stats = policy->pass_cpu_stats;
+       struct pass_table *table = policy->pass_table;
+       unsigned int level = policy->curr_level;
+       unsigned int cpu_threshold = 0;
+       unsigned int busy_cpu;
+       unsigned int cur_freq;
+       unsigned int load;
+       unsigned int sum_load;
+       unsigned int sum_runnable_load;
+       unsigned int nr_runnings;
+       int limit_max_cpu;
+       int i;
+       int j;
+
+       limit_max_cpu = table[level].limit_max_cpu;
+
+       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
+               cur_freq = stats[i].freq;
+               nr_runnings = stats[i].nr_runnings;
+
+               stats[i].num_busy_cpu = 0;
+               stats[i].avg_load = 0;
+               stats[i].avg_runnable_load = 0;
+               stats[i].avg_thread_load = 0;
+               stats[i].avg_thread_runnable_load = 0;
+
+               busy_cpu = 0;
+               sum_load = 0;
+               sum_runnable_load = 0;
+
+               /* Calculate the number of busy cpu */
+               for (j = 0; j < policy->cpufreq.num_nr_cpus; j++) {
+                       load = stats[i].load[j];
+                       sum_load += stats[i].load[j];
+                       sum_runnable_load += stats[i].runnable_load[j];
+                       if (!load)
+                               continue;
+
+                       cpu_threshold =
+                               (unsigned int)(cur_freq * load)
+                                               / policy->cpufreq.max_freq;
+                       if (load == 100
+                               || cpu_threshold >= policy->pass_cpu_threshold)
+                               busy_cpu++;
+               }
+
+               stats[i].num_busy_cpu = busy_cpu;
+               stats[i].avg_load = sum_load / limit_max_cpu;
+               stats[i].avg_runnable_load = sum_runnable_load / limit_max_cpu;
+               if (nr_runnings) {
+                       stats[i].avg_thread_load
+                               = (sum_load * 100) / nr_runnings;
+                       stats[i].avg_thread_runnable_load
+                               = (sum_runnable_load * 100) / nr_runnings;
+               }
+       }
+}
+
+/*
+ * pass_governor_stop - Stop PASS governor through D-Bus
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void pass_governor_stop(struct pass_policy *policy)
+{
+       if (!policy->governor) {
+               _E("cannot stop PASS governor");
+               return;
+       }
+
+       if (policy->gov_state == PASS_GOV_STOP) {
+               _E("PASS governor is already inactive state");
+               return;
+       }
+
+       /* Restore maximum cpu freq/the number of online cpu */
+       pass_governor_change_level(policy, policy->num_levels - 1);
+
+       pass_hotplug_stop(policy);
+
+       if (policy->governor->gov_timer_id) {
+               ecore_timer_del(policy->governor->gov_timer_id);
+               policy->governor->gov_timer_id = NULL;
+       }
+
+       /* Set PASS state as PASS_GOV_STOP */
+       policy->gov_state = PASS_GOV_STOP;
+
+       _I("Stop PASS governor");
+}
+
+/*
+ * pass_governor_core_timer - Callback function of core timer for PASS governor
+ *
+ * @data: the instance of struct pass_policy
+ */
+static Eina_Bool pass_governor_core_timer(void *data)
+{
+       struct pass_policy *policy = (struct pass_policy *)data;
+       static int count = 0;
+       int level;
+       int online;
+       int ret;
+
+       if (!policy) {
+               _E("cannot execute PASS core timer");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /*
+        * Collect data related to system state
+        * - current cpu frequency
+        * - the number of nr_running
+        * - cpu load (= runnable_avg_sum * 100 / runnable_avg_period)
+        */
+       ret = get_pass_cpu_stats(policy);
+       if (ret < 0) {
+               if (count++ < PASS_CPU_STATS_MAX_COUNT)
+                       return ECORE_CALLBACK_RENEW;
+
+               count = 0;
+
+               _E("cannot read 'pass_cpu_stats' sysfs entry");
+               pass_governor_stop(policy);
+
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /* Calculate the number of busy cpu */
+       pass_calculate_busy_cpu(policy);
+
+       /* Determine the amount of proper resource */
+       if (policy->governor->governor) {
+               level = policy->governor->governor(policy);
+
+               pass_governor_change_level(policy, level);
+       } else {
+               _E("cannot execute governor function");
+               pass_governor_stop(policy);
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /*
+        * Change the period of govenor timer according to PASS level
+        */
+       if (policy->pass_table[level].gov_timeout >= PASS_MIN_GOV_TIMEOUT &&
+               (policy->governor->gov_timeout
+                != policy->pass_table[level].gov_timeout)) {
+
+               _I("Change the period of governor timer from %fs to %fs\n",
+                               policy->governor->gov_timeout,
+                               policy->pass_table[level].gov_timeout);
+
+               policy->governor->gov_timeout =
+                       policy->pass_table[level].gov_timeout;
+               ecore_timer_interval_set(policy->governor->gov_timer_id,
+                                       policy->governor->gov_timeout);
+               ecore_timer_reset(policy->governor->gov_timer_id);
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+/*
+ * pass_governor_start - Start PASS governor through D-Bus
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void pass_governor_start(struct pass_policy *policy)
+{
+       if (!policy->governor) {
+               _E("cannot start PASS governor");
+               return;
+       }
+
+       if (is_enabled(policy)) {
+               _E("PASS governor is already active state");
+               return;
+       }
+
+       /* Create the core timer of PASS governor */
+       policy->governor->gov_timer_id = ecore_timer_add(
+                               policy->governor->gov_timeout,
+                               (Ecore_Task_Cb)pass_governor_core_timer,
+                               (void *)policy);
+       if (!policy->governor->gov_timer_id) {
+               _E("cannot add core timer for governor");
+               pass_governor_stop(policy);
+               return;
+       }
+
+       /*
+        * Set default pass level when starting pass
+        * - default pass level according to policy->init_level
+        */
+       policy->curr_level = -1;
+       if (policy->init_level > policy->max_level)
+               policy->init_level = policy->max_level;
+       pass_governor_change_level(policy, policy->init_level);
+
+       /* Set PASS state as PASS_GOV_START */
+       policy->gov_state = PASS_GOV_START;
+
+       _I("Start PASS governor");
+}
+
+/*
+ * pass_governor_init - Initialize PASS governor
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static int pass_governor_init(struct pass_policy *policy)
+{
+       int max_level;
+       int ret;
+
+       if(policy->governor->gov_timeout < 0) {
+               _E("invalid timeout value [%d]!",
+                       policy->governor->gov_timeout);
+               pass_governor_stop(policy);
+               return -EINVAL;
+       }
+
+       /* Set default PASS state */
+       policy->gov_state = PASS_GOV_STOP;
+
+       /* Initialize notifier */
+       pass_notifier_init(policy);
+
+       _I("Initialize PASS (Power Aware System Service)");
+
+       return 0;
+}
+
+/*
+ * pass_governor_exit - Exit PASS governor
+ */
+static int pass_governor_exit(struct pass_policy *policy)
+{
+       int i;
+
+       /* Exit notifier */
+       pass_notifier_exit(policy);
+
+       /*
+        * Stop core timer and
+        * Restore maximum online cpu/cpu frequency
+        */
+       pass_governor_stop(policy);
+
+       /* Free allocated memory */
+       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
+               free(policy->pass_cpu_stats[i].load);
+               free(policy->pass_cpu_stats[i].nr_running);
+               free(policy->pass_cpu_stats[i].runnable_load);
+       }
+       free(policy->pass_cpu_stats);
+
+       if (policy->hotplug)
+               free(policy->hotplug->sequence);
+
+       /* Set pass_policy structure as default value */
+       policy->pass_cpu_threshold = 0;
+       policy->up_threshold = 0;
+       policy->down_threshold = 0;
+
+       policy->prev_level = 0;
+       policy->curr_level = 0;
+       policy->min_level = 0;
+       policy->max_level = 0;
+       policy->level_up_threshold = 0;
+
+       policy->pass_table = NULL;
+       policy->num_pass_cpu_stats = 0;
+
+       policy->governor->gov_timeout = 0;
+
+       policy->governor = NULL;
+
+       _I("Exit PASS (Power Aware System Service)");
+
+       return 0;
+}
+
+/*
+ * pass_governor_update - Restart/Pause PASS governor
+ *
+ * @cond: the instance of struct pass_policy
+ */
+static int pass_governor_update(struct pass_policy *policy,
+                       enum pass_gov_state state)
+{
+       if (!policy) {
+               _E("cannot update PASS governor");
+               return -EINVAL;
+       }
+
+       switch (state) {
+       case PASS_GOV_START:
+               pass_governor_start(policy);
+               break;
+       case PASS_GOV_STOP:
+               pass_governor_stop(policy);
+               break;
+       default:
+               _E("Unknown governor state");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * Define PASS governor
+ *
+ * - Step governor
+ * - Radiation governor
+ */
+static struct pass_governor pass_gov_step = {
+       .name           = "pass_step",
+       .init           = pass_governor_init,
+       .exit           = pass_governor_exit,
+       .update         = pass_governor_update,
+
+       .governor       = pass_step_governor,
+};
+
+static struct pass_governor pass_gov_radiation = {
+       .name           = "pass_radiation",
+       .init           = pass_governor_init,
+       .exit           = pass_governor_exit,
+       .update         = pass_governor_update,
+
+       .governor       = pass_radiation_governor,
+};
+
+/*
+ * pass_get_governor - Return specific governor instance according to type
+ *
+ * @type: the type of PASS governor
+ */
+struct pass_governor* pass_get_governor(struct pass_policy *policy,
+                                               enum pass_gov_type type)
+{
+       switch (type) {
+       case PASS_GOV_STEP:
+               return &pass_gov_step;
+       case PASS_GOV_RADIATION:
+               return &pass_gov_radiation;
+       default:
+               _E("Unknown governor type");
+               break;
+       };
+
+       return NULL;
+}
diff --git a/src/pass/pass-core.h b/src/pass/pass-core.h
new file mode 100644 (file)
index 0000000..0486098
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __PASS_CORE__
+#define __PASS_CORE__
+/*
+ * pass_get_governor - Return specific governor instance according to type
+ *
+ * @policy: the instance of struct pass_policy
+ * @type: the type of PASS governor
+ */
+struct pass_governor* pass_get_governor(struct pass_policy *policy,
+                                               enum pass_gov_type type);
+
+/*
+ * pass_get_hotplug - Return specific hotplug instance according to type
+ *
+ * @policy: the instance of struct pass_policy
+ * @type: the type of PASS governor
+ */
+struct pass_hotplug* pass_get_hotplug(struct pass_policy *policy,
+                                               enum pass_gov_type type);
+
+#endif /* __PASS_CORE__ */
diff --git a/src/pass/pass-gov-radiation.c b/src/pass/pass-gov-radiation.c
new file mode 100644 (file)
index 0000000..63a3924
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pass.h"
+
+/*
+ * pass_radiation_governor - Check cpu state and determine the amount of resource
+ *
+ * @stats: structure for getting cpu frequency state from kerncel
+ *
+ * This function check periodically current following state of system
+ * and then determine whether pass level up or down according to pass
+ * policy with gathered data.
+ * - current cpu frequency
+ * - the number of nr_running
+ * - the number of busy_cpu
+ */
+int pass_radiation_governor(struct pass_policy *policy)
+{
+       struct pass_table *table = policy->pass_table;
+       struct pass_cpu_stats *cpu_stats = policy->pass_cpu_stats;
+       int up_threshold = policy->up_threshold;
+       int down_threshold = policy->down_threshold;
+       int num_pass_gov = 0;
+       int level = policy->curr_level;
+       int up_count = 0;
+       int down_count = 0;
+       int left_count = 0;
+       int right_count = 0;
+       bool up_condition;
+       bool down_condition;
+       bool left_condition;
+       bool right_condition;
+       int freq;
+       int nr_running;
+       int busy_cpu;
+       int i;
+       int j;
+       int64_t time;
+       static int64_t last_time = 0;
+
+       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
+               time = cpu_stats[i].time;
+               freq = cpu_stats[i].freq;
+               nr_running = cpu_stats[i].nr_runnings;
+               busy_cpu = cpu_stats[i].num_busy_cpu;
+               up_condition = true;
+               down_condition = true;
+               left_condition = true;
+               right_condition = true;
+
+               if (last_time >= time)
+                       continue;
+               last_time = time;
+               num_pass_gov++;
+
+               /*
+               _I("[Level%d][%d][%lld] %d | %d | %d", level, i, time, freq,
+                                               nr_running, busy_cpu);
+               */
+
+               /* Check level up condition */
+               for (j = 0; j < table[level].num_up_cond && up_condition; j++) {
+                       if (table[level].up_cond[j].freq &&
+                               !(freq >= table[level].up_cond[j].freq))
+                               up_condition = false;
+               }
+
+               if (table[level].num_up_cond && up_condition) {
+                       up_count++;
+
+                       /*
+                       _I("[Level%d] [up_count : %2d] \
+                               freq(%d), nr_running(%d), busy_cpu(%d)",
+                               level, up_count,
+                               table[level].up_cond[j].freq ? freq : -1,
+                       */
+               }
+
+               /* Check level down condition */
+               for (j = 0; j < table[level].num_down_cond && down_condition; j++) {
+                       if (table[level].down_cond[j].freq
+                               && !(freq <= table[level].down_cond[j].freq))
+                               down_condition = false;
+               }
+
+               if (table[level].num_down_cond && down_condition) {
+                       down_count++;
+
+                       /*
+                       _I("[Level%d] [dw_count : %2d] \
+                               freq(%d), nr_running(%d), busy_cpu(%d)",
+                               level, down_count,
+                               table[level].down_cond[j].freq ? freq : -1,
+                       */
+               }
+
+               /* Check level right condition */
+               for (j = 0; j < table[level].num_right_cond && right_condition; j++) {
+                       /*
+                        * If one more conditions are false among following
+                        * conditions, don't increment right_count.
+                        */
+                       if (table[level].right_cond[j].nr_running
+                               && !(nr_running > table[level].right_cond[j].nr_running))
+                               right_condition = false;
+
+                       if (table[level].right_cond[j].busy_cpu
+                               && !(busy_cpu >= table[level].right_cond[j].busy_cpu))
+                               right_condition = false;
+               }
+
+               if (table[level].num_right_cond && right_condition) {
+                       right_count++;
+
+                       /*
+                       _I("[Level%d] [right_count : %2d] \
+                               nr_running(%d), busy_cpu(%d)",
+                               level, right_count,
+                               table[level].right_cond[j].nr_running ? nr_running : -1,
+                               table[level].right_cond[j].busy_cpu ? busy_cpu : -1);
+                       */
+               }
+
+               /* Check level left condition */
+               for (j = 0; j < table[level].num_left_cond && left_condition; j++) {
+                       /*
+                        * If one more conditions are false among following
+                        * conditions, don't increment left_count.
+                        */
+                       if (table[level].left_cond[j].nr_running
+                               && !(nr_running <= table[level].left_cond[j].nr_running))
+                               left_condition = false;
+
+                       if (table[level].left_cond[j].busy_cpu
+                               && !(busy_cpu < table[level].left_cond[j].busy_cpu))
+                               left_condition = false;
+               }
+
+               if (table[level].num_left_cond && left_condition) {
+                       left_count++;
+
+                       /*
+                       _I("[Level%d] [ left_count : %2d] \
+                               nr_running(%d), busy_cpu(%d)",
+                               level, left_count,
+                               table[level].left_cond[j].nr_running ? nr_running : -1,
+                               table[level].left_cond[j].busy_cpu ? busy_cpu : -1);
+                       */
+               }
+       }
+
+       if (up_count * 100 >= num_pass_gov * up_threshold)
+               level += policy->cpufreq.num_nr_cpus;
+       else if (down_count * 100 >= num_pass_gov * down_threshold)
+               level -= policy->cpufreq.num_nr_cpus;
+
+       if (right_count * 100 >= num_pass_gov * up_threshold)
+               level += 1;
+       else if (left_count * 100 >= num_pass_gov * down_threshold)
+               level -= 1;
+
+       /*
+       if (level == policy->prev_level) {
+               for (i = num_pass_gov; i < policy->num_pass_cpu_stats; i++) {
+                       time = cpu_stats[i].time;
+                       freq = cpu_stats[i].freq;
+                       nr_running = cpu_stats[i].nr_runnings;
+                       busy_cpu = cpu_stats[i].num_busy_cpu;
+
+                       _I("[Level%d][%d][%lld] %d | %d | %d",
+                                       level, i, time, freq,
+                                       nr_running, busy_cpu);
+               }
+       }
+
+       if (level != policy->curr_level) {
+               _I("\n[Level%d] num_pass_gov: [%2d]", level, num_pass_gov);
+               _I("[Level%d] down_count  : %2d (%3d >= %3d)", level, down_count,
+                               down_count * 100, num_pass_gov * down_threshold);
+               _I("[Level%d] up_count    : %2d (%3d >= %3d)", level, up_count,
+                               up_count * 100, num_pass_gov * up_threshold);
+               _I("[Level%d] left_count  : %2d (%3d >= %3d)", level, left_count,
+                               left_count * 100, num_pass_gov * down_threshold);
+               _I("[Level%d] right_count : %2d (%3d >= %3d)", level, right_count,
+                               right_count * 100, num_pass_gov * up_threshold);
+       }
+       */
+
+       return level;
+}
diff --git a/src/pass/pass-gov-step.c b/src/pass/pass-gov-step.c
new file mode 100644 (file)
index 0000000..89ee2dc
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pass.h"
+
+/*
+ * pass_step_governor - Check cpu state and determine the amount of resource
+ *
+ * @stats: structure for getting cpu frequency state from kerncel
+ *
+ * This function check periodically current following state of system
+ * and then determine whether pass level up or down according to pass
+ * policy with gathered data.
+ * - current cpu frequency
+ * - the number of nr_running
+ * - the number of busy_cpu
+ */
+int pass_step_governor(struct pass_policy *policy)
+{
+       struct pass_table *table = policy->pass_table;
+       struct pass_cpu_stats *cpu_stats = policy->pass_cpu_stats;
+       int up_threshold = policy->up_threshold;
+       int down_threshold = policy->down_threshold;
+       int num_pass_gov = 0;
+       int level = policy->curr_level;
+       int count = 0;
+       int up_count = 0;
+       int up_max_count = 0;
+       int down_count = 0;
+       bool up_condition;
+       bool down_condition;
+       int freq;
+       int nr_running;
+       int busy_cpu;
+       int i;
+       int j;
+       int64_t time;
+       static int64_t last_time = 0;
+
+       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
+               time = cpu_stats[i].time;
+               freq = cpu_stats[i].freq;
+               nr_running = cpu_stats[i].nr_runnings;
+               busy_cpu = cpu_stats[i].num_busy_cpu;
+               up_condition = false;
+               down_condition = false;
+
+               if (last_time >= time)
+                       continue;
+               last_time = time;
+               num_pass_gov++;
+
+               /* Check level up condition */
+               for (j = 0; j < table[level].num_up_cond; j++) {
+                       /*
+                        * If one more conditions are false among following
+                        * conditions, don't increment up_count.
+                        */
+                       if (freq >= table[level].up_cond[j].freq
+                               && nr_running >= table[level].up_cond[j].nr_running
+                               && busy_cpu >= table[level].up_cond[j].busy_cpu)
+                               up_condition = true;
+               }
+
+               if (table[level].num_up_cond && up_condition) {
+                       up_count++;
+
+                       /*
+                       _I("[Level%d] [up_count : %2d] \
+                               freq(%d), nr_running(%d), busy_cpu(%d)",
+                               level, up_count,
+                               table[level].up_cond[j].freq ? freq : -1,
+                               table[level].up_cond[j].nr_running ? nr_running : -1,
+                               table[level].up_cond[j].busy_cpu ? busy_cpu : -1);
+                       */
+               }
+
+               /* Check level down condition */
+               for (j = 0; j < table[level].num_down_cond; j++) {
+                       /*
+                        * If one more conditions are false among following
+                        * conditions, don't increment down_count.
+                        */
+                       if (freq <= table[level].down_cond[j].freq
+                               && nr_running < table[level].down_cond[j].nr_running
+                               && busy_cpu < table[level].down_cond[j].busy_cpu)
+                               down_condition = true;
+               }
+
+               if (table[level].num_down_cond && down_condition) {
+                       down_count++;
+
+                       /*
+                       _I("[Level%d] [dw_count : %2d] \
+                               freq(%d), nr_running(%d), busy_cpu(%d)",
+                               level, down_count,
+                               table[level].down_cond[j].freq ? freq : -1,
+                               table[level].down_cond[j].nr_running ? nr_running : -1,
+                               table[level].down_cond[j].busy_cpu ? busy_cpu : -1);
+                       */
+               }
+
+               if (level < policy->max_level &&
+                       freq == table[level].limit_max_freq)
+                       up_max_count++;
+       }
+
+       if (!num_pass_gov)
+               return level;
+
+       if (up_count && level < policy->max_level &&
+                       up_count * 100 >= num_pass_gov * up_threshold) {
+               level += 1;
+       } else if (down_count && level > policy->min_level &&
+                       down_count * 100 >= num_pass_gov * down_threshold) {
+               level -= 1;
+       }
+
+       return level;
+}
similarity index 71%
rename from src/core/sysnoti.h
rename to src/pass/pass-gov.h
index aee5fee..ca79351 100644 (file)
  * limitations under the License.
  */
 
+#ifndef __PASS_GOV__
+#define __PASS_GOV__
 
-#ifndef __SYSNOTI_H__
-#define __SYSNOTI_H__
+/* PASS Step governor function */
+int pass_step_governor(struct pass_policy *policy);
 
-#define SYSMAN_MAXARG  16
+/* PASS Radiation governor function */
+int pass_radiation_governor(struct pass_policy *policy);
 
-struct sysnoti {
-       int pid;
-       int cmd;
-       char *type;
-       char *path;
-       int argc;
-       char *argv[SYSMAN_MAXARG];
-};
-
-#endif /* __SYSNOTI_H__ */
+#endif /* __PASS_GOV__ */
similarity index 77%
rename from src/core/data.h
rename to src/pass/pass-hotplug.h
index d07c356..454f45f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * deviced
+ * PASS Hotplug
  *
  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
  *
  * limitations under the License.
  */
 
+#ifndef __PASS_HOTPLUG__
+#define __PASS_HOTPLUG__
 
-#ifndef __DD_DATA_H__
-#define __DD_DATA_H__
-
-#include <Ecore.h>
-#include <unistd.h>
-
-struct main_data {
-       int sysnoti_fd;
-       int noti_fd;
-};
-
-#endif /* __DD_DATA_H__ */
+#endif /* __PASS_HOTPLUG__ */
diff --git a/src/pass/pass-micro.conf b/src/pass/pass-micro.conf
new file mode 100644 (file)
index 0000000..ac68745
--- /dev/null
@@ -0,0 +1,245 @@
+[Pass]
+pass_compatible=samsung,tizen-w
+pass_support=1
+
+pass_gov_type=0
+pass_num_levels=6
+pass_min_level=0
+pass_max_level=5
+pass_init_level=2
+
+pass_num_cpu_stats=20
+
+pass_cpu_threshold=60
+pass_up_threshold=50
+pass_down_threshold=80
+pass_level_up_threshold=1
+
+pass_governor_timeout=0.4
+
+[CpufreqLevel0]
+limit_max_freq=600000
+limit_max_cpu=1
+
+num_down_cond=0
+num_up_cond=1
+num_up_cond_freq=500000
+num_up_cond_nr_running=150
+num_up_cond_busy_cpu=1
+num_left_cond=0
+num_right_cond=0
+
+[CpufreqLevel1]
+limit_max_freq=700000
+limit_max_cpu=1
+
+num_down_cond=1
+num_down_cond_freq=500000
+num_down_cond_nr_running=250
+num_down_cond_busy_cpu=2
+num_up_cond=1
+num_up_cond_freq=700000
+num_up_cond_nr_running=250
+num_up_cond_busy_cpu=1
+num_left_cond=0
+num_right_cond=0
+
+[CpufreqLevel2]
+limit_max_freq=800000
+limit_max_cpu=1
+
+num_down_cond=1
+num_down_cond_freq=700000
+num_down_cond_nr_running=300
+num_down_cond_busy_cpu=2
+num_up_cond=1
+num_up_cond_freq=800000
+num_up_cond_nr_running=200
+num_up_cond_busy_cpu=1
+num_left_cond=0
+num_right_cond=0
+
+[CpufreqLevel3]
+limit_max_freq=700000
+limit_max_cpu=2
+
+num_down_cond=1
+num_down_cond_freq=600000
+num_down_cond_nr_running=250
+num_down_cond_busy_cpu=1
+num_up_cond=1
+num_up_cond_freq=700000
+num_up_cond_nr_running=300
+num_up_cond_busy_cpu=2
+num_left_cond=0
+num_right_cond=0
+
+[CpufreqLevel4]
+limit_max_freq=700000
+limit_max_cpu=2
+
+num_down_cond=1
+num_down_cond_freq=600000
+num_down_cond_nr_running=300
+num_down_cond_busy_cpu=2
+num_up_cond=1
+num_up_cond_freq=700000
+num_up_cond_nr_running=350
+num_up_cond_busy_cpu=2
+num_left_cond=0
+num_right_cond=0
+
+[CpufreqLevel5]
+limit_max_freq=800000
+limit_max_cpu=2
+
+num_down_cond=1
+num_down_cond_freq=700000
+num_down_cond_nr_running=200
+num_down_cond_busy_cpu=1
+num_up_cond=0
+num_left_cond=0
+num_right_cond=0
+
+############################
+### Add list of scenario ###
+############################
+[PassScenario]
+pass_scenario_support=yes
+pass_num_scenarios=28
+
+[Scenario0]
+name=AppLaunch
+support=yes
+
+cpufreq_min_level=5
+cpufreq_max_level=5
+
+[Scenario1]
+name=MtpSendFile
+support=no
+
+[Scenario2]
+name=PowerSaving
+support=no
+
+[Scenario3]
+name=LowBattery
+support=no
+
+[Scenario4]
+name=Emergency
+support=no
+
+[Scenario5]
+name=CameraPreview
+support=yes
+
+cpufreq_min_level=3
+cpufreq_max_level=5
+
+[Scenario6]
+name=CameraBurstShot
+support=yes
+
+cpufreq_min_level=3
+cpufreq_max_level=5
+
+[Scenario7]
+name=CameraCaptureAtRec
+support=yes
+
+cpufreq_min_level=3
+cpufreq_max_level=5
+
+[Scenario8]
+name=Browser
+support=no
+
+[Scenario9]
+name=BrowserDash
+support=no
+
+[Scenario10]
+name=BrowserJavaScript
+support=no
+
+[Scenario11]
+name=BrowserLoading
+support=no
+
+[Scenario12]
+name=BrowserScroll
+support=no
+
+[Scenario13]
+name=GpuWakeup
+support=no
+
+[Scenario14]
+name=WifiThroughput
+support=no
+
+[Scenario15]
+name=SmemoZoom
+support=no
+
+[Scenario16]
+name=IMEInput
+support=no
+
+[Scenario17]
+name=CallSound
+support=no
+
+[Scenario18]
+name=LockScreen
+support=no
+
+[Scenario19]
+name=GalleryRotation
+support=no
+
+[Scenario20]
+name=ReservedMode
+support=no
+
+[Scenario21]
+name=GetDefaultLockTime
+support=no
+
+[Scenario22]
+name=GpuBoost
+support=no
+
+[Scenario23]
+name=WebappLaunch
+support=yes
+
+cpufreq_min_level=3
+cpufreq_max_level=5
+
+[Scenario24]
+name=ImageViewer
+support=no
+
+[Scenario25]
+name=PowerOff
+support=yes
+
+cpufreq_min_level=5
+cpufreq_max_level=5
+
+[Scenario26]
+name=ProcessCrashed
+support=yes
+
+cpufreq_min_level=5
+cpufreq_max_level=5
+
+[Scenario27]
+name=SVoice
+support=yes
+
+cpufreq_min_level=5
+cpufreq_max_level=5
diff --git a/src/pass/pass-plugin.c b/src/pass/pass-plugin.c
new file mode 100644 (file)
index 0000000..217cc74
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <errno.h>
+#include <fcntl.h>
+
+#include "pass.h"
+#include "pass-plugin.h"
+
+#include "core/config-parser.h"
+
+#define BUFF_MAX                       255
+
+/* Linux standard sysfs node */
+#define CPUFREQ_SCALING_MAX_FREQ       "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
+#define CPUFREQ_SCALING_MIN_FREQ       "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq"
+#define CPUFREQ_SAMPLING_RATE          "/sys/devices/system/cpu/cpufreq/ondemand/sampling_rate"
+#define CPUFREQ_UP_THRESHOLD           "/sys/devices/system/cpu/cpufreq/ondemand/up_threshold"
+
+#define PROC_DT_COMPATIBLE             "/proc/device-tree/compatible"
+
+/* PASS specific sysfs node */
+#define PASS_CPU_STATS                 "/sys/kernel/debug/cpufreq/cpu0/load_table"
+
+int get_pass_cpu_stats(struct pass_policy *policy)
+{
+       struct pass_cpu_stats *stats = policy->pass_cpu_stats;
+       char path[PATH_MAX] = PASS_CPU_STATS;
+       char str[BUFF_MAX];
+       FILE *fp_stats = NULL;
+       int i, j;
+       int ret = 1;
+
+       if (!stats) {
+               _E("invalid parameter of structure pass_cpu_stats");
+               return -EINVAL;
+       }
+
+       fp_stats = fopen(path, "r");
+       if (fp_stats == NULL)
+               return -EIO;
+
+       fgets(str, BUFF_MAX, fp_stats);
+       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
+               ret = fscanf(fp_stats, "%lld %d %d %d",
+                       &stats[i].time,
+                       &stats[i].freq,
+                       &stats[i].freq_new,
+                       &stats[i].nr_runnings);
+
+               for (j = 0; j < policy->cpufreq.num_nr_cpus; j++)
+                       ret = fscanf(fp_stats, "%d", &stats[i].load[j]);
+       }
+       fclose(fp_stats);
+
+       return 0;
+}
+
+/*
+ * Helper function
+ * - Read from sysfs entry
+ * - Write to sysfs entry
+ */
+static int sys_read_buf(char *file, char *buf)
+{
+       int fd;
+       int r;
+       int ret = 0;
+
+       fd = open(file, O_RDONLY);
+       if (fd == -1)
+               return -ENOENT;
+
+       r = read(fd, buf, BUFF_MAX);
+       if ((r >= 0) && (r < BUFF_MAX))
+               buf[r] = '\0';
+       else
+               ret = -EIO;
+
+       close(fd);
+
+       return ret;
+}
+
+static int sys_write_buf(char *file, char *buf)
+{
+       int fd;
+       int r;
+       int ret = 0;
+
+       fd = open(file, O_WRONLY);
+       if (fd == -1)
+               return -1;
+
+       r = write(fd, buf, strlen(buf));
+       if (r < 0)
+               ret = -EIO;
+
+       close(fd);
+
+       return ret;
+}
+
+static int sys_get_int(char *fname, int *val)
+{
+       char buf[BUFF_MAX];
+
+       if (sys_read_buf(fname, buf) == 0) {
+               *val = atoi(buf);
+               return 0;
+       } else {
+               *val = -1;
+               return -1;
+       }
+}
+
+static int sys_set_int(char *fname, int val)
+{
+       char buf[BUFF_MAX];
+       int r = -1;
+       snprintf(buf, sizeof(buf), "%d", val);
+
+       if (sys_write_buf(fname, buf) == 0)
+               r = 0;
+
+       return r;
+}
+
+/*
+ * Get/Set maximum cpu frequency
+ */
+#define GET_VALUE(name, path)                  \
+int get_##name(void)                           \
+{                                              \
+       int value, ret;                         \
+                                               \
+       ret =  sys_get_int(path, &value);       \
+       if (ret < 0)                            \
+               return -EAGAIN;                 \
+                                               \
+       return value;                           \
+}                                              \
+
+#define SET_VALUE(name, path)                  \
+int set_##name(int value)                      \
+{                                              \
+       return sys_set_int(path, value);        \
+}                                              \
+
+GET_VALUE(cpufreq_scaling_max_freq, CPUFREQ_SCALING_MAX_FREQ);
+SET_VALUE(cpufreq_scaling_max_freq, CPUFREQ_SCALING_MAX_FREQ);
+
+GET_VALUE(cpufreq_scaling_min_freq, CPUFREQ_SCALING_MIN_FREQ);
+SET_VALUE(cpufreq_scaling_min_freq, CPUFREQ_SCALING_MIN_FREQ);
+
+GET_VALUE(cpufreq_sampling_rate, CPUFREQ_SAMPLING_RATE);
+SET_VALUE(cpufreq_sampling_rate, CPUFREQ_SAMPLING_RATE);
+
+GET_VALUE(cpufreq_up_threshold, CPUFREQ_UP_THRESHOLD);
+SET_VALUE(cpufreq_up_threshold, CPUFREQ_UP_THRESHOLD);
+
+int get_cpu_online(int cpu)
+{
+       char path[BUFF_MAX];
+       int online;
+       int ret;
+
+       ret = sprintf(path, "/sys/devices/system/cpu/cpu%d/online", cpu);
+       if (ret < 0)
+               return -EINVAL;
+
+       ret = sys_get_int(path, &online);
+       if (ret < 0)
+               return -EAGAIN;
+
+       return online;
+}
+int set_cpu_online(int cpu, int online)
+{
+       char path[BUFF_MAX];
+       int ret;
+
+       ret = sprintf(path, "/sys/devices/system/cpu/cpu%d/online", cpu);
+       if (ret < 0)
+               return -EINVAL;
+
+       ret = sys_set_int(path, online);
+       if (ret < 0)
+               return -EAGAIN;
+
+       return 0;
+}
+
+/***************************************************************************
+ *                            Parse pass.conf                              *
+ ***************************************************************************/
+
+static enum pass_state is_supported(char *value)
+{
+       enum pass_state state;
+
+       if (!value)
+               return -EINVAL;
+
+       if (MATCH(value, "yes"))
+               state = PASS_ON;
+       else if (MATCH(value, "no"))
+               state = PASS_OFF;
+       else
+               state = PASS_UNUSED;
+
+       return state;
+}
+
+static int pass_parse_scenario(struct parse_result *result, void *user_data,
+                              unsigned int index)
+{
+       struct pass_policy *policy = user_data;
+       struct pass_scenario_policy *scenario = &policy->scenario;
+       char section_name[BUFF_MAX];
+       int i;
+
+       if (!policy && !scenario && !result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       /* Parse 'PassScenario' section */
+       if (MATCH(result->section, "PassScenario")) {
+               if (MATCH(result->name, "pass_scenario_support")) {
+                       scenario->state = is_supported(result->value);
+                       if (scenario->state < 0)
+                               return -EINVAL;
+
+               } else if (MATCH(result->name, "pass_num_scenarios")) {
+                       scenario->num_scenarios = atoi(result->value);
+
+                       if (scenario->num_scenarios > 0 && !scenario->list) {
+                               scenario->list = malloc(sizeof(struct pass_scenario)
+                                                       * scenario->num_scenarios);
+                               if (!scenario->list) {
+                                       _E("cannot allocate memory for Scenario\n");
+                                       return -EINVAL;
+                               }
+                       }
+               }
+       }
+
+       if (scenario->state != PASS_ON)
+               return 0;
+
+       if (!scenario->num_scenarios)
+               return 0;
+
+       if (index > scenario->num_scenarios || index == PASS_UNUSED)
+               return 0;
+
+       /* Parse 'Scenario' section */
+       if (MATCH(result->name, "name")) {
+               strcpy(scenario->list[index].name, result->value);
+       } else if (MATCH(result->name, "support")) {
+               scenario->list[index].state = is_supported(result->value);
+               if (scenario->list[index].state < 0)
+                       return -EINVAL;
+       } else if (MATCH(result->name, "cpufreq_min_level")) {
+               scenario->list[index].cpufreq_min_level = atoi(result->value);
+       } else if (MATCH(result->name, "cpufreq_max_level")) {
+               scenario->list[index].cpufreq_max_level = atoi(result->value);
+       } else if (MATCH(result->name, "busfreq_min_level")) {
+               scenario->list[index].busfreq_min_level = atoi(result->value);
+       } else if (MATCH(result->name, "busfreq_max_level")) {
+               scenario->list[index].busfreq_max_level = atoi(result->value);
+       } else if (MATCH(result->name, "gpufreq_min_level")) {
+               scenario->list[index].gpufreq_min_level = atoi(result->value);
+       } else if (MATCH(result->name, "gpufreq_max_level")) {
+               scenario->list[index].gpufreq_max_level = atoi(result->value);
+       }
+
+       return 0;
+}
+
+static int  pass_parse_cpufreq_level(struct parse_result *result,
+                                   void *user_data, int level)
+{
+       struct pass_policy *policy = user_data;
+       char section_name[BUFF_MAX];
+       int i, ret;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       if (MATCH(result->name, "limit_max_freq"))
+               policy->pass_table[level].limit_max_freq = atoi(result->value);
+       else if (MATCH(result->name, "limit_max_cpu"))
+               policy->pass_table[level].limit_max_cpu = atoi(result->value);
+
+       else if (MATCH(result->name, "num_down_cond"))
+               policy->pass_table[level].num_down_cond = atoi(result->value);
+       else if (MATCH(result->name, "num_down_cond_freq"))
+               policy->pass_table[level].down_cond[0].freq = atoi(result->value);
+       else if (MATCH(result->name, "num_down_cond_nr_running"))
+               policy->pass_table[level].down_cond[0].nr_running = atoi(result->value);
+       else if (MATCH(result->name, "num_down_cond_busy_cpu"))
+               policy->pass_table[level].down_cond[0].busy_cpu = atoi(result->value);
+
+       else if (MATCH(result->name, "num_up_cond"))
+               policy->pass_table[level].num_up_cond = atoi(result->value);
+       else if (MATCH(result->name, "num_up_cond_freq"))
+               policy->pass_table[level].up_cond[0].freq = atoi(result->value);
+       else if (MATCH(result->name, "num_up_cond_nr_running"))
+               policy->pass_table[level].up_cond[0].nr_running = atoi(result->value);
+       else if (MATCH(result->name, "num_up_cond_busy_cpu"))
+               policy->pass_table[level].up_cond[0].busy_cpu = atoi(result->value);
+
+       else if (MATCH(result->name, "num_left_cond"))
+               policy->pass_table[level].num_left_cond = atoi(result->value);
+       else if (MATCH(result->name, "num_left_cond_freq"))
+               policy->pass_table[level].left_cond[0].freq = atoi(result->value);
+       else if (MATCH(result->name, "num_left_cond_nr_running"))
+               policy->pass_table[level].left_cond[0].nr_running = atoi(result->value);
+       else if (MATCH(result->name, "num_left_cond_busy_cpu"))
+               policy->pass_table[level].left_cond[0].busy_cpu = atoi(result->value);
+
+       else if (MATCH(result->name, "num_right_cond"))
+               policy->pass_table[level].num_right_cond = atoi(result->value);
+       else if (MATCH(result->name, "num_right_cond_freq"))
+               policy->pass_table[level].right_cond[0].freq = atoi(result->value);
+       else if (MATCH(result->name, "num_right_cond_nr_running"))
+               policy->pass_table[level].right_cond[0].nr_running = atoi(result->value);
+       else if (MATCH(result->name, "num_right_cond_busy_cpu"))
+               policy->pass_table[level].right_cond[0].busy_cpu = atoi(result->value);
+
+       return 0;
+}
+
+static int pass_parse_core(struct parse_result *result, void *user_data)
+{
+       struct pass_policy *policy = user_data;
+       char section_name[BUFF_MAX];
+       int i, ret;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       if (MATCH(result->name, "pass_compatible")) {
+               char compatible[BUFF_MAX];
+
+               ret = sys_read_buf(PROC_DT_COMPATIBLE, compatible);
+               if (ret < 0)
+                       return -EEXIST;
+
+               if (strcmp(compatible, result->value))
+                       return -EINVAL;
+
+               _I("Match compatible string : %s\n", compatible);
+       } else if (MATCH(result->name, "pass_support"))
+               policy->state = atoi(result->value);
+       else if (MATCH(result->name, "pass_gov_type"))
+               policy->gov_type = atoi(result->value);
+       else if (MATCH(result->name, "pass_num_levels"))
+               policy->num_levels = atoi(result->value);
+       else if (MATCH(result->name, "pass_min_level"))
+               policy->min_level = atoi(result->value);
+       else if (MATCH(result->name, "pass_max_level"))
+               policy->max_level = atoi(result->value);
+       else if (MATCH(result->name, "pass_num_cpu_stats"))
+               policy->num_pass_cpu_stats = atoi(result->value);
+       else if (MATCH(result->name, "pass_cpu_threshold"))
+               policy->pass_cpu_threshold = atoi(result->value);
+       else if (MATCH(result->name, "pass_up_threshold"))
+               policy->up_threshold = atoi(result->value);
+       else if (MATCH(result->name, "pass_down_threshold"))
+               policy->down_threshold = atoi(result->value);
+       else if (MATCH(result->name, "pass_init_level"))
+               policy->init_level = atoi(result->value);
+       else if (MATCH(result->name, "pass_level_up_threshold"))
+               policy->level_up_threshold = atoi(result->value);
+       else if (MATCH(result->name, "pass_governor_timeout")) {
+               policy->gov_timeout = atof(result->value);
+
+               if (PASS_MIN_GOV_TIMEOUT > policy->gov_timeout)
+                       policy->gov_timeout = PASS_MIN_GOV_TIMEOUT;
+       }
+
+       if (policy->num_levels > 0 && !policy->pass_table) {
+               policy->pass_table = malloc(sizeof(struct pass_table)
+                              * policy->num_levels);
+               if (!policy->pass_table) {
+                       _E("cannot allocate memory for pass_table\n");
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int pass_load_config(struct parse_result *result, void *user_data)
+{
+       struct pass_policy *policy = user_data;
+       struct pass_scenario_policy *scenario = &policy->scenario;
+       char section_name[BUFF_MAX];
+       int level = PASS_UNUSED;
+       int index = PASS_UNUSED;
+       int i, ret;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       /* Parsing 'PASS' section */
+       if (MATCH(result->section, "Pass")) {
+               ret = pass_parse_core(result, user_data);
+               if (ret < 0) {
+                       _E("cannot parse the core part\n");
+                       return ret;
+               }
+
+               goto out;
+       }
+
+       /* Parsing 'CpufreqLevel' section to get pass-table */
+       for (level = 0; level < policy->num_levels; level++) {
+               ret = sprintf(section_name, "CpufreqLevel%d", level);
+
+               if (MATCH(result->section, section_name)) {
+                       ret = pass_parse_cpufreq_level(result, user_data, level);
+                       if (ret < 0) {
+                               _E("cannot parse 'Cpufreq' section\n");
+                               return ret;
+                       }
+
+                       goto out;
+               }
+       }
+
+       /* Parsing 'PassScenario' section */
+       if (MATCH(result->section, "PassScenario")) {
+               ret = pass_parse_scenario(result, user_data, PASS_UNUSED);
+               if (ret < 0) {
+                       _E("cannot parse 'PassScenario' section\n");
+                       return ret;
+               }
+
+               goto out;
+       }
+
+       /* Parsing 'Scenario' section */
+       for (index = 0; index < scenario->num_scenarios; index++) {
+               ret = sprintf(section_name, "Scenario%d", index);
+
+               if (MATCH(result->section, section_name)) {
+                       ret = pass_parse_scenario(result, user_data, index);
+                       if (ret < 0) {
+                               _E("cannot parse 'Scenario' section\n");
+                               return ret;
+                       }
+
+                       goto out;
+               }
+       }
+
+out:
+       return 0;
+}
+
+int get_pass_table(struct pass_policy *policy, char *pass_conf_path)
+{
+       int ret;
+
+       policy->state = PASS_UNUSED;
+       policy->scenario.state = PASS_UNUSED;
+
+       ret = config_parse(pass_conf_path, pass_load_config, policy);
+       if (ret < 0) {
+               _E("cannot parse %s\n", pass_conf_path);
+               return -EINVAL;
+       }
+
+       if (policy->state == PASS_UNUSED)
+               return -EINVAL;
+
+       if (policy->scenario.state == PASS_UNUSED)
+               _W("%s don't include the list of pass-scenario\n");
+       else
+               _I("can%s use pass-scenario",
+                               policy->scenario.state ? "" : "not");
+
+       return 0;
+}
+
+void put_pass_table(struct pass_policy *policy)
+{
+       if(policy->pass_table)
+               free(policy->pass_table);
+
+       if(policy->scenario.list)
+               free(policy->scenario.list);
+}
+
+/*
+ * get_time_ms - Return current time (unit: millisecond)
+ */
+int64_t get_time_ms(void)
+{
+       struct timeval now;
+
+       gettimeofday(&now, NULL);
+
+       return (int64_t)(now.tv_sec * 1000 + now.tv_usec / 1000);
+}
diff --git a/src/pass/pass-plugin.h b/src/pass/pass-plugin.h
new file mode 100644 (file)
index 0000000..0e4450e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __PASS_PLUGIN__
+#define __PASS_PLUGIN__
+
+#include "pass.h"
+
+int get_pass_cpu_stats(struct pass_policy *policy);
+
+int get_pass_table(struct pass_policy *policy, char *pass_conf_path);
+void put_pass_table(struct pass_policy *policy);
+
+int get_cpufreq_scaling_max_freq(void);
+int set_cpufreq_scaling_max_freq(int);
+
+int get_cpufreq_scaling_min_freq(void);
+int set_cpufreq_scaling_min_freq(int);
+
+int get_cpufreq_sampling_rate(void);
+int set_cpufreq_sampling_rate(int);
+
+int get_cpufreq_up_threshold(void);
+int set_cpufreq_up_threshold(int);
+
+int get_cpu_online(int);
+int set_cpu_online(int, int);
+
+int64_t get_time_ms(void);
+
+#endif /* __PASS_PLUGIN__ */
diff --git a/src/pass/pass-table.h b/src/pass/pass-table.h
new file mode 100644 (file)
index 0000000..ce2c977
--- /dev/null
@@ -0,0 +1,881 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __PASS_TABLE__
+#define __PASS_TABLE__
+
+#include "pass.h"
+
+static struct pass_table pass_table_exynos4412[] = {
+       {
+       /* Low Level */
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1000000,
+               .limit_max_cpu = 3,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 800000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1000000,
+               .limit_max_cpu = 4,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 800000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                               .nr_running = 200,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1100000,
+               .limit_max_cpu = 3,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 900000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                               .nr_running = 200,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1100000,
+               .limit_max_cpu = 4,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 900000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                               .nr_running = 200,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+       /* Middle Level */
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1200000,
+               .limit_max_cpu = 3,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1100000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                               .nr_running = 200,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1200000,
+               .limit_max_cpu = 4,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1100000,
+                               .nr_running =300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1300000,
+               .limit_max_cpu = 3,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1300000,
+               .limit_max_cpu = 4,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+       /* High Level */
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1400000,
+               .limit_max_cpu = 3,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1300000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1400000,
+               .limit_max_cpu = 4,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1300000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1500000,
+               .limit_max_cpu = 3,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1300000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1100000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1500000,
+               .limit_max_cpu = 4,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1300000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1100000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1600000,
+               .limit_max_cpu = 3,
+
+               /* Level up for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1400000,
+                               .nr_running = 400,
+                               .busy_cpu = 3,
+                       },
+               },
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* Maximum constraint for Level */
+               .limit_max_freq = 1600000,
+               .limit_max_cpu = -1,
+
+               /* Level down for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                               .nr_running = 300,
+                               .busy_cpu = 3,
+                       },
+               },
+       },
+};
+
+static struct pass_table pass_table_exynos4412_radiation[] = {
+       {
+               /* level 0 - 0,0 */
+               .limit_max_freq = 1100000,
+               .limit_max_cpu = 1,
+
+               /* Level up/down/left/right for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+               /* level 1 - 0,1 */
+               .limit_max_freq = 1100000,
+               .limit_max_cpu = 2,
+
+               /* Level up/down/left/right for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 2 - 0,2 */
+               .limit_max_freq = 1100000,
+               .limit_max_cpu = 3,
+
+               /* Level up/down/left/right for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 3 - 0,3 */
+               .limit_max_freq = 1100000,
+               .limit_max_cpu = 4,
+
+               /* Level up/down/left/right for condition */
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1000000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 4 - 1,0 */
+               .limit_max_freq = 1200000,
+               .limit_max_cpu = 1,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+               /* level 5 - 1,1 */
+               .limit_max_freq = 1200000,
+               .limit_max_cpu = 2,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 200000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 6 - 1,2 */
+               .limit_max_freq = 1200000,
+               .limit_max_cpu = 3,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 200000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 7 - 1,3 */
+               .limit_max_freq = 1200000,
+               .limit_max_cpu = 4,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 200000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1200000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 8 - 2,0 */
+               .limit_max_freq = 1400000,
+               .limit_max_cpu = 1,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1400000,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+               /* level 9 - 2,1 */
+               .limit_max_freq = 1400000,
+               .limit_max_cpu = 2,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1400000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 10 - 2,2 */
+               .limit_max_freq = 1400000,
+               .limit_max_cpu = 3,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1400000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 11 - 2,3 */
+               .limit_max_freq = 1400000,
+               .limit_max_cpu = 4,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                       },
+               },
+               .num_up_cond = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 1400000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 12 - 3,0 */
+               .limit_max_freq = 1600000,
+               .limit_max_cpu = 1,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 800000,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+       }, {
+               /* level 13 - 3,1 */
+               .limit_max_freq = 1600000,
+               .limit_max_cpu = 2,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 800000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 14 - 3,2 */
+               .limit_max_freq = 1600000,
+               .limit_max_cpu = 3,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 800000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+               .num_right_cond = 1,
+               .right_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       }, {
+               /* level 15 - 3,3 */
+               .limit_max_freq = 1600000,
+               .limit_max_cpu = 4,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 800000,
+                       },
+               },
+               .num_left_cond = 1,
+               .left_cond = {
+                       [0] = {
+                               .nr_running = 300,
+                               .busy_cpu = 2,
+                       },
+               },
+       },
+};
+
+
+static struct pass_table pass_table_w_exynos4212[] = {
+       {
+               /* level 0 - 0,0 */
+               .limit_max_freq = 600000,
+               .limit_max_cpu = 1,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond  = 0,
+               .num_up_cond    = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 600000,
+                       },
+               },
+               .num_left_cond  = 0,
+               .num_right_cond = 0,
+       }, {
+               /* level 1 - 1,0 */
+               .limit_max_freq = 700000,
+               .limit_max_cpu = 1,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond  = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                       },
+               },
+               .num_up_cond    = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 700000,
+                       },
+               },
+               .num_left_cond  = 0,
+               .num_right_cond = 0,
+       }, {
+               /* level 2 - 2,0 */
+               .limit_max_freq = 800000,
+               .limit_max_cpu = 1,
+
+               /* Level up/down/left/right for condition */
+               .num_down_cond  = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 700000,
+                       },
+               },
+               .num_up_cond    = 1,
+               .up_cond = {
+                       [0] = {
+                               .freq = 800000,
+                               .nr_running = 200,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_left_cond  = 0,
+               .num_right_cond = 0,
+       }, {
+               /* level 3 - 0,1 */
+               .limit_max_freq = 600000,
+               .limit_max_cpu = 2,
+
+               .num_down_cond  = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 500000,
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_up_cond    = 1,
+               .up_cond = {
+                       [0] = { .freq = 600000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+               .num_left_cond  = 0,
+               .num_right_cond = 0,
+       }, {
+               /* level 4 - 1,1 */
+               .limit_max_freq = 700000,
+               .limit_max_cpu = 2,
+
+               .num_down_cond  = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 600000,
+                               .nr_running = 100,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_up_cond    = 1,
+               .up_cond = {
+                       [0] = { .freq = 700000,
+                               .nr_running = 200,
+                               .busy_cpu = 2,
+                       },
+               },
+               .num_left_cond  = 0,
+               .num_right_cond = 0,
+       }, {
+               /* level 5 - 2,1 */
+               .limit_max_freq = 800000,
+               .limit_max_cpu = 2,
+
+               .num_down_cond  = 1,
+               .down_cond = {
+                       [0] = {
+                               .freq = 600000,
+                               .nr_running = 150,
+                               .busy_cpu = 1,
+                       },
+               },
+               .num_up_cond    = 0,
+               .num_left_cond  = 0,
+               .num_right_cond = 0,
+       },
+};
+#endif /* __PASS_TABLE__ */
diff --git a/src/pass/pass-target.h b/src/pass/pass-target.h
new file mode 100644 (file)
index 0000000..9a127e1
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __PASS_TARGET__
+#define __PASS_TARGET__
+
+enum pass_target_type {
+       PASS_TARGET_UNKNOWN = 0,
+       PASS_TARGET_REDWOOD_EXYNOS4412_STEP,
+       PASS_TARGET_REDWOOD_EXYNOS4412_RADIATION,
+       PASS_TARGET_W_EXYNOS4212,
+
+       PASS_TARGET_TYPE_END,
+};
+
+#endif /* __PASS_TARGET__ */
similarity index 76%
rename from src/core/noti.h
rename to src/pass/pass-util.h
index 6895e31..32daea2 100644 (file)
  */
 
 
-#ifndef __NOTI_H__
-#define __NOTI_H__
+#ifndef __PASS_UTIL_H__
+#define __PASS_UTIL_H__
 
-int noti_getfd(void);
-int noti_send(char *filename);
-int noti_add(const char *noti, void (*cb) (void *), void *data);
-int noti_init(void);
+#ifdef ENABLE_DEVICED_DLOG
+#define ENABLE_DLOG
+#endif
 
-#endif /* __NOTI_H__ */
+#define LOG_TAG "PASS"
+#include "shared/log-macro.h"
+
+#endif /* __PASS_UTIL_H__ */
diff --git a/src/pass/pass.c b/src/pass/pass.c
new file mode 100644 (file)
index 0000000..ec24e40
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * PASS (Power Aware System Service)
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pass.h"
+#include "pass-core.h"
+#include "pass-target.h"
+
+#include "core/devices.h"
+#include "core/common.h"
+#include "core/edbus-handler.h"
+
+#define PASS_DEFAULT_MIN_LEVEL                 0
+#define PASS_DEFAULT_CPU_THRESHOLD             20
+#define PASS_DEFAULT_LEVEL_UP_THRESHOLD                30
+#define PASS_DEFAULT_LEVEL_DOWN_THRESHOLD      80
+
+/*
+ * Per-target pass policy
+ */
+static struct pass_policy policy;
+
+/******************************************************
+ *                PASS D-Bus interface                *
+ ******************************************************/
+static DBusMessage* e_dbus_start_cb(E_DBus_Object *obj, DBusMessage* msg)
+{
+       if (policy.governor)
+               policy.governor->update(&policy, PASS_GOV_START);
+       return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage* e_dbus_stop_cb(E_DBus_Object *obj, DBusMessage* msg)
+{
+       if (policy.governor)
+               policy.governor->update(&policy, PASS_GOV_STOP);
+       return dbus_message_new_method_return(msg);
+}
+
+static const struct edbus_method edbus_methods[] = {
+        { "start",           NULL,  NULL, e_dbus_start_cb },
+        { "stop",            NULL,  NULL, e_dbus_stop_cb },
+};
+
+/******************************************************
+ *                PASS interface (Init/Exit)          *
+ ******************************************************/
+
+/*
+ * pass_init - Initialize PASS(Power Aware System Service)
+ *
+ * @data: the instance of structre pass_policy
+ */
+static void pass_init(void *data)
+{
+       enum pass_target_type target_type;
+       int max_freq = 0;
+       int max_cpu = 0;
+       int ret;
+       int i;
+
+       /*
+        * Initialize pass-table by parsing pass.conf
+        */
+       ret = get_pass_table(&policy, PASS_CONF_PATH);
+       if (ret < 0) {
+               _E("cannot parse %s\n", PASS_CONF_PATH);
+               return;
+       }
+
+       /*
+        * Initialzie D-Bus interface of PASS. User can be able to
+        * turn on/off PASS through D-Bus interface.
+        */
+       ret = register_edbus_method(DEVICED_PATH_PASS, edbus_methods,
+                                   ARRAY_SIZE(edbus_methods));
+       if (ret < 0) {
+               _I("cannot initialize PASS D-Bus (%d)", ret);
+               return;
+       }
+
+       /* Check whether PASS is initialzied state or not */
+       if (policy.governor) {
+               _I("PASS is already active state");
+               return;
+       }
+
+       /*
+        * Set default value to global pass_policy instance
+        * if variable isn't initialized.
+        */
+       if (!policy.min_level)
+               policy.min_level = PASS_DEFAULT_MIN_LEVEL;
+       policy.default_min_level = policy.min_level;
+
+       if (!policy.max_level)
+               policy.max_level = policy.num_levels - 1;
+       policy.default_max_level = policy.max_level;
+
+       if (!policy.init_level)
+               policy.init_level = PASS_DEFAULT_MIN_LEVEL;
+
+       if (!policy.pass_cpu_threshold)
+               policy.pass_cpu_threshold = PASS_DEFAULT_CPU_THRESHOLD;
+
+       if (!policy.up_threshold)
+               policy.up_threshold = PASS_DEFAULT_LEVEL_UP_THRESHOLD;
+
+       if (!policy.down_threshold)
+               policy.down_threshold = PASS_DEFAULT_LEVEL_DOWN_THRESHOLD;
+
+       if (!policy.level_up_threshold)
+               policy.level_up_threshold = policy.max_level;
+
+       if (!policy.num_pass_cpu_stats)
+               policy.num_pass_cpu_stats = PASS_CPU_STATS_DEFAULT;
+
+       for (i = 0; i < policy.num_levels; i++) {
+               if (max_freq < policy.pass_table[i].limit_max_freq)
+                       max_freq = policy.pass_table[i].limit_max_freq;
+               if (max_cpu < policy.pass_table[i].limit_max_cpu)
+                       max_cpu = policy.pass_table[i].limit_max_cpu;
+       }
+       policy.cpufreq.max_freq = max_freq;
+       policy.cpufreq.num_nr_cpus = max_cpu;
+
+       /* Allocate memory according to the number of data and cpu */
+       policy.pass_cpu_stats = malloc(sizeof(struct pass_cpu_stats)
+                                               * policy.num_pass_cpu_stats);
+
+       for (i = 0; i < policy.num_pass_cpu_stats; i++) {
+               policy.pass_cpu_stats[i].load =
+                       malloc(sizeof(unsigned int) * policy.cpufreq.num_nr_cpus);
+               policy.pass_cpu_stats[i].nr_running =
+                       malloc(sizeof(unsigned int) * policy.cpufreq.num_nr_cpus);
+               policy.pass_cpu_stats[i].runnable_load =
+                       malloc(sizeof(unsigned int) * policy.cpufreq.num_nr_cpus);
+       }
+
+       /* Get the instance of PASS governor */
+       policy.governor = pass_get_governor(&policy, policy.gov_type);
+       if (!policy.governor) {
+               _E("cannot get the instance of PASS governor");
+               return;
+       }
+       policy.governor->gov_timeout    = policy.gov_timeout;
+
+       /* Get the instance of PASS hotplulg */
+       policy.hotplug = pass_get_hotplug(&policy, policy.gov_type);
+       if (!policy.hotplug) {
+               _E("cannot get the instance of PASS hotplug");
+       } else {
+               policy.hotplug->sequence = malloc(sizeof(int)
+                                                 * policy.cpufreq.num_nr_cpus);
+               for (i = 0; i < policy.cpufreq.num_nr_cpus; i++)
+                       policy.hotplug->sequence[i] = i;
+       }
+
+       if (policy.governor->init) {
+               ret = policy.governor->init(&policy);
+               if (ret < 0) {
+                       _E("cannot initialize PASS governor");
+                       return;
+               }
+       } else {
+               _E("cannot execute init() of PASS governor");
+               return;
+       }
+}
+
+/*
+ * pass_exit - Exit PASS
+ *
+ * @data: the instance of structre pass_policy
+ */
+static void pass_exit(void *data)
+{
+       int ret;
+
+       if (!policy.governor) {
+               _E("cannot exit PASS");
+               return;
+       }
+
+       put_pass_table(&policy);
+
+       if (policy.governor->exit) {
+               ret = policy.governor->exit(&policy);
+               if (ret < 0) {
+                       _E("cannot exit PASS governor");
+                       return;
+               }
+       } else {
+               _E("cannot execute exit() of PASS governor");
+               return;
+       }
+
+       policy.governor = NULL;
+}
+
+static const struct device_ops pass_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "pass",
+       .init     = pass_init,
+       .exit     = pass_exit,
+};
+
+DEVICE_OPS_REGISTER(&pass_device_ops)
diff --git a/src/pass/pass.conf b/src/pass/pass.conf
new file mode 100644 (file)
index 0000000..b2f6873
--- /dev/null
@@ -0,0 +1,4 @@
+# Default pass.conf
+# - If you want to use PASS(Power Aware System Service), you have to create
+# new 'pass-[target type].conf' configuration file.
+[Pass]
diff --git a/src/pass/pass.h b/src/pass/pass.h
new file mode 100644 (file)
index 0000000..3da7c86
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __PASS__
+#define __PASS__
+
+#include <Ecore.h>
+#include "pass-util.h"
+
+/******************************************************
+ *                   PASS Governors                   *
+ ******************************************************/
+#define PASS_NAME_LEN          128
+#define PASS_LEVEL_COND_MAX    3
+#define PASS_CPU_STATS_DEFAULT 20
+#define PASS_MIN_GOV_TIMEOUT   0.2
+
+#define PASS_CONF_PATH         "/etc/deviced/pass.conf"
+
+struct pass_policy;
+
+/*
+ * PASS state
+ */
+enum pass_state {
+       PASS_UNUSED = -1,
+       PASS_OFF = 0,
+       PASS_ON = 1,
+};
+
+/*
+ * PASS Governor type
+ */
+enum pass_gov_type {
+       PASS_GOV_STEP,
+       PASS_GOV_RADIATION,
+
+       PASS_GOV_END,
+};
+
+enum pass_gov_state {
+       PASS_GOV_NONE = 0,
+       PASS_GOV_START,
+       PASS_GOV_STOP,
+};
+
+/*
+ * PASS cpu state
+ */
+enum pass_cpu_state {
+       PASS_CPU_DOWN = 0,
+       PASS_CPU_UP,
+};
+
+/*
+ * struct pass_governor
+ */
+struct pass_governor {
+       char name[PASS_NAME_LEN];
+       int (*init)(struct pass_policy *);
+       int (*exit)(struct pass_policy *);
+       int (*update)(struct pass_policy *, enum pass_gov_state state);
+       int (*governor)(struct pass_policy *);
+       Ecore_Timer *gov_timer_id;
+       double gov_timeout;
+};
+
+/******************************************************
+ *                   PASS basic data                  *
+ ******************************************************/
+
+/*
+ * struct pass_cpu_stats
+ *
+ * @time: current time
+ * @freq: current cpu frequency
+ * @freq: new cpu frequency
+ * @nr_runnings: the average number of running threads
+ * @nr_running[]: current number of running threads of each core
+ * @runnable_load[]: the runnable load of each core
+ * @busy_cpu: the number of busy cpu
+ * @avg_load: the average load of all CPUs
+ * @avg_runnable_load: the average runnable load of all CPUs
+ * @avg_thread_load: the Per-thread load
+ * @avg_thread_runnable_load: the Per-thread runnable load
+ */
+struct pass_cpu_stats {
+       int64_t time;
+       unsigned int freq;
+       unsigned int freq_new;
+       unsigned int nr_runnings;
+
+       unsigned int *load;
+       unsigned int *nr_running;
+       unsigned int *runnable_load;
+
+       unsigned int num_busy_cpu;
+       unsigned int avg_load;
+       unsigned int avg_runnable_load;
+       unsigned int avg_thread_load;
+       unsigned int avg_thread_runnable_load;
+};
+
+/******************************************************
+ *                   PASS interface             *
+ ******************************************************/
+struct pass_level_condition {
+       int freq;
+       int nr_running;
+       int busy_cpu;
+       int avg_load;
+};
+
+struct pass_table {
+       /* Constraints condition for powersaving */
+       int limit_max_freq;
+       int limit_max_cpu;
+
+       /* Governor timer's timeout for each pass level */
+       double gov_timeout;
+
+       /* Condition to determine up/down of pass level */
+       struct pass_level_condition comm_cond;
+       struct pass_level_condition up_cond[PASS_LEVEL_COND_MAX];
+       struct pass_level_condition down_cond[PASS_LEVEL_COND_MAX];
+       struct pass_level_condition left_cond[PASS_LEVEL_COND_MAX];
+       struct pass_level_condition right_cond[PASS_LEVEL_COND_MAX];
+       int num_up_cond;
+       int num_down_cond;
+       int num_left_cond;
+       int num_right_cond;
+};
+
+/*
+ * struct pass_hotplug - store information of cpu hotplug
+ * @max_online: the possible maximum number of online cpu
+ * @online: the current number of online cpu
+ * @sequence: the sequence to turn on/off cpu
+ */
+struct pass_hotplug {
+       char name[PASS_NAME_LEN];
+       unsigned int max_online;
+       unsigned int online;
+       unsigned int *sequence;
+       int (*governor)(struct pass_policy *);
+};
+
+
+struct pass_cpufreq_policy {
+       unsigned int max_freq;
+       unsigned int num_nr_cpus;
+       unsigned int sampling_rate;
+       unsigned int up_threshold;
+};
+
+struct pass_busfreq_policy {
+       /* TODO */
+};
+
+struct pass_gpufreq_policy {
+       /* TODO */
+};
+
+struct pass_scenario {
+       char name[PASS_NAME_LEN];
+       enum pass_state state;
+       enum pass_state locked;
+       int64_t locked_time;
+
+       unsigned int cpufreq_min_level;
+       unsigned int cpufreq_max_level;
+
+       unsigned int busfreq_min_level;
+       unsigned int busfreq_max_level;
+
+       unsigned int gpufreq_min_level;
+       unsigned int gpufreq_max_level;
+};
+
+struct pass_scenario_policy {
+       enum pass_state state;
+       unsigned int num_scenarios;
+
+       struct pass_scenario *list;
+};
+
+/*
+ * struct pass_policy
+ */
+struct pass_policy {
+       enum pass_state state;
+       enum pass_gov_type gov_type;
+       enum pass_gov_state gov_state;
+       unsigned int pass_cpu_threshold;
+       unsigned int up_threshold;
+       unsigned int down_threshold;
+
+       unsigned int init_level;
+       unsigned int prev_level;
+       unsigned int curr_level;
+       unsigned int min_level;
+       unsigned int max_level;
+
+       unsigned int default_min_level;
+       unsigned int default_max_level;
+
+       unsigned int num_levels;
+       unsigned int level_up_threshold;
+
+       struct pass_cpufreq_policy cpufreq;
+       struct pass_busfreq_policy busfreq;
+       struct pass_gpufreq_policy gpufreq;
+       struct pass_scenario_policy scenario;
+
+       struct pass_table *pass_table;
+       struct pass_cpu_stats *pass_cpu_stats;
+       int num_pass_cpu_stats;
+
+       struct pass_governor *governor;
+       double gov_timeout;
+       struct pass_hotplug *hotplug;
+};
+#endif /* __pass__ */
index 51af26d..75ba964 100644 (file)
@@ -29,6 +29,7 @@
 #include "core/common.h"
 #include "core/list.h"
 #include "core/device-notifier.h"
+#include "powersaver/powersaver.h"
 #include "pmqos.h"
 
 #define DEFAULT_PMQOS_TIMER            3000
@@ -161,6 +162,30 @@ static int pmqos_poweroff(void *data)
        return set_cpu_pmqos("PowerOff", (int)data);
 }
 
+static int pmqos_ultrapowersaving(void *data)
+{
+       int mode = (int)data;
+       bool on;
+
+       switch (mode) {
+       case POWERSAVER_OFF:
+       case POWERSAVER_BASIC:
+               on = false;
+               break;
+       case POWERSAVER_ENHANCED:
+               on = true;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return set_cpu_pmqos("UltraPowerSaving", (int)on);
+}
+
+static int pmqos_hall(void *data)
+{
+       return pmqos_cpu_request("LockScreen", (int)data);
+}
+
 static DBusMessage *dbus_pmqos_handler(E_DBus_Object *obj, DBusMessage *msg)
 {
        DBusMessageIter iter;
@@ -300,6 +325,7 @@ static int get_methods_from_conf(const char *path, struct edbus_method **edbus_m
 /* Add pmqos name as alphabetically */
 static const struct edbus_method edbus_methods[] = {
        { "AppLaunch",            "i",    "i", dbus_pmqos_handler },
+       { "AppLaunchHome",        "i",    "i", dbus_pmqos_handler },
        { "BeautyShot",           "i",    "i", dbus_pmqos_handler },
        { "Browser",              "i",    "i", dbus_pmqos_handler },
        { "BrowserDash",          "i",    "i", dbus_pmqos_handler },
@@ -311,17 +337,21 @@ static const struct edbus_method edbus_methods[] = {
        { "CameraCaptureAtRec",   "i",    "i", dbus_pmqos_handler },
        { "CameraPreview",        "i",    "i", dbus_pmqos_handler },
        { "CameraSoundAndShot",   "i",    "i", dbus_pmqos_handler },
+       { "ContactSearch",        "i",    "i", dbus_pmqos_handler },
        { "Emergency",            "i",    "i", dbus_pmqos_handler },
+       { "GalleryScroll",        "i",    "i", dbus_pmqos_handler },
        { "GalleryRotation",      "i",    "i", dbus_pmqos_handler },
        { "GetDefaultLockTime",  NULL,    "i", dbus_getdefaultlocktime },
        { "GpsSerialCno",         "i",    "i", dbus_pmqos_handler },
        { "GpuBoost",             "i",    "i", dbus_pmqos_handler },
        { "GpuWakeup",            "i",    "i", dbus_pmqos_handler },
+       { "HomeScreen",           "i",    "i", dbus_pmqos_handler },
        { "ImageViewer",          "i",    "i", dbus_pmqos_handler },
        { "IMEInput",             "i",    "i", dbus_pmqos_handler },
        { "LockScreen",           "i",    "i", dbus_pmqos_handler },
        { "LowBattery",           "i",    "i", dbus_pmqos_handler },
        { "MtpSendFile",          "i",    "i", dbus_pmqos_handler },
+       { "MusicPlayLcdOn",       "i",    "i", dbus_pmqos_handler },
        { "PowerSaving",          "i",    "i", dbus_pmqos_handler },
        { "ProcessCrashed",       "i",    "i", dbus_pmqos_handler },
        { "ReservedMode",         "i",    "i", dbus_pmqos_handler },
@@ -336,11 +366,18 @@ static const struct edbus_method edbus_methods[] = {
        { "SensorWakeup",          "i",    "i", dbus_pmqos_handler },
 };
 
-static void pmqos_init(void *data)
+static int booting_done(void *data)
 {
+       static int done = 0;
        struct edbus_method *methods = NULL;
        int ret, size;
 
+       if (data == NULL)
+               goto out;
+       done = (int)data;
+       if (!done)
+               goto out;
+       _I("booting done");
        /* register edbus methods */
        ret = register_edbus_method(DEVICED_PATH_PMQOS, edbus_methods, ARRAY_SIZE(edbus_methods));
        if (ret < 0)
@@ -364,6 +401,17 @@ static void pmqos_init(void *data)
        register_notifier(DEVICE_NOTIFIER_PMQOS_LOWBAT, pmqos_lowbat);
        register_notifier(DEVICE_NOTIFIER_PMQOS_EMERGENCY, pmqos_emergency);
        register_notifier(DEVICE_NOTIFIER_PMQOS_POWEROFF, pmqos_poweroff);
+       register_notifier(DEVICE_NOTIFIER_PMQOS_ULTRAPOWERSAVING,
+           pmqos_ultrapowersaving);
+       register_notifier(DEVICE_NOTIFIER_PMQOS_HALL, pmqos_hall);
+
+out:
+       return done;
+}
+
+static void pmqos_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
 }
 
 static void pmqos_exit(void *data)
@@ -373,6 +421,9 @@ static void pmqos_exit(void *data)
        unregister_notifier(DEVICE_NOTIFIER_PMQOS_LOWBAT, pmqos_lowbat);
        unregister_notifier(DEVICE_NOTIFIER_PMQOS_EMERGENCY, pmqos_emergency);
        unregister_notifier(DEVICE_NOTIFIER_PMQOS_POWEROFF, pmqos_poweroff);
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS_ULTRAPOWERSAVING,
+           pmqos_ultrapowersaving);
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS_HALL, pmqos_hall);
 }
 
 static const struct device_ops pmqos_device_ops = {
index 80321e8..efc491b 100644 (file)
 #include <mntent.h>
 #include <sys/mount.h>
 #include <device-node.h>
+#include <journal/system.h>
 #include "dd-deviced.h"
 #include "core/log.h"
 #include "core/launch.h"
-#include "core/queue.h"
 #include "core/device-handler.h"
 #include "core/device-notifier.h"
-#include "core/predefine.h"
-#include "core/data.h"
 #include "core/common.h"
 #include "core/devices.h"
 #include "proc/proc-handler.h"
@@ -53,9 +51,6 @@
 #define SIGNAL_NAME_POWEROFF_POPUP     "poweroffpopup"
 #define SIGNAL_BOOTING_DONE            "BootingDone"
 
-#define PREDEF_PWROFF_POPUP            "pwroff-popup"
-#define PREDEF_INTERNAL_POWEROFF       "internal_poweroff"
-
 #define POWEROFF_NOTI_NAME             "power_off_start"
 #define POWEROFF_DURATION              2
 #define MAX_RETRY                      2
@@ -67,6 +62,7 @@
 #define POWEROFF_POPUP_NAME    "poweroff-syspopup"
 #define UMOUNT_RW_PATH "/opt/usr"
 
+static void poweroff_control_cb(keynode_t *in_key, void *data);
 
 struct popup_data {
        char *name;
@@ -76,37 +72,207 @@ struct popup_data {
 static struct timeval tv_start_poweroff;
 
 static int power_off = 0;
-static const struct device_ops *telephony;
+static const struct device_ops *telephony = NULL;
 static const struct device_ops *hall_ic = NULL;
+
 static void telephony_init(void)
 {
-       if (telephony)
-               return;
-       telephony = find_device("telephony");
+       FIND_DEVICE_VOID(telephony, "telephony");
        _I("telephony (%d)", telephony);
 }
 
 static void telephony_start(void)
 {
        telephony_init();
-       if (telephony)
-               telephony->start();
+       device_start(telephony);
 }
 
 static void telephony_stop(void)
 {
-       if (telephony)
-               telephony->stop();
+       device_stop(telephony);
 }
 
 static int telephony_exit(void *data)
 {
-       if (!telephony)
-               return -EINVAL;
-       telephony->exit(data);
+       int ret;
+
+       ret = device_exit(telephony, data);
+       return ret;
+}
+
+static int systemd_manager_object(const char *opt, char **param)
+{
+       return dbus_method_async("org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                opt,
+                                "ss", param);
+}
+
+static int systemd_manager_object_start_unit(char **param)
+{
+       return systemd_manager_object("StartUnit", param);
+}
+
+static int systemd_manager_object_stop_unit(char **param)
+{
+       return systemd_manager_object("StopUnit", param);
+}
+
+static int stop_systemd_journald(void)
+{
+       char *journal_socket[2]  = { "systemd-journald.socket",    "replace" };
+       char *journal_service[2] = { "systemd-journald.service",   "replace" };
+
+       int ret = 0;
+
+       ret = systemd_manager_object_stop_unit(journal_socket);
+       if (ret < 0) {
+               _E("failed to stop 'systemd-journald.socket'");
+               return ret;
+       }
+       ret |= systemd_manager_object_stop_unit(journal_service);
+       if (ret < 0) {
+               _E("failed to stop 'systemd-journald.service'");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int hall_ic_status(void)
+{
+       int ret;
+
+       ret = device_get_status(hall_ic);
+       if (ret < 0)
+               return HALL_IC_OPENED;
+       return ret;
+}
+
+static void poweroff_start_animation(void)
+{
+       char params[128];
+       snprintf(params, sizeof(params), "/usr/bin/boot-animation --stop --clear");
+       launch_app_cmd_with_nice(params, -20);
+       launch_evenif_exist("/usr/bin/sound_server", "--poweroff");
+       device_notify(DEVICE_NOTIFIER_POWEROFF_HAPTIC, NULL);
+}
+
+int previous_poweroff(void)
+{
+       int ret;
+       static const struct device_ops *display_device_ops = NULL;
+
+       telephony_start();
+
+       FIND_DEVICE_INT(display_device_ops, "display");
+
+       display_device_ops->exit(NULL);
+       sync();
+
+       gettimeofday(&tv_start_poweroff, NULL);
+
+       ret = telephony_exit(POWER_POWEROFF);
+
+       if (ret < 0) {
+               powerdown_ap(NULL);
+               return 0;
+       }
+       return ret;
+}
+
+static int poweroff(void)
+{
+       int retry_count = 0;
+       poweroff_start_animation();
+       while (retry_count < MAX_RETRY) {
+               if (previous_poweroff() < 0) {
+                       _E("failed to request poweroff to deviced");
+                       retry_count++;
+                       continue;
+               }
+               vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
+               return 0;
+       }
+       return -1;
+}
+
+static int pwroff_popup(void)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+       int val;
+
+       val = hall_ic_status();
+       if (val == HALL_IC_CLOSED) {
+               _I("cover is closed");
+               return 0;
+       }
+
+       FIND_DEVICE_INT(apps, "apps");
+
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+       params->name = POWEROFF_POPUP_NAME;
+       apps->init((void *)params);
+       free(params);
        return 0;
 }
 
+static int power_reboot(int type)
+{
+       int ret;
+
+       const struct device_ops *display_device_ops = NULL;
+       poweroff_start_animation();
+       telephony_start();
+
+       FIND_DEVICE_INT(display_device_ops, "display");
+
+       pm_change_internal(getpid(), LCD_NORMAL);
+       display_device_ops->exit(NULL);
+       sync();
+
+       gettimeofday(&tv_start_poweroff, NULL);
+
+       if (type == SYSTEMD_STOP_POWER_RESTART_RECOVERY)
+               ret = telephony_exit(POWER_RECOVERY);
+       else if (type == SYSTEMD_STOP_POWER_RESTART_FOTA)
+               ret = telephony_exit(POWER_FOTA);
+       else
+               ret = telephony_exit(POWER_REBOOT);
+
+       if (ret < 0) {
+               restart_ap((void *)type);
+               return 0;
+       }
+       return ret;
+}
+
+static int power_execute(void *data)
+{
+       int ret = 0;
+
+       if (strncmp(POWER_POWEROFF, (char *)data, POWER_POWEROFF_LEN) == 0)
+               ret = poweroff();
+       else if (strncmp(PWROFF_POPUP, (char *)data, PWROFF_POPUP_LEN) == 0)
+               ret = pwroff_popup();
+       else if (strncmp(POWER_REBOOT, (char *)data, POWER_REBOOT_LEN) == 0)
+               ret = power_reboot(VCONFKEY_SYSMAN_POWER_OFF_RESTART);
+       else if (strncmp(POWER_RECOVERY, (char *)data, POWER_RECOVERY_LEN) == 0)
+               ret = power_reboot(SYSTEMD_STOP_POWER_RESTART_RECOVERY);
+       else if (strncmp(POWER_FOTA, (char *)data, POWER_FOTA_LEN) == 0)
+               ret = power_reboot(SYSTEMD_STOP_POWER_RESTART_FOTA);
+       else if (strncmp(INTERNAL_PWROFF, (char *)data, INTERNAL_PWROFF_LEN) == 0)
+               ret = previous_poweroff();
+
+       return ret;
+}
+
 static void poweroff_popup_edbus_signal_handler(void *data, DBusMessage *msg)
 {
        DBusError err;
@@ -125,13 +291,13 @@ static void poweroff_popup_edbus_signal_handler(void *data, DBusMessage *msg)
                return;
        }
 
-       if (strncmp(str, PREDEF_PWROFF_POPUP, strlen(PREDEF_PWROFF_POPUP)) == 0)
+       if (!strncmp(str, PWROFF_POPUP, PWROFF_POPUP_LEN))
                val = VCONFKEY_SYSMAN_POWER_OFF_POPUP;
-       else if (strncmp(str, PREDEF_POWEROFF, strlen(PREDEF_POWEROFF)) == 0)
-               val = VCONFKEY_SYSMAN_POWER_OFF_DIRECT;
-       else if (strncmp(str, PREDEF_REBOOT, strlen(PREDEF_REBOOT)) == 0)
-               val = VCONFKEY_SYSMAN_POWER_OFF_RESTART;
-       else if (strncmp(str, PREDEF_FOTA_REBOOT, strlen(PREDEF_FOTA_REBOOT)) == 0)
+       else if (!strncmp(str, POWER_POWEROFF, POWER_POWEROFF_LEN))
+               val = SYSTEMD_STOP_POWER_OFF;
+       else if (!strncmp(str, POWER_REBOOT, POWER_REBOOT_LEN))
+               val = SYSTEMD_STOP_POWER_RESTART;
+       else if (!strncmp(str, POWER_FOTA, POWER_FOTA_LEN))
                val = SYSTEMD_STOP_POWER_RESTART_FOTA;
        if (val == 0) {
                _E("not supported message : %s", str);
@@ -140,15 +306,33 @@ static void poweroff_popup_edbus_signal_handler(void *data, DBusMessage *msg)
        vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, val);
 }
 
+static int booting_done(void *data)
+{
+       static int done = 0;
+
+       if (data == NULL)
+               goto out;
+
+       done = (int)data;
+       telephony_init();
+out:
+       return done;
+}
+
 static void booting_done_edbus_signal_handler(void *data, DBusMessage *msg)
 {
+       int done;
+
        if (!dbus_message_is_signal(msg, DEVICED_INTERFACE_CORE, SIGNAL_BOOTING_DONE)) {
                _E("there is no bootingdone signal");
                return;
        }
+       done = booting_done(NULL);
+       if (done)
+               return;
 
+       _I("signal booting done");
        device_notify(DEVICE_NOTIFIER_BOOTING_DONE, (void *)TRUE);
-       telephony_init();
 }
 
 static void poweroff_send_broadcast(int status)
@@ -177,16 +361,7 @@ static void poweroff_stop_systemd_service(void)
        umount2("/sys/fs/cgroup", MNT_FORCE |MNT_DETACH);
 }
 
-static void poweroff_start_animation(void)
-{
-       char params[128];
-       snprintf(params, sizeof(params), "/usr/bin/boot-animation --stop --clear");
-       launch_app_cmd_with_nice(params, -20);
-       launch_evenif_exist("/usr/bin/sound_server", "--poweroff");
-       device_notify(DEVICE_NOTIFIER_POWEROFF_HAPTIC, NULL);
-}
-
-static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
+static void poweroff_control_cb(keynode_t *in_key, void *data)
 {
        int val;
        int ret;
@@ -203,6 +378,7 @@ static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
            val == SYSTEMD_STOP_POWER_RESTART ||
            val == SYSTEMD_STOP_POWER_RESTART_RECOVERY ||
            val == SYSTEMD_STOP_POWER_RESTART_FOTA) {
+               pm_lock_internal(INTERNAL_LOCK_POWEROFF, LCD_OFF, STAY_CUR_STATE, 0);
                poweroff_stop_systemd_service();
                if (val == SYSTEMD_STOP_POWER_OFF)
                        val = VCONFKEY_SYSMAN_POWER_OFF_DIRECT;
@@ -218,19 +394,14 @@ static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
        switch (val) {
        case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
                device_notify(DEVICE_NOTIFIER_POWEROFF, (void *)val);
-               notify_action(PREDEF_POWEROFF, 0);
+               poweroff();
                break;
        case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
-               notify_action(PREDEF_PWROFF_POPUP, 0);
+               pwroff_popup();
                break;
        case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
                device_notify(DEVICE_NOTIFIER_POWEROFF, (void *)val);
-               if (recovery == SYSTEMD_STOP_POWER_RESTART_RECOVERY)
-                       notify_action(PREDEF_RECOVERY, 0);
-               else if (recovery == SYSTEMD_STOP_POWER_RESTART_FOTA)
-                       notify_action(PREDEF_FOTA_REBOOT, 0);
-               else
-                       notify_action(PREDEF_REBOOT, 0);
+               power_reboot(recovery);
                break;
        }
 
@@ -243,8 +414,10 @@ static void unmount_rw_partition()
 {
        int retry = 0;
        sync();
+#ifdef MICRO_DD
        if (!mount_check(UMOUNT_RW_PATH))
                return;
+#endif
        while (1) {
                switch (retry++) {
                case 0:
@@ -286,6 +459,9 @@ static void powerdown(void)
                _E("during power off");
                return;
        }
+       journal_system_shutdown();
+       /* if this fails, that's OK */
+       stop_systemd_journald();
        telephony_stop();
        vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
        power_off = 1;
@@ -309,7 +485,9 @@ static void powerdown(void)
                if (check_duration < 0)
                        break;
        }
+#ifndef EMULATOR
        unmount_rw_partition();
+#endif
 }
 
 static void restart_by_mode(int mode)
@@ -322,149 +500,6 @@ static void restart_by_mode(int mode)
                reboot(RB_AUTOBOOT);
 }
 
-int internal_poweroff_def_predefine_action(int argc, char **argv)
-{
-       int ret;
-       const struct device_ops *display_device_ops;
-
-       telephony_start();
-
-       display_device_ops = find_device("display");
-       if (!display_device_ops) {
-               _E("Can't find display_device_ops");
-               return -ENODEV;
-       }
-
-       display_device_ops->exit(NULL);
-       sync();
-
-       gettimeofday(&tv_start_poweroff, NULL);
-
-       ret = telephony_exit(PREDEF_POWEROFF);
-
-       if (ret < 0) {
-               powerdown_ap(NULL);
-               return 0;
-       }
-       return ret;
-}
-
-int do_poweroff(int argc, char **argv)
-{
-       return internal_poweroff_def_predefine_action(argc, argv);
-}
-
-int poweroff_def_predefine_action(int argc, char **argv)
-{
-       int retry_count = 0;
-       poweroff_start_animation();
-       while (retry_count < MAX_RETRY) {
-               if (notify_action(PREDEF_INTERNAL_POWEROFF, 0) < 0) {
-                       _E("failed to request poweroff to deviced");
-                       retry_count++;
-                       continue;
-               }
-               vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
-               return 0;
-       }
-       return -1;
-}
-
-static int hall_ic_status(void)
-{
-       if (!hall_ic)
-               return HALL_IC_OPENED;
-       return hall_ic->status();
-}
-
-int launching_predefine_action(int argc, char **argv)
-{
-       struct popup_data *params;
-       static const struct device_ops *apps = NULL;
-       int val;
-
-       val = hall_ic_status();
-       if (val == HALL_IC_CLOSED) {
-               _I("cover is closed");
-               return 0;
-       }
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return 0;
-       }
-       params = malloc(sizeof(struct popup_data));
-       if (params == NULL) {
-               _E("Malloc failed");
-               return -1;
-       }
-       params->name = POWEROFF_POPUP_NAME;
-       apps->init((void *)params);
-       free(params);
-       return 0;
-}
-
-int restart_def_predefine_action(int argc, char **argv)
-{
-       int ret;
-       int data = 0;
-
-       const struct device_ops *display_device_ops;
-       poweroff_start_animation();
-       telephony_start();
-
-       display_device_ops = find_device("display");
-       if (!display_device_ops) {
-               _E("Can't find display_device_ops");
-               return -ENODEV;
-       }
-
-       pm_change_internal(getpid(), LCD_NORMAL);
-       display_device_ops->exit(NULL);
-       sync();
-
-       gettimeofday(&tv_start_poweroff, NULL);
-
-       if (argc == 1 && argv)
-               data = atoi(argv[0]);
-       if (data == SYSTEMD_STOP_POWER_RESTART_RECOVERY)
-               ret = telephony_exit(PREDEF_RECOVERY);
-       else if (data == SYSTEMD_STOP_POWER_RESTART_FOTA)
-               ret = telephony_exit(PREDEF_FOTA_REBOOT);
-       else
-               ret = telephony_exit(PREDEF_REBOOT);
-
-       if (ret < 0) {
-               restart_ap((void *)data);
-               return 0;
-       }
-       return ret;
-}
-
-int restart_recovery_def_predefine_action(int argc, char **argv)
-{
-       int ret;
-       char *param[1];
-       char status[32];
-
-       snprintf(status, sizeof(status), "%d", SYSTEMD_STOP_POWER_RESTART_RECOVERY);
-       param[0] = status;
-
-       return restart_def_predefine_action(1, param);
-}
-
-int restart_fota_def_predefine_action(int argc, char **argv)
-{
-       int ret;
-       char *param[1];
-       char status[32];
-
-       snprintf(status, sizeof(status), "%d", SYSTEMD_STOP_POWER_RESTART_FOTA);
-       param[0] = status;
-
-       return restart_def_predefine_action(1, param);
-}
-
 int reset_resetkey_disable(char *name, enum watch_id id)
 {
        _D("force reset power resetkey disable to zero");
@@ -577,12 +612,12 @@ static DBusMessage *dbus_power_handler(E_DBus_Object *obj, DBusMessage *msg)
 
        telephony_start();
 
-       if(strncmp(type_str, PREDEF_REBOOT, strlen(PREDEF_REBOOT)) == 0)
-               restart_def_predefine_action(0, NULL);
-       else if(strncmp(type_str, PREDEF_RECOVERY, strlen(PREDEF_RECOVERY)) == 0)
-               restart_recovery_def_predefine_action(0, NULL);
-       else if(strncmp(type_str, PREDEF_PWROFF_POPUP, strlen(PREDEF_PWROFF_POPUP)) == 0)
-               launching_predefine_action(0, NULL);
+       if(!strncmp(type_str, POWER_REBOOT, POWER_REBOOT_LEN))
+               ret = power_reboot(VCONFKEY_SYSMAN_POWER_OFF_RESTART);
+       else if(!strncmp(type_str, POWER_RECOVERY, POWER_RECOVERY_LEN))
+               ret = power_reboot(SYSTEMD_STOP_POWER_RESTART_RECOVERY);
+       else if(!strncmp(type_str, PWROFF_POPUP, PWROFF_POPUP_LEN))
+               ret = pwroff_popup();
 
 out:
        reply = dbus_message_new_method_return(msg);
@@ -602,6 +637,7 @@ void powerdown_ap(void *data)
 void restart_ap(void *data)
 {
        _I("Restart %d", (int)data);
+       journal_system_device_reboot((int)data);
        powerdown();
        restart_by_mode((int)data);
 }
@@ -609,9 +645,9 @@ void restart_ap(void *data)
 static const struct edbus_method edbus_methods[] = {
        { "setresetkeydisable",   "i",   "i", edbus_resetkeydisable },
        { "SetWakeupKey", "i", "i", edbus_set_wakeup_key },
-       { PREDEF_REBOOT, "si", "i", dbus_power_handler },
-       { PREDEF_RECOVERY, "si", "i", dbus_power_handler },
-       { PREDEF_PWROFF_POPUP, "si", "i", dbus_power_handler },
+       { POWER_REBOOT, "si", "i", dbus_power_handler },
+       { POWER_RECOVERY, "si", "i", dbus_power_handler },
+       { PWROFF_POPUP, "si", "i", dbus_power_handler },
        /* Add methods here */
 };
 
@@ -625,20 +661,6 @@ static void power_init(void *data)
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
 
-       register_action(PREDEF_POWEROFF,
-                                    poweroff_def_predefine_action, NULL, NULL);
-       register_action(PREDEF_PWROFF_POPUP,
-                                    launching_predefine_action, NULL, NULL);
-       register_action(PREDEF_REBOOT,
-                                    restart_def_predefine_action, NULL, NULL);
-       register_action(PREDEF_RECOVERY,
-                                    restart_recovery_def_predefine_action, NULL, NULL);
-       register_action(PREDEF_FOTA_REBOOT,
-                                    restart_fota_def_predefine_action, NULL, NULL);
-
-       register_action(PREDEF_INTERNAL_POWEROFF,
-                                    internal_poweroff_def_predefine_action, NULL, NULL);
-
        if (vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void *)poweroff_control_cb, NULL) < 0) {
                _E("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_SYSMAN_POWER_OFF_STATUS);
        }
@@ -650,13 +672,16 @@ static void power_init(void *data)
                    DEVICED_INTERFACE_CORE,
                    SIGNAL_BOOTING_DONE,
                    booting_done_edbus_signal_handler);
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+
        hall_ic = find_device(HALL_IC_NAME);
 }
 
 static const struct device_ops power_device_ops = {
        .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "power",
+       .name     = POWER_OPS_NAME,
        .init     = power_init,
+       .execute  = power_execute,
 };
 
 DEVICE_OPS_REGISTER(&power_device_ops)
index 106bfe5..e01c600 100644 (file)
 #ifndef __POWER_HANDLE_H__
 #define __POWER_HANDLE_H__
 
-#define PREDEF_POWEROFF         "poweroff"
-#define PREDEF_REBOOT           "reboot"
-#define PREDEF_RECOVERY         "reboot-recovery"
-#define PREDEF_FOTA_REBOOT      "fota"
+#define POWER_OPS_NAME      "power"
+
+#define POWER_POWEROFF      "poweroff"
+#define POWER_POWEROFF_LEN  8
+#define POWER_REBOOT        "reboot"
+#define POWER_REBOOT_LEN    6
+#define POWER_RECOVERY      "reboot-recovery"
+#define POWER_RECOVERY_LEN  15
+#define POWER_FOTA          "fota"
+#define POWER_FOTA_LEN      4
+#define PWROFF_POPUP        "pwroff-popup"
+#define PWROFF_POPUP_LEN    12
+#define INTERNAL_PWROFF     "internal"
+#define INTERNAL_PWROFF_LEN 8
 
 #define SYSTEMD_STOP_POWER_RESTART              5
 #define SYSTEMD_STOP_POWER_RESTART_RECOVERY     6
index 40a402c..ae76f2d 100644 (file)
 #include <sys/mount.h>
 #include <device-node.h>
 #include "core/common.h"
-#include "core/data.h"
 #include "core/device-handler.h"
 #include "core/device-notifier.h"
 #include "core/devices.h"
 #include "core/edbus-handler.h"
 #include "core/launch.h"
 #include "core/log.h"
-#include "core/predefine.h"
-#include "core/queue.h"
 #include "dd-deviced.h"
 #include "display/poll.h"
 #include "display/setting.h"
@@ -47,7 +44,6 @@
 #include "proc/proc-handler.h"
 
 #define SIGNAL_BOOTING_DONE            "BootingDone"
-#define PREDEF_PWROFF_POPUP            "pwroff-popup"
 #define POWEROFF_POPUP_NAME            "poweroff-syspopup"
 #define RECOVERY_POWER_OFF             "reboot recovery"
 
@@ -88,18 +84,56 @@ static int systemd_shutdown(const char *arg)
        assert(arg);
        systemd_poweroff_timer = ecore_timer_add(SYSTEMD_CHECK_POWER_OFF,
                            systemd_force_shutdown_cb, (void *)arg);
+#ifdef MICRO_DD
        start_boot_animation();
        device_notify(DEVICE_NOTIFIER_POWEROFF_HAPTIC, NULL);
+#endif
        return launch_evenif_exist("/usr/bin/systemctl", arg);
 }
 
-int do_poweroff(int argc, char **argv)
+static int poweroff(void)
 {
        return vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
                             VCONFKEY_SYSMAN_POWER_OFF_DIRECT);
 }
 
-static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
+static int pwroff_popup(void)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+       int val;
+
+       val = hall_ic_status();
+       if (val == HALL_IC_CLOSED) {
+               _I("cover is closed");
+               return 0;
+       }
+
+       FIND_DEVICE_INT(apps, "apps");
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+       params->name = POWEROFF_POPUP_NAME;
+       apps->init((void *)params);
+       free(params);
+       return 0;
+}
+
+static int power_execute(void *data)
+{
+       int ret;
+
+       if (strncmp(POWER_POWEROFF, (char *)data, LEN_POWER_POWEROFF) == 0)
+               ret = poweroff();
+       else if (strncmp(PWROFF_POPUP, (char *)data, LEN_PWROFF_POPUP) == 0)
+               ret = pwroff_popup();
+
+       return ret;
+}
+
+static void poweroff_control_cb(keynode_t *in_key, void *data)
 {
        int val;
        int ret;
@@ -130,9 +164,9 @@ static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
        case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
                device_notify(DEVICE_NOTIFIER_POWEROFF,
                              (void *)VCONFKEY_SYSMAN_POWER_OFF_RESTART);
-               ret = systemd_shutdown(PREDEF_REBOOT);
+               ret = systemd_shutdown(POWER_REBOOT);
                if (ret < 0)
-                       _E("fail to do (%s)", PREDEF_REBOOT);
+                       _E("fail to do (%s)", POWER_REBOOT);
                break;
        case SYSTEMD_STOP_POWER_RESTART_RECOVERY:
                device_notify(DEVICE_NOTIFIER_POWEROFF,
@@ -142,7 +176,7 @@ static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
                        _E("fail to do (%s)", RECOVERY_POWER_OFF);
                break;
        case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
-               notify_action(PREDEF_PWROFF_POPUP, 0);
+               power_execute(PWROFF_POPUP);
                break;
        }
 
@@ -164,9 +198,12 @@ static void booting_done_edbus_signal_handler(void *data, DBusMessage *msg)
 
 static int hall_ic_status(void)
 {
-       if (!hall_ic)
+       int ret;
+
+       ret = device_get_status(hall_ic);
+       if (ret < 0)
                return HALL_IC_OPENED;
-       return hall_ic->status();
+       return ret;
 }
 
 int reset_resetkey_disable(char *name, enum watch_id id)
@@ -259,33 +296,6 @@ static const struct edbus_method edbus_methods[] = {
        /* Add methods here */
 };
 
-int launching_predefine_action(int argc, char **argv)
-{
-       struct popup_data *params;
-       static const struct device_ops *apps = NULL;
-       int val;
-
-       val = hall_ic_status();
-       if (val == HALL_IC_CLOSED) {
-               _I("cover is closed");
-               return 0;
-       }
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return 0;
-       }
-       params = malloc(sizeof(struct popup_data));
-       if (params == NULL) {
-               _E("Malloc failed");
-               return -1;
-       }
-       params->name = POWEROFF_POPUP_NAME;
-       apps->init((void *)params);
-       free(params);
-       return 0;
-}
-
 static void power_init(void *data)
 {
        int bTelReady = 0;
@@ -306,11 +316,6 @@ static void power_init(void *data)
                _E("fail to register handler for signal: %s",
                   SIGNAL_BOOTING_DONE);
 
-       register_action(PREDEF_POWEROFF,
-                       do_poweroff, NULL, NULL);
-       register_action(PREDEF_PWROFF_POPUP,
-                       launching_predefine_action, NULL, NULL);
-
        ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
                                       (void *)poweroff_control_cb,
                                       NULL);
@@ -322,8 +327,9 @@ static void power_init(void *data)
 
 static const struct device_ops power_device_ops = {
        .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "systemd-power",
-       .init     = power_init,
+       .name     = "systemd-power",
+       .init     = power_init,
+       .execute  = power_execute,
 };
 
 DEVICE_OPS_REGISTER(&power_device_ops)
diff --git a/src/powersaver/powersaver-micro.c b/src/powersaver/powersaver-micro.c
new file mode 100644 (file)
index 0000000..0517590
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <vconf.h>
+
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/log.h"
+#include "display/core.h"
+#include "display/device-interface.h"
+#include "powersaver.h"
+
+static int set_powersaver_mode(int mode)
+{
+       int ret;
+       int brightness, timeout;
+
+       _I("powersaver mode %d", mode);
+       device_notify(DEVICE_NOTIFIER_PMQOS_ULTRAPOWERSAVING, (void*)mode);
+
+       /* powersaver mode off */
+       if (mode == POWERSAVER_OFF ||
+           mode == POWERSAVER_BASIC ||
+           mode == POWERSAVER_ENHANCED) {
+               backlight_ops.set_force_brightness(0);
+               set_force_lcdtimeout(0);
+               goto update_state;
+       }
+
+       /* powersaver mode on (brightness) */
+       ret = vconf_get_int(VCONFKEY_SETAPPL_EMERGENCY_LCD_BRIGHTNESS_INT,
+           &brightness);
+       if (ret != 0) {
+               _E("Failed to get powersaver brightness!");
+               return ret;
+       }
+       ret = backlight_ops.set_force_brightness(brightness);
+       if (ret < 0) {
+               _E("Failed to set force brightness!");
+               return ret;
+       }
+       _I("force brightness %d", brightness);
+
+       /* powersaver mode on (lcd timeout) */
+       ret = vconf_get_int(VCONFKEY_SETAPPL_EMERGENCY_LCD_TIMEOUT_INT,
+           &timeout);
+       if (ret != 0) {
+               _E("Failed to get powersaver lcd timeout!");
+               return ret;
+       }
+       ret = set_force_lcdtimeout(timeout);
+       if (ret < 0) {
+               _E("Failed to set force timeout!");
+               return ret;
+       }
+       _I("force timeout %d", timeout);
+
+update_state:
+       /* update internal state */
+       if (hbm_get_state())
+               hbm_set_state_with_timeout(false, 0);
+       backlight_ops.update();
+       ret = get_run_timeout(&timeout);
+       if (ret >= 0)
+               states[S_NORMAL].timeout = timeout;
+       states[pm_cur_state].trans(EVENT_INPUT);
+
+       return 0;
+}
+
+static void powersaver_status_changed(keynode_t *key_nodes, void *data)
+{
+       int status, mode, ret;
+
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+
+       status = vconf_keynode_get_int(key_nodes);
+       if (status == SETTING_PSMODE_NORMAL)
+               mode = POWERSAVER_OFF;
+       else if (status == SETTING_PSMODE_WEARABLE)
+               mode = POWERSAVER_BASIC;
+       else if (status == SETTING_PSMODE_WEARABLE_ENHANCED)
+               mode = POWERSAVER_ENHANCED;
+       else
+               return;
+
+       ret = set_powersaver_mode(mode);
+       if (ret < 0)
+               _E("Failed to update powersaver state %d", ret);
+}
+
+static void powersaver_init(void *data)
+{
+       int ret, status;
+       int mode = POWERSAVER_OFF;
+
+       ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
+           powersaver_status_changed, NULL);
+       if (ret != 0)
+               _E("Failed to vconf_notify_key_changed!");
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &status);
+       if (ret != 0) {
+               _E("Failed to vconf get bool!");
+               return;
+       }
+
+       switch (status) {
+       case SETTING_PSMODE_WEARABLE:
+               mode = POWERSAVER_BASIC;
+               break;
+       case SETTING_PSMODE_WEARABLE_ENHANCED:
+               mode = POWERSAVER_ENHANCED;
+               break;
+       default:
+               return;
+       }
+
+       _D("powersaver mode on! %d", mode);
+       ret = set_powersaver_mode(mode);
+       if (ret < 0)
+               _E("Failed to update powersaver state %d", ret);
+}
+
+static void powersaver_exit(void *data)
+{
+       int ret;
+
+       ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
+           powersaver_status_changed);
+       if (ret != 0)
+               _E("Failed to vconf_ignore_key_changed!");
+}
+
+static const struct device_ops powersaver_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "powersaver-micro",
+       .init     = powersaver_init,
+       .exit     = powersaver_exit,
+};
+
+DEVICE_OPS_REGISTER(&powersaver_device_ops)
index dae3128..b10579a 100644 (file)
 #include "core/devices.h"
 #include "core/device-notifier.h"
 #include "core/log.h"
-#include "display/core.h"
-#include "display/device-interface.h"
 
-static int set_powersaver_mode(int on)
+static int power_saving_custom_cpu_cb(keynode_t *key_nodes, void *data)
 {
-       int ret;
-       int brightness, timeout;
-
-       _I("powersaver mode %s", (on ? "on" : "off"));
-       device_notify(DEVICE_NOTIFIER_POWERSAVER, (void*)on);
+       int val = 0;
 
-       /* powersaver mode off */
-       if (!on) {
-               backlight_ops.set_force_brightness(0);
-               set_force_lcdtimeout(0);
-               goto update_state;
-       }
+       val = vconf_keynode_get_bool(key_nodes);
+       device_notify(DEVICE_NOTIFIER_PMQOS_POWERSAVING, (void*)val);
+       return 0;
+}
 
-       /* powersaver mode on (brightness) */
-       ret = vconf_get_int(VCONFKEY_SETAPPL_EMERGENCY_LCD_BRIGHTNESS_INT,
-           &brightness);
-       if (ret != 0) {
-               _E("Failed to get powersaver brightness!");
-               return ret;
-       }
-       ret = backlight_ops.set_force_brightness(brightness);
-       if (ret < 0) {
-               _E("Failed to set force brightness!");
-               return ret;
-       }
-       _I("force brightness %d", brightness);
-
-       /* powersaver mode on (lcd timeout) */
-       ret = vconf_get_int(VCONFKEY_SETAPPL_EMERGENCY_LCD_TIMEOUT_INT,
-           &timeout);
-       if (ret != 0) {
-               _E("Failed to get powersaver lcd timeout!");
-               return ret;
-       }
-       ret = set_force_lcdtimeout(timeout);
-       if (ret < 0) {
-               _E("Failed to set force timeout!");
-               return ret;
-       }
-       _I("force timeout %d", timeout);
-
-update_state:
-       /* update internal state */
-       if (hbm_get_state())
-               hbm_set_state_with_timeout(false, 0);
-       backlight_ops.update();
-       ret = get_run_timeout(&timeout);
-       if (ret >= 0)
-               states[S_NORMAL].timeout = timeout;
-       states[pm_cur_state].trans(EVENT_INPUT);
+static int emergency_cpu_cb(keynode_t *key_nodes, void *data)
+{
+       int val;
 
+       val = vconf_keynode_get_int(key_nodes);
+       if (val == SETTING_PSMODE_EMERGENCY)
+               val = 1;
+       else
+               val = 0;
+       device_notify(DEVICE_NOTIFIER_PMQOS_EMERGENCY, (void*)val);
        return 0;
 }
 
-static void powersaver_status_changed(keynode_t *key_nodes, void *data)
+static void set_freq_limit(void)
 {
-       int status, on, ret;
+       int ret = 0;
+       int val = 0;
 
-       if (key_nodes == NULL) {
-               _E("wrong parameter, key_nodes is null");
+       ret = vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU,
+                       &val);
+       if (ret < 0) {
+               _E("failed to get vconf key");
                return;
        }
-
-       status = vconf_keynode_get_int(key_nodes);
-       if (status == SETTING_PSMODE_NORMAL)
-               on = false;
-       else if (status == SETTING_PSMODE_WEARABLE)
-               on = true;
-       else
+       if (val == 0)
                return;
-
-       ret = set_powersaver_mode(on);
-       if (ret < 0)
-               _E("Failed to update powersaver state %d", ret);
+       _I("init");
+       device_notify(DEVICE_NOTIFIER_PMQOS_POWERSAVING, (void*)val);
 }
 
-static int booting_done(void *data)
+static void set_emergency_limit(void)
 {
-       int ret, status;
+       int ret, val;
 
-       ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &status);
-       if (ret != 0) {
-               _E("Failed to vconf get bool!");
-               return -EIO;
+       ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &val);
+       if (ret < 0) {
+               _E("failed to get vconf key");
+               return;
        }
+       if (val != SETTING_PSMODE_EMERGENCY)
+               return;
 
-       if (status != SETTING_PSMODE_WEARABLE)
-               return 0;
+       val = 1;
+       device_notify(DEVICE_NOTIFIER_PMQOS_EMERGENCY, (void*)val);
 
-       _D("powersaver mode on!");
-       ret = set_powersaver_mode(true);
-       if (ret < 0)
-               _E("Failed to update powersaver state %d", ret);
+}
+
+static int booting_done(void *data)
+{
+       set_freq_limit();
+       set_emergency_limit();
 
-       return ret;
+       return 0;
 }
 
 static void powersaver_init(void *data)
 {
        int ret;
 
+       ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU,
+               (void *)power_saving_custom_cpu_cb, NULL);
+       if (ret != 0)
+               _E("Failed to vconf_notify_key_changed!");
        ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
-           powersaver_status_changed, NULL);
+               (void *)emergency_cpu_cb, NULL);
        if (ret != 0)
                _E("Failed to vconf_notify_key_changed!");
-
        register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
 }
 
 static void powersaver_exit(void *data)
 {
-       int ret;
-
-       ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
-           powersaver_status_changed);
-       if (ret != 0)
-               _E("Failed to vconf_ignore_key_changed!");
-
        unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
 }
 
diff --git a/src/powersaver/powersaver.h b/src/powersaver/powersaver.h
new file mode 100644 (file)
index 0000000..84312c8
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 __POWERSAVER_H__
+#define __POWERSAVER_H__
+
+enum powersaver_state {
+       POWERSAVER_OFF,
+       POWERSAVER_ENHANCED,
+       POWERSAVER_BASIC,
+};
+
+#endif //__POWERSAVER_H__
index 98abc37..7f88d0f 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "core/log.h"
 #include "core/launch.h"
-#include "core/data.h"
 #include "core/common.h"
 #include "core/devices.h"
 
@@ -34,7 +33,7 @@
 
 static Ecore_Fd_Handler *pmon_efd = NULL;
 
-static int __pmon_start(struct main_data *ad);
+static int __pmon_start(void);
 static int __pmon_stop(int fd);
 static int replace_char(int size, char *t)
 {
@@ -92,7 +91,7 @@ static void print_pmon_state(unsigned int dead_pid)
        _D("[Process MON] %d killed", dead_pid);
 }
 
-static int pmon_process(int pid, void *ad)
+static int pmon_process(int pid)
 {
        char *cmdline;
        int new_pid;
@@ -193,7 +192,6 @@ static unsigned int pmon_read(int fd)
 static Eina_Bool pmon_cb(void *data, Ecore_Fd_Handler * fd_handler)
 {
        int fd;
-       struct main_data *ad = (struct main_data *)data;
        int dead_pid;
        char pid_str[PATH_MAX];
        int ret;
@@ -215,19 +213,19 @@ static Eina_Bool pmon_cb(void *data, Ecore_Fd_Handler * fd_handler)
        if (ret < 0 || ret >= PATH_MAX) {
                __pmon_stop(fd);
                _E("Reading DEAD_PID failed, restart ecore fd");
-               __pmon_start(ad);
+               __pmon_start();
                goto out;
        }
 
        pid_str[ret] = '\0';
        dead_pid = strtoul(pid_str, NULL, 10);
        print_pmon_state(dead_pid);
-       pmon_process(dead_pid, ad);
+       pmon_process(dead_pid);
 out:
        return EINA_TRUE;
 }
 
-static int __pmon_start(struct main_data *ad)
+static int __pmon_start(void)
 {
        int pmon_fd = -1;
        char pmon_dev_node[PATH_MAX];
@@ -264,14 +262,13 @@ static int __pmon_stop(int fd)
 
 static void pmon_init(void *data)
 {
-       struct main_data *ad = (struct main_data*)data;
        int ret = -1;
 
        if (pmon_efd) {
                ecore_main_fd_handler_del(pmon_efd);
                pmon_efd = NULL;
        }
-       if (__pmon_start(ad) == -1) {
+       if (__pmon_start() == -1) {
                _E("fail pmon control fd init");
        }
 }
index 7b4c258..feb4e31 100644 (file)
@@ -30,8 +30,6 @@
 #include <vconf-keys.h>
 #include <fcntl.h>
 
-#include "core/data.h"
-#include "core/queue.h"
 #include "core/log.h"
 #include "core/common.h"
 #include "core/devices.h"
 #include "proc-handler.h"
 #include "core/edbus-handler.h"
 
+#define TEMPERATURE_DBUS_INTERFACE     "org.tizen.trm.siop"
+#define TEMPERATURE_DBUS_PATH          "/Org/Tizen/Trm/Siop"
+#define TEMPERATURE_DBUS_SIGNAL                "ChangedTemperature"
+
 #define LIMITED_PROCESS_OOMADJ 15
 
 #define PROCESS_VIP            "process_vip"
@@ -74,6 +76,11 @@ enum SIOP_DOMAIN_TYPE {
        SIOP_POSITIVE = 1,
 };
 
+struct siop_data {
+       int siop;
+       int rear;
+};
+
 static int siop = 0;
 static int mode = 0;
 static int siop_domain = SIOP_POSITIVE;
@@ -197,9 +204,6 @@ static void siop_level_action(int level)
 
 static int siop_changed(int argc, char **argv)
 {
-#ifdef MICRO_DD
-       return 0;
-#else
        int siop_level = 0;
        int rear_level = 0;
        int level;
@@ -238,7 +242,6 @@ out:
        level = SIOP_CTRL_VALUE(siop_level, rear_level);
        siop_level_action(level);
        return 0;
-#endif
 }
 
 static int siop_mode_lcd(keynode_t *key_nodes, void *data)
@@ -720,7 +723,6 @@ static void dbus_proc_oomadj_set_signal_handler(void *data, DBusMessage *msg)
                _E("set_process_action error!");
 }
 
-
 static const struct edbus_method edbus_methods[] = {
        { PREDEF_FOREGRD, "sis", "i", dbus_proc_handler },
        { PREDEF_BACKGRD, "sis", "i", dbus_proc_handler },
@@ -735,12 +737,78 @@ static const struct edbus_method edbus_methods[] = {
 
 static int proc_booting_done(void *data)
 {
-       register_action(SIOP_CHANGED, siop_changed, NULL, NULL);
+       static int done = 0;
+
+       if (data == NULL)
+               goto out;
+       done = (int)data;
        if (vconf_notify_key_changed(VCONFKEY_PM_STATE, (void *)siop_mode_lcd, NULL) < 0)
                _E("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_PM_STATE);
        siop_mode_lcd(NULL, NULL);
+out:
+       return done;
+}
+
+static int process_execute(void *data)
+{
+       struct siop_data* key_data = (struct siop_data *)data;
+       int siop_level = 0;
+       int rear_level = 0;
+       int level;
+       int siop_disable;
+       int ret;
+       int booting_done;
+
+       booting_done = proc_booting_done(NULL);
+       if (!booting_done)
+               return 0;
+
+       if (key_data == NULL)
+               goto out;
+
+       level = key_data->siop;
+       device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_ELVSS_CONTROL, level);
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_SIOP_LEVEL, &level);
+       if (ret != 0)
+               goto check_rear;
+
+       if (level <= SIOP_NEGATIVE)
+               siop_domain = SIOP_NEGATIVE;
+       else
+               siop_domain = SIOP_POSITIVE;
+       siop_level = siop_domain * level;
+
+check_rear:
+       level = key_data->rear;
+       if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_REAR_LEVEL, &level) == 0)
+               rear_level = level;
+
+out:
+       level = SIOP_CTRL_VALUE(siop_level, rear_level);
+       siop_level_action(level);
        return 0;
 }
+
+static void temp_change_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int level = 0;
+
+       if (dbus_message_is_signal(msg, TEMPERATURE_DBUS_INTERFACE, TEMPERATURE_DBUS_SIGNAL) == 0) {
+               _E("there is no cool down signal");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       if (dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level, DBUS_TYPE_INVALID) == 0) {
+               _E("there is no message");
+               return;
+       }
+       _D("%d", level);
+       device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_ELVSS_CONTROL, level);
+}
+
 static void process_init(void *data)
 {
        int ret;
@@ -748,25 +816,22 @@ static void process_init(void *data)
        register_edbus_signal_handler(DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
                        SIGNAL_NAME_OOMADJ_SET,
                    dbus_proc_oomadj_set_signal_handler);
+       register_edbus_signal_handler(TEMPERATURE_DBUS_PATH, TEMPERATURE_DBUS_INTERFACE,
+                       TEMPERATURE_DBUS_SIGNAL,
+                   temp_change_signal_handler);
 
        ret = register_edbus_method(DEVICED_PATH_PROCESS, edbus_methods, ARRAY_SIZE(edbus_methods));
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
 
-       register_action(PREDEF_FOREGRD, set_process_action, NULL, NULL);
-       register_action(PREDEF_BACKGRD, set_process_action, NULL, NULL);
-       register_action(PREDEF_ACTIVE, set_active_action, NULL, NULL);
-       register_action(PREDEF_INACTIVE, set_inactive_action, NULL, NULL);
-       register_action(OOMADJ_SET, set_oom_score_adj_action, NULL, NULL);
-       register_action(PROCESS_GROUP_SET, set_process_group_action, NULL, NULL);
-
        register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, proc_booting_done);
 }
 
 static const struct device_ops process_device_ops = {
        .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "process",
+       .name     = PROC_OPS_NAME,
        .init     = process_init,
+       .execute  = process_execute,
 };
 
 DEVICE_OPS_REGISTER(&process_device_ops)
index 4a87faf..5eec8c8 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "shared/score-defines.h"
 
-#define SIOP_CHANGED   "siop_level"
+#define PROC_OPS_NAME  "process"
 
 int get_oom_score_adj(int pid, int *oom_score_adj);
 int set_oom_score_adj(int pid, int new_oom_score_adj);
index 23bedad..835a01a 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <errno.h>
 
@@ -39,6 +40,7 @@ int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
        char *ch;
        int i;
        int int_type;
+       dbus_bool_t bool_type;
        uint64_t int64_type;
        DBusMessageIter arr;
        struct dbus_byte *byte;
@@ -48,6 +50,10 @@ int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
 
        for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
                switch (*ch) {
+               case 'b':
+                       bool_type = (atoi(param[i])) ? TRUE:FALSE;
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &bool_type);
+                       break;
                case 'i':
                        int_type = atoi(param[i]);
                        dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
@@ -192,6 +198,62 @@ int dbus_method_sync(const char *dest, const char *path,
        return result;
 }
 
+int dbus_method_sync_timeout(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[], int timeout)
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       DBusError err;
+       int ret, result;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return -EPERM;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return -EBADMSG;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       ret = append_variant(&iter, sig, param);
+       if (ret < 0) {
+               _E("append_variant error(%d) %s %s:%s-%s",
+                       ret, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return ret;
+       }
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
+       dbus_message_unref(msg);
+       if (!reply) {
+               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               return -ECOMM;
+       }
+
+       ret = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+       dbus_message_unref(reply);
+       if (!ret) {
+               _E("no message : [%s:%s] %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               return -ENOMSG;
+       }
+
+       return result;
+}
+
 int dbus_method_async(const char *dest, const char *path,
                const char *interface, const char *method,
                const char *sig, char *param[])
@@ -319,6 +381,8 @@ int dbus_method_async_with_reply(const char *dest, const char *path,
                return -ECOMM;
        }
 
+       dbus_message_unref(msg);
+
        if (cb && pending) {
                pdata = malloc(sizeof(struct pending_call_data));
                if (!pdata)
@@ -330,7 +394,6 @@ int dbus_method_async_with_reply(const char *dest, const char *path,
                ret = dbus_pending_call_set_notify(pending, cb_pending, pdata, free);
                if (!ret) {
                        free(pdata);
-                       dbus_message_unref(msg);
                        dbus_pending_call_cancel(pending);
                        return -ECOMM;
                }
@@ -339,6 +402,50 @@ int dbus_method_async_with_reply(const char *dest, const char *path,
        return 0;
 }
 
+int check_systemd_active(void)
+{
+       int ret = FALSE;
+       DBusError err;
+       DBusMessage *msg;
+       DBusMessageIter iter, sub;
+       const char *state;
+       char *pa[2];
+
+       pa[0] = "org.freedesktop.systemd1.Unit";
+       pa[1] = "ActiveState";
+
+       _I("%s %s", pa[0], pa[1]);
+
+       msg = dbus_method_sync_with_reply("org.freedesktop.systemd1",
+                       "/org/freedesktop/systemd1/unit/default_2etarget",
+                       "org.freedesktop.DBus.Properties",
+                       "Get", "ss", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_iter_init(msg, &iter) ||
+           dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+               goto out;
+
+       dbus_message_iter_recurse(&iter, &sub);
+
+       if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
+               ret = -EBADMSG;
+               goto out;
+       }
+
+       dbus_message_iter_get_basic(&sub, &state);
+
+       if (strncmp(state, "active", 6) == 0)
+               ret = TRUE;
+out:
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       return ret;
+}
+
 static void __CONSTRUCTOR__ dbus_init(void)
 {
        dbus_threads_init_default();
index 1aa4bc9..f4b04b8 100644 (file)
 #define DEVICED_PATH_TESTMODE               DEVICED_OBJECT_PATH"/Testmode"
 #define DEVICED_INTERFACE_TESTMODE           DEVICED_INTERFACE_NAME".Testmode"
 
+/* Apps service */
+#define DEVICED_PATH_APPS               DEVICED_OBJECT_PATH"/Apps"
+#define DEVICED_INTERFACE_APPS           DEVICED_INTERFACE_NAME".Apps"
+
+/* GPIO service: status check about gpio */
+#define DEVICED_PATH_GPIO                    DEVICED_OBJECT_PATH"/Gpio"
+#define DEVICED_INTERFACE_GPIO               DEVICED_INTERFACE_NAME".Gpio"
+
+/* HDMICEC service: status check about gpio */
+#define DEVICED_PATH_HDMICEC                    DEVICED_OBJECT_PATH"/HdmiCec"
+#define DEVICED_INTERFACE_HDMICEC               DEVICED_INTERFACE_NAME".HdmiCec"
+
 /*
  * Resource daemon
  */
@@ -209,6 +221,10 @@ int dbus_method_sync(const char *dest, const char *path,
                const char *interface, const char *method,
                const char *sig, char *param[]);
 
+int dbus_method_sync_timeout(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[], int timeout);
+
 int dbus_method_async(const char *dest, const char *path,
                const char *interface, const char *method,
                const char *sig, char *param[]);
@@ -218,4 +234,6 @@ typedef void (*dbus_pending_cb)(void *data, DBusMessage *msg, DBusError *err);
 int dbus_method_async_with_reply(const char *dest, const char *path,
                const char *interface, const char *method,
                const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data);
+
+int check_systemd_active(void);
 #endif
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
new file mode 100644 (file)
index 0000000..de91a6c
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <time.h>
+
+#include "core/log.h"
+#include "core/device-notifier.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/common.h"
+#include "display/core.h"
+#include "sleep.h"
+
+#define SLEEP_CHECK_DURATION 3600 /* 1hour */
+
+enum sleep_enum {
+       DEVICE_AWAKE = 0,
+       DEVICE_SLEEP = 1,
+};
+
+struct sleep_type {
+       int sleep_status;
+};
+
+static struct sleep_type monitor = {
+       .sleep_status = -1,
+};
+static time_t old = 0;
+static time_t diff = 0;
+
+static void sleep_changed(int status)
+{
+       if (monitor.sleep_status == status)
+               return;
+       monitor.sleep_status = status;
+       _I("sleep status %d", status);
+}
+
+static void check_sleep(void)
+{
+       time_t now;
+
+       if (monitor.sleep_status == DEVICE_SLEEP)
+               return;
+
+       time(&now);
+       diff = now - old;
+
+       if (diff > SLEEP_CHECK_DURATION)
+               sleep_changed(DEVICE_SLEEP);
+}
+
+static int display_changed(void *data)
+{
+       enum state_t state = (enum state_t)data;
+
+       if (state == S_LCDOFF || state == S_SLEEP)
+               goto out;
+
+       time(&old);
+       diff = 0;
+
+       sleep_changed(DEVICE_AWAKE);
+out:
+       return 0;
+}
+
+static int booting_done(void *data)
+{
+       time(&old);
+       register_notifier(DEVICE_NOTIFIER_LCD, display_changed);
+       return 0;
+}
+
+static void sleep_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+}
+
+static void sleep_exit(void *data)
+{
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       unregister_notifier(DEVICE_NOTIFIER_LCD, display_changed);
+}
+
+static int sleep_execute(void *data)
+{
+       check_sleep();
+       return 0;
+}
+
+static const struct device_ops sleep_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = DEVICE_SLEEP_OPS,
+       .init     = sleep_init,
+       .exit     = sleep_exit,
+       .execute  = sleep_execute,
+};
+
+DEVICE_OPS_REGISTER(&sleep_device_ops)
+
diff --git a/src/sleep/sleep.h b/src/sleep/sleep.h
new file mode 100644 (file)
index 0000000..31e42c5
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 __DEVICE_SLEEP_H__
+#define __DEVICE_SLEEP_H__
+
+#define DEVICE_SLEEP_OPS  "sleep-monitor"
+
+#endif /* __DEVICE_SLEEP_H__ */
similarity index 72%
rename from src/core/lowstorage.c
rename to src/storage/storage.c
index ce6a98e..60e4393 100755 (executable)
 #include <sys/stat.h>
 #include <sys/shm.h>
 #include <time.h>
+#include <storage.h>
 
 #include "device-node.h"
 #include "core/log.h"
-#include "core/noti.h"
-#include "core/queue.h"
-#include "core/predefine.h"
-#include "core/data.h"
 #include "core/devices.h"
 #include "core/common.h"
 #include "core/edbus-handler.h"
 #include "core/device-notifier.h"
+#include "core/config-parser.h"
 
 #define MEMNOTIFY_NORMAL       0x0000
 #define MEMNOTIFY_LOW          0xfaac
 #define MEMNOTIFY_CRITICAL     0xdead
 #define MEMNOTIFY_REBOOT       0xb00f
 
-#define MEMORY_STATUS_USR_PATH         "/opt/usr"
-#define MEMORY_MAX_MEM_STR_LEN         30
-#define MEMORY_KILOBYTE_VALUE          1024
-#define MEMORY_MEGABYTE_VALUE          1048576
-#define MEMORY_GIGABYTE_VALUE          1073741824
-#define MEMORY_RESERVE_VALUE           (100*MEMORY_MEGABYTE_VALUE)
-#define MEMNOTI_WARNING_VALUE          (5) // 5% under
-#define MEMNOTI_CRITICAL_VALUE         (0.1) // 0.1% under
-#define MEMNOTI_CRITICAL_SIZE(val)     ((val*MEMNOTI_CRITICAL_VALUE)/100)
-#define MEMNOTI_FULL_SIZE              (MEMORY_RESERVE_VALUE + MEMORY_MEGABYTE_VALUE)
+#define MEMORY_STATUS_USR_PATH  "/opt/usr"
+#define MEMORY_MEGABYTE_VALUE   1048576
 
-#define SIGNAL_LOWMEM_STATE    "ChangeState"
-#define SIGNAL_LOWMEM_FULL     "Full"
+#define MEMNOTI_WARNING_VALUE  (5) // 5% under
+#define MEMNOTI_CRITICAL_VALUE (0.1) // 0.1% under
+#define MEMNOTI_FULL_VALUE     (0.0) // 0.0% under
 
-#define POPUP_KEY_MEMNOTI      "_MEM_NOTI_"
-#define POPUP_KEY_APPNAME      "_APP_NAME_"
+#define SIGNAL_LOWMEM_STATE     "ChangeState"
+#define SIGNAL_LOWMEM_FULL      "Full"
 
-#define LOWMEM_POPUP_NAME      "lowmem-syspopup"
+#define POPUP_KEY_MEMNOTI       "_MEM_NOTI_"
+#define POPUP_KEY_APPNAME       "_APP_NAME_"
 
-#define MEMNOTI_TIMER_INTERVAL 5
-#define MEM_TRIM_TIMER_INTERVAL        86400 /* 24 hour */
-#define MEM_FSTRIM_PATH                "/sbin/fstrim"
+#define LOWMEM_POPUP_NAME       "lowmem-syspopup"
 
-#define MEM_TRIM_START_TIME    2 // AM 02:00:00
-#define MIN_SEC                        (60)
-#define HOUR_SEC               (MIN_SEC * MIN_SEC)
+#define MEMNOTI_TIMER_INTERVAL  5
+#define MEM_TRIM_TIMER_INTERVAL 86400 /* 24 hour */
+#define MEM_FSTRIM_PATH         "/sbin/fstrim"
 
-#define BUF_MAX 1024
+#define MEM_TRIM_START_TIME     2 // AM 02:00:00
+#define MIN_SEC                 (60)
+#define HOUR_SEC                (MIN_SEC * MIN_SEC)
+
+#define BUF_MAX                 1024
+
+#define STORAGE_CONF_FILE       "/etc/deviced/storage.conf"
 
 enum memnoti_level {
        MEMNOTI_LEVEL_CRITICAL = 0,
@@ -84,6 +80,12 @@ struct popup_data {
        char *value;
 };
 
+struct storage_config_info {
+       double warning_level;
+       double critical_level;
+       double full_level;
+};
+
 static Ecore_Fd_Handler *lowmem_efd = NULL;
 static int lowmem_fd;
 static int cur_mem_state = MEMNOTIFY_NORMAL;
@@ -91,9 +93,11 @@ static int cur_mem_state = MEMNOTIFY_NORMAL;
 static Ecore_Timer *memnoti_timer = NULL;
 static Ecore_Timer *mem_trim_timer = NULL;
 
-static double memnoti_warning_level = MEMNOTI_WARNING_VALUE;
-static double memnoti_critical_level = MEMNOTI_CRITICAL_VALUE;
-static double memnoti_full_level;
+static struct storage_config_info storage_info = {
+       .warning_level   = MEMNOTI_WARNING_VALUE,
+       .critical_level = MEMNOTI_CRITICAL_VALUE,
+       .full_level      = MEMNOTI_FULL_VALUE,
+};
 
 static void memnoti_send_broadcast(int status)
 {
@@ -146,11 +150,9 @@ static int memnoti_popup(enum memnoti_level level)
        ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
        if (val == 0 || ret != 0)
                goto out;
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return 0;
-       }
+
+       FIND_DEVICE_INT(apps, "apps");
+
        params = malloc(sizeof(struct popup_data));
        if (params == NULL) {
                _E("Malloc failed");
@@ -170,9 +172,9 @@ static enum memnoti_level check_memnoti_level(double total, double avail)
 {
        double tmp_size = (avail/total)*100;
 
-       if (tmp_size > memnoti_warning_level)
+       if (tmp_size > storage_info.warning_level)
                return MEMNOTI_LEVEL_NORMAL;
-       if (tmp_size > memnoti_critical_level)
+       if (tmp_size > storage_info.critical_level)
                return MEMNOTI_LEVEL_WARNING;
        return MEMNOTI_LEVEL_CRITICAL;
 }
@@ -186,9 +188,9 @@ static void memnoti_full_broadcast(double total, double avail)
        char str_status[32];
 
        tmp = status;
-       if (tmp_size <= memnoti_full_level && status == 0)
+       if (tmp_size <= storage_info.full_level && status == 0)
                status = 1;
-       else if (tmp_size > memnoti_full_level && status == 1)
+       else if (tmp_size > storage_info.full_level && status == 1)
                status = 0;
        if (status == tmp)
                return;
@@ -200,44 +202,20 @@ static void memnoti_full_broadcast(double total, double avail)
                        SIGNAL_LOWMEM_FULL, "i", arr);
 }
 
-static int __fs_stat(double* pdTotal, double* pdAvail, const char* szPath)
-{
-       struct statvfs s;
-       double reserved;
-
-       if (NULL == pdAvail) {
-               _E("input param error");
-               return 0;
-       }
-
-       if (!statvfs(szPath, &s)) {
-               reserved = MEMORY_RESERVE_VALUE/s.f_bsize;
-               if (s.f_bavail < reserved)
-                       s.f_bavail = 0;
-               else
-                       s.f_bavail -= reserved;
-               *pdTotal = (double)s.f_frsize * s.f_blocks;
-               *pdAvail = (double)s.f_bsize * s.f_bavail;
-       } else {
-               _E("fail to get memory size");
-               return 0;
-       }
-
-       return 1;
-}
-
 static void memory_status_set_full_mem_size(void)
 {
-       double dAvail = 0.0;
+       struct statvfs s;
        double dTotal = 0.0;
+       double dAvail = 0.0;
 
-       if (__fs_stat(&dTotal, &dAvail, MEMORY_STATUS_USR_PATH) == 0) {
-               _E("fail to get mem size of %s",MEMORY_STATUS_USR_PATH);
-               return;
-       }
+       storage_get_internal_memory_size(&s);
+       dTotal = (double)s.f_frsize * s.f_blocks;
+       dAvail = (double)s.f_bsize * s.f_bavail;
 
-       memnoti_full_level = (MEMNOTI_FULL_SIZE/dTotal)*100;
-       _I("memnoti_full_level : %4.4lf(%d)", memnoti_full_level, MEMNOTI_FULL_SIZE);
+       storage_info.full_level += (MEMORY_MEGABYTE_VALUE/dTotal)*100;
+       _I("full : %4.4lf avail : %4.4lf warning : %4.4lf critical : %4.4lf",
+               storage_info.full_level, (dAvail*100/dTotal),
+               storage_info.warning_level, storage_info.critical_level);
 }
 
 static Eina_Bool memory_status_get_available_size(void *data)
@@ -245,14 +223,13 @@ static Eina_Bool memory_status_get_available_size(void *data)
        static enum memnoti_level old = MEMNOTI_LEVEL_NORMAL;
        enum memnoti_level now;
        int ret;
+       struct statvfs s;
        double dAvail = 0.0;
        double dTotal = 0.0;
 
-       ret = __fs_stat(&dTotal, &dAvail, MEMORY_STATUS_USR_PATH);
-       if (ret == 0) {
-               _E("fail to get mem size of %s",MEMORY_STATUS_USR_PATH);
-               goto out;
-       }
+       storage_get_internal_memory_size(&s);
+       dTotal = (double)s.f_frsize * s.f_blocks;
+       dAvail = (double)s.f_bsize * s.f_bavail;
 
        memnoti_full_broadcast(dTotal, dAvail);
 
@@ -272,12 +249,12 @@ out:
        return EINA_TRUE;
 }
 
-static int __memnoti_fd_init(struct main_data *ad)
+static int __memnoti_fd_init(void)
 {
        memory_status_set_full_mem_size();
-       memory_status_get_available_size(ad);
+       memory_status_get_available_size(NULL);
        memnoti_timer = ecore_timer_add(MEMNOTI_TIMER_INTERVAL,
-                               memory_status_get_available_size, ad);
+                               memory_status_get_available_size, NULL);
        if (memnoti_timer == NULL)
            _E("fail mem available noti timer add");
        return 0;
@@ -344,10 +321,13 @@ static DBusMessage *edbus_getstatus(E_DBus_Object *obj, DBusMessage *msg)
        DBusMessageIter iter;
        DBusMessage *reply;
        int ret;
+       struct statvfs s;
        double dAvail = 0.0;
        double dTotal = 0.0;
 
-       ret = __fs_stat(&dTotal, &dAvail, MEMORY_STATUS_USR_PATH);
+       storage_get_internal_memory_size(&s);
+       dTotal = (double)s.f_frsize * s.f_blocks;
+       dAvail = (double)s.f_bsize * s.f_bavail;
 
        reply = dbus_message_new_method_return(msg);
        dbus_message_iter_init_append(reply, &iter);
@@ -389,7 +369,7 @@ static int booting_done(void *data)
                done = (int)data;
                if (done)
                        _I("booting done");
-               if (__memnoti_fd_init(NULL) == -1)
+               if (__memnoti_fd_init() == -1)
                        _E("fail remain mem noti control fd init");
        }
        return done;
@@ -408,10 +388,45 @@ static int lowmem_poweroff(void *data)
        return 0;
 }
 
+static int load_config(struct parse_result *result, void *user_data)
+{
+       struct storage_config_info *info = (struct storage_config_info *)user_data;
+       char *name;
+       char *value;
+
+       if (!info)
+               return -EINVAL;
+
+       if (!MATCH(result->section, "LOWSTORAGE"))
+               return -EINVAL;
+
+       name = result->name;
+       value = result->value;
+
+       if (MATCH(name, "WARNING_LEVEL"))
+               info->warning_level = (double)atof(value);
+       else if (MATCH(name, "CRITICAL_LEVEL"))
+               info->critical_level = (double)atof(value);
+       else if (MATCH(name, "FULL_LEVEL"))
+               info->full_level = (double)atof(value);
+
+       return 0;
+}
+
+static void storage_config_load(struct storage_config_info *info)
+{
+       int ret;
+
+       ret = config_parse(STORAGE_CONF_FILE, load_config, info);
+       if (ret < 0)
+               _E("Failed to load %s, %d Use default value!", STORAGE_CONF_FILE, ret);
+}
+
 static void lowmem_init(void *data)
 {
-       struct main_data *ad = (struct main_data*)data;
        int ret;
+
+       storage_config_load(&storage_info);
        register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
        register_notifier(DEVICE_NOTIFIER_POWEROFF, lowmem_poweroff);
        ret = register_edbus_method(DEVICED_PATH_STORAGE, edbus_methods, ARRAY_SIZE(edbus_methods));
diff --git a/src/storage/storage.conf b/src/storage/storage.conf
new file mode 100644 (file)
index 0000000..331e786
--- /dev/null
@@ -0,0 +1,7 @@
+[LOWSTORAGE]
+#5%
+WARNING_LEVEL=5
+#0.1%
+CRITICAL_LEVEL=0.1
+#0.0%
+FULL_LEVEL=0
index e67c9ea..bfa7770 100644 (file)
@@ -21,7 +21,6 @@
 #include <device-node.h>
 
 #include "core/log.h"
-#include "core/data.h"
 #include "core/devices.h"
 #include "display/poll.h"
 #include "core/common.h"
index cd28f7e..8841a31 100644 (file)
@@ -21,9 +21,6 @@
 #include <TelPower.h>
 #include <tapi_event.h>
 #include <tapi_common.h>
-#include <TapiCommon.h>
-#include <TapiEvent.h>
-#include <ITapiProductivity.h>
 
 #include <unistd.h>
 #include <assert.h>
@@ -32,9 +29,6 @@
 #include <device-node.h>
 #include "dd-deviced.h"
 #include "core/log.h"
-#include "core/queue.h"
-#include "core/predefine.h"
-#include "core/data.h"
 #include "core/common.h"
 #include "core/devices.h"
 #include "core/edbus-handler.h"
@@ -91,7 +85,7 @@ static Eina_Bool telephony_powerdown_ap_by_force(void *data)
        return EINA_TRUE;
 }
 
-static int telephony_start(void)
+static int telephony_start(enum device_flags flags)
 {
        int ready = 0;
 
@@ -111,10 +105,14 @@ static int telephony_start(void)
        return 0;
 }
 
-static int telephony_stop(void)
+static int telephony_stop(enum device_flags flags)
 {
        int ret;
-       tel_deregister_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER);
+
+       ret = tel_deregister_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER);
+       if (ret != TAPI_API_SUCCESS)
+               _E("tel_deregister_noti_event is not subscribed. error %d", ret);
+
        ret = tel_deinit(tapi_handle);
        if (ret != 0) {
                _E("fail to deinit");
@@ -133,7 +131,7 @@ static void telephony_exit(void *data)
                return;
        }
 
-       if (!strncmp(data, PREDEF_POWEROFF, strlen(PREDEF_POWEROFF))) {
+       if (!strncmp(data, POWER_POWEROFF, POWER_POWEROFF_LEN)) {
                _I("Terminate");
                ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER,
                                telephony_powerdown_ap, NULL);
@@ -154,19 +152,19 @@ static void telephony_exit(void *data)
                return;
        }
 
-       if (strncmp(data, PREDEF_REBOOT, strlen(PREDEF_REBOOT)) &&
-           strncmp(data, PREDEF_RECOVERY, strlen(PREDEF_RECOVERY)) &&
-           strncmp(data, PREDEF_FOTA_REBOOT, strlen(PREDEF_FOTA_REBOOT))) {
+       if (strncmp(data, POWER_REBOOT, POWER_REBOOT_LEN) &&
+           strncmp(data, POWER_RECOVERY, POWER_RECOVERY_LEN) &&
+           strncmp(data, POWER_FOTA, POWER_FOTA_LEN)) {
                _E("Fail %s", data);
                return;
        }
 
        _I("Option: %s", data);
-        if (!strncmp(data, PREDEF_RECOVERY, strlen(PREDEF_RECOVERY)))
+        if (!strncmp(data, POWER_RECOVERY, POWER_RECOVERY_LEN))
                reboot_opt = SYSTEMD_STOP_POWER_RESTART_RECOVERY;
-       else if (!strncmp(data, PREDEF_REBOOT, strlen(PREDEF_REBOOT)))
+       else if (!strncmp(data, POWER_REBOOT, POWER_REBOOT_LEN))
                reboot_opt = SYSTEMD_STOP_POWER_RESTART;
-       else if (!strncmp(data, PREDEF_FOTA_REBOOT, strlen(PREDEF_FOTA_REBOOT)))
+       else if (!strncmp(data, POWER_FOTA, POWER_FOTA_LEN))
                reboot_opt = SYSTEMD_STOP_POWER_RESTART_FOTA;
 
        ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER,
@@ -221,20 +219,14 @@ static void telephony_flight_mode_off(TapiHandle *handle, int result, void *data
                _E("failed to get vconf key");
 }
 
-static int telephony_flight_mode(int argc, char **argv)
+static int telephony_execute(void *data)
 {
        int ret;
-       int mode;
+       int mode = *(int *)(data);
        int err = TAPI_API_SUCCESS;
 
-       if (argc != 1 || argv[0] == NULL) {
-               _E("FlightMode Set predefine action failed");
-               return -1;
-       }
-       mode = atoi(argv[0]);
-
        if (tapi_handle == NULL) {
-               ret = telephony_start();
+               ret = telephony_start(NORMAL_MODE);
                if (ret != 0) {
                        _E("fail to get tapi handle");
                        return -1;
@@ -254,6 +246,19 @@ static int telephony_flight_mode(int argc, char **argv)
        return 0;
 }
 
+static int telephony_flight_mode(int argc, char **argv)
+{
+       int mode;
+
+       if (argc != 1 || argv[0] == NULL) {
+               _E("FlightMode Set predefine action failed");
+               return -1;
+       }
+       mode = atoi(argv[0]);
+       telephony_execute(&mode);
+       return 0;
+}
+
 static int telephony_enter_sleep(int argc, char **argv)
 {
        int ret;
@@ -370,7 +375,7 @@ static DBusMessage *telephony_handler(E_DBus_Object *obj, DBusMessage *msg)
        }
 
        if (tapi_handle == NULL) {
-               if (telephony_start() != 0)
+               if (telephony_start(NORMAL_MODE) != 0)
                        _E("fail to get tapi handle");
        }
 
@@ -403,19 +408,16 @@ static void telephony_init(void *data)
                        ARRAY_SIZE(edbus_methods));
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
-
-       register_action(PREDEF_FLIGHT_MODE, telephony_flight_mode, NULL, NULL);
-       register_action(PREDEF_ENTERSLEEP, telephony_enter_sleep, NULL, NULL);
-       register_action(PREDEF_LEAVESLEEP, telephony_leave_sleep, NULL, NULL);
 }
 
 static const struct device_ops tel_device_ops = {
-       .priority       = DEVICE_PRIORITY_NORMAL,
-       .name           = "telephony",
-       .init           = telephony_init,
-       .start          = telephony_start,
-       .stop           = telephony_stop,
-       .exit           = telephony_exit,
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "telephony",
+       .init     = telephony_init,
+       .start    = telephony_start,
+       .stop     = telephony_stop,
+       .exit     = telephony_exit,
+       .execute = telephony_execute,
 };
 
 DEVICE_OPS_REGISTER(&tel_device_ops)
index 0c246b9..0604cd6 100644 (file)
@@ -55,8 +55,41 @@ out:
        return reply;
 }
 
+static DBusMessage *edbus_factory_15_launch(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *argv;
+       char param[32];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+       sprintf(param, "%s", argv);
+       _D("param %s", param);
+
+       launch_evenif_exist("/usr/bin/factory-15-env.sh", param);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+
 static const struct edbus_method edbus_methods[] = {
        { "Launch", "s",   "i", edbus_testmode_launch },
+       { "factory15", "s",   "i", edbus_factory_15_launch },
        /* Add methods here */
 };
 
index 3d1b36a..35df13d 100755 (executable)
@@ -21,7 +21,6 @@
 
 
 #include "core/common.h"
-#include "core/data.h"
 
 enum ticker_type {
        WITHOUT_QUEUE, /* for usb client */
diff --git a/src/tima/noti.c b/src/tima/noti.c
new file mode 100644 (file)
index 0000000..04da065
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * TIMA Notification
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <assert.h>
+#include <E_DBus.h>
+
+#include "core/log.h"
+#include "core/common.h"
+
+#define SYSTEM_POPUP_BUS_NAME  "org.tizen.system.popup"
+#define SYSTEM_POPUP_DBUS_PATH "/Org/Tizen/System/Popup"
+
+#define SYSTEM_POPUP_PATH_TIMA SYSTEM_POPUP_DBUS_PATH"/Tima"
+#define SYSTEM_POPUP_IFACE_TIMA        SYSTEM_POPUP_BUS_NAME".Tima"
+
+#define METHOD_PKM_NOTI_ON     "PKMDetectionNotiOn"
+#define METHOD_PKM_NOTI_OFF    "PKMDetectionNotiOff"
+#define METHOD_LKM_NOTI_ON     "LKMPreventionNotiOn"
+#define METHOD_LKM_NOTI_OFF    "LKMPreventionNotiOff"
+
+#define RETRY_MAX              10
+#define DBUS_REPLY_TIMEOUT     (120 * 1000)
+
+static int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
+{
+       char *ch;
+       int i, int_type;
+
+       if (!sig || !param)
+               return 0;
+
+       for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
+               switch (*ch) {
+               case 's':
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &param[i]);
+                       break;
+               case 'i':
+                       int_type = atoi(param[i]);
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
+                       break;
+               default:
+                       _E("ERROR: %s %c", sig, *ch);
+                       return -EINVAL;
+               }
+       }
+       return 0;
+}
+
+DBusMessage *call_dbus_method(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[])
+{
+       DBusConnection *conn;
+       DBusMessage *msg = NULL;
+       DBusMessageIter iter;
+       DBusMessage *ret;
+       DBusError err;
+       int r;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               ret = NULL;
+               goto out;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               ret = NULL;
+               goto out;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       r = append_variant(&iter, sig, param);
+       if (r < 0) {
+               ret = NULL;
+               goto out;
+       }
+
+       /*This function is for synchronous dbus method call */
+       dbus_error_init(&err);
+       ret = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
+       dbus_error_free(&err);
+
+out:
+       dbus_message_unref(msg);
+
+       return ret;
+}
+
+int request_to_launch_by_dbus(char *bus, char *path, char *iface,
+               char *method, char *ptype, char *param[])
+{
+       DBusMessage *msg;
+       DBusError err;
+       int i, r, ret_val;
+
+       i = 0;
+       do {
+               msg = call_dbus_method(bus, path, iface, method, ptype, param);
+               if (msg)
+                       break;
+               i++;
+       } while (i < RETRY_MAX);
+       if (!msg) {
+               _E("fail to call dbus method");
+               return -ECONNREFUSED;
+       }
+
+       dbus_error_init(&err);
+
+       r = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!r) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       return ret_val;
+}
+
+/* This function returns notification ID (ID >= 0) */
+int tima_lkm_prevention_noti_on(void)
+{
+       return request_to_launch_by_dbus(SYSTEM_POPUP_BUS_NAME,
+                       SYSTEM_POPUP_PATH_TIMA, SYSTEM_POPUP_IFACE_TIMA,
+                       METHOD_LKM_NOTI_ON, NULL, NULL);
+}
+
+/* This function needs the notification ID to remove
+ * This function return 0 if success */
+int tima_lkm_prevention_noti_off(int noti_id)
+{
+       char *param[1];
+       char str[8];
+       snprintf(str, sizeof(str), "%d", noti_id);
+       param[0] = str;
+
+       return request_to_launch_by_dbus(SYSTEM_POPUP_BUS_NAME,
+                       SYSTEM_POPUP_PATH_TIMA, SYSTEM_POPUP_IFACE_TIMA,
+                       METHOD_LKM_NOTI_OFF, "i", param);
+}
+
+/* This function returns notification ID (ID >= 0) */
+int tima_pkm_detection_noti_on(void)
+{
+       return request_to_launch_by_dbus(SYSTEM_POPUP_BUS_NAME,
+                       SYSTEM_POPUP_PATH_TIMA, SYSTEM_POPUP_IFACE_TIMA,
+                       METHOD_PKM_NOTI_ON, NULL, NULL);
+}
+
+/* This function needs the notification ID to remove
+ * This function return 0 if success */
+int tima_pkm_detection_noti_off(int noti_id)
+{
+       char *param[1];
+       char str[8];
+       snprintf(str, sizeof(str), "%d", noti_id);
+       param[0] = str;
+
+       return request_to_launch_by_dbus(SYSTEM_POPUP_BUS_NAME,
+                       SYSTEM_POPUP_PATH_TIMA, SYSTEM_POPUP_IFACE_TIMA,
+                       METHOD_PKM_NOTI_OFF, "i", param);
+}
similarity index 63%
rename from src/core/predefine.h
rename to src/tima/noti.h
index a20aaf5..b9a02bc 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * deviced
+ * TIMA(TZ based Integrity Measurement Architecture)
  *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the License);
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
+#ifndef __TIMA_NOTI_H
+#define __TIMA_NOTI_H
 
-#ifndef __PREDEFINE_H__
-#define __PREDEFINE_H__
+int tima_lkm_prevention_noti_on(void);
+int tima_lkm_prevention_noti_off(int noti_id);
+int tima_pkm_detection_noti_on(void);
+int tima_pkm_detection_noti_off(int noti_id);
 
-int call_predefine_action(int argc, char **argv);
-int is_factory_mode(void);
-void predefine_pm_change_state(unsigned int s_bits);
-int predefine_get_pid(const char *execpath);
-#endif /* __PREDEFINE_H__ */
+#endif
diff --git a/src/tima/tima-lkm.c b/src/tima/tima-lkm.c
new file mode 100644 (file)
index 0000000..db3b3f1
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * LKM in TIMA(TZ based Integrity Measurement Architecture)
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <assert.h>
+#include <limits.h>
+#include <libudev.h>
+#include <Ecore.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/udev.h"
+
+#include "noti.h"
+
+/*
+ * tzapp interface
+ */
+#define LKM_FAIL               -1
+#define LKM_SUCCESS            0
+#define LKM_ERROR              1
+
+/*
+ * udev
+ */
+#define TIMA_SUBSYSTEM         "tima"
+#define TIMA_STATUS            "TIMA_STATUS"
+#define TIMA_RESULT            "TIMA_RESULT"
+
+static struct udev *udev;
+static struct udev_monitor *mon;
+static int ufd;
+static Ecore_Fd_Handler        *ufdh;
+
+static int noti_id = 0;
+
+static void tima_notification(int status)
+{
+       switch (status) {
+       case LKM_FAIL:
+               _I("certification failed");
+               break;
+       default:
+               _E("internal error (%d)", status);
+               break;
+       }
+
+       noti_id = tima_lkm_prevention_noti_on();
+       if (noti_id < 0) {
+               _E("FAIL: tima_lkm_prevention_noti_on()");
+               noti_id = 0;
+       }
+}
+
+/*
+ * tima_uevent_cb - uevent callback
+ *
+ * This callback receive the uevent from kernel module driver
+ */
+static Eina_Bool tima_uevent_cb(void *data, Ecore_Fd_Handler *handler)
+{
+       struct udev_device *dev;
+       struct udev_list_entry *list, *entry;
+       const char *name, *value, *msg;
+       int status;
+
+       dev = udev_monitor_receive_device(mon);
+       if (!dev)
+               return EINA_TRUE;
+
+       /* Getting the First element of the device entry list */
+       list = udev_device_get_properties_list_entry(dev);
+       if (!list) {
+               _E("can't get udev_device_get_properties_list_entry()");
+               goto err_unref_dev;
+       }
+
+       udev_list_entry_foreach(entry, list) {
+               name = udev_list_entry_get_name(entry);
+
+               if (!strcmp(name, TIMA_RESULT)) {
+                       msg = udev_list_entry_get_value(entry);
+                       _D("tzapp: msg(%s)", msg);
+               }
+
+               if (!strcmp(name, TIMA_STATUS)) {
+                       value = udev_list_entry_get_value(entry);
+                       status = atoi(value);
+                       _D("tzapp: ret(%d)", status);
+
+                       if (status != LKM_SUCCESS) {
+                               tima_notification(status);
+                               goto err_unref_dev;
+                       }
+               }
+       }
+       udev_device_unref(dev);
+       return EINA_TRUE;
+
+err_unref_dev:
+       udev_device_unref(dev);
+err:
+       return EINA_FALSE;
+}
+
+/*
+ * tima_uevent_stop - disable udev event control
+ */
+static int tima_uevent_stop(void)
+{
+       if (ufdh) {
+               ecore_main_fd_handler_del(ufdh);
+               ufdh = NULL;
+       }
+
+       if (ufd >= 0) {
+               close(ufd);
+               ufd = -1;
+       }
+
+       if (mon) {
+               struct udev_device *dev = udev_monitor_receive_device(mon);
+               if (dev) {
+                       udev_device_unref(dev);
+                       dev = NULL;
+               }
+               udev_monitor_unref(mon);
+               mon = NULL;
+       }
+
+       if (udev) {
+               udev_unref(udev);
+               udev = NULL;
+       }
+
+       return 0;
+}
+
+/*
+ * tima_uevent_start - enable udev event for TIMA
+ */
+static int tima_uevent_start(void)
+{
+       int ret;
+
+       udev = udev_new();
+       if (!udev) {
+               _E("can't create udev");
+               goto stop;
+       }
+
+       mon = udev_monitor_new_from_netlink(udev, UDEV);
+       if (!mon) {
+               _E("can't udev_monitor create");
+               goto stop;
+       }
+
+       ret = udev_monitor_set_receive_buffer_size(mon, 1024);
+       if (ret < 0) {
+               _E("fail to set receive buffer size");
+               goto stop;
+       }
+
+       ret = udev_monitor_filter_add_match_subsystem_devtype(mon, TIMA_SUBSYSTEM, NULL);
+       if (ret < 0) {
+               _E("can't apply subsystem filter");
+               goto stop;
+       }
+
+       ret = udev_monitor_filter_update(mon);
+       if (ret < 0)
+               _E("error udev_monitor_filter_update");
+
+       ufd = udev_monitor_get_fd(mon);
+       if (ufd < 0) {
+               _E("can't udev_monitor_get_fd");
+               goto stop;
+       }
+
+       ufdh = ecore_main_fd_handler_add(ufd, ECORE_FD_READ, tima_uevent_cb, NULL, NULL, NULL);
+       if (!ufdh) {
+               _E("can't ecore_main_fd_handler_add");
+               goto stop;
+       }
+
+       ret = udev_monitor_enable_receiving(mon);
+       if (ret < 0) {
+               _E("can't unable to subscribe to udev events");
+               goto stop;
+       }
+
+       return 0;
+stop:
+       tima_uevent_stop();
+       return -EINVAL;
+}
+
+void tima_lkm_init(void)
+{
+       tima_uevent_start();
+}
+
+void tima_lkm_exit(void)
+{
+       tima_uevent_stop();
+}
diff --git a/src/tima/tima-lkm.h b/src/tima/tima-lkm.h
new file mode 100644 (file)
index 0000000..29f8ff1
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * TIMA(TZ based Integrity Measurement Architecture)
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __TIMA_LKM_H
+#define __TIMA_LKM_H
+
+void tima_lkm_init(void);
+void tima_lkm_exit(void);
+
+#endif
diff --git a/src/tima/tima-pkm.c b/src/tima/tima-pkm.c
new file mode 100644 (file)
index 0000000..cd6c85c
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * LKM in TIMA(TZ based Integrity Measurement Architecture)
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <fcntl.h>
+#include <assert.h>
+#include <limits.h>
+#include <libudev.h>
+#include <Ecore.h>
+#include <QSEEComAPI.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/udev.h"
+
+#include "noti.h"
+
+/*
+ * tzapp interface - commands for tima tzapp
+ */
+#define TIMA_PKM_ID            0x00070000
+#define TIMA_MEASURE_REG_PROC  (TIMA_PKM_ID | 0x00)
+#define TIMA_MEASURE_PROC      (TIMA_PKM_ID | 0x01)
+#define TIMA_MEASURE_KERNEL    (TIMA_PKM_ID | 0x02)
+#define TIMA_MEASURE_UNREG_PROC        (TIMA_PKM_ID | 0x03)
+#define TIMA_MEASURE_VERIFY    (TIMA_PKM_ID | 0x04)
+#define TIMA_MEASURE_KERNEL_ONDEMAND (TIMA_PKM_ID | 0x05)
+#define TIMA_SECURE_LOG                (TIMA_PKM_ID | 0x06)
+#define TIMA_INIT              (TIMA_PKM_ID | 0x07)
+
+/* return value from tzapp(lkmauth) */
+#define PKM_MODIFIED           -1
+#define PKM_SUCCESS            0
+#define PKM_ERROR              1
+#define PKM_META_MODIFIED      2
+#define PKM_INIT_FAIL          3
+#define PKM_INIT_SUCCESS       4
+
+struct tima_gen_req {
+       int cmd_id;
+       union {
+               unsigned int buf_size;
+               struct {
+                       int log_region;         /* 0: Page Table, 1: Periodic TIMA & LKM */
+                       int log_entry_index;    /* 0: Log Meta Data, others: Log Entry Index */
+               } __attribute__((packed)) log;
+       } __attribute__((packed)) param;
+} __attribute__((packed));
+
+struct tima_measure_rsp_s {
+       int cmd_id;
+       int ret;
+       union {
+               unsigned char hash[20];
+               char result_ondemand[4096];
+       }  __attribute__((packed)) result;
+} __attribute__((packed));
+
+/*
+ * QSEECom interface
+ */
+#define FIRMWARE_PATH          "/lib/firmware"
+
+struct QSEECom_handle *qseecom_handle = NULL;
+
+/*
+ * ECore interface
+ */
+#define TIMA_TIMER_START       (5)
+#define TIMA_TIMER_INTERVAL    (5 * 60)
+
+static Ecore_Timer *timer_id;
+
+/*
+ * kernel signature file handle
+ */
+#define KERN_HASH_FILE         "/usr/system/kern_sec_info"
+
+static int kern_info_fd = -1;
+static unsigned int kern_info_len;
+
+static int noti_id = 0;
+
+
+/*
+ * tima_shutdown_tzapp
+ *
+ * This function is written to temporarily bypass a problem in QSEECOM
+ * driver. In ideal situations, this fuction should not be needed.
+ *
+ * We are running into the -22 error, which stops the tima tzapp from
+ * working after it occurs. This function is used to shut down the tima
+ * tzapp every time when a periodic measurement is done.
+ * When the -22 error is fixed, this function shouldn't be needed.
+ */
+static int tima_shutdown_tzapp(void)
+{
+       int ret = -1;
+
+       if ((qseecom_handle != NULL) &&
+           (QSEECom_app_load_query(qseecom_handle, "tima") == QSEECOM_APP_ALREADY_LOADED)) {
+               ret = QSEECom_shutdown_app(&qseecom_handle);
+               if (!ret) {
+                       qseecom_handle = NULL;
+                       _D("tzapp is shut down!");
+               } else {
+                       _E("Unable to shut down the TIMA tzapp; ret(%d)", errno);
+               }
+       } else {
+               _D("tzapp is not loaded! nothing to shut down.");
+       }
+
+       return ret;
+}
+
+/*
+ * tima_send_initcmd
+ *
+ * This function is written explictly to tell the TIMA periodic
+ * Trustzone application to accept the passed KERN_HASH_FILE
+ * via the buffer. We saw a lot of issues with the listener
+ * service, when the TIMA application was explicitly calling
+ * the filesystem API's to load this file on the TZ side
+ */
+static int tima_send_initcmd(uint32_t req_len, struct tima_measure_rsp_s *recv_cmd)
+{
+       int ret = -1;
+       void *file_ptr = NULL;
+       struct tima_gen_req *req;
+       struct tima_measure_rsp_s *rsp;
+       uint32_t rsp_len = 0;
+
+       _D("signature load request\n");
+
+       if ((kern_info_fd < 0) || (kern_info_len == 0)) {
+               _E("%s not loaded", KERN_HASH_FILE);
+               return ret;
+       }
+
+       rsp_len = sizeof(struct tima_measure_rsp_s);
+
+       req = (struct tima_gen_req *)qseecom_handle->ion_sbuffer;
+       req->cmd_id = TIMA_INIT;
+       req->param.buf_size = kern_info_len;
+       file_ptr = (void *)((char *)req + sizeof(struct tima_gen_req));
+
+       if (read(kern_info_fd, file_ptr, kern_info_len) != kern_info_len) {
+               _E("cann't load signature, ret(%d)", errno);
+               return ret;
+       }
+
+       rsp = (struct tima_measure_rsp_s *)(qseecom_handle->ion_sbuffer + req_len);
+
+       _D("req: cmd(0x%08X), size(%d)@%p", req->cmd_id, req_len, req);
+
+       QSEECom_set_bandwidth(qseecom_handle, true);
+       do {
+               ret = QSEECom_send_cmd(qseecom_handle, req, req_len, rsp, rsp_len);
+               if (ret) {
+                       _E("QSEECom_send_cmd failed, ret(%d)", ret);
+                       break;
+               } else if ((rsp->ret != 0) && (rsp->ret != 512)) {
+                       _E("internal error in tima tzapp, ret(%d)", rsp->ret);
+                       ret = -1;
+                       break;
+               }
+       } while(rsp->ret == 512);
+       QSEECom_set_bandwidth(qseecom_handle, false);
+
+       _D("rsp: cmd(0x%08x), ret(%d), msg(%s)", rsp->cmd_id, rsp->ret, rsp->result.result_ondemand);
+
+       return ret;
+}
+
+static int tima_load_tzapp(struct tima_measure_rsp_s *recv_cmd)
+{
+       int ret = -1;
+       uint32_t req_len, rsp_len;
+
+       if ((qseecom_handle != NULL) &&
+           (QSEECom_app_load_query(qseecom_handle, "tima") == QSEECOM_APP_ALREADY_LOADED)) {
+               recv_cmd->ret = 0;
+               return 0;
+       }
+
+       kern_info_fd = open(KERN_HASH_FILE, O_RDONLY);
+       if (kern_info_fd < 0) {
+               _E("%s open failed, ret(%d)", KERN_HASH_FILE, errno);
+               /*
+                * Simulate TZ response for kern metadata modified
+                * This is necessary for the notification to show up.
+                * I cringed while writing this code, so that makes the two of us.
+                */
+               recv_cmd->ret = 2;
+               snprintf(recv_cmd->result.result_ondemand, 256, "MSG=kern_metadata_modified;");
+               /* Indicate load_app succeed, but open kern_kern_info fail */
+               return 0;
+       }
+
+       /* determine the length of the kern_info file */
+       lseek(kern_info_fd, 0, SEEK_END);
+       kern_info_len = lseek(kern_info_fd, 0, SEEK_CUR);
+       lseek(kern_info_fd, 0, SEEK_SET);
+
+       req_len = kern_info_len + sizeof(struct tima_gen_req);
+       rsp_len = sizeof(struct tima_measure_rsp_s);
+
+       req_len = (req_len > rsp_len) ? req_len : rsp_len;
+
+       if (req_len & QSEECOM_ALIGN_MASK)
+               req_len = QSEECOM_ALIGN(req_len);
+
+       _D("attempting to load tzapp");
+
+       /* Load up the secure world counter-part */
+       ret = QSEECom_start_app(&qseecom_handle, FIRMWARE_PATH, "tima", req_len * 2);
+       if (!ret) {
+               _I("tzapp(%s) successfully loaded\n", FIRMWARE_PATH "/tima");
+
+               if ((ret = tima_send_initcmd(req_len, recv_cmd)) != 0) {
+                       _E("failed to send QSEE cmd (TIMA_INIT) to tzapp!");
+                       tima_shutdown_tzapp();
+                       ret = -1;
+                       goto error;
+               } else {
+                       _D("signature successfully loaded");
+               }
+       } else {
+               _E("failed to load the tzapp, ret(%d)", errno);
+       }
+
+error:
+       close(kern_info_fd);
+       kern_info_fd = -1;
+       return ret;
+}
+
+static int tima_send_command(struct tima_measure_rsp_s *recv_cmd)
+{
+       int req_len = 0, rsp_len = 0;
+       struct tima_gen_req *req;
+       struct tima_measure_rsp_s *rsp;
+       int ret = -1;
+
+       req_len = sizeof(struct tima_gen_req);
+       rsp_len = sizeof(struct tima_measure_rsp_s);
+       if (req_len & QSEECOM_ALIGN_MASK)
+               req_len = QSEECOM_ALIGN(req_len);
+
+       if (rsp_len & QSEECOM_ALIGN_MASK)
+               rsp_len = QSEECOM_ALIGN(rsp_len);
+
+       req = (struct tima_gen_req *)qseecom_handle->ion_sbuffer;
+       req->cmd_id = TIMA_MEASURE_KERNEL_ONDEMAND;
+       rsp = (struct tima_measure_rsp_s *)(qseecom_handle->ion_sbuffer + req_len);
+
+       _D("req: cmd(0x%08X), size(%d)@%p", req->cmd_id, req_len, req);
+
+       QSEECom_set_bandwidth(qseecom_handle, true);
+       do {
+               ret = QSEECom_send_cmd(qseecom_handle, req, req_len, rsp, rsp_len);
+               if (ret) {
+                       _E("QSEECom_send_cmd failed, ret(%d)", errno);
+                       break;
+               }
+
+               usleep(5000);
+       } while (rsp->ret == 512);
+       QSEECom_set_bandwidth(qseecom_handle, false);
+
+       _D("rsp: cmd(0x%08x), ret(%d), msg(%s)", rsp->cmd_id, rsp->ret, rsp->result.result_ondemand);
+
+       memcpy(recv_cmd, rsp, sizeof(struct tima_measure_rsp_s));
+
+       return ret;
+}
+
+static int tima_check_event(void)
+{
+       int ret = -1;
+       struct tima_measure_rsp_s recv_cmd;
+
+       if (tima_load_tzapp(&recv_cmd)) {
+               _E("Failed to load tzapp!");
+               return -1;
+       } else if (recv_cmd.ret != 0) {
+               goto skip_measurement;
+       }
+
+       if (tima_send_command(&recv_cmd)) {
+               _E("Failed to send QSEE cmd to tzapp!");
+               /* The following call needs to be removed after fixing the -22 error problem */
+               tima_shutdown_tzapp ();
+
+               return -1;
+       }
+
+       /* The following call needs to be removed after fixing the -22 error problem */
+       tima_shutdown_tzapp ();
+
+       if ((recv_cmd.ret == 0) &&
+           (recv_cmd.cmd_id != TIMA_MEASURE_KERNEL_ONDEMAND)) {
+               _E("Invalid QSEE result!");
+               return -1;
+       }
+
+       switch (recv_cmd.ret) {
+       case PKM_SUCCESS:
+               _I("verify successed");
+               ret = 0;
+               break;
+       case PKM_MODIFIED:
+               _I("verify failed");
+               ret = 1;
+               break;
+       case PKM_META_MODIFIED:
+               _I("check metadata (%s)", KERN_HASH_FILE);
+               ret = 1;
+               break;
+       default:
+               _E("internal error (%d)", recv_cmd.ret);
+               break;
+       }
+
+skip_measurement:
+       return ret;
+}
+
+static Eina_Bool tima_pkm_monitor(void *data)
+{
+       int ret;
+       static int is_first = 1;
+
+       ret = tima_check_event();
+       if (ret) {
+               noti_id = tima_pkm_detection_noti_on();
+               if (noti_id < 0) {
+                       _E("FAIL: tima_pkm_detection_noti_on()");
+                       noti_id = 0;
+               }
+
+               ecore_timer_del(timer_id);
+               timer_id = NULL;
+               return EINA_FALSE;
+       }
+
+       if (is_first) {
+               is_first = 0;
+               ecore_timer_interval_set(timer_id, TIMA_TIMER_INTERVAL);
+       }
+
+       return EINA_TRUE;
+}
+
+/* tima-pkm init funcion */
+void tima_pkm_init(void)
+{
+       timer_id = ecore_timer_add(TIMA_TIMER_START, tima_pkm_monitor, NULL);
+       if (!timer_id) {
+               _E("can't add timer for tima-pkm");
+               return;
+       }
+}
+
+/* tima-pkm exit funcion */
+void tima_pkm_exit(void)
+{
+       if (timer_id) {
+               ecore_timer_del(timer_id);
+               timer_id = NULL;
+       }
+}
diff --git a/src/tima/tima-pkm.h b/src/tima/tima-pkm.h
new file mode 100644 (file)
index 0000000..275d27a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * TIMA(TZ based Integrity Measurement Architecture)
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __TIMA_PKM_H
+#define __TIMA_PKM_H
+
+void tima_pkm_init(void);
+void tima_pkm_exit(void);
+
+#endif
diff --git a/src/tima/tima.c b/src/tima/tima.c
new file mode 100644 (file)
index 0000000..c2b754d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * TIMA(TZ based Integrity Measurement Architecture)
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <assert.h>
+#include <limits.h>
+#include <libudev.h>
+#include <Ecore.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/udev.h"
+
+#include "tima-lkm.h"
+#include "tima-pkm.h"
+
+static void tima_init(void *data)
+{
+       tima_lkm_init();
+       tima_pkm_init();
+}
+
+static void tima_exit(void *data)
+{
+       tima_lkm_exit();
+       tima_pkm_exit();
+}
+
+static const struct device_ops tima_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "tima",
+       .init     = tima_init,
+       .exit     = tima_exit,
+};
+
+DEVICE_OPS_REGISTER(&tima_device_ops)
index 3eb241b..d5fdcec 100644 (file)
@@ -30,8 +30,6 @@
 #include <fcntl.h>
 #include <sys/timerfd.h>
 
-#include "core/data.h"
-#include "core/queue.h"
 #include "core/log.h"
 #include "core/devices.h"
 #include "display/poll.h"
@@ -365,8 +363,6 @@ static void time_init(void *data)
        if (ret < 0)
                _E("fail to init edbus method(%d)", ret);
 
-       register_action(PREDEF_SET_DATETIME, set_datetime_action, NULL, NULL);
-       register_action(PREDEF_SET_TIMEZONE, set_timezone_action, NULL, NULL);
        if (timerfd_check_start() == -1) {
                _E("fail system time change detector init");
        }
index bb1ab61..5444320 100644 (file)
@@ -69,7 +69,7 @@ void touch_boost_enable(struct touch_control *touch_control,
 /* Define global variable of struct touch_control */
 static struct touch_control touch_control;
 
-static int touch_stop(void)
+static int touch_stop(enum device_flags flags)
 {
        /* Restore touch boost state as ON state */
        set_cpufreq_touch_boost_off(TOUCH_BOOST_ON);
@@ -81,7 +81,7 @@ static int touch_stop(void)
        return 0;
 }
 
-static int touch_start(void)
+static int touch_start(enum device_flags flags)
 {
        int i;
 
diff --git a/src/touch/touchkey.c b/src/touch/touchkey.c
new file mode 100644 (file)
index 0000000..c6bdd5a
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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 "core/devices.h"
+#include "core/common.h"
+#include "core/log.h"
+
+#define TOUCH_ON       1
+#define TOUCH_OFF      0
+
+static char *touchkey_node;
+
+/*
+ * touchkey_init - Initialize Touchkey module
+ */
+static void touchkey_init(void *data)
+{
+       if (touchkey_node)
+               return;
+
+       touchkey_node = getenv("PM_TOUCHKEY");
+       _D("touchkey node : %s", touchkey_node);
+}
+
+static int touchkey_start(enum device_flags flags)
+{
+       int ret;
+
+       touchkey_init((void *)NORMAL_MODE);
+
+       if (!touchkey_node || !(*touchkey_node))
+               return -ENOENT;
+
+       ret = sys_set_int(touchkey_node, TOUCH_ON);
+       if (ret < 0)
+               _E("Failed to on touch key!");
+
+       return ret;
+}
+
+static int touchkey_stop(enum device_flags flags)
+{
+       int ret;
+
+       touchkey_init((void *)NORMAL_MODE);
+       if (!touchkey_node || !(*touchkey_node))
+               return -ENOENT;
+
+       ret = sys_set_int(touchkey_node, TOUCH_OFF);
+       if (ret < 0)
+               _E("Failed to off touch key!");
+
+       return ret;
+}
+
+static const struct device_ops touchkey_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "touchkey",
+       .init     = touchkey_init,
+       .start    = touchkey_start,
+       .stop     = touchkey_stop,
+};
+
+DEVICE_OPS_REGISTER(&touchkey_device_ops)
+
diff --git a/src/touch/touchscreen.c b/src/touch/touchscreen.c
new file mode 100644 (file)
index 0000000..cd2db83
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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 "core/devices.h"
+#include "core/common.h"
+#include "core/log.h"
+
+#define TOUCH_ON       1
+#define TOUCH_OFF      0
+
+static char *touchscreen_node;
+
+/*
+ * touchscreen_init - Initialize Touchscreen module
+ */
+static void touchscreen_init(void *data)
+{
+       if (touchscreen_node)
+               return;
+
+       touchscreen_node = getenv("PM_TOUCHSCREEN");
+       _D("touchscreen node : %s", touchscreen_node);
+}
+
+static int touchscreen_start(enum device_flags flags)
+{
+       int ret;
+
+       touchscreen_init((void *)NORMAL_MODE);
+       if (!touchscreen_node)
+               return -ENOENT;
+
+       if (flags & TOUCH_SCREEN_OFF_MODE)
+               return 0;
+
+       ret = sys_set_int(touchscreen_node, TOUCH_ON);
+       if (ret < 0)
+               _E("Failed to on touch screen!");
+
+       return ret;
+}
+
+static int touchscreen_stop(enum device_flags flags)
+{
+       int ret;
+
+       touchscreen_init((void *)NORMAL_MODE);
+       if (!touchscreen_node)
+               return -ENOENT;
+
+       if (flags & AMBIENT_MODE)
+               return 0;
+
+       ret = sys_set_int(touchscreen_node, TOUCH_OFF);
+       if (ret < 0)
+               _E("Failed to off touch screen!");
+
+       return ret;
+}
+
+static const struct device_ops touchscreen_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "touchscreen",
+       .init     = touchscreen_init,
+       .start    = touchscreen_start,
+       .stop     = touchscreen_stop,
+};
+
+DEVICE_OPS_REGISTER(&touchscreen_device_ops)
+
diff --git a/src/usb/configurations/conf-supported.xml b/src/usb/configurations/conf-supported.xml
deleted file mode 100644 (file)
index 306d75e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<supported>
-       <mode value="0"/>
-       <mode value="1"/>
-       <mode value="2"/>
-       <mode value="3"/>
-       <mode value="4"/>
-       <mode value="5"/>
-       <mode value="6"/>
-       <mode value="8"/>
-</supported>
diff --git a/src/usb/configurations/usb-configurations.xml b/src/usb/configurations/usb-configurations.xml
deleted file mode 100644 (file)
index 8f71d22..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<usb-config>
-       <config-nodes>
-
-               <driver          value="/sys/class/usb_mode/version"/>
-
-               <usb-drv ver="1.1&#10;">
-                       <disable     value="/sys/class/usb_mode/usb0/enable"/>
-                       <idVendor    value="/sys/class/usb_mode/usb0/idVendor"/>
-                       <idProduct   value="/sys/class/usb_mode/usb0/idProduct"/>
-                       <funcs_fconf value="/sys/class/usb_mode/usb0/funcs_fconf"/>
-                       <funcs_sconf value="/sys/class/usb_mode/usb0/funcs_sconf"/>
-                       <devClass    value="/sys/class/usb_mode/usb0/bDeviceClass"/>
-                       <devSubClass value="/sys/class/usb_mode/usb0/bDeviceSubClass"/>
-                       <devProtocol value="/sys/class/usb_mode/usb0/bDeviceProtocol"/>
-                       <wceis       value="/sys/class/usb_mode/usb0/f_rndis/wceis"/>
-                       <diagClients value="/sys/class/usb_mode/usb0/f_diag/clients"/>
-                       <iProduct    value="/sys/class/usb_mode/usb0/iProduct"/>
-                       <enable      value="/sys/class/usb_mode/usb0/enable"/>
-               </usb-drv>
-
-               <usb-drv ver="1.0&#10;">
-                       <disable     value="/sys/class/usb_mode/usb0/enable"/>
-                       <idVendor    value="/sys/class/usb_mode/usb0/idVendor"/>
-                       <idProduct   value="/sys/class/usb_mode/usb0/idProduct"/>
-                       <functions   value="/sys/class/usb_mode/usb0/functions"/>
-                       <devClass    value="/sys/class/usb_mode/usb0/bDeviceClass"/>
-                       <devSubClass value="/sys/class/usb_mode/usb0/bDeviceSubClass"/>
-                       <devProtocol value="/sys/class/usb_mode/usb0/bDeviceProtocol"/>
-                       <wceis       value="/sys/class/usb_mode/usb0/f_rndis/wceis"/>
-                       <diagClients value="/sys/class/usb_mode/usb0/f_diag/clients"/>
-                       <enable      value="/sys/class/usb_mode/usb0/enable"/>
-               </usb-drv>
-
-       </config-nodes>
-
-       <usb-operations>
-               <action value="set">
-                       <!-- none -->
-                       <mode value="0">
-                       </mode>
-                       <!-- mtp -->
-                       <mode value="1">
-                               <dr-start         value="/usr/bin/start_dr.sh"/>
-                               <mtp-start        value="/usr/bin/mtp-responder"    background="true"/>
-                       </mode>
-                       <!-- mtp,sdb -->
-                       <mode value="2">
-                               <dr-start         value="/usr/bin/start_dr.sh"/>
-                               <mtp-start        value="/usr/bin/mtp-responder"    background="true"/>
-                               <sdbd-start       value="/usr/bin/systemctl start sdbd.service"/>
-                       </mode>
-                       <!-- mtp,sdb,diag -->
-                       <mode value="3">
-                               <dr-start         value="/usr/bin/start_dr.sh"/>
-                               <mtp-start        value="/usr/bin/mtp-responder"    background="true"/>
-                               <sdbd-start       value="/usr/bin/systemctl start sdbd.service"/>
-                       </mode>
-                       <!-- rndis for tethering -->
-                       <mode value="4">
-                               <ip-ethernet-set  value="/sbin/ifconfig usb0 192.168.129.3 up"/>
-                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
-                       </mode>
-                       <!-- rndis -->
-                       <mode value="5">
-                               <ip-tethering-set value="/sbin/ifconfig usb0 192.168.129.3 up"/>
-                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
-                               <sshd-start       value="/usr/bin/systemctl start sshd.service"/>
-                       </mode>
-                       <!-- rndis,sdb -->
-                       <mode value="6">
-                               <ip-ethernet-set  value="/sbin/ifconfig usb0 192.168.129.3 up"/>
-                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
-                               <sshd-start       value="/usr/bin/systemctl start sshd.service"/>
-                               <sdbd-start       value="/usr/bin/systemctl start sdbd.service"/>
-                       </mode>
-                       <!-- rndis,diag -->
-                       <mode value="8">
-                               <ip-tethering-set value="/sbin/ifconfig usb0 192.168.129.3 up"/>
-                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
-                               <sshd-start       value="/usr/bin/systemctl start sshd.service"/>
-                       </mode>
-
-               </action>
-
-               <action value="unset">
-                       <!-- none -->
-                       <mode value="0">
-                       </mode>
-                       <!-- mtp -->
-                       <mode value="1">
-                       </mode>
-                       <!-- mtp,sdb -->
-                       <mode value="2">
-                               <sdbd-stop        value="/usr/bin/systemctl stop sdbd.service"/>
-                       </mode>
-                       <!-- mtp,sdb,diag -->
-                       <mode value="3">
-                               <sdbd-stop        value="/usr/bin/systemctl stop sdbd.service"/>
-                       </mode>
-                       <!-- rndis for tethering -->
-                       <mode value="4">
-                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
-                       </mode>
-                       <!-- rndis -->
-                       <mode value="5">
-                               <sshd-stop        value="/usr/bin/systemctl stop sshd.service"/>
-                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
-                       </mode>
-                       <!-- rndis,sdb -->
-                       <mode value="6">
-                               <sshd-stop        value="/usr/bin/systemctl stop sshd.service"/>
-                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
-                               <sdbd-stop        value="/usr/bin/systemctl stop sdbd.service"/>
-                       </mode>
-                       <!-- rndisi,diag -->
-                       <mode value="8">
-                               <sshd-stop        value="/usr/bin/systemctl stop sshd.service"/>
-                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
-                       </mode>
-
-               </action>
-       </usb-operations>
-
-       <usb-configurations>
-               <usb-drv ver="1.1&#10;">
-                       <!-- none -->
-                       <mode value="0">
-                               <disable     value="0"/>
-                       </mode>
-                       <!-- mtp -->
-                       <mode value="1">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6860"/>
-                               <funcs_fconf value="mtp"/>
-                               <funcs_sconf value="mtp,acm"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- mtp,sdb -->
-                       <mode value="2">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6860"/>
-                               <funcs_fconf value="mtp"/>
-                               <funcs_sconf value="mtp,acm,sdb"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- mtp,sdb,diag -->
-                       <mode value="3">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6860"/>
-                               <funcs_fconf value="mtp"/>
-                               <funcs_sconf value="mtp,acm,sdb,diag"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <diagClients value="diag"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndis for tethering -->
-                       <mode value="4">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6863"/>
-                               <funcs_fconf value="rndis"/>
-                               <funcs_sconf value=" "/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <wceis       value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndis -->
-                       <mode value="5">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6863"/>
-                               <funcs_fconf value="rndis"/>
-                               <funcs_sconf value=" "/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <wceis       value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndis,sdb -->
-                       <mode value="6">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6864"/>
-                               <funcs_fconf value="rndis,sdb"/>
-                               <funcs_sconf value=" "/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndis,diag -->
-                       <mode value="8">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6864"/>
-                               <funcs_fconf value="rndis,diag"/>
-                               <funcs_sconf value=" "/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <diagClients value="diag"/>
-                               <wceis       value="0"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-
-               </usb-drv>
-
-               <usb-drv ver="1.0&#10;">
-                       <!-- none -->
-                       <mode value="0">
-                               <disable     value="0"/>
-                       </mode>
-                       <!-- mtp -->
-                       <mode value="1">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6860"/>
-                               <functions   value="mtp,acm"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- mtp,sdb -->
-                       <mode value="2">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6860"/>
-                               <functions   value="mtp,acm,sdb"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- mtp,sdb,diag -->
-                       <mode value="3">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6860"/>
-                               <functions   value="mtp,acm,sdb,diag"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <diagClients value="diag"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndis for tethering -->
-                       <mode value="4">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6863"/>
-                               <functions   value="rndis"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <wceis       value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndis -->
-                       <mode value="5">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6863"/>
-                               <functions   value="rndis"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <wceis       value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndis,sdb -->
-                       <mode value="6">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6864"/>
-                               <functions   value="rndis,sdb"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-                       <!-- rndisi,diag -->
-                       <mode value="8">
-                               <disable     value="0"/>
-                               <idVendor    value="04e8"/>
-                               <idProduct   value="6864"/>
-                               <functions   value="rndis,diag"/>
-                               <devClass    value="239"/>
-                               <devSubClass value="2"/>
-                               <devProtocol value="1"/>
-                               <diagClients value="diag"/>
-                               <wceis       value="0"/>
-                               <iProduct    value="TIZEN"/>
-                               <enable      value="1"/>
-                       </mode>
-
-               </usb-drv>
-
-       </usb-configurations>
-</usb-config>
diff --git a/src/usb/usb-client-config.c b/src/usb/usb-client-config.c
new file mode 100755 (executable)
index 0000000..e02f153
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 <vconf.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include "core/log.h"
+#include "core/list.h"
+#include "usb-client.h"
+#include "core/config-parser.h"
+
+#define BUF_MAX 128
+
+#define USB_CLIENT_CONFIGURATION    "/etc/deviced/usb-client-configuration.conf"
+#define USB_CLIENT_OPERATION        "/etc/deviced/usb-client-operation.conf"
+
+#define SECTION_ROOT_PATH  "RootPath"
+#define NAME_PATH          "path"
+
+struct operation_data {
+       char *action;
+       char *mode;
+};
+
+struct usb_client_mode {
+       int mode;
+       char *name;
+};
+
+struct usb_client_mode usb_mode_match[] = {
+       { SET_USB_NONE             ,    "None"      },
+       { SET_USB_DEFAULT          ,    "Default"   },
+       { SET_USB_SDB              ,    "Sdb"       },
+       { SET_USB_SDB_DIAG         ,    "SdbDiag"   },
+       { SET_USB_RNDIS            ,    "Rndis"     },
+       { SET_USB_RNDIS_TETHERING  ,    "Rndis"     },
+       { SET_USB_RNDIS_DIAG       ,    "RndisDiag" },
+       { SET_USB_RNDIS_SDB        ,    "RndisSdb"  },
+       { SET_USB_DIAG_SDB         ,    "DiagSdb"   },
+       { SET_USB_DIAG_RMNET       ,    "DiagRmnet" },
+};
+
+static dd_list *oper_list;       /* Operations for USB mode */
+static dd_list *conf_list;       /* Configurations for usb mode */
+static char root_path[BUF_MAX] = {0,};
+
+
+int get_operations_list(dd_list **list)
+{
+       if (!list)
+               return -EINVAL;
+
+       *list = oper_list;
+       return 0;
+}
+
+int get_configurations_list(dd_list **list)
+{
+       if (!list)
+               return -EINVAL;
+
+       *list = conf_list;
+       return 0;
+}
+
+int get_root_path(char **path)
+{
+       if (strlen(root_path) <= 0)
+               return -EINVAL;
+
+       *path = root_path;
+       return 0;
+}
+
+static int find_usb_mode_str(int usb_mode, char **name)
+{
+       int i;
+
+       if (!name)
+               return -EINVAL;
+
+       for (i = 0 ; i < ARRAY_SIZE(usb_mode_match) ; i++) {
+               if (usb_mode == usb_mode_match[i].mode) {
+                       *name = usb_mode_match[i].name;
+                       return 0;
+               }
+       }
+
+       _E("Failed to find usb mode (%d)", usb_mode);
+       return -EINVAL;
+}
+
+static int load_configuration_config(struct parse_result *result, void *user_data)
+{
+       char *name = user_data;
+       int i;
+       size_t res_sec_len, res_name_len, name_len;
+       size_t root_path_len, path_len;
+       struct usb_configuration *conf;
+
+       if (!result)
+               return -EINVAL;
+
+       res_sec_len = strlen(result->section);
+
+       root_path_len = strlen(SECTION_ROOT_PATH);
+       if (res_sec_len == root_path_len
+                       && !strncmp(result->section, SECTION_ROOT_PATH, res_sec_len)) {
+
+               res_name_len = strlen(result->name);
+               path_len = strlen(NAME_PATH);
+               if (res_name_len == path_len
+                               && !strncmp(result->name, NAME_PATH, res_name_len))
+                       snprintf(root_path, sizeof(root_path), "%s", result->value);
+
+               return 0;
+       }
+
+       name_len = strlen(name);
+       if (res_sec_len != name_len
+                       || strncmp(result->section, name, res_sec_len))
+               return 0;
+
+       conf = (struct usb_configuration *)malloc(sizeof(struct usb_configuration));
+       if (!conf) {
+               _E("malloc() failed");
+               return -ENOMEM;
+       }
+
+       snprintf(conf->name, sizeof(conf->name), "%s", result->name);
+       snprintf(conf->value, sizeof(conf->value), "%s", result->value);
+
+       DD_LIST_APPEND(conf_list, conf);
+       _I("USB configuration: name(%s), value(%s)", conf->name, conf->value);
+
+       return 0;
+}
+
+int make_configuration_list(int usb_mode)
+{
+       int i, ret = 0;
+       char *name = NULL;
+
+       ret = find_usb_mode_str(usb_mode, &name);
+       if (ret < 0) {
+               _E("Failed to get usb mode string (%d)", ret);
+               return ret;
+       }
+
+       ret = config_parse(USB_CLIENT_CONFIGURATION, load_configuration_config, name);
+       if (ret < 0)
+               _E("Failed to load usb configurations");
+
+       return ret;
+}
+
+void release_configuration_list(void)
+{
+       dd_list *l;
+       struct usb_configuration *conf;
+
+       if (!conf_list)
+               return;
+
+       DD_LIST_FOREACH(conf_list, l, conf) {
+               if (conf)
+                       free(conf);
+       }
+
+       DD_LIST_FREE_LIST(conf_list);
+       conf_list = NULL;
+}
+
+/* Getting operations for each usb mode */
+static int load_operation_config(struct parse_result *result, void *user_data)
+{
+       struct operation_data *op_data = user_data;
+       int i;
+       size_t res_sec_len, res_name_len, mode_len, action_len;
+       struct usb_operation *oper;
+
+       if (!result)
+               return -EINVAL;
+
+       res_sec_len = strlen(result->section);
+       mode_len = strlen(op_data->mode);
+       if (res_sec_len != mode_len
+                       || strncmp(result->section, op_data->mode, res_sec_len))
+               return 0;
+
+       res_name_len = strlen(result->name);
+       action_len = strlen(op_data->action);
+       if (res_name_len != action_len
+                       || strncmp(result->name, op_data->action, res_name_len))
+               return 0;
+
+       oper = (struct usb_operation *)malloc(sizeof(struct usb_operation));
+       if (!oper) {
+               _E("malloc() failed");
+               return -ENOMEM;
+       }
+
+       snprintf(oper->name, sizeof(oper->name), "%s", result->name);
+       snprintf(oper->oper, sizeof(oper->oper), "%s", result->value);
+
+       DD_LIST_APPEND(oper_list, oper);
+       _I("USB operation: name(%s), value(%s)", oper->name, oper->oper);
+
+       return 0;
+}
+
+int make_operation_list(int usb_mode, char *action)
+{
+       int ret = 0;
+       char *mode;
+       struct operation_data op_data;
+
+       if (!action)
+               return -EINVAL;
+
+       ret = find_usb_mode_str(usb_mode, &mode);
+       if (ret < 0) {
+               _E("Failed to get usb mode string (%d)", ret);
+               return ret;
+       }
+
+       op_data.action = action;
+       op_data.mode = mode;
+
+       ret = config_parse(USB_CLIENT_OPERATION, load_operation_config, &op_data);
+       if (ret < 0)
+               _E("Failed to load usb configurations");
+
+       return ret;
+}
+
+void release_operations_list(void)
+{
+       dd_list *l;
+       struct usb_operation *oper;
+
+       if (!oper_list)
+               return;
+
+       DD_LIST_FOREACH(oper_list, l, oper) {
+               if (oper)
+                       free(oper);
+       }
+
+       DD_LIST_FREE_LIST(oper_list);
+       oper_list = NULL;
+}
diff --git a/src/usb/usb-client-configuration-micro.conf b/src/usb/usb-client-configuration-micro.conf
new file mode 100644 (file)
index 0000000..685a783
--- /dev/null
@@ -0,0 +1,95 @@
+[RootPath]
+path=/sys/class/usb_mode/usb0
+
+[None]
+enable=0
+
+[Default]
+enable=0
+idVendor=04e8
+idProduct=6860
+funcs_fconf=mtp
+funcs_sconf=mtp,acm
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+iProduct=TIZEN
+enable=1
+
+[Sdb]
+enable=0
+idVendor=04e8
+idProduct=6860
+funcs_fconf=mtp
+funcs_sconf=mtp,acm,sdb
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+iProduct=TIZEN
+enable=1
+
+[SdbDiag]
+enable=0
+idVendor=04e8
+idProduct=6860
+funcs_fconf=mtp
+funcs_sconf=mtp,acm,sdb,diag
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+f_diag/clients=diag
+iProduct=TIZEN
+enable=1
+
+[Rndis]
+enable=0
+idVendor=04e8
+idProduct=6863
+funcs_fconf=rndis
+funcs_sconf=
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+f_rndis/wceis=1
+iProduct=TIZEN
+enable=1
+
+[RndisSdb]
+enable=0
+idVendor=04e8
+idProduct=6864
+funcs_fconf=rndis,sdb
+funcs_sconf=
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+iProduct=TIZEN
+enable=1
+
+[RndisDiag]
+enable=0
+idVendor=04e8
+idProduct=6864
+funcs_fconf=rndis,diag
+funcs_sconf=
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+f_diag/clients=diag
+f_rndis/wceis=0
+iProduct=TIZEN
+enable=1
+
+[DiagRmnet]
+enable=0
+idVendor=04e8
+idProduct=685d
+funcs_fconf=diag,acm,rmnet
+funcs_sconf=
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+f_diag/clients=diag
+f_rmnet/transports=smd,bam
+iProduct=TIZEN
+enable=1
diff --git a/src/usb/usb-client-configuration.conf b/src/usb/usb-client-configuration.conf
new file mode 100644 (file)
index 0000000..9921cfd
--- /dev/null
@@ -0,0 +1,81 @@
+[RootPath]
+path=/sys/class/usb_mode/usb0
+
+[None]
+enable=0
+
+[Default]
+enable=0
+idVendor=04e8
+idProduct=6860
+funcs_fconf=mtp
+funcs_sconf=mtp,acm
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+iProduct=TIZEN
+enable=1
+
+[Sdb]
+enable=0
+idVendor=04e8
+idProduct=6860
+funcs_fconf=mtp
+funcs_sconf=mtp,acm,sdb
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+iProduct=TIZEN
+enable=1
+
+[SdbDiag]
+enable=0
+idVendor=04e8
+idProduct=6860
+funcs_fconf=mtp
+funcs_sconf=mtp,acm,sdb,diag
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+f_diag/clients=diag
+iProduct=TIZEN
+enable=1
+
+[Rndis]
+enable=0
+idVendor=04e8
+idProduct=6863
+funcs_fconf=rndis
+funcs_sconf=
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+f_rndis/wceis=1
+iProduct=TIZEN
+enable=1
+
+[RndisSdb]
+enable=0
+idVendor=04e8
+idProduct=6864
+funcs_fconf=rndis,sdb
+funcs_sconf=
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+iProduct=TIZEN
+enable=1
+
+[RndisDiag]
+enable=0
+idVendor=04e8
+idProduct=6864
+funcs_fconf=rndis,diag
+funcs_sconf=
+bDeviceClass=239
+bDeviceSubClass=2
+bDeviceProtocol=1
+f_diag/clients=diag
+f_rndis/wceis=0
+iProduct=TIZEN
+enable=1
index 2c4d36d..b60f6d9 100755 (executable)
 
 static int usb_control = DEVICE_OPS_STATUS_START;
 
-int control_start(void)
+int control_start(enum device_flags flags)
 {
+       int state;
+
        if (usb_control == DEVICE_OPS_STATUS_START)
                return 0;
 
@@ -34,13 +36,16 @@ int control_start(void)
        if (vconf_set_int(VCONFKEY_USB_CONTROL, usb_control) != 0)
                _E("Failed to set vconf");
 
-       if (check_current_usb_state() > 0)
+       state = get_current_usb_physical_state();
+       usb_state_changed(state);
+
+       if (state > 0)
                act_usb_connected();
 
        return 0;
 }
 
-int control_stop(void)
+int control_stop(enum device_flags flags)
 {
        int cur_mode;
        if (usb_control == DEVICE_OPS_STATUS_STOP)
@@ -76,12 +81,17 @@ static void check_prev_control_status(void)
 
 static int usb_client_booting_done(void *data)
 {
+       int state;
+
        unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usb_client_booting_done);
        check_prev_control_status();
 
        usbclient_init_booting_done();
 
-       if (check_current_usb_state() > 0)
+       state = get_current_usb_physical_state();
+       usb_state_changed(state);
+
+       if (state > 0)
                act_usb_connected();
 
        return 0;
index 4aa0a95..90a1627 100755 (executable)
  */
 
 #include <vconf.h>
+#include <limits.h>
 #include "usb-client.h"
 #include "core/edbus-handler.h"
 
 #define CHANGE_USB_MODE "ChangeUsbMode"
 
+#define METHOD_GET_STATE      "GetState"
+#define METHOD_GET_MODE       "GetMode"
+#define SIGNAL_STATE_CHANGED  "StateChanged"
+#define SIGNAL_MODE_CHANGED   "ModeChanged"
+
+#define USB_STATE_MAX   UINT_MAX
+#define USB_MODE_MAX    UINT_MAX
+
+enum usbclient_state {
+       USBCLIENT_STATE_DISCONNECTED = 0x00,
+       USBCLIENT_STATE_CONNECTED    = 0x01,
+       USBCLIENT_STATE_AVAILABLE    = 0x02,
+};
+
 static void change_usb_client_mode(void *data, DBusMessage *msg)
 {
        DBusError err;
@@ -43,6 +58,7 @@ static void change_usb_client_mode(void *data, DBusMessage *msg)
        case SET_USB_DEFAULT:
        case SET_USB_RNDIS:
        case SET_USB_RNDIS_DIAG:
+       case SET_USB_DIAG_RMNET:
                debug = 0;
                break;
        case SET_USB_SDB:
@@ -74,3 +90,114 @@ int register_usb_client_change_request(void)
                        CHANGE_USB_MODE, change_usb_client_mode);
 }
 
+static unsigned int get_usb_state(void)
+{
+       unsigned int state = USBCLIENT_STATE_DISCONNECTED;
+
+       if (get_current_usb_physical_state() == 0) {
+               state |= USBCLIENT_STATE_DISCONNECTED;
+               goto out;
+       }
+
+       state |= USBCLIENT_STATE_CONNECTED;
+
+       if (get_current_usb_logical_state() > 0
+                       && get_current_usb_mode() > SET_USB_NONE)
+               state |= USBCLIENT_STATE_AVAILABLE;
+
+out:
+       return state;
+}
+
+static unsigned int get_usb_mode(void)
+{
+       return get_current_usb_gadget_info(get_current_usb_mode());
+}
+
+void send_msg_usb_state_changed(void)
+{
+       char *param[1];
+       char text[16];
+       unsigned int state;
+       static unsigned int prev_state = USB_STATE_MAX;
+
+       state = get_usb_state();
+       if (state == prev_state)
+               return;
+       prev_state = state;
+
+       _I("USB state changed (%u)", state);
+
+       snprintf(text, sizeof(text), "%u", state);
+       param[0] = text;
+
+       if (broadcast_edbus_signal(
+                               DEVICED_PATH_USB,
+                               DEVICED_INTERFACE_USB,
+                               SIGNAL_STATE_CHANGED,
+                               "u", param) < 0)
+               _E("Failed to send dbus signal");
+}
+
+void send_msg_usb_mode_changed(void)
+{
+       char *param[1];
+       char text[16];
+       unsigned int mode;
+       static unsigned int prev_mode = USB_MODE_MAX;
+
+       mode = get_usb_mode();
+       if (mode == prev_mode)
+               return;
+       prev_mode = mode;
+
+       snprintf(text, sizeof(text), "%u", mode);
+       param[0] = text;
+
+       _I("USB mode changed (%u)", mode);
+
+       if (broadcast_edbus_signal(
+                               DEVICED_PATH_USB,
+                               DEVICED_INTERFACE_USB,
+                               SIGNAL_MODE_CHANGED,
+                               "u", param) < 0)
+               _E("Failed to send dbus signal");
+}
+
+static DBusMessage *get_usb_client_state(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int state;
+
+       state = get_usb_state();
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &state);
+       return reply;
+}
+
+static DBusMessage *get_usb_client_mode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int mode;
+
+       mode = get_usb_mode();
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &mode);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { METHOD_GET_STATE    ,  NULL, "u" ,  get_usb_client_state },
+       { METHOD_GET_MODE     ,  NULL, "u" ,  get_usb_client_mode  },
+};
+
+int register_usbclient_dbus_methods(void)
+{
+       return register_edbus_method(DEVICED_PATH_USB, edbus_methods, ARRAY_SIZE(edbus_methods));
+}
diff --git a/src/usb/usb-client-event-sdk.c b/src/usb/usb-client-event-sdk.c
new file mode 100755 (executable)
index 0000000..af9935c
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdbool.h>
+#include <vconf.h>
+#include "usb-client.h"
+
+#ifdef EMULATOR
+
+static void act_usb_connected_sdk(void)
+{
+       if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_ENABLED) != 0)
+               _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
+
+       update_current_usb_mode(SET_USB_SDB);
+
+       if (update_usb_state(VCONFKEY_SYSMAN_USB_AVAILABLE) < 0)
+               _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_AVAILABLE);
+
+       pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
+}
+
+static void act_usb_disconnected_sdk(void)
+{
+       pm_unlock_internal(getpid(), LCD_OFF, STAY_CUR_STATE);
+
+       if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_DISABLED) != 0)
+               _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
+
+       update_current_usb_mode(SET_USB_NONE);
+
+       if (update_usb_state(VCONFKEY_SYSMAN_USB_DISCONNECTED) < 0)
+               _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_DISCONNECTED);
+}
+
+void usb_state_changed(int state)
+{
+       if (state == 0)
+               act_usb_disconnected_sdk();
+       else if (state == 1)
+               act_usb_connected_sdk();
+       else
+               _E("Invalid USB state (%d)", state);
+}
+#else
+void usb_state_changed(int state)
+{
+       /* Do nothing */
+}
+#endif
diff --git a/src/usb/usb-client-mode-micro.c b/src/usb/usb-client-mode-micro.c
new file mode 100755 (executable)
index 0000000..0119d39
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 "usb-client.h"
+
+enum usbclient_mode {
+       USBCLIENT_MODE_NONE          = 0x00,
+       USBCLIENT_MODE_MTP           = 0x01,
+       USBCLIENT_MODE_ACM           = 0x02,
+       USBCLIENT_MODE_SDB           = 0x04,
+       USBCLIENT_MODE_RNDIS         = 0x08,
+       USBCLIENT_MODE_DIAG          = 0x10,
+       USBCLIENT_MODE_RMNET         = 0x20,
+};
+
+unsigned int get_current_usb_gadget_info(int mode)
+{
+       unsigned int gadgets = USBCLIENT_MODE_NONE;
+
+       switch (mode) {
+       case SET_USB_DEFAULT:
+               gadgets |= USBCLIENT_MODE_MTP;
+               gadgets |= USBCLIENT_MODE_ACM;
+               break;
+       case SET_USB_SDB:
+               gadgets |= USBCLIENT_MODE_MTP;
+               gadgets |= USBCLIENT_MODE_ACM;
+               gadgets |= USBCLIENT_MODE_SDB;
+               break;
+       case SET_USB_SDB_DIAG:
+               gadgets |= USBCLIENT_MODE_MTP;
+               gadgets |= USBCLIENT_MODE_ACM;
+               gadgets |= USBCLIENT_MODE_SDB;
+               gadgets |= USBCLIENT_MODE_DIAG;
+               break;
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_TETHERING:
+               gadgets |= USBCLIENT_MODE_RNDIS;
+               break;
+       case SET_USB_RNDIS_DIAG:
+               gadgets |= USBCLIENT_MODE_RNDIS;
+               gadgets |= USBCLIENT_MODE_DIAG;
+               break;
+       case SET_USB_RNDIS_SDB:
+               gadgets |= USBCLIENT_MODE_RNDIS;
+               gadgets |= USBCLIENT_MODE_SDB;
+               break;
+       case SET_USB_DIAG_SDB:
+               gadgets |= USBCLIENT_MODE_DIAG;
+               gadgets |= USBCLIENT_MODE_SDB;
+               break;
+       case SET_USB_DIAG_RMNET:
+               gadgets |= USBCLIENT_MODE_DIAG;
+               gadgets |= USBCLIENT_MODE_ACM;
+               gadgets |= USBCLIENT_MODE_RMNET;
+               break;
+       default:
+               break;
+       }
+
+       return gadgets;
+}
diff --git a/src/usb/usb-client-mode.c b/src/usb/usb-client-mode.c
new file mode 100755 (executable)
index 0000000..81027ec
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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 "usb-client.h"
+
+enum usbclient_mode {
+       USBCLIENT_MODE_NONE          = 0x00,
+       USBCLIENT_MODE_MTP           = 0x01,
+       USBCLIENT_MODE_ACM           = 0x02,
+       USBCLIENT_MODE_SDB           = 0x04,
+       USBCLIENT_MODE_RNDIS         = 0x08,
+       USBCLIENT_MODE_DIAG          = 0x10,
+       USBCLIENT_MODE_CONN_GADGET   = 0x20,
+};
+
+unsigned int get_current_usb_gadget_info(int mode)
+{
+       unsigned int gadgets = USBCLIENT_MODE_NONE;
+
+       switch (mode) {
+       case SET_USB_DEFAULT:
+               gadgets |= USBCLIENT_MODE_MTP;
+               gadgets |= USBCLIENT_MODE_ACM;
+               gadgets |= USBCLIENT_MODE_CONN_GADGET;
+               break;
+       case SET_USB_SDB:
+               gadgets |= USBCLIENT_MODE_MTP;
+               gadgets |= USBCLIENT_MODE_ACM;
+               gadgets |= USBCLIENT_MODE_SDB;
+               gadgets |= USBCLIENT_MODE_CONN_GADGET;
+               break;
+       case SET_USB_SDB_DIAG:
+               gadgets |= USBCLIENT_MODE_MTP;
+               gadgets |= USBCLIENT_MODE_ACM;
+               gadgets |= USBCLIENT_MODE_SDB;
+               gadgets |= USBCLIENT_MODE_DIAG;
+               break;
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_TETHERING:
+               gadgets |= USBCLIENT_MODE_RNDIS;
+               break;
+       case SET_USB_RNDIS_DIAG:
+               gadgets |= USBCLIENT_MODE_RNDIS;
+               gadgets |= USBCLIENT_MODE_DIAG;
+               break;
+       case SET_USB_RNDIS_SDB:
+               gadgets |= USBCLIENT_MODE_RNDIS;
+               gadgets |= USBCLIENT_MODE_SDB;
+               break;
+       case SET_USB_DIAG_SDB:
+               gadgets |= USBCLIENT_MODE_DIAG;
+               gadgets |= USBCLIENT_MODE_SDB;
+               break;
+       default:
+               break;
+       }
+
+       return gadgets;
+}
diff --git a/src/usb/usb-client-operation.conf b/src/usb/usb-client-operation.conf
new file mode 100644 (file)
index 0000000..4f3c118
--- /dev/null
@@ -0,0 +1,41 @@
+[Default]
+start=/usr/bin/data-router
+start=/usr/bin/mtp-responder
+
+[Sdb]
+start=/usr/bin/data-router
+start=/usr/bin/mtp-responder
+start=/usr/bin/systemctl start sdbd.service
+stop=/usr/bin/systemctl stop sdbd.service
+
+[SdbDiag]
+start=/usr/bin/data-router
+start=/usr/bin/mtp-responder
+start=/usr/bin/systemctl start sdbd.service
+stop=/usr/bin/systemctl stop sdbd.service
+
+[Rndis]
+start=/sbin/ifconfig usb0 192.168.129.3 up
+start=/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0
+start=/usr/bin/systemctl start sshd.service
+stop=/usr/bin/systemctl stop sshd.service
+stop=/sbin/ifconfig usb0 down
+
+[RndisSdb]
+start=/sbin/ifconfig usb0 192.168.129.3 up
+start=/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0
+start=/usr/bin/systemctl start sshd.service
+start=/usr/bin/systemctl start sdbd.service
+stop=/usr/bin/systemctl stop sshd.service
+stop=/sbin/ifconfig usb0 down
+stop=/usr/bin/systemctl stop sdbd.service
+
+[RndisDiag]
+start=/sbin/ifconfig usb0 192.168.129.3 up
+start=/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0
+start=/usr/bin/systemctl start sshd.service
+stop=/usr/bin/systemctl stop sshd.service
+stop=/sbin/ifconfig usb0 down
+
+[DiagRmnet]
+start=/usr/bin/data-router
index 5ed9152..f4e8aae 100755 (executable)
@@ -34,35 +34,34 @@ const static bool eng_mode = true;
 const static bool eng_mode = false;
 #endif
 
-struct ticker_data {
-       char *name;
-       int type;
-};
-
 static int debug = 0;
 
 static int write_sysfs(char *path, char *value)
 {
        FILE *fp;
        int ret;
+       char *conf;
 
-       if (!path || !value)
+       if (strlen(path) == 0)
                return -ENOMEM;
 
+       if (strlen(value) > 0)
+               conf = value;
+       else
+               conf = " ";
+
        fp = fopen(path, "w");
        if (!fp) {
                _E("FAIL: fopen(%s)", path);
                return -ENOMEM;
        }
 
-       ret = fwrite(value, sizeof(char), strlen(value), fp);
-       if (ret < strlen(value)) {
-               _E("FAIL: fwrite(%s)", value);
+       ret = fwrite(conf, sizeof(char), strlen(conf), fp);
+       if (ret < strlen(conf)) {
+               _E("FAIL: fwrite(%s)", conf);
                ret = -ENOMEM;
-               goto out;
        }
 
-out:
        if (fclose(fp) != 0)
                _E("FAIL: fclose()");
        return ret;
@@ -71,19 +70,25 @@ out:
 static int set_configurations_to_sysfs(dd_list *list)
 {
        dd_list *l;
-       struct xmlConfiguration *conf;
+       struct usb_configuration *conf;
        int ret;
+       char *root_path, path[BUF_MAX];
 
        if (!list)
                return -EINVAL;
 
-       DD_LIST_FOREACH(list, l, conf) {
-               if (!(conf->value))
-                       continue;
+       ret = get_root_path(&root_path);
+       if (ret < 0) {
+               _E("Failed to get root path for usb configuration (%d)", ret);
+               return ret;
+       }
 
-               ret = write_sysfs(conf->path, conf->value);
+       DD_LIST_FOREACH(list, l, conf) {
+               snprintf(path, sizeof(path), "%s/%s", root_path, conf->name);
+               _I("Usb conf: (%s, %s)", path, conf->value);
+               ret = write_sysfs(path, conf->value);
                if (ret < 0) {
-                       _E("FAIL: write_sysfs(%s, %s)", conf->path, conf->value);
+                       _E("FAIL: write_sysfs(%s, %s)", path, conf->value);
                        return ret;
                }
        }
@@ -93,16 +98,16 @@ static int set_configurations_to_sysfs(dd_list *list)
 static void run_operations_for_usb_mode(dd_list *list)
 {
        dd_list *l;
-       int ret;
-       struct xmlOperation *oper;
+       int ret, argc;
+       struct usb_operation *oper;
 
        if (!list)
                return ;
 
-        DD_LIST_FOREACH(list, l, oper) {
-                ret = launch_app_cmd(oper->oper);
-                _I("operation: %s(%d)", oper->oper, ret);
-        }
+       DD_LIST_FOREACH(list, l, oper) {
+               ret = launch_app_cmd(oper->oper);
+               _I("operation: %s(%d)", oper->oper, ret);
+       }
 }
 
 void unset_client_mode(int mode, bool change)
@@ -126,63 +131,17 @@ void unset_client_mode(int mode, bool change)
                                _E("FAIL: set_configurations_to_sysfs()");
                }
        }
+       release_configuration_list();
 
-       ret = make_operation_list(mode, USB_CON_UNSET);
+       ret = make_operation_list(mode, USB_CON_STOP);
        if (ret == 0) {
                ret = get_operations_list(&oper_list);
                if (ret == 0)
                        run_operations_for_usb_mode(oper_list);
        }
-
        release_operations_list();
 }
 
-static void launch_ticker_notification(int cur_mode, int sel_mode)
-{
-       struct ticker_data ticker;
-       const struct device_ops *ticker_ops;
-
-       switch(sel_mode) {
-       case SET_USB_DEFAULT:
-       case SET_USB_SDB:
-       case SET_USB_SDB_DIAG:
-               if (cur_mode == SET_USB_DEFAULT
-                               || cur_mode == SET_USB_SDB
-                               || cur_mode == SET_USB_SDB_DIAG)
-                       return;
-
-               ticker.name = TICKER_TYPE_DEFAULT;
-               ticker.type = 0; /* WITHOUT_QUEUE */
-               break;
-       case SET_USB_RNDIS:
-       case SET_USB_RNDIS_DIAG:
-       case SET_USB_RNDIS_SDB:
-               if (cur_mode == SET_USB_RNDIS
-                               || cur_mode == SET_USB_RNDIS_TETHERING
-                               || cur_mode == SET_USB_RNDIS_DIAG
-                               || cur_mode == SET_USB_RNDIS_SDB)
-                       return;
-
-               ticker.name = TICKER_TYPE_SSH;
-               ticker.type = 0; /* WITHOUT_QUEUE */
-               break;
-       case SET_USB_NONE:
-       case SET_USB_RNDIS_TETHERING:
-       default:
-               return;
-       }
-
-       ticker_ops = find_device("ticker");
-
-       if (get_cradle_status() > 0)
-               return;
-
-       if (ticker_ops && ticker_ops->init)
-               ticker_ops->init(&ticker);
-       else
-               _E("cannot find \"ticker\" ops");
-}
-
 static int get_selected_mode_by_debug_mode(int mode)
 {
        int ret;
@@ -325,33 +284,33 @@ void change_client_setting(int options)
                ret = make_configuration_list(sel_mode);
                if (ret < 0) {
                        _E("FAIL: make_configuration_list(%d)", sel_mode);
-                       goto out_configuration;
+                       goto out;
                }
 
                ret = get_configurations_list(&conf_list);
                if (ret < 0) {
                        _E("failed to get configuration list");
-                       goto out_configuration;
+                       goto out;
                }
 
                ret = set_configurations_to_sysfs(conf_list);
                if (ret < 0) {
                        _E("FAIL: set_configurations_to_sysfs()");
-                       goto out_configuration;
+                       goto out;
                }
        }
 
        if (options & SET_OPERATION) {
-               ret = make_operation_list(sel_mode, USB_CON_SET);
+               ret = make_operation_list(sel_mode, USB_CON_START);
                if (ret < 0) {
                        _E("FAIL: make_operation_list()");
-                       goto out_operation;
+                       goto out;
                }
 
                ret = get_operations_list(&oper_list);
                if (ret < 0) {
                        _E("failed to get operation list");
-                       goto out_operation;
+                       goto out;
                }
 
                if (update_usb_state(VCONFKEY_SYSMAN_USB_AVAILABLE) < 0)
@@ -363,17 +322,14 @@ void change_client_setting(int options)
        }
 
        if (options & SET_NOTIFICATION) {
-               launch_ticker_notification(cur_mode, sel_mode);
+               /* Do nothing */
        }
 
        ret = 0;
 
-out_operation:
+out:
        release_operations_list();
-
-out_configuration:
-       if (make_configuration_list(SET_USB_NONE) < 0)
-               _E("Release configurations info error");
+       release_configuration_list();
 
        if (ret < 0)
                launch_syspopup(USB_ERROR);
@@ -391,103 +347,6 @@ void client_mode_changed(keynode_t* key, void *data)
        change_client_setting(SET_CONFIGURATION | SET_OPERATION | SET_NOTIFICATION);
 }
 
-#if 0
-void client_mode_changed(keynode_t* key, void *data)
-{
-       int sel_mode;
-       int cur_mode;
-       int ret;
-       char *action;
-       dd_list *conf_list;
-       dd_list *oper_list;
-
-       if (control_status() == DEVICE_OPS_STATUS_STOP) {
-               launch_syspopup(USB_RESTRICT);
-               return;
-       }
-
-       sel_mode = get_selected_usb_mode();
-       if (sel_mode <= SET_USB_NONE) {
-               _E("Getting selected usb mode error(%d)", sel_mode);
-               return;
-       }
-
-       if (check_usb_tethering()) {
-               _I("Turning on the usb tethering");
-               return;
-       }
-
-       ret = check_debug_mode(sel_mode);
-       if (ret != 0)
-               return;
-
-       sel_mode = check_first_eng_mode(sel_mode);
-
-       cur_mode = get_current_usb_mode();
-       if (cur_mode < SET_USB_NONE) {
-               _E("Getting current usb mode error(%d)", cur_mode);
-               return ;
-       }
-
-       if (cur_mode == sel_mode) {
-               _I("Current usb mode(%d) is same with selected usb mode(%d)", cur_mode, sel_mode);
-               return ;
-       }
-
-       if (cur_mode != SET_USB_NONE) {
-               unset_client_mode(cur_mode);
-       }
-
-       ret = make_configuration_list(sel_mode);
-       if (ret < 0) {
-               _E("FAIL: make_configuration_list(%d)", sel_mode);
-               goto out;
-       }
-
-       ret = make_operation_list(sel_mode, USB_CON_SET);
-       if (ret < 0) {
-               _E("FAIL: make_operation_list()");
-               goto out;
-       }
-
-       ret = get_configurations_list(&conf_list);
-       if (ret < 0) {
-               _E("failed to get configuration list");
-               goto out;
-       }
-
-       ret = get_operations_list(&oper_list);
-       if (ret < 0) {
-               _E("failed to get operation list");
-               goto out;
-       }
-
-       ret = set_configurations_to_sysfs(conf_list);
-       if (ret < 0) {
-               _E("FAIL: set_configurations_to_sysfs()");
-               goto out;
-       }
-
-       update_current_usb_mode(sel_mode);
-
-       run_operations_for_usb_mode(oper_list);
-
-       launch_ticker_notification(cur_mode, sel_mode);
-
-       ret = 0;
-
-out:
-       if (ret < 0)
-               launch_syspopup(USB_ERROR);
-
-       release_operations_list();
-       ret = make_configuration_list(SET_USB_NONE);
-       if (ret < 0)
-               _E("release configurations info error");
-       return;
-}
-#endif
-
 void debug_mode_changed(keynode_t* key, void *data)
 {
        int new_debug;
diff --git a/src/usb/usb-client-xml.c b/src/usb/usb-client-xml.c
deleted file mode 100755 (executable)
index 49d27a7..0000000
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 <vconf.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <libxml/parser.h>
-#include "core/log.h"
-#include "core/list.h"
-#include "usb-client.h"
-
-#define BUF_MAX 256
-
-#define DEFAULT_IPRODUCT_NAME "TIZEN"
-
-#define CONF_PATH                "/usr/share/deviced/usb-configurations"
-#define SUPPORTED_CONF_PATH      CONF_PATH"/conf-supported.xml"
-#define USB_CONFIGURATIONS_PATH  CONF_PATH"/usb-configurations.xml"
-
-#define USB_CON_SET             "set"
-#define USB_CON_UNSET           "unset"
-
-#define NODE_NAME_TEXT          "text"
-#define NODE_NAME_COMMENT       "comment"
-#define NODE_NAME_CONFIG_NODES  "config-nodes"
-#define NODE_NAME_CONFIG_files  "config-files"
-#define NODE_NAME_USB_CONFIG    "usb-config"
-#define NODE_NAME_CONF_FILE     "conf-file"
-#define NODE_NAME_USB_CONFS     "usb-configurations"
-#define NODE_NAME_USB_OPERS     "usb-operations"
-#define NODE_NAME_DRIVER        "driver"
-#define NODE_NAME_USB_DRV       "usb-drv"
-#define NODE_NAME_MODE          "mode"
-#define NODE_NAME_ACTION        "action"
-#define NODE_NAME_IPRODUCT      "iProduct"
-#define ATTR_VALUE              "value"
-#define ATTR_VERSION            "ver"
-#define ATTR_BACKGROUND         "background"
-
-static dd_list *supported_list;  /* Supported Configurations */
-static dd_list *oper_list;       /* Operations for USB mode */
-static dd_list *conf_list;       /* Configurations for usb mode */
-static char *driver;             /* usb driver version (ex. 1.0, 1.1, none, ... ) */
-
-int get_operations_list(dd_list **list)
-{
-       if (!list)
-               return -EINVAL;
-
-       *list = oper_list;
-       return 0;
-}
-
-int get_configurations_list(dd_list **list)
-{
-       if (!list)
-               return -EINVAL;
-
-       *list = conf_list;
-       return 0;
-}
-
-#ifdef USB_DEBUG
-static void show_supported_confs_list(void)
-{
-       int i;
-       dd_list *l;
-       struct xmlSupported *sp;
-       void *mode;
-
-       if (!supported_list) {
-               _D("Supported Confs list is empty");
-               return;
-       }
-
-       _D("********************************");
-       _D("** Supported Confs list");
-       _D("********************************");
-
-       DD_LIST_FOREACH(supported_list, l, sp) {
-               _D("** Mode      : %d", sp->mode);
-               _D("********************************");
-       }
-}
-
-static void show_operation_list(void)
-{
-       int i;
-       dd_list *l;
-       struct xmlOperation *oper;
-
-       _D("********************************");
-       _D("** Operation list");
-       _D("********************************");
-       if (!oper_list) {
-               _D("Operation list is empty");
-               _D("********************************");
-               return;
-       }
-
-       i = 0;
-       DD_LIST_FOREACH(oper_list, l, oper) {
-               _D("** Number    : %d", i++);
-               _D("** Name      : %s", oper->name);
-               _D("** Operation : %s", oper->oper);
-               _D("** Background: %d", oper->background);
-               _D("********************************");
-       }
-}
-
-static void show_configuration_list(void)
-{
-       int i;
-       dd_list *l;
-       struct xmlConfiguration *conf;
-
-       if (!conf_list) {
-               _D("Configuration list is empty");
-               return;
-       }
-
-       _D("********************************");
-       _D("** Configuration list");
-       _D("********************************");
-
-       i = 0;
-       DD_LIST_FOREACH(conf_list, l, conf) {
-               _D("** Number: %d", i++);
-               _D("** Name  : %s", conf->name);
-               _D("** Path  : %s", conf->path);
-               _D("** Value : %s", conf->value);
-               _D("********************************");
-       }
-}
-#else
-#define show_supported_confs_list() do {} while(0)
-#define show_operation_list() do {} while(0)
-#define show_configuration_list() do {} while(0)
-#endif
-
-static xmlDocPtr xml_open(const char *xml)
-{
-       if (!xml)
-               return NULL;
-
-       return xmlReadFile(xml, NULL, 0);
-}
-
-static void xml_close(xmlDocPtr doc)
-{
-       xmlFreeDoc(doc);
-}
-
-static bool skip_node(xmlNodePtr node)
-{
-       if (!node)
-               return true;
-
-       if (!xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_TEXT))
-               return true;
-       if (!xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_COMMENT))
-               return true;
-
-       return false;
-}
-
-static int get_xml_property(xmlNodePtr node, char *property, char *value, int len)
-{
-       xmlChar *xmlprop;
-
-       xmlprop = xmlGetProp(node, (const xmlChar *)property);
-       if (!xmlprop)
-               return -ENOMEM;
-
-       snprintf(value, len, "%s", (char *)xmlprop);
-       xmlFree(xmlprop);
-
-       return 0;
-}
-
-static bool is_usb_mode_supported(int usb_mode)
-{
-       dd_list *l;
-       struct xmlSupported *sp;
-
-       DD_LIST_FOREACH(supported_list, l, sp) {
-               if (sp->mode == usb_mode)
-                       return true;
-       }
-
-       return false;
-}
-
-static int get_iproduct_name(char *name, int size)
-{
-       if (!name)
-               return -EINVAL;
-
-       /* TODO: Product name should be set using device model
-        * ex) TIZEN_SM-Z9005 */
-
-       snprintf(name, size, "%s", DEFAULT_IPRODUCT_NAME);
-       return 0;
-}
-
-static int get_driver_version(xmlNodePtr root)
-{
-       int ret;
-       xmlNodePtr node;
-       FILE *fp;
-       char buf[BUF_MAX];
-       char path[BUF_MAX];
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_DRIVER))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VALUE, path, sizeof(path));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               if (access(path, F_OK) != 0) {
-                       /* TODO: If the path does not exist,
-                        * usb gadgets are not from Galaxy, but from Linux Kernel */
-                       driver = NULL;
-                       return 0;
-               }
-
-               fp = fopen(path, "r");
-               if (!fp) {
-                       _E("fopen() failed(%s)", path);
-                       return -ENOMEM;
-               }
-
-               if (!fgets(buf, sizeof(buf), fp)) {
-                       _E("fgets() failed");
-                       fclose(fp);
-                       return -ENOMEM;
-               }
-
-               fclose(fp);
-
-               driver = strdup(buf);
-               break;
-       }
-       return 0;
-}
-
-/* Getting sysfs nodes to set usb configurations */
-static int add_conf_nodes_to_list(xmlNodePtr root)
-{
-       int ret;
-       xmlNodePtr node;
-       struct xmlConfiguration *conf;
-       char path[BUF_MAX];
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VALUE, path, sizeof(path));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               conf = (struct xmlConfiguration *)malloc(sizeof(struct xmlConfiguration));
-               if (!conf) {
-                       _E("malloc() failed");
-                       return -ENOMEM;
-               }
-
-               conf->name = strdup((const char *)(node->name));
-               conf->path = strdup(path);
-               conf->value = NULL;
-
-               if (!(conf->name) || !(conf->path)) {
-                       _E("strdup() failed");
-                       if (conf->name)
-                               free(conf->name);
-                       if (conf->path)
-                               free(conf->path);
-                       free(conf);
-                       continue;
-               }
-
-               DD_LIST_APPEND(conf_list, conf);
-       }
-
-       return 0;
-}
-
-static int get_configuration_nodes(xmlNodePtr root)
-{
-       int ret;
-       xmlNodePtr node;
-       char ver[BUF_MAX];
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_DRV))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VERSION, ver, sizeof(ver));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               if (strncmp(ver, driver, strlen(ver)))
-                       continue;
-
-               return add_conf_nodes_to_list(node);
-       }
-
-       return -ENOMEM;
-}
-
-int make_empty_configuration_list(void)
-{
-       int ret;
-       xmlDocPtr doc;
-       xmlNodePtr root;
-       xmlNodePtr node;
-
-       doc = xml_open(USB_CONFIGURATIONS_PATH);
-       if (!doc) {
-               _E("fail to open xml file (%s)", USB_CONFIGURATIONS_PATH);
-               return -ENOMEM;
-       }
-
-       root = xmlDocGetRootElement(doc);
-       if (!root) {
-               _E("FAIL: xmlDocGetRootElement()");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (!xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_CONFIG_NODES)) {
-                       ret = get_driver_version(node);
-                       if (ret < 0) {
-                               _E("Failed to get usb driver version");
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-
-                       ret = get_configuration_nodes(node);
-                       if (ret < 0) {
-                               _E("Failed to get conf nodes");
-                               ret = -ENOMEM;
-                               goto out;
-                       }
-
-                       show_configuration_list();
-                       break;
-               }
-       }
-
-       ret = 0;
-
-out:
-       xml_close(doc);
-       return ret;
-}
-
-static int add_configurations_to_list(xmlNodePtr root)
-{
-       int ret;
-       dd_list *l;
-       struct xmlConfiguration *conf;
-       xmlNodePtr node;
-       char buf[BUF_MAX];
-       char value[BUF_MAX];
-
-       if (!root)
-               return -EINVAL;
-
-       DD_LIST_FOREACH(conf_list, l, conf) {
-               if (conf->value) {
-                       free(conf->value);
-                       conf->value = NULL;
-               }
-
-               if (!strncmp(conf->name, NODE_NAME_IPRODUCT, strlen(NODE_NAME_IPRODUCT))) {
-                       ret = get_iproduct_name(buf, sizeof(buf));
-                       if (ret == 0)
-                               conf->value = strdup(buf);
-                       continue;
-               }
-
-               for (node = root->children ; node ; node = node->next) {
-                       if (skip_node(node))
-                               continue;
-
-                       if (xmlStrcmp((const xmlChar *)conf->name, node->name))
-                               continue;
-
-                       ret = get_xml_property(node, ATTR_VALUE, value, sizeof(value));
-                       if (ret < 0) {
-                               _E("Failed to get property(%d)", ret);
-                               return ret;
-                       }
-
-                       conf->value = strdup(value);
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static int get_configurations_by_usb_mode(xmlNodePtr root, int mode)
-{
-       xmlNodePtr node;
-       char cMode[BUF_MAX];
-       int iMode, ret;
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_MODE))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VALUE, cMode, sizeof(cMode));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               iMode = atoi(cMode);
-               if (mode != iMode)
-                       continue;
-
-               return add_configurations_to_list(node);
-       }
-       return -EINVAL;
-}
-
-static int get_configurations_by_version(xmlNodePtr root, int mode)
-{
-       xmlNodePtr node;
-       char ver[BUF_MAX];
-       int ret;
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_DRV))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VERSION, ver, sizeof(ver));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               if (strncmp(ver, driver, strlen(ver)))
-                       continue;
-
-               return get_configurations_by_usb_mode(node, mode);
-       }
-
-       return -EINVAL;
-}
-
-static int get_configurations_info(xmlNodePtr root, int mode)
-{
-       xmlNodePtr node;
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_CONFS))
-                       continue;
-
-               return get_configurations_by_version(node, mode);
-       }
-
-       return -EINVAL;
-}
-
-int make_configuration_list(int usb_mode)
-{
-       int ret;
-       xmlDocPtr doc;
-       xmlNodePtr root;
-       xmlNodePtr node;
-
-       if (!is_usb_mode_supported(usb_mode)) {
-               _E("USB mode (%d) is not supported", usb_mode);
-               return -EINVAL;
-       }
-
-       doc = xml_open(USB_CONFIGURATIONS_PATH);
-       if (!doc) {
-               _E("fail to open xml file (%s)", USB_CONFIGURATIONS_PATH);
-               return -ENOMEM;
-       }
-
-       root = xmlDocGetRootElement(doc);
-       if (!root) {
-               _E("FAIL: xmlDocGetRootElement()");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = get_configurations_info(root, usb_mode);
-       if (ret < 0) {
-               _E("Failed to get operations for usb mode(%d)", usb_mode);
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       show_configuration_list();
-       ret = 0;
-
-out:
-       xml_close(doc);
-       return ret;
-}
-
-
-void release_configuration_list(void)
-{
-       dd_list *l;
-       struct xmlConfiguration *conf;
-
-       if (!conf_list)
-               return;
-
-       DD_LIST_FOREACH(conf_list, l, conf) {
-               if (conf->name)
-                       free(conf->name);
-               if (conf->path)
-                       free(conf->path);
-               if (conf->value)
-                       free(conf->value);
-               if (conf)
-                       free(conf);
-       }
-
-       DD_LIST_FREE_LIST(conf_list);
-       conf_list = NULL;
-}
-
-/* Getting configurations supported */
-static int get_supported_confs(xmlNodePtr root)
-{
-       int ret;
-       xmlNodePtr node;
-       char cMode[BUF_MAX];
-       int iMode;
-       struct xmlSupported *sp;
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_MODE))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VALUE, cMode, sizeof(cMode));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               iMode = atoi(cMode);
-
-               sp = (struct xmlSupported *)malloc(sizeof(struct xmlSupported));
-               if (!sp) {
-                       _E("malloc() failed");
-                       return -ENOMEM;
-               }
-
-               sp->mode = iMode;
-
-               DD_LIST_APPEND(supported_list, sp);
-       }
-
-       return 0;
-}
-
-int make_supported_confs_list(void)
-{
-       int ret;
-       xmlDocPtr doc;
-       xmlNodePtr root;
-       xmlNodePtr node;
-
-       doc = xml_open(SUPPORTED_CONF_PATH);
-       if (!doc) {
-               _E("fail to open xml file (%s)", SUPPORTED_CONF_PATH);
-               return -ENOMEM;
-       }
-
-       root = xmlDocGetRootElement(doc);
-       if (!root) {
-               _E("FAIL: xmlDocGetRootElement()");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = get_supported_confs(root);
-       if (ret < 0) {
-               _E("Failed to get supported confs");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       show_supported_confs_list();
-       ret = 0;
-
-out:
-       xml_close(doc);
-       return ret;
-}
-
-void release_supported_confs_list(void)
-{
-       struct xmlSupported *sp;
-       dd_list *l;
-
-       if (!supported_list)
-               return;
-
-       DD_LIST_FOREACH(supported_list, l, sp) {
-               free(sp);
-       }
-
-       DD_LIST_FREE_LIST(supported_list);
-       supported_list = NULL;
-}
-
-/* Getting operations for each usb mode */
-static int get_operations_info(xmlNodePtr node, struct xmlOperation **oper)
-{
-       int ret;
-       char background[BUF_MAX];
-       char operation[BUF_MAX];
-
-       if (!node || !oper)
-               return -EINVAL;
-
-       ret = get_xml_property(node, ATTR_VALUE, operation, sizeof(operation));
-       if (ret < 0) {
-               _E("Failed to get property(%d)", ret);
-               return ret;
-       }
-
-       *oper = (struct xmlOperation *)malloc(sizeof(struct xmlOperation));
-       if (!(*oper)) {
-               _E("malloc() failed");
-               return -ENOMEM;
-       }
-
-       (*oper)->name = strdup((const char *)(node->name));
-       (*oper)->oper = strdup(operation);
-
-       if (!((*oper)->name) || !((*oper)->oper)) {
-               if ((*oper)->name)
-                       free((*oper)->name);
-               if ((*oper)->oper)
-                       free((*oper)->oper);
-               if (*oper) {
-                       free(*oper);
-                       *oper = NULL;
-               }
-               return -ENOMEM;
-       }
-
-       ret = get_xml_property(node, ATTR_BACKGROUND, background, sizeof(background));
-       if (ret < 0) {
-               (*oper)->background = false;
-               return 0;
-       }
-
-       if (strncmp(background, "true", strlen(background)))
-               (*oper)->background = false;
-       else
-               (*oper)->background = true;
-
-       return 0;
-}
-
-static int add_operations_to_list(xmlNodePtr root)
-{
-       int ret;
-       xmlNodePtr node;
-       struct xmlOperation *oper;
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               ret = get_operations_info(node, &oper);
-               if (ret < 0 || !oper) {
-                       _E("Failed to get operations info");
-                       return -ENOMEM;
-               }
-
-               DD_LIST_APPEND(oper_list, oper);
-       }
-
-       return 0;
-}
-
-static int get_operations_by_usb_mode(xmlNodePtr root, int usb_mode)
-{
-       int ret;
-       xmlNodePtr node;
-       char cMode[BUF_MAX];
-       int iMode;
-
-       if (!root)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_MODE))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VALUE, cMode, sizeof(cMode));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               iMode = atoi(cMode);
-
-               if (usb_mode != iMode)
-                       continue;
-
-               ret = add_operations_to_list(node);
-               if (ret < 0) {
-                       _E("Failed to add operations to list ");
-                       return -ENOMEM;
-               }
-               break;
-       }
-
-       return 0;
-}
-
-static int get_operations_by_action(xmlNodePtr root, int usb_mode, char *action)
-{
-       int ret;
-       xmlNodePtr node;
-       char act[BUF_MAX];
-
-       if (!root || !action)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_ACTION))
-                       continue;
-
-               ret = get_xml_property(node, ATTR_VALUE, act, sizeof(act));
-               if (ret < 0) {
-                       _E("Failed to get property(%d)", ret);
-                       return ret;
-               }
-
-               if (strncmp(act, action, strlen(act)))
-                       continue;
-
-               ret = get_operations_by_usb_mode(node, usb_mode);
-               if (ret < 0) {
-                       _E("Failed to get operations for usb_mode (%d)", usb_mode);
-                       return -ENOMEM;
-               }
-               break;
-       }
-
-       return 0;
-}
-
-static int get_usb_operations(xmlNodePtr root, int usb_mode, char *action)
-{
-       xmlNodePtr node;
-
-       if (!root || !action)
-               return -EINVAL;
-
-       for (node = root->children ; node ; node = node->next) {
-               if (skip_node(node))
-                       continue;
-
-               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_OPERS))
-                       continue;
-
-               return get_operations_by_action(node, usb_mode, action);
-       }
-
-       return -ENOMEM;
-}
-
-int make_operation_list(int usb_mode, char *action)
-{
-       int ret;
-       xmlDocPtr doc;
-       xmlNodePtr root;
-       xmlNodePtr node;
-       char conf_file_path[BUF_MAX];
-
-       if (!action)
-               return -EINVAL;
-
-       if (!is_usb_mode_supported(usb_mode)) {
-               _E("USB mode (%d) is not supported", usb_mode);
-               return -EINVAL;
-       }
-
-       doc = xml_open(USB_CONFIGURATIONS_PATH);
-       if (!doc) {
-               _E("fail to open xml file (%s)", USB_CONFIGURATIONS_PATH);
-               return -ENOMEM;
-       }
-
-       root = xmlDocGetRootElement(doc);
-       if (!root) {
-               _E("FAIL: xmlDocGetRootElement()");
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = get_usb_operations(root, usb_mode, action);
-       if (ret < 0) {
-               _E("Failed to get operations info(%d, %s)", usb_mode, action);
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       show_operation_list();
-       ret = 0;
-
-out:
-       xml_close(doc);
-       return ret;
-}
-
-void release_operations_list(void)
-{
-       dd_list *l;
-       struct xmlOperation *oper;
-
-       if (!oper_list)
-               return;
-
-       DD_LIST_FOREACH(oper_list, l, oper) {
-               if (oper->name)
-                       free(oper->name);
-               if (oper->oper)
-                       free(oper->oper);
-               if (oper)
-                       free(oper);
-       }
-
-       DD_LIST_FREE_LIST(oper_list);
-       oper_list = NULL;
-}
index 5df9f42..8aa6cdf 100755 (executable)
 
 #define USB_POPUP_NAME "usb-syspopup"
 
-#ifndef VCONFKEY_USB_CONFIGURATION_ENABLED
-#define VCONFKEY_USB_CONFIGURATION_ENABLED "memory/private/usb/conf_enabled"
-#endif
-
 struct popup_data {
        char *name;
        char *key;
        char *value;
 };
 
-enum usb_enabled {
-       USB_CONF_DISABLED,
-       USB_CONF_ENABLED,
-};
-
 static bool client_mode = false;
 static char *driver_version = NULL;
 static bool wait_configured = false;
@@ -47,12 +38,7 @@ void launch_syspopup(char *str)
        struct popup_data params;
        static const struct device_ops *apps = NULL;
 
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return;
-       }
-
+       FIND_DEVICE_VOID(apps, "apps");
        params.name = USB_POPUP_NAME;
        params.key = POPUP_KEY_CONTENT;
        params.value = str;
@@ -85,7 +71,13 @@ int get_default_mode(void)
 
 int update_usb_state(int state)
 {
-       return vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS, state);
+       int ret;
+
+       ret = vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS, state);
+       if (ret == 0)
+               send_msg_usb_state_changed();
+
+       return ret;
 }
 
 int update_current_usb_mode(int mode)
@@ -93,7 +85,7 @@ int update_current_usb_mode(int mode)
        /*************************************************/
        /* TODO: This legacy vconf key should be removed */
        /* The legacy vconf key is used by mtp and OSP   */
-       int legacy;
+       int legacy, ret;
 
        switch(mode) {
        case SET_USB_DEFAULT:
@@ -119,18 +111,32 @@ int update_current_usb_mode(int mode)
                _E("Failed to set legacy vconf key for current usb mode");
        /****************************************************/
 
-       return vconf_set_int(VCONFKEY_USB_CUR_MODE, mode);
+       ret = vconf_set_int(VCONFKEY_USB_CUR_MODE, mode);
+       if (ret == 0) {
+               send_msg_usb_mode_changed();
+               send_msg_usb_state_changed();
+       }
+       return ret;
 }
 
-int check_current_usb_state(void)
+int get_current_usb_logical_state(void)
 {
-       int ret;
-       int state;
+       int value;
 
-       ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &state);
-       if (ret != 0)
+       if (vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &value) != 0)
                return -ENOMEM;
 
+       return value;
+}
+
+int get_current_usb_physical_state(void)
+{
+       int state;
+
+       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &state) != 0
+                       || (state != 0 && state != 1))
+               state = get_usb_state_direct();
+
        return state;
 }
 
@@ -165,6 +171,31 @@ int change_selected_usb_mode(int mode)
        return vconf_set_int(VCONFKEY_USB_SEL_MODE, mode);
 }
 
+static void reconfigure_boot_usb_mode(void)
+{
+       int prev, now;
+
+       prev = get_selected_usb_mode();
+
+       switch (prev) {
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_TETHERING:
+               now = SET_USB_DEFAULT;
+               break;
+       case SET_USB_RNDIS_DIAG:
+               now = SET_USB_SDB_DIAG;
+               break;
+       case SET_USB_RNDIS_SDB:
+               now = SET_USB_SDB;
+               break;
+       default:
+               return;
+       }
+
+       if (change_selected_usb_mode(now) != 0)
+               _E("Failed to set selected usb mode");
+}
+
 static int notify_vconf_keys(void)
 {
        int ret;
@@ -246,21 +277,6 @@ static int unregister_client_handlers(void)
        return 0;
 }
 
-static int init_client_values(void)
-{
-       int ret;
-
-       ret = make_empty_configuration_list();
-       if (ret < 0)
-               _E("Failed to get information of usb configurations");
-
-       ret = make_supported_confs_list();
-       if (ret < 0)
-               _E("Failed to get information of usb configuration files");
-
-       return 0;
-}
-
 static void deinit_client_values(void)
 {
        int sel_mode;
@@ -275,9 +291,6 @@ static void deinit_client_values(void)
        default:
                break;
        }
-
-       release_supported_confs_list();
-       release_configuration_list();
 }
 
 static int init_client(void)
@@ -290,10 +303,6 @@ static int init_client(void)
        if (ret < 0)
                return ret;
 
-       ret = init_client_values();
-       if (ret < 0)
-               return ret;
-
        return 0;
 }
 
@@ -312,7 +321,6 @@ static int deinit_client(void)
        return 0;
 }
 
-#ifdef MICRO_DD
 void act_usb_connected(void)
 {
        wait_configured = false;
@@ -327,22 +335,6 @@ void act_usb_connected(void)
 
        pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
 }
-#else
-void act_usb_connected(void)
-{
-       wait_configured = true;
-
-       if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_ENABLED) != 0)
-               _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
-
-       if (init_client() < 0)
-               _E("FAIL: init_client()");
-
-       change_client_setting(SET_CONFIGURATION);
-
-       pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
-}
-#endif
 
 static void act_usb_disconnected(void)
 {
@@ -465,6 +457,8 @@ void usbclient_init_booting_done(void)
 {
        int ret, i;
 
+       reconfigure_boot_usb_mode();
+
        for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
                ret = register_kernel_uevent_control(&uhs[i]);
                if (ret < 0)
@@ -473,6 +467,9 @@ void usbclient_init_booting_done(void)
 
        if (register_usb_client_change_request() < 0)
                _E("Failed to register the request to change usb mode");
+
+       if (register_usbclient_dbus_methods() < 0)
+               _E("Failed to register dbus handler for usbclient");
 }
 
 static void usbclient_init(void *data)
index 674afe1..69debcf 100755 (executable)
 #define UDEV_PROP_KEY_CHGDET       "CHGDET"
 #define UDEV_PROP_VALUE_USB        "usb"
 
-#define USB_CON_SET    "set"
-#define USB_CON_UNSET  "unset"
+#define USB_CON_START  "start"
+#define USB_CON_STOP   "stop"
 
 #define USB_RESTRICT  "restrict"
 #define USB_ERROR     "error"
 
-//#define USB_DEBUG
+#define USB_BUF_LEN 64
+
+#ifndef VCONFKEY_USB_CONFIGURATION_ENABLED
+#define VCONFKEY_USB_CONFIGURATION_ENABLED "memory/private/usb/conf_enabled"
+#endif
+
+enum internal_usb_mode {
+       SET_USB_DIAG_RMNET = 11,
+};
 
 enum usbclient_setting_option {
-       SET_CONFIGURATION = 0x0001,
-       SET_OPERATION     = 0x0010,
-       SET_NOTIFICATION  = 0x0100,
+       SET_CONFIGURATION = 0x01,
+       SET_OPERATION     = 0x02,
+       SET_NOTIFICATION  = 0x04,
 };
 
-struct xmlSupported {
-       int mode;
+enum usb_enabled {
+       USB_CONF_DISABLED,
+       USB_CONF_ENABLED,
 };
 
-struct xmlOperation {
-       char *name;
-       char *oper;
-       bool background;
+struct usb_configuration {
+       char name[USB_BUF_LEN];
+       char value[USB_BUF_LEN];
 };
 
-struct xmlConfiguration {
-       char *name;
-       char *path;
-       char *value;
+struct usb_operation {
+       char name[USB_BUF_LEN];
+       char oper[USB_BUF_LEN];
 };
 
-/* XML */
-int make_empty_configuration_list(void);
+/* config */
 int make_configuration_list(int usb_mode);
 void release_configuration_list(void);
-int make_supported_confs_list(void);
-void release_supported_confs_list(void);
 int make_operation_list(int usb_mode, char *action);
 void release_operations_list(void);
 
+int get_root_path(char **path);
 int get_operations_list(dd_list **list);
 int get_configurations_list(dd_list **list);
 
@@ -98,24 +103,29 @@ void tethering_status_changed(keynode_t* key, void *data);
 
 /* Check usb state */
 int get_default_mode(void);
-int check_current_usb_state(void);
+int get_current_usb_physical_state(void);
+int get_current_usb_logical_state(void);
 int get_current_usb_mode(void);
 int get_selected_usb_mode(void);
 int get_debug_mode(void);
 int change_selected_usb_mode(int mode);
 int update_current_usb_mode(int mode);
 int update_usb_state(int state);
+unsigned int get_current_usb_gadget_info(int mode);
 
 /* Unset usb mode */
 void unset_client_mode(int mode, bool change);
 
 /* USB control */
-int control_start(void);
-int control_stop(void);
+int control_start(enum device_flags flags);
+int control_stop(enum device_flags flags);
 int control_status(void);
 void wait_until_booting_done(void);
 void usbclient_init_booting_done(void);
 void act_usb_connected(void);
+int register_usbclient_dbus_methods(void);
+void send_msg_usb_state_changed(void);
+void send_msg_usb_mode_changed(void);
 
 /* USB syspopup */
 void launch_syspopup(char *str);
@@ -124,4 +134,7 @@ void launch_syspopup(char *str);
 void change_client_setting(int options);
 bool get_wait_configured(void);
 
+/* For SDK */
+void usb_state_changed(int state);
+
 #endif /* __USB_CLIENT_H__ */
diff --git a/src/usb/usb-handler.c b/src/usb/usb-handler.c
deleted file mode 100755 (executable)
index 2c913aa..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * deviced
- *
- * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * 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 <vconf.h>
-#include <device-node.h>
-
-#include "core/log.h"
-#include "core/launch.h"
-#include "core/data.h"
-#include "core/devices.h"
-#include "core/edbus-handler.h"
-#include "display/poll.h"
-#include "core/common.h"
-
-#define USBCON_EXEC_PATH       PREFIX"/bin/usb-server"
-#define RETRY                  3
-
-#define SIGNAL_USB_CONTROL "UsbControl"
-
-static int usb_control = DEVICE_OPS_STATUS_START;
-
-static void usb_init(void *data)
-{
-       int val, i = 0, pid;
-
-       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val) == 0) {
-               if (val==1) {
-                       vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
-                                       VCONFKEY_SYSMAN_USB_AVAILABLE);
-                       while (i < RETRY
-                                       && pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0) == -1) {
-                               i++;
-                               sleep(1);
-                       }
-                       pid = launch_if_noexist(USBCON_EXEC_PATH, NULL);
-                       if (pid < 0) {
-                               _E("usb appl launching failed\n");
-                               return;
-                       }
-               }
-               else if (val==0)
-                       vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,VCONFKEY_SYSMAN_USB_DISCONNECTED);
-       }
-}
-
-static int usb_set_control(int control)
-{
-       char buf[2];
-       char *arr[1];
-
-       if (usb_control == control)
-               return 0;
-
-       usb_control = control;
-       _D("USB control: %d", usb_control);
-
-       snprintf(buf, sizeof(buf), "%d", usb_control);
-       arr[0] = buf;
-
-       broadcast_edbus_signal(DEVICED_PATH_USB_CONTROL,
-                       DEVICED_INTERFACE_USB_CONTROL,
-                       SIGNAL_USB_CONTROL, "i", arr);
-
-       return 0;
-}
-
-static int usb_start(void)
-{
-       return usb_set_control(DEVICE_OPS_STATUS_START);
-}
-
-static int usb_stop(void)
-{
-       return usb_set_control(DEVICE_OPS_STATUS_STOP);
-}
-
-static int usb_status(void)
-{
-       return usb_control;
-}
-
-static const struct device_ops usb_device_ops = {
-       .priority = DEVICE_PRIORITY_NORMAL,
-       .name     = "usb",
-       .init     = usb_init,
-       .start    = usb_start,
-       .stop     = usb_stop,
-       .status   = usb_status,
-};
-
-DEVICE_OPS_REGISTER(&usb_device_ops)
index a92cb3f..d38fe5f 100755 (executable)
@@ -119,7 +119,7 @@ int verify_vendor_name(const char *vendor, char *buf, int len)
 
        remove_non_alphabet(name);
 
-       change_to_short(name, strlen(name));
+       change_to_short(name, sizeof(name));
 
        snprintf(buf, len, "%s", name);
        return 0;
@@ -138,7 +138,7 @@ int verify_model_name(const char *model, char *vendor, char *buf, int len)
 
        remove_non_alphabet(name);
 
-       change_to_short(name, strlen(name));
+       change_to_short(name, sizeof(name));
 
        remove_vendor(name, vendor);
 
diff --git a/src/usb/usb-host-storage-exfat.c b/src/usb/usb-host-storage-exfat.c
new file mode 100644 (file)
index 0000000..80556b3
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <fcntl.h>
+#include <string.h>
+#include <sys/mount.h>
+
+#include "core/common.h"
+#include "usb-host.h"
+
+#define EXFAT_MOUNT_OPT        "uid=5000,gid=5000,dmask=0002,fmask=0002"
+#define SMACK_MOUNT_OPT "smackfsroot=*,smackfsdef=*"
+
+static const char *exfat_check_arg[] = {
+       "/sbin/fsck.exfat",
+       "-f", "-R", NULL, NULL,
+};
+
+static const char *exfat_arg[] = {
+       "/sbin/mkfs.exfat",
+       "-t", "exfat", "-s", "9", "-c", "8", "-b", "11", "-f", "1", "-l", "tizen", NULL, NULL,
+};
+
+static int exfat_check(const char *devname)
+{
+       int argc;
+       argc = ARRAY_SIZE(exfat_check_arg);
+       exfat_check_arg[argc - 2] = devname;
+       return run_child(argc, exfat_check_arg);
+}
+
+static void get_mount_options(bool smack, char *options, int len)
+{
+       if (smack)
+               snprintf(options, len, "%s,%s", EXFAT_MOUNT_OPT, SMACK_MOUNT_OPT);
+       else
+               snprintf(options, len, "%s", EXFAT_MOUNT_OPT);
+}
+
+static int exfat_mount(bool smack, const char *devpath, const char *mount_point)
+{
+       char options[NAME_MAX];
+       get_mount_options(smack, options, sizeof(options));
+       return mount(devpath, mount_point, "exfat", 0, options);
+}
+
+static int exfat_mount_rdonly(bool smack, const char *devpath, const char *mount_point)
+{
+       char options[NAME_MAX];
+       get_mount_options(smack, options, sizeof(options));
+       return mount(devpath, mount_point, "exfat", MS_RDONLY, options);
+}
+
+static int exfat_format(const char *path)
+{
+       int argc;
+       argc = ARRAY_SIZE(exfat_arg);
+       exfat_arg[argc - 2] = path;
+       return run_child(argc, exfat_arg);
+}
+
+static const struct storage_fs_ops exfat_ops = {
+       .name         = "exfat",
+       .check        = exfat_check,
+       .mount        = exfat_mount,
+       .mount_rdonly = exfat_mount_rdonly,
+       .format       = exfat_format,
+};
+
+static void __CONSTRUCTOR__ exfat_init(void)
+{
+       register_fs(&exfat_ops);
+}
index cc2bf78..a1cc108 100644 (file)
@@ -34,8 +34,8 @@ static const char *vfat_check_arg[] = {
 };
 
 static const char *vfat_arg[] = {
-       "/sbin/mkfs.vfat",
-       NULL, NULL,
+       "/usr/bin/newfs_msdos",
+       "-F", "32", "-O", "tizen", "-c", "8", NULL, NULL,
 };
 
 static int vfat_check(const char *devname)
index 80c9cf6..78e19c2 100755 (executable)
@@ -65,7 +65,7 @@ dd_list *get_device_list(void)
 void launch_ticker_notification(char *name)
 {
        struct ticker_data ticker;
-       const struct device_ops *ticker_ops;
+       const struct device_ops *ticker_ops = NULL;
 
        if (!name) {
                _E("ticker noti name is NULL");
@@ -75,8 +75,7 @@ void launch_ticker_notification(char *name)
        ticker.name = name;
        ticker.type = 0; /* WITHOUT_QUEUE */
 
-       ticker_ops = find_device("ticker");
-
+       FIND_DEVICE_VOID(ticker_ops, "ticker");
        if (ticker_ops && ticker_ops->init)
                ticker_ops->init(&ticker);
        else
@@ -93,12 +92,7 @@ void launch_host_syspopup(char *name, char *method,
        if (!name || !method)
                return;
 
-       if (apps == NULL) {
-               apps = find_device("apps");
-               if (apps == NULL)
-                       return;
-       }
-
+       FIND_DEVICE_VOID(apps, "apps");
        params.name = name;
        params.method = method;
        params.key1 = key1;
diff --git a/test/_export_env.sh b/test/_export_env.sh
deleted file mode 100755 (executable)
index 72a11ec..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-. ./config
-export TET_INSTALL_PATH=$TET_INSTALL_HOST_PATH # tetware root path
-export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target # tetware target path
-export PATH=$TET_TARGET_PATH/bin:$PATH
-export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH
-export TET_ROOT=$TET_TARGET_PATH
diff --git a/test/_export_target_env.sh b/test/_export_target_env.sh
deleted file mode 100755 (executable)
index 5ddaa53..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-. ./config
-export TET_INSTALL_PATH=$TET_INSTALL_TARGET_PATH # path to path
-export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target
-export PATH=$TET_TARGET_PATH/bin:$PATH
-export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH
-export TET_ROOT=$TET_TARGET_PATH
diff --git a/test/build.sh b/test/build.sh
deleted file mode 100755 (executable)
index d58c039..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-. ./_export_env.sh                              # setting environment variables
-
-export TET_SUITE_ROOT=`pwd`
-FILE_NAME_EXTENSION=`date +%s`
-
-RESULT_DIR=results
-HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html
-JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal
-
-mkdir -p $RESULT_DIR
-
-tcc -c -p ./
-tcc -b -j $JOURNAL_RESULT -p ./
-grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
diff --git a/test/clean.sh b/test/clean.sh
deleted file mode 100755 (executable)
index 29743e0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-. ./_export_env.sh                              # setting environment variables
-
-export TET_SUITE_ROOT=`pwd`
-RESULT_DIR=results
-
-tcc -c -p ./                                # executing tcc, with clean option (-c)
-rm -r $RESULT_DIR
-rm -r tet_tmp_dir
-rm testcase/tet_captured
diff --git a/test/config b/test/config
deleted file mode 100644 (file)
index 457c529..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-PKG_NAME=deviced
-TET_INSTALL_HOST_PATH=/var/tmp/dts_fw/TETware
-TET_INSTALL_TARGET_PATH=/opt/home/TETware
diff --git a/test/execute.sh b/test/execute.sh
deleted file mode 100755 (executable)
index a4f6095..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-
-. ./_export_target_env.sh                    # setting environment variables
-
-export TET_SUITE_ROOT=`pwd`
-FILE_NAME_EXTENSION=`date +%s`
-
-RESULT_DIR=results
-HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html
-JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal
-
-mkdir -p $RESULT_DIR
-
-tcc -e -j $JOURNAL_RESULT -p ./
-grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
diff --git a/test/push.sh b/test/push.sh
deleted file mode 100755 (executable)
index 2bbab27..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-. ./config
-
-TC_PATH=/opt/home/$PKG_NAME
-
-echo $TC_PATH
-
-sdb root on
-sdb shell "mkdir -p $TC_PATH"
-sdb push . $TC_PATH
diff --git a/test/testcase/Makefile b/test/testcase/Makefile
deleted file mode 100644 (file)
index db70570..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-CC = gcc
-
-C_FILES = $(shell ls *.c)
-
-PKGS = deviced
-
-#TET_ROOT = /home/idkiller/work/tetware/TETware/tetware-target
-
-LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o
-LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s
-LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s
-LDFLAGS += `pkg-config --libs $(PKGS)`
-
-CFLAGS += `pkg-config --cflags $(PKGS)`
-CFLAGS += -I.
-CFLAGS += -I$(TET_ROOT)/inc/tet3
-CFLAGS += -Wall
-
-#TARGETS = $(C_FILES:%.c=tc-%)
-TCS := $(shell ls -1 *.c | cut -d. -f1)
-
-all: $(TCS)
-
-%: %.c
-       $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
-
-clean:
-       rm -f $(TCS)
diff --git a/test/testcase/tslist b/test/testcase/tslist
deleted file mode 100644 (file)
index cc10762..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/testcase/utc_system_deviced_battery
-/testcase/utc_system_deviced_control
-/testcase/utc_system_deviced_deviced
-/testcase/utc_system_deviced_deviced_managed
-/testcase/utc_system_deviced_display
-/testcase/utc_system_deviced_haptic
-/testcase/utc_system_deviced_led
-/testcase/utc_system_deviced_mmc
-/testcase/utc_system_deviced_storage
-
diff --git a/test/testcase/utc_system_deviced_battery.c b/test/testcase/utc_system_deviced_battery.c
deleted file mode 100644 (file)
index 83eea6a..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <dd-battery.h>
-
-#define API_NAME_BATTERY_GET_PERCENT "battery_get_percent"
-#define API_NAME_BATTERY_GET_PERCENT_RAW "battery_get_percent_raw"
-#define API_NAME_BATTERY_IS_FULL "battery_is_full"
-#define API_NAME_BATTERY_GET_HEALTH "battery_get_health"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_battery_get_percent_p(void);
-static void utc_system_deviced_battery_get_percent_raw_p(void);
-static void utc_system_deviced_battery_is_full_p(void);
-static void utc_system_deviced_battery_get_health_p(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_battery_get_percent_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_battery_get_percent_raw_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_battery_is_full_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_battery_get_health_p, POSITIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of battery_get_percent()
- */
-static void utc_system_deviced_battery_get_percent_p(void)
-{
-       int ret;
-
-       ret = battery_get_percent();
-       dts_check_ge(API_NAME_BATTERY_GET_PERCENT, ret, 0);
-}
-
-/**
- * @brief Positive test case of battery_get_percent_raw()
- */
-static void utc_system_deviced_battery_get_percent_raw_p(void)
-{
-       int ret;
-
-       ret = battery_get_percent_raw();
-       dts_check_ge(API_NAME_BATTERY_GET_PERCENT_RAW, ret, 0);
-}
-
-/**
- * @brief Positive test case of battery_is_full()
- */
-static void utc_system_deviced_battery_is_full_p(void)
-{
-       int ret;
-
-       ret = battery_is_full();
-       dts_check_ge(API_NAME_BATTERY_IS_FULL, ret, 0);
-}
-
-/**
- * @brief Positive test case of battery_get_health()
- */
-static void utc_system_deviced_battery_get_health_p(void)
-{
-       int ret;
-
-       ret = battery_get_health();
-       dts_check_ge(API_NAME_BATTERY_GET_HEALTH, ret, 0);
-}
diff --git a/test/testcase/utc_system_deviced_control.c b/test/testcase/utc_system_deviced_control.c
deleted file mode 100644 (file)
index ab12ade..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <dd-control.h>
-
-#define API_NAME_DEVICED_MMC_CONTROL "deviced_mmc_control"
-#define API_NAME_DEVICED_USB_CONTROL "deviced_usb_control"
-#define API_NAME_DEVICED_GET_USB_CONTROL "deviced_get_usb_control"
-#define API_NAME_DEVICED_RGBLED_CONTROL "deviced_rgbled_control"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_deviced_mmc_control_p_1(void);
-static void utc_system_deviced_deviced_mmc_control_p_2(void);
-static void utc_system_deviced_deviced_usb_control_p_1(void);
-static void utc_system_deviced_deviced_usb_control_p_2(void);
-static void utc_system_deviced_deviced_get_usb_control_p(void);
-static void utc_system_deviced_deviced_rgbled_control_p_1(void);
-static void utc_system_deviced_deviced_rgbled_control_p_2(void);
-static void utc_system_deviced_deviced_rgbled_control_n(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_deviced_mmc_control_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_mmc_control_p_2, POSITIVE_TC_IDX },
-//     { utc_system_deviced_deviced_usb_control_p_1, POSITIVE_TC_IDX },
-//     { utc_system_deviced_deviced_usb_control_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_usb_control_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_rgbled_control_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_rgbled_control_p_2, POSITIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of deviced_mmc_control()
- */
-static void utc_system_deviced_deviced_mmc_control_p_1(void)
-{
-       int ret;
-
-       ret = deviced_mmc_control(false);
-       dts_check_eq(API_NAME_DEVICED_MMC_CONTROL, ret, 0, "Disable MMC");
-}
-
-/**
- * @brief Positive test case of deviced_mmc_control()
- */
-static void utc_system_deviced_deviced_mmc_control_p_2(void)
-{
-       int ret;
-
-       ret = deviced_mmc_control(true);
-       dts_check_eq(API_NAME_DEVICED_MMC_CONTROL, ret, 0, "Enable MMC");
-}
-
-/**
- * @brief Positive test case of deviced_usb_control()
- */
-static void utc_system_deviced_deviced_usb_control_p_1(void)
-{
-       int ret;
-
-       ret = deviced_usb_control(false);
-       dts_check_eq(API_NAME_DEVICED_USB_CONTROL, ret, 0, "Disable USB");
-}
-
-/**
- * @brief Positive test case of deviced_usb_control()
- */
-static void utc_system_deviced_deviced_usb_control_p_2(void)
-{
-       int ret;
-
-       ret = deviced_usb_control(true);
-       dts_check_eq(API_NAME_DEVICED_USB_CONTROL, ret, 0, "Enable USB");
-}
-
-/**
- * @brief Positive test case of deviced_get_usb_control()
- */
-static void utc_system_deviced_deviced_get_usb_control_p(void)
-{
-       int ret;
-
-       ret = deviced_get_usb_control();
-       dts_check_ge(API_NAME_DEVICED_GET_USB_CONTROL, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_rgbled_control()
- */
-static void utc_system_deviced_deviced_rgbled_control_p_1(void)
-{
-       int ret;
-
-       ret = deviced_rgbled_control(false);
-       dts_check_eq(API_NAME_DEVICED_RGBLED_CONTROL, ret, 0, "Disable RGB led");
-}
-
-/**
- * @brief Positive test case of deviced_rgbled_control()
- */
-static void utc_system_deviced_deviced_rgbled_control_p_2(void)
-{
-       int ret;
-
-       ret = deviced_rgbled_control(true);
-       dts_check_eq(API_NAME_DEVICED_USB_CONTROL, ret, 0, "Enable RGB led");
-}
diff --git a/test/testcase/utc_system_deviced_deviced.c b/test/testcase/utc_system_deviced_deviced.c
deleted file mode 100644 (file)
index 6782bbf..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <dd-deviced.h>
-
-#define API_NAME_DEVICED_GET_CMDLINE_NAME "deviced_get_cmdline_name"
-#define API_NAME_DEVICED_GET_APPPATH "deviced_get_apppath"
-#define API_NAME_DEVICED_CONF_SET_MEMPOLICY "deviced_conf_set_mempolicy"
-#define API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID "deviced_conf_set_mempolicy_bypid"
-#define API_NAME_DEVICED_CONF_SET_PERMANENT "deviced_conf_set_permanent"
-#define API_NAME_DEVICED_CONF_SET_PERMANENT_BYPID "deviced_conf_set_permanent_bypid"
-#define API_NAME_DEVICED_CONF_SET_VIP "deviced_conf_set_vip"
-#define API_NAME_DEVICED_CONF_IS_VIP "deviced_conf_is_vip"
-#define API_NAME_DEVICED_SET_TIMEZONE "deviced_set_timezone"
-#define API_NAME_DEVICED_INFORM_FOREGRD "deviced_inform_foregrd"
-#define API_NAME_DEVICED_INFORM_BACKGRD "deviced_inform_backgrd"
-#define API_NAME_DEVICED_INFORM_ACTIVE "deviced_inform_active"
-#define API_NAME_DEVICED_INFORM_INACTIVE "deviced_inform_active"
-#define API_NAME_DEVICED_REQUEST_POWEROFF "deviced_request_poweroff"
-#define API_NAME_DEVICED_REQUEST_ENTERSLEEP "deviced_request_entersleep"
-#define API_NAME_DEVICED_REQUEST_LEAVESLEEP "deviced_request_leavesleep"
-#define API_NAME_DEVICED_REQUEST_REBOOT "deviced_request_reboot"
-#define API_NAME_DEVICED_REQUEST_SET_CPU_MAX_FREQUENCY "deviced_request_set_cpu_max_frequency"
-#define API_NAME_DEVICED_REQUEST_SET_CPU_MIN_FREQUENCY "deviced_request_set_cpu_min_frequency"
-#define API_NAME_DEVICED_RELEASE_CPU_MAX_FREQUENCY "deviced_release_cpu_max_frequency"
-#define API_NAME_DEVICED_RELEASE_CPU_MIN_FREQUENCY "deviced_release_cpu_min_frequency"
-#define API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE "deviced_request_set_factory_mode"
-#define API_NAME_DEVICED_REQUEST_DUMP_LOG "deviced_request_dump_log"
-#define API_NAME_DEVICED_REQUEST_DELETE_DUMP "deviced_request_delete_dump"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_deviced_get_cmdline_name_p(void);
-static void utc_system_deviced_deviced_get_cmdline_name_n_1(void);
-static void utc_system_deviced_deviced_get_cmdline_name_n_2(void);
-static void utc_system_deviced_deviced_get_cmdline_name_n_3(void);
-static void utc_system_deviced_deviced_get_apppath_p(void);
-static void utc_system_deviced_deviced_get_apppath_n_1(void);
-static void utc_system_deviced_deviced_get_apppath_n_2(void);
-static void utc_system_deviced_deviced_get_apppath_n_3(void);
-static void utc_system_deviced_deviced_conf_set_mempolicy_p(void);
-static void utc_system_deviced_deviced_conf_set_mempolicy_n(void);
-static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_p(void);
-static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_1(void);
-static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_2(void);
-static void utc_system_deviced_deviced_conf_set_permanent_p(void);
-static void utc_system_deviced_deviced_conf_set_permanent_bypid_p(void);
-static void utc_system_deviced_deviced_conf_set_permanent_bypid_n(void);
-static void utc_system_deviced_deviced_conf_set_vip_p(void);
-static void utc_system_deviced_deviced_conf_set_vip_n(void);
-static void utc_system_deviced_deviced_conf_is_vip_p(void);
-static void utc_system_deviced_deviced_conf_is_vip_n(void);
-static void utc_system_deviced_deviced_set_timezone_p(void);
-static void utc_system_deviced_deviced_set_timezone_n(void);
-static void utc_system_deviced_deviced_inform_foregrd_p(void);
-static void utc_system_deviced_deviced_inform_backgrd_p(void);
-static void utc_system_deviced_deviced_inform_active_p(void);
-static void utc_system_deviced_deviced_inform_active_n(void);
-static void utc_system_deviced_deviced_inform_inactive_p(void);
-static void utc_system_deviced_deviced_inform_inactive_n(void);
-static void utc_system_deviced_deviced_request_poweroff_p(void);
-static void utc_system_deviced_deviced_request_entersleep_p(void);
-static void utc_system_deviced_deviced_request_leavesleep_p(void);
-static void utc_system_deviced_deviced_request_reboot_p(void);
-static void utc_system_deviced_deviced_request_set_cpu_max_frequency_p(void);
-static void utc_system_deviced_deviced_request_set_cpu_max_frequency_n(void);
-static void utc_system_deviced_deviced_request_set_cpu_min_frequency_p(void);
-static void utc_system_deviced_deviced_request_set_cpu_min_frequency_n(void);
-static void utc_system_deviced_deviced_release_cpu_max_frequency_p(void);
-static void utc_system_deviced_deviced_release_cpu_min_frequency_p(void);
-static void utc_system_deviced_deviced_request_set_factory_mode_p_1(void);
-static void utc_system_deviced_deviced_request_set_factory_mode_p_2(void);
-static void utc_system_deviced_deviced_request_set_factory_mode_n(void);
-static void utc_system_deviced_deviced_request_dump_log_p_1(void);
-static void utc_system_deviced_deviced_request_dump_log_p_2(void);
-static void utc_system_deviced_deviced_request_dump_log_n(void);
-static void utc_system_deviced_deviced_request_delete_dump_p(void);
-static void utc_system_deviced_deviced_request_delete_dump_n(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_deviced_get_cmdline_name_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_cmdline_name_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_cmdline_name_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_cmdline_name_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_apppath_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_apppath_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_apppath_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_get_apppath_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_mempolicy_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_mempolicy_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_mempolicy_bypid_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_permanent_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_permanent_bypid_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_permanent_bypid_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_vip_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_set_vip_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_is_vip_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_conf_is_vip_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_set_timezone_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_set_timezone_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_inform_foregrd_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_inform_backgrd_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_inform_active_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_inform_active_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_inform_inactive_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_inform_inactive_n, NEGATIVE_TC_IDX },
-//     { utc_system_deviced_deviced_request_poweroff_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_entersleep_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_leavesleep_p, POSITIVE_TC_IDX },
-//     { utc_system_deviced_deviced_request_reboot_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_set_cpu_max_frequency_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_set_cpu_max_frequency_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_set_cpu_min_frequency_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_set_cpu_min_frequency_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_release_cpu_max_frequency_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_release_cpu_min_frequency_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_set_factory_mode_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_set_factory_mode_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_set_factory_mode_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_dump_log_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_dump_log_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_dump_log_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_delete_dump_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_delete_dump_n, NEGATIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of deviced_get_cmdline_name()
- */
-static void utc_system_deviced_deviced_get_cmdline_name_p(void)
-{
-       pid_t pid;
-       char str[1024];
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_get_cmdline_name(pid, str, sizeof(str));
-       dts_check_eq(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_get_cmdline_name()
- */
-static void utc_system_deviced_deviced_get_cmdline_name_n_1(void)
-{
-       char str[1024];
-       int ret;
-
-       ret = deviced_get_cmdline_name(-1, str, sizeof(str));
-       dts_check_ne(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_get_cmdline_name()
- */
-static void utc_system_deviced_deviced_get_cmdline_name_n_2(void)
-{
-       pid_t pid;
-       char str[1024];
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_get_cmdline_name(pid, NULL, sizeof(str));
-       dts_check_ne(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_get_cmdline_name()
- */
-static void utc_system_deviced_deviced_get_cmdline_name_n_3(void)
-{
-       pid_t pid;
-       char str[1024];
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_get_cmdline_name(pid, str, -1);
-       dts_check_ne(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_get_apppath()
- */
-static void utc_system_deviced_deviced_get_apppath_p(void)
-{
-       pid_t pid;
-       char str[1024];
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_get_apppath(pid, str, sizeof(str));
-       dts_check_eq(API_NAME_DEVICED_GET_APPPATH, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_get_apppath()
- */
-static void utc_system_deviced_deviced_get_apppath_n_1(void)
-{
-       char str[1024];
-       int ret;
-
-       ret = deviced_get_apppath(-1, str, sizeof(str));
-       dts_check_ne(API_NAME_DEVICED_GET_APPPATH, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_get_apppath()
- */
-static void utc_system_deviced_deviced_get_apppath_n_2(void)
-{
-       pid_t pid;
-       char str[1024];
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_get_apppath(pid, NULL, sizeof(str));
-       dts_check_ne(API_NAME_DEVICED_GET_APPPATH, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_get_apppath()
- */
-static void utc_system_deviced_deviced_get_apppath_n_3(void)
-{
-       pid_t pid;
-       char str[1024];
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_get_apppath(pid, str, -1);
-       dts_check_ne(API_NAME_DEVICED_GET_APPPATH, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_conf_set_mempolicy()
- */
-static void utc_system_deviced_deviced_conf_set_mempolicy_p(void)
-{
-       int ret;
-
-       ret = deviced_conf_set_mempolicy(OOM_LIKELY);
-       dts_check_eq(API_NAME_DEVICED_CONF_SET_MEMPOLICY, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_conf_set_mempolicy()
- */
-static void utc_system_deviced_deviced_conf_set_mempolicy_n(void)
-{
-       int ret;
-
-       ret = deviced_conf_set_mempolicy(-1);
-       dts_check_ne(API_NAME_DEVICED_CONF_SET_MEMPOLICY, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_conf_set_mempolicy_bypid()
- */
-static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_p(void)
-{
-       pid_t pid;
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_conf_set_mempolicy_bypid(pid, OOM_LIKELY);
-       dts_check_eq(API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_conf_set_mempolicy_bypid()
- */
-static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_1(void)
-{
-       int ret;
-
-       ret = deviced_conf_set_mempolicy_bypid(-1, OOM_LIKELY);
-       dts_check_ne(API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_conf_set_mempolicy_bypid()
- */
-static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_2(void)
-{
-       pid_t pid;
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_conf_set_mempolicy_bypid(pid, -1);
-       dts_check_ne(API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_conf_set_permanent()
- */
-static void utc_system_deviced_deviced_conf_set_permanent_p(void)
-{
-       int ret;
-
-       ret = deviced_conf_set_permanent();
-       dts_check_eq(API_NAME_DEVICED_CONF_SET_PERMANENT, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_conf_set_permanent_bypid()
- */
-static void utc_system_deviced_deviced_conf_set_permanent_bypid_p(void)
-{
-       pid_t pid;
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_conf_set_permanent_bypid(pid);
-       dts_check_eq(API_NAME_DEVICED_CONF_SET_PERMANENT_BYPID, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_conf_set_permanent_bypid()
- */
-static void utc_system_deviced_deviced_conf_set_permanent_bypid_n(void)
-{
-       int ret;
-
-       ret = deviced_conf_set_permanent_bypid(-1);
-       dts_check_ne(API_NAME_DEVICED_CONF_SET_PERMANENT_BYPID, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_conf_set_vip()
- */
-static void utc_system_deviced_deviced_conf_set_vip_p(void)
-{
-       pid_t pid;
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_conf_set_vip(pid);
-       dts_check_eq(API_NAME_DEVICED_CONF_SET_VIP, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_conf_set_vip()
- */
-static void utc_system_deviced_deviced_conf_set_vip_n(void)
-{
-       int ret;
-
-       ret = deviced_conf_set_vip(-1);
-       dts_check_ne(API_NAME_DEVICED_CONF_SET_VIP, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_conf_is_vip()
- */
-static void utc_system_deviced_deviced_conf_is_vip_p(void)
-{
-       pid_t pid;
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_conf_is_vip(pid);
-       dts_check_ge(API_NAME_DEVICED_CONF_IS_VIP, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_conf_is_vip()
- */
-static void utc_system_deviced_deviced_conf_is_vip_n(void)
-{
-       int ret;
-
-       ret = deviced_conf_is_vip(-1);
-       dts_check_lt(API_NAME_DEVICED_CONF_IS_VIP, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_set_timezone()
- */
-static void utc_system_deviced_deviced_set_timezone_p(void)
-{
-       int ret;
-
-       ret = deviced_set_timezone("/usr/share/zoneinfo/Asia/Seoul");
-       dts_check_eq(API_NAME_DEVICED_SET_TIMEZONE, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_set_timezone()
- */
-static void utc_system_deviced_deviced_set_timezone_n(void)
-{
-       int ret;
-
-       ret = deviced_set_timezone(NULL);
-       dts_check_ne(API_NAME_DEVICED_SET_TIMEZONE, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_inform_foregrd()
- */
-static void utc_system_deviced_deviced_inform_foregrd_p(void)
-{
-       int ret;
-
-       ret = deviced_inform_foregrd();
-       dts_check_eq(API_NAME_DEVICED_INFORM_FOREGRD, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_inform_backgrd()
- */
-static void utc_system_deviced_deviced_inform_backgrd_p(void)
-{
-       int ret;
-
-       ret = deviced_inform_backgrd();
-       dts_check_eq(API_NAME_DEVICED_INFORM_BACKGRD, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_inform_active()
- */
-static void utc_system_deviced_deviced_inform_active_p(void)
-{
-       pid_t pid;
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_inform_active(pid);
-       dts_check_eq(API_NAME_DEVICED_INFORM_ACTIVE, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_inform_active()
- */
-static void utc_system_deviced_deviced_inform_active_n(void)
-{
-       int ret;
-
-       ret = deviced_inform_active(-1);
-       dts_check_ne(API_NAME_DEVICED_INFORM_ACTIVE, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_inform_inactive()
- */
-static void utc_system_deviced_deviced_inform_inactive_p(void)
-{
-       pid_t pid;
-       int ret;
-
-       pid = getpid();
-
-       ret = deviced_inform_inactive(pid);
-       dts_check_eq(API_NAME_DEVICED_INFORM_INACTIVE, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_inform_inactive()
- */
-static void utc_system_deviced_deviced_inform_inactive_n(void)
-{
-       int ret;
-
-       ret = deviced_inform_inactive(-1);
-       dts_check_ne(API_NAME_DEVICED_INFORM_INACTIVE, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_poweroff()
- */
-static void utc_system_deviced_deviced_request_poweroff_p(void)
-{
-       int ret;
-
-       ret = deviced_request_poweroff();
-       dts_check_eq(API_NAME_DEVICED_REQUEST_POWEROFF, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_entersleep()
- */
-static void utc_system_deviced_deviced_request_entersleep_p(void)
-{
-       int ret;
-
-       ret = deviced_request_entersleep();
-       dts_check_eq(API_NAME_DEVICED_REQUEST_ENTERSLEEP, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_leavesleep()
- */
-static void utc_system_deviced_deviced_request_leavesleep_p(void)
-{
-       int ret;
-
-       ret = deviced_request_leavesleep();
-       dts_check_eq(API_NAME_DEVICED_REQUEST_LEAVESLEEP, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_reboot()
- */
-static void utc_system_deviced_deviced_request_reboot_p(void)
-{
-       int ret;
-
-       ret = deviced_request_reboot();
-       dts_check_eq(API_NAME_DEVICED_REQUEST_REBOOT, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_set_cpu_max_frequency()
- */
-static void utc_system_deviced_deviced_request_set_cpu_max_frequency_p(void)
-{
-       int ret;
-
-       ret = deviced_request_set_cpu_max_frequency(60);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_CPU_MAX_FREQUENCY, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_request_set_cpu_max_frequency()
- */
-static void utc_system_deviced_deviced_request_set_cpu_max_frequency_n(void)
-{
-       int ret;
-
-       ret = deviced_request_set_cpu_max_frequency(-1);
-       dts_check_ne(API_NAME_DEVICED_REQUEST_SET_CPU_MAX_FREQUENCY, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_set_cpu_min_frequency()
- */
-static void utc_system_deviced_deviced_request_set_cpu_min_frequency_p(void)
-{
-       int ret;
-
-       ret = deviced_request_set_cpu_min_frequency(60);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_CPU_MIN_FREQUENCY, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_request_set_cpu_min_frequency()
- */
-static void utc_system_deviced_deviced_request_set_cpu_min_frequency_n(void)
-{
-       int ret;
-
-       ret = deviced_request_set_cpu_min_frequency(-1);
-       dts_check_ne(API_NAME_DEVICED_REQUEST_SET_CPU_MIN_FREQUENCY, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_release_cpu_max_frequency()
- */
-static void utc_system_deviced_deviced_release_cpu_max_frequency_p(void)
-{
-       int ret;
-
-       ret = deviced_release_cpu_max_frequency();
-       dts_check_eq(API_NAME_DEVICED_RELEASE_CPU_MAX_FREQUENCY, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_release_cpu_min_frequency()
- */
-static void utc_system_deviced_deviced_release_cpu_min_frequency_p(void)
-{
-       int ret;
-
-       ret = deviced_release_cpu_min_frequency();
-       dts_check_eq(API_NAME_DEVICED_RELEASE_CPU_MIN_FREQUENCY, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_set_factory_mode()
- */
-static void utc_system_deviced_deviced_request_set_factory_mode_p_1(void)
-{
-       int ret;
-
-       ret = deviced_request_set_factory_mode(1);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE, ret, 1, "Enable factory mode");
-}
-
-/**
- * @brief Positive test case of deviced_request_set_factory_mode()
- */
-static void utc_system_deviced_deviced_request_set_factory_mode_p_2(void)
-{
-       int ret;
-
-       ret = deviced_request_set_factory_mode(0);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE, ret, 0, "Disable factory mode");
-}
-
-/**
- * @brief Negative test case of deviced_request_set_factory_mode()
- */
-static void utc_system_deviced_deviced_request_set_factory_mode_n(void)
-{
-       int ret;
-
-       ret = deviced_request_set_factory_mode(-1);
-       dts_check_ne(API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_dump_log()
- */
-static void utc_system_deviced_deviced_request_dump_log_p_1(void)
-{
-       int ret;
-
-       ret = deviced_request_dump_log(AP_DUMP);
-       dts_check_ge(API_NAME_DEVICED_REQUEST_DUMP_LOG, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_dump_log()
- */
-static void utc_system_deviced_deviced_request_dump_log_p_2(void)
-{
-       int ret;
-
-       ret = deviced_request_dump_log(CP_DUMP);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_DUMP_LOG, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_dump_log()
- */
-static void utc_system_deviced_deviced_request_dump_log_n(void)
-{
-       int ret;
-
-       ret = deviced_request_dump_log(-1);
-       dts_check_ne(API_NAME_DEVICED_REQUEST_DUMP_LOG, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_request_delete_dump()
- */
-static void utc_system_deviced_deviced_request_delete_dump_p(void)
-{
-       int ret;
-
-       ret = deviced_request_delete_dump("");
-       dts_check_eq(API_NAME_DEVICED_REQUEST_DELETE_DUMP, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_request_delete_dump()
- */
-static void utc_system_deviced_deviced_request_delete_dump_n(void)
-{
-       int ret;
-
-       ret = deviced_request_delete_dump(NULL);
-       dts_check_ne(API_NAME_DEVICED_REQUEST_DELETE_DUMP, ret, 0);
-}
diff --git a/test/testcase/utc_system_deviced_deviced_managed.c b/test/testcase/utc_system_deviced_deviced_managed.c
deleted file mode 100644 (file)
index 78ac62f..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <stdbool.h>
-#include <dd-deviced-managed.h>
-
-#define API_NAME_DEVICED_GET_PID "deviced_get_pid"
-#define API_NAME_DEVICED_SET_DATETIME "deviced_set_datetime"
-#define API_NAME_DEVICED_REQUEST_MOUNT_MMC "deviced_request_mount_mmc"
-#define API_NAME_DEVICED_REQUEST_UNMOUNT_MMC "deviced_request_unmount_mmc"
-#define API_NAME_DEVICED_REQUEST_FORMAT_MMC "deviced_request_format_mmc"
-#define API_NAME_DEVICED_FORMAT_MMC "deviced_format_mmc"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_deviced_get_pid_p(void);
-static void utc_system_deviced_deviced_get_pid_n(void);
-static void utc_system_deviced_deviced_set_datetime_n(void);
-static void utc_system_deviced_deviced_set_datetime_p(void);
-static void utc_system_deviced_deviced_request_mount_mmc_p_1(void);
-static void utc_system_deviced_deviced_request_mount_mmc_p_2(void);
-static void utc_system_deviced_deviced_request_mount_mmc_p_3(void);
-static void utc_system_deviced_deviced_request_unmount_mmc_p_1(void);
-static void utc_system_deviced_deviced_request_unmount_mmc_p_2(void);
-static void utc_system_deviced_deviced_request_unmount_mmc_p_3(void);
-static void utc_system_deviced_deviced_request_unmount_mmc_p_4(void);
-static void utc_system_deviced_deviced_request_unmount_mmc_n(void);
-static void utc_system_deviced_deviced_request_format_mmc_p_1(void);
-static void utc_system_deviced_deviced_request_format_mmc_p_2(void);
-static void utc_system_deviced_deviced_request_format_mmc_p_3(void);
-static void utc_system_deviced_deviced_format_mmc_p_1(void);
-static void utc_system_deviced_deviced_format_mmc_p_2(void);
-static void utc_system_deviced_deviced_format_mmc_p_3(void);
-static void utc_system_deviced_deviced_format_mmc_p_4(void);
-static void utc_system_deviced_deviced_format_mmc_n(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       /* The following TCs are for root application */
-//     { utc_system_deviced_deviced_get_pid_p, POSITIVE_TC_IDX },
-//     { utc_system_deviced_deviced_get_pid_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_set_datetime_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_set_datetime_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_mount_mmc_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_mount_mmc_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_mount_mmc_p_3, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_unmount_mmc_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_unmount_mmc_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_unmount_mmc_p_3, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_unmount_mmc_p_4, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_unmount_mmc_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_format_mmc_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_format_mmc_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_request_format_mmc_p_3, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_format_mmc_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_format_mmc_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_format_mmc_p_3, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_format_mmc_p_4, POSITIVE_TC_IDX },
-       { utc_system_deviced_deviced_format_mmc_n, NEGATIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of deviced_get_pid()
- */
-static void utc_system_deviced_deviced_get_pid_p(void)
-{
-       int ret;
-
-       ret = deviced_get_pid("/usb/bin/deviced");
-       dts_check_ge(API_NAME_DEVICED_GET_PID, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_get_pid()
- */
-static void utc_system_deviced_deviced_get_pid_n(void)
-{
-       int ret;
-
-       ret = deviced_get_pid(NULL);
-       dts_check_lt(API_NAME_DEVICED_GET_PID, ret, 0);
-}
-
-/**
- * @brief Negative test case of deviced_set_datetime()
- */
-static void utc_system_deviced_deviced_set_datetime_n(void)
-{
-       int ret;
-
-       ret = deviced_set_datetime(-1);
-       dts_check_lt(API_NAME_DEVICED_SET_DATETIME, ret, 0);
-}
-
-/**
- * @brief Positive test case of deviced_set_datetime()
- */
-static void utc_system_deviced_deviced_set_datetime_p(void)
-{
-       int ret;
-       time_t now;
-
-       localtime(&now);
-
-       ret = deviced_set_datetime(now);
-       dts_check_ge(API_NAME_DEVICED_SET_DATETIME, ret, 0);
-}
-
-static void mount_cb(int result, void *data)
-{
-       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
-                       "mount callback result : %d", result);
-}
-
-/**
- * @brief Positive test case of deviced_request_mount_mmc()
- */
-static void utc_system_deviced_deviced_request_mount_mmc_p_1(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = mount_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_mount_mmc(&data);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_MOUNT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_request_mount_mmc()
- */
-static void utc_system_deviced_deviced_request_mount_mmc_p_2(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_mount_mmc(&data);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_MOUNT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_request_mount_mmc()
- */
-static void utc_system_deviced_deviced_request_mount_mmc_p_3(void)
-{
-       int ret;
-
-       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_mount_mmc(NULL);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_MOUNT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-static void unmount_cb(int result, void *data)
-{
-       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
-                       "unmount callback result : %d", result);
-}
-
-/**
- * @brief Positive test case of deviced_request_unmount_mmc()
- */
-static void utc_system_deviced_deviced_request_unmount_mmc_p_1(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = unmount_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_unmount_mmc(&data, 0);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_request_unmount_mmc()
- */
-static void utc_system_deviced_deviced_request_unmount_mmc_p_2(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = unmount_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_unmount_mmc(&data, 1);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_request_unmount_mmc()
- */
-static void utc_system_deviced_deviced_request_unmount_mmc_p_3(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_unmount_mmc(&data, 1);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_request_unmount_mmc()
- */
-static void utc_system_deviced_deviced_request_unmount_mmc_p_4(void)
-{
-       int ret;
-
-       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_unmount_mmc(NULL, 0);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Negative test case of deviced_request_unmount_mmc()
- */
-static void utc_system_deviced_deviced_request_unmount_mmc_n(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = unmount_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_unmount_mmc(&data, -1);
-       dts_check_ne(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
-}
-
-static void format_cb(int result, void *data)
-{
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "format callback result : %d", result);
-}
-
-/**
- * @brief Positive test case of deviced_request_format_mmc()
- */
-static void utc_system_deviced_deviced_request_format_mmc_p_1(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_format_mmc(&data);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_FORMAT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_request_format_mmc()
- */
-static void utc_system_deviced_deviced_request_format_mmc_p_2(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_format_mmc(&data);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_FORMAT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_request_format_mmc()
- */
-static void utc_system_deviced_deviced_request_format_mmc_p_3(void)
-{
-       int ret;
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_request_format_mmc(NULL);
-       dts_check_eq(API_NAME_DEVICED_REQUEST_FORMAT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_format_mmc()
- */
-static void utc_system_deviced_deviced_format_mmc_p_1(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_format_mmc(&data, 0);
-       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_format_mmc()
- */
-static void utc_system_deviced_deviced_format_mmc_p_2(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_format_mmc(&data, 1);
-       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_format_mmc()
- */
-static void utc_system_deviced_deviced_format_mmc_p_3(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_format_mmc(&data, 1);
-       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Positive test case of deviced_format_mmc()
- */
-static void utc_system_deviced_deviced_format_mmc_p_4(void)
-{
-       int ret;
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_format_mmc(NULL, 0);
-       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
-
-       sleep(1);
-}
-
-/**
- * @brief Negative test case of deviced_format_mmc()
- */
-static void utc_system_deviced_deviced_format_mmc_n(void)
-{
-       int ret;
-       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
-
-       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
-                       "This testcase is only valid when mmc is inserted");
-
-       ret = deviced_format_mmc(&data, -1);
-       dts_check_ne(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
-}
diff --git a/test/testcase/utc_system_deviced_display.c b/test/testcase/utc_system_deviced_display.c
deleted file mode 100644 (file)
index 812b4bd..0000000
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <stdbool.h>
-#include <dd-display.h>
-
-#define API_NAME_DISPLAY_GET_COUNT "display_get_count"
-#define API_NAME_DISPLAY_GET_MAX_BRIGHTNESS "display_get_max_brightness"
-#define API_NAME_DISPLAY_GET_MIN_BRIGHTNESS "display_get_min_brightness"
-#define API_NAME_DISPLAY_GET_BRIGHTNESS "display_get_brightness"
-#define API_NAME_DISPLAY_SET_BRIGHTNESS_WITH_SETTING "display_set_brightness_with_setting"
-#define API_NAME_DISPLAY_SET_BRIGHTNESS "display_set_brightness"
-#define API_NAME_DISPLAY_RELEASE_BRIGHTNESS "display_release_brightness"
-#define API_NAME_DISPLAY_GET_ACL_STATUS "display_get_acl_status"
-#define API_NAME_DISPLAY_SET_ACL_STATUS "display_set_acl_status"
-#define API_NAME_DISPLAY_GET_IMAGE_ENHANCE_INFO "display_get_enhance_info"
-#define API_NAME_DISPLAY_GET_IMAGE_ENHANCE "display_get_image_enhance"
-#define API_NAME_DISPLAY_SET_IMAGE_ENHANCE "display_set_image_enhance"
-#define API_NAME_DISPLAY_SET_REFRESH_RATE "display_set_refresh_rate"
-#define API_NAME_DISPLAY_LOCK_STATE "display_lock_state"
-#define API_NAME_DISPLAY_UNLOCK_STATE "display_unlock_state"
-#define API_NAME_DISPLAY_CHANGE_STATE "display_change_state"
-#define API_NAME_DISPLAY_GET_AUTO_SCREEN_TONE "display_get_auto_screen_tone"
-#define API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE "display_Set_auto_screen_tone"
-#define API_NAME_DISPLAY_GET_COLOR_BLIND "display_get_color_blind"
-#define API_NAME_DISPLAY_SET_COLOR_BLIND "display_set_color_blind"
-#define API_NAME_DISPLAY_GET_ENHANCED_TOUCH "display_get_enhanced_touch"
-#define API_NAME_DISPLAY_SET_ENHANCED_TOUCH "display_set_enhanced_touch"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_display_get_count_p(void);
-static void utc_system_deviced_display_get_max_brightness_p(void);
-static void utc_system_deviced_display_get_min_brightness_p(void);
-static void utc_system_deviced_display_get_brightness_p(void);
-static void utc_system_deviced_display_set_brightness_with_setting_p(void);
-static void utc_system_deviced_display_set_brightness_with_setting_n(void);
-static void utc_system_deviced_display_set_brightness_p(void);
-static void utc_system_deviced_display_set_brightness_n(void);
-static void utc_system_deviced_display_release_brightness_p(void);
-static void utc_system_deviced_display_get_acl_status_p(void);
-static void utc_system_deviced_display_set_acl_status_p_1(void);
-static void utc_system_deviced_display_set_acl_status_p_2(void);
-static void utc_system_deviced_display_set_acl_status_n(void);
-static void utc_system_deviced_display_get_image_enhance_info_p(void);
-static void utc_system_deviced_display_get_image_enhance_p(void);
-static void utc_system_deviced_display_get_image_enhance_n(void);
-static void utc_system_deviced_display_set_image_enhance_p(void);
-static void utc_system_deviced_display_set_image_enhance_n_1(void);
-static void utc_system_deviced_display_set_image_enhance_n_2(void);
-static void utc_system_deviced_display_set_refresh_rate_p(void);
-static void utc_system_deviced_display_set_refresh_rate_n_1(void);
-static void utc_system_deviced_display_set_refresh_rate_n_2(void);
-static void utc_system_deviced_display_lock_state_p(void);
-static void utc_system_deviced_display_lock_state_n_1(void);
-static void utc_system_deviced_display_lock_state_n_2(void);
-static void utc_system_deviced_display_lock_state_n_3(void);
-static void utc_system_deviced_display_unlock_state_p(void);
-static void utc_system_deviced_display_unlock_state_n_1(void);
-static void utc_system_deviced_display_unlock_state_n_2(void);
-static void utc_system_deviced_display_change_state_p(void);
-static void utc_system_deviced_display_change_state_n(void);
-static void utc_system_deviced_display_get_auto_screen_tone_p(void);
-static void utc_system_deviced_display_set_auto_screen_tone_p_1(void);
-static void utc_system_deviced_display_set_auto_screen_tone_p_2(void);
-static void utc_system_deviced_display_set_auto_screen_tone_n(void);
-static void utc_system_deviced_display_get_color_blind_p(void);
-static void utc_system_deviced_display_set_color_blind_p_1(void);
-static void utc_system_deviced_display_set_color_blind_p_2(void);
-static void utc_system_deviced_display_set_color_blind_n_1(void);
-static void utc_system_deviced_display_set_color_blind_n_2(void);
-static void utc_system_deviced_display_get_enhanced_touch_p(void);
-static void utc_system_deviced_display_set_enhanced_touch_p_1(void);
-static void utc_system_deviced_display_set_enhanced_touch_p_2(void);
-static void utc_system_deviced_display_set_enhanced_touch_n(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_display_get_count_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_get_max_brightness_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_get_min_brightness_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_get_brightness_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_brightness_with_setting_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_brightness_with_setting_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_set_brightness_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_brightness_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_release_brightness_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_get_acl_status_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_acl_status_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_acl_status_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_acl_status_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_get_image_enhance_info_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_get_image_enhance_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_get_image_enhance_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_set_image_enhance_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_image_enhance_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_set_image_enhance_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_set_refresh_rate_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_refresh_rate_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_set_refresh_rate_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_lock_state_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_lock_state_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_lock_state_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_lock_state_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_unlock_state_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_unlock_state_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_unlock_state_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_change_state_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_change_state_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_get_auto_screen_tone_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_auto_screen_tone_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_auto_screen_tone_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_auto_screen_tone_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_get_color_blind_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_color_blind_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_color_blind_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_color_blind_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_set_color_blind_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_display_get_enhanced_touch_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_enhanced_touch_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_enhanced_touch_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_display_set_enhanced_touch_n, NEGATIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of display_get_count()
- */
-static void utc_system_deviced_display_get_count_p(void)
-{
-       int ret;
-
-       ret = display_get_count();
-       dts_check_ge(API_NAME_DISPLAY_GET_COUNT, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_max_brightness()
- */
-static void utc_system_deviced_display_get_max_brightness_p(void)
-{
-       int ret;
-
-       ret = display_get_max_brightness();
-       dts_check_ge(API_NAME_DISPLAY_GET_MAX_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_min_brightness()
- */
-static void utc_system_deviced_display_get_min_brightness_p(void)
-{
-       int ret;
-
-       ret = display_get_min_brightness();
-       dts_check_ge(API_NAME_DISPLAY_GET_MIN_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_brightness()
- */
-static void utc_system_deviced_display_get_brightness_p(void)
-{
-       int ret;
-
-       ret = display_get_brightness();
-       dts_check_ge(API_NAME_DISPLAY_GET_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_brightness_with_setting()
- */
-static void utc_system_deviced_display_set_brightness_with_setting_p(void)
-{
-       int ret;
-
-       ret = display_set_brightness_with_setting(100);
-       dts_check_eq(API_NAME_DISPLAY_SET_BRIGHTNESS_WITH_SETTING, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_set_brightness_with_setting()
- */
-static void utc_system_deviced_display_set_brightness_with_setting_n(void)
-{
-       int ret;
-
-       ret = display_set_brightness_with_setting(-1);
-       dts_check_ne(API_NAME_DISPLAY_SET_BRIGHTNESS_WITH_SETTING, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_brightness()
- */
-static void utc_system_deviced_display_set_brightness_p(void)
-{
-       int ret;
-
-       ret = display_set_brightness(50);
-       dts_check_eq(API_NAME_DISPLAY_SET_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_set_brightness()
- */
-static void utc_system_deviced_display_set_brightness_n(void)
-{
-       int ret;
-
-       ret = display_set_brightness(-1);
-       dts_check_ne(API_NAME_DISPLAY_SET_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_release_brightness()
- */
-static void utc_system_deviced_display_release_brightness_p(void)
-{
-       int ret;
-
-       ret = display_release_brightness();
-       dts_check_eq(API_NAME_DISPLAY_RELEASE_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_acl_status()
- */
-static void utc_system_deviced_display_get_acl_status_p(void)
-{
-       int ret;
-
-       ret = display_get_acl_status();
-       dts_check_ge(API_NAME_DISPLAY_GET_ACL_STATUS, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_acl_status()
- */
-static void utc_system_deviced_display_set_acl_status_p_1(void)
-{
-       int ret;
-
-       ret = display_set_acl_status(1);
-       dts_check_eq(API_NAME_DISPLAY_SET_ACL_STATUS, ret, 0, "Enable acl");
-}
-
-/**
- * @brief Positive test case of display_set_acl_status()
- */
-static void utc_system_deviced_display_set_acl_status_p_2(void)
-{
-       int ret;
-
-       ret = display_set_acl_status(0);
-       dts_check_eq(API_NAME_DISPLAY_SET_ACL_STATUS, ret, 0, "Disable acl");
-}
-
-/**
- * @brief Negative test case of display_set_acl_status()
- */
-static void utc_system_deviced_display_set_acl_status_n(void)
-{
-       int ret;
-
-       ret = display_set_acl_status(-1);
-       dts_check_ne(API_NAME_DISPLAY_SET_ACL_STATUS, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_image_enhance_info()
- */
-static void utc_system_deviced_display_get_image_enhance_info_p(void)
-{
-       int ret;
-
-       ret = display_get_image_enhance_info();
-       dts_check_ge(API_NAME_DISPLAY_GET_IMAGE_ENHANCE_INFO, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_image_enhance()
- */
-static void utc_system_deviced_display_get_image_enhance_p(void)
-{
-       int i, ret;
-
-       for (i = ENHANCE_MODE; i <= ENHANCE_OUTDOOR; ++i) {
-               ret = display_get_image_enhance(i);
-               dts_check_ge(API_NAME_DISPLAY_GET_IMAGE_ENHANCE, ret, 0, "enhance type : %d", i);
-       }
-}
-
-/**
- * @brief Negative test case of display_get_image_enhance()
- */
-static void utc_system_deviced_display_get_image_enhance_n(void)
-{
-       int ret;
-
-       ret = display_get_image_enhance(-1);
-       dts_check_ne(API_NAME_DISPLAY_GET_IMAGE_ENHANCE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_image_enhance()
- */
-static void utc_system_deviced_display_set_image_enhance_p(void)
-{
-       int i, ret;
-
-       for (i = ENHANCE_MODE; i <= ENHANCE_OUTDOOR; ++i) {
-               ret = display_set_image_enhance(i, 0);
-               dts_check_eq(API_NAME_DISPLAY_SET_IMAGE_ENHANCE, ret, 0, "enhance type : %d", i);
-       }
-}
-
-/**
- * @brief Negative test case of display_set_image_enhance()
- */
-static void utc_system_deviced_display_set_image_enhance_n_1(void)
-{
-       int ret;
-
-       ret = display_set_image_enhance(-1, 0);
-       dts_check_ne(API_NAME_DISPLAY_SET_IMAGE_ENHANCE, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_set_image_enhance()
- */
-static void utc_system_deviced_display_set_image_enhance_n_2(void)
-{
-       int ret;
-
-       ret = display_set_image_enhance(0, -1);
-       dts_check_ne(API_NAME_DISPLAY_SET_IMAGE_ENHANCE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_refresh_rate()
- */
-static void utc_system_deviced_display_set_refresh_rate_p(void)
-{
-       int i, ret;
-
-       for (i = REFRESH_SETTING; i <= REFRESH_WEB; ++i) {
-               ret = display_set_refresh_rate(i, 60);
-               dts_check_eq(API_NAME_DISPLAY_SET_REFRESH_RATE, ret, 0, "refresh type : %d", i);
-       }
-}
-
-/**
- * @brief Negative test case of display_set_refresh_rate()
- */
-static void utc_system_deviced_display_set_refresh_rate_n_1(void)
-{
-       int ret;
-
-       ret = display_set_refresh_rate(-1, 60);
-       dts_check_ne(API_NAME_DISPLAY_SET_REFRESH_RATE, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_set_refresh_rate()
- */
-static void utc_system_deviced_display_set_refresh_rate_n_2(void)
-{
-       int ret;
-
-       ret = display_set_refresh_rate(0, -1);
-       dts_check_ne(API_NAME_DISPLAY_SET_REFRESH_RATE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_lock_state()
- */
-static void utc_system_deviced_display_lock_state_p(void)
-{
-       int ret;
-
-       ret = display_lock_state(LCD_NORMAL, GOTO_STATE_NOW, 0);
-       dts_check_eq(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_lock_state()
- */
-static void utc_system_deviced_display_lock_state_n_1(void)
-{
-       int ret;
-
-       ret = display_lock_state(-1, GOTO_STATE_NOW, 0);
-       dts_check_ne(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_lock_state()
- */
-static void utc_system_deviced_display_lock_state_n_2(void)
-{
-       int ret;
-
-       ret = display_lock_state(LCD_NORMAL, -1, 0);
-       dts_check_ne(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_lock_state()
- */
-static void utc_system_deviced_display_lock_state_n_3(void)
-{
-       int ret;
-
-       ret = display_lock_state(LCD_NORMAL, GOTO_STATE_NOW, -1);
-       dts_check_ne(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_unlock_state()
- */
-static void utc_system_deviced_display_unlock_state_p(void)
-{
-       int ret;
-
-       ret = display_unlock_state(LCD_NORMAL, PM_RESET_TIMER);
-       dts_check_eq(API_NAME_DISPLAY_UNLOCK_STATE, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_unlock_state()
- */
-static void utc_system_deviced_display_unlock_state_n_1(void)
-{
-       int ret;
-
-       ret = display_unlock_state(-1, PM_RESET_TIMER);
-       dts_check_ne(API_NAME_DISPLAY_UNLOCK_STATE, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_unlock_state()
- */
-static void utc_system_deviced_display_unlock_state_n_2(void)
-{
-       int ret;
-
-       ret = display_unlock_state(LCD_NORMAL, -1);
-       dts_check_ne(API_NAME_DISPLAY_UNLOCK_STATE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_change_state()
- */
-static void utc_system_deviced_display_change_state_p(void)
-{
-       int ret;
-
-       ret = display_change_state(LCD_NORMAL);
-       dts_check_eq(API_NAME_DISPLAY_CHANGE_STATE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_change_state()
- */
-static void utc_system_deviced_display_change_state_n(void)
-{
-       int ret;
-
-       ret = display_change_state(-1);
-       dts_check_ne(API_NAME_DISPLAY_CHANGE_STATE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_auto_screen_tone()
- */
-static void utc_system_deviced_display_get_auto_screen_tone_p(void)
-{
-       int ret;
-
-       ret = display_get_auto_screen_tone();
-       dts_check_ge(API_NAME_DISPLAY_GET_AUTO_SCREEN_TONE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_auto_screen_tone()
- */
-static void utc_system_deviced_display_set_auto_screen_tone_p_1(void)
-{
-       int ret;
-
-       ret = display_set_auto_screen_tone(TONE_ON);
-       dts_check_eq(API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE, ret, 0, "Enable auto screen tone");
-}
-
-/**
- * @brief Positive test case of display_set_auto_screen_tone()
- */
-static void utc_system_deviced_display_set_auto_screen_tone_p_2(void)
-{
-       int ret;
-
-       ret = display_set_auto_screen_tone(TONE_OFF);
-       dts_check_eq(API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE, ret, 0, "Disable auto screen tone");
-}
-
-/**
- * @brief Negative test case of display_set_auto_screen_tone()
- */
-static void utc_system_deviced_display_set_auto_screen_tone_n(void)
-{
-       int ret;
-
-       ret = display_set_auto_screen_tone(-1);
-       dts_check_ne(API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_color_blind()
- */
-static void utc_system_deviced_display_get_color_blind_p(void)
-{
-       int ret;
-
-       ret = display_get_color_blind();
-       dts_check_ge(API_NAME_DISPLAY_GET_COLOR_BLIND, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_color_blind()
- */
-static void utc_system_deviced_display_set_color_blind_p_1(void)
-{
-       int ret;
-       struct blind_color_info info = {0,};
-
-       ret = display_set_color_blind(true, &info);
-       dts_check_eq(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_color_blind()
- */
-static void utc_system_deviced_display_set_color_blind_p_2(void)
-{
-       int ret;
-       struct blind_color_info info = {0,};
-
-       ret = display_set_color_blind(false, &info);
-       dts_check_eq(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
-}
-
-/**
- * @brief Negative test case of display_set_color_blind()
- */
-static void utc_system_deviced_display_set_color_blind_n_1(void)
-{
-       int ret;
-       struct blind_color_info info = {0,};
-
-       ret = display_set_color_blind(-1, &info);
-       dts_check_ne(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_color_blind()
- */
-static void utc_system_deviced_display_set_color_blind_n_2(void)
-{
-       int ret;
-
-       ret = display_set_color_blind(true, NULL);
-       dts_check_ne(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_get_enhanced_touch()
- */
-static void utc_system_deviced_display_get_enhanced_touch_p(void)
-{
-       int ret;
-
-       ret = display_get_enhanced_touch();
-       dts_check_ge(API_NAME_DISPLAY_GET_ENHANCED_TOUCH, ret, 0);
-}
-
-/**
- * @brief Positive test case of display_set_enhanced_touch()
- */
-static void utc_system_deviced_display_set_enhanced_touch_p_1(void)
-{
-       int ret;
-
-       ret = display_set_enhanced_touch(true);
-       dts_check_eq(API_NAME_DISPLAY_SET_ENHANCED_TOUCH, ret, 0, "Enable enhanced touch");
-}
-
-/**
- * @brief Positive test case of display_set_enhanced_touch()
- */
-static void utc_system_deviced_display_set_enhanced_touch_p_2(void)
-{
-       int ret;
-
-       ret = display_set_enhanced_touch(false);
-       dts_check_eq(API_NAME_DISPLAY_SET_ENHANCED_TOUCH, ret, 0, "Disable enhanced touch");
-}
-
-/**
- * @brief Negative test case of display_set_enhanced_touch()
- */
-static void utc_system_deviced_display_set_enhanced_touch_n(void)
-{
-       int ret;
-
-       ret = display_set_enhanced_touch(-1);
-       dts_check_ne(API_NAME_DISPLAY_SET_ENHANCED_TOUCH, ret, 0);
-}
diff --git a/test/testcase/utc_system_deviced_haptic.c b/test/testcase/utc_system_deviced_haptic.c
deleted file mode 100644 (file)
index d32283e..0000000
+++ /dev/null
@@ -1,984 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <dd-haptic.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#define API_NAME_HAPTIC_STARTUP "haptic_startup"
-#define API_NAME_HAPTIC_GET_COUNT "haptic_get_count"
-#define API_NAME_HAPTIC_OPEN "haptic_open"
-#define API_NAME_HAPTIC_CLOSE "haptic_close"
-#define API_NAME_HAPTIC_VIBRATE_MONOTONE "haptic_vibrate_monotone"
-#define API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL "haptic_vibrate_monotone_with_detail"
-#define API_NAME_HAPTIC_VIBRATE_FILE "haptic_vibrate_file"
-#define API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL "haptic_vibrate_file_with_detail"
-#define API_NAME_HAPTIC_VIBRATE_BUFFERS "haptic_vibrate_buffers"
-#define API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL "haptic_vibrate_buffers_with_detail"
-#define API_NAME_HAPTIC_STOP_ALL_EFFECTS "haptic_stop_all_effects"
-#define API_NAME_HAPTIC_GET_EFFECT_STATE "haptic_get_effect_state"
-#define API_NAME_HAPTIC_CREATE_EFFECT "haptic_create_effect"
-#define API_NAME_HAPTIC_SAVE_EFFECT "haptic_save_effect"
-#define API_NAME_HAPTIC_GET_FILE_DURATION "haptic_get_file_duration"
-#define API_NAME_HAPTIC_GET_BUFFER_DURATION "haptic_get_buffer_duration"
-#define API_NAME_HAPTIC_SAVE_LED "haptic_save_led"
-
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_haptic_get_count_p(void);
-static void utc_system_deviced_haptic_get_count_n(void);
-static void utc_system_deviced_haptic_open_p(void);
-static void utc_system_deviced_haptic_open_n_1(void);
-static void utc_system_deviced_haptic_open_n_2(void);
-static void utc_system_deviced_haptic_close_p(void);
-static void utc_system_deviced_haptic_close_n(void);
-static void utc_system_deviced_haptic_vibrate_monotone_p_1(void);
-static void utc_system_deviced_haptic_vibrate_monotone_p_2(void);
-static void utc_system_deviced_haptic_vibrate_monotone_n_1(void);
-static void utc_system_deviced_haptic_vibrate_monotone_n_2(void);
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_1(void);
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_2(void);
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_1(void);
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_2(void);
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_3(void);
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_4(void);
-static void utc_system_deviced_haptic_vibrate_file_p_1(void);
-static void utc_system_deviced_haptic_vibrate_file_p_2(void);
-static void utc_system_deviced_haptic_vibrate_file_n_1(void);
-static void utc_system_deviced_haptic_vibrate_file_n_2(void);
-static void utc_system_deviced_haptic_vibrate_file_with_detail_p_1(void);
-static void utc_system_deviced_haptic_vibrate_file_with_detail_p_2(void);
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_1(void);
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_2(void);
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_3(void);
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_4(void);
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_5(void);
-static void utc_system_deviced_haptic_vibrate_buffers_p_1(void);
-static void utc_system_deviced_haptic_vibrate_buffers_p_2(void);
-static void utc_system_deviced_haptic_vibrate_buffers_n_1(void);
-static void utc_system_deviced_haptic_vibrate_buffers_n_2(void);
-static void utc_system_deviced_haptic_vibrate_buffers_n_3(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_1(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_2(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_1(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_2(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_3(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_4(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_5(void);
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_6(void);
-static void utc_system_deviced_haptic_stop_all_effects_p(void);
-static void utc_system_deviced_haptic_stop_all_effects_n(void);
-static void utc_system_deviced_haptic_get_effect_state_p(void);
-static void utc_system_deviced_haptic_get_effect_state_n_1(void);
-static void utc_system_deviced_haptic_get_effect_state_n_2(void);
-static void utc_system_deviced_haptic_create_effect_p(void);
-static void utc_system_deviced_haptic_create_effect_n_1(void);
-static void utc_system_deviced_haptic_create_effect_n_2(void);
-static void utc_system_deviced_haptic_create_effect_n_3(void);
-static void utc_system_deviced_haptic_create_effect_n_4(void);
-static void utc_system_deviced_haptic_save_effect_p(void);
-static void utc_system_deviced_haptic_save_effect_n_1(void);
-static void utc_system_deviced_haptic_save_effect_n_2(void);
-static void utc_system_deviced_haptic_save_effect_n_3(void);
-static void utc_system_deviced_haptic_get_file_duration_p(void);
-static void utc_system_deviced_haptic_get_file_duration_n_1(void);
-static void utc_system_deviced_haptic_get_file_duration_n_2(void);
-static void utc_system_deviced_haptic_get_file_duration_n_3(void);
-static void utc_system_deviced_haptic_get_buffer_duration_p(void);
-static void utc_system_deviced_haptic_get_buffer_duration_n_1(void);
-static void utc_system_deviced_haptic_get_buffer_duration_n_2(void);
-static void utc_system_deviced_haptic_get_buffer_duration_n_3(void);
-static void utc_system_deviced_haptic_save_led_p(void);
-static void utc_system_deviced_haptic_save_led_n_1(void);
-static void utc_system_deviced_haptic_save_led_n_2(void);
-static void utc_system_deviced_haptic_save_led_n_3(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_haptic_get_count_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_count_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_open_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_open_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_open_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_create_effect_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_create_effect_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_create_effect_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_create_effect_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_create_effect_n_4, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_effect_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_effect_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_effect_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_effect_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_with_detail_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_with_detail_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_4, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_with_detail_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_with_detail_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_with_detail_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_with_detail_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_with_detail_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_with_detail_n_4, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_file_with_detail_n_5, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_4, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_5, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_6, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_stop_all_effects_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_stop_all_effects_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_effect_state_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_effect_state_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_effect_state_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_file_duration_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_file_duration_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_file_duration_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_file_duration_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_buffer_duration_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_buffer_duration_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_buffer_duration_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_get_buffer_duration_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_led_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_led_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_led_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_save_led_n_3, NEGATIVE_TC_IDX },
-       { utc_system_deviced_haptic_close_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_haptic_close_n, NEGATIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-#define DEVICED_FILE_PATH "/opt/usr/share/deviced"
-#define HAPTIC_FILE_PATH DEVICED_FILE_PATH"/test.ivt"
-#define BINARY_FILE_PATH DEVICED_FILE_PATH"/test.led"
-
-static haptic_device_h haptic_h;
-static unsigned char haptic_buffer[1024];
-static int haptic_buf_size = 1024;
-
-static void startup(void)
-{
-       int ret;
-
-       ret = mkdir(DEVICED_FILE_PATH, 0777);
-       if (ret < 0)
-               dts_message(API_NAME_HAPTIC_STARTUP,
-                               "fail to make direcotry(%s) : %s",
-                               DEVICED_FILE_PATH, strerror(errno));
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of haptic_get_count()
- */
-static void utc_system_deviced_haptic_get_count_p(void)
-{
-       int val, ret;
-
-       ret = haptic_get_count(&val);
-       dts_check_eq(API_NAME_HAPTIC_GET_COUNT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_count()
- */
-static void utc_system_deviced_haptic_get_count_n(void)
-{
-       int ret;
-
-       ret = haptic_get_count(NULL);
-       dts_check_ne(API_NAME_HAPTIC_GET_COUNT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_open()
- */
-static void utc_system_deviced_haptic_open_p(void)
-{
-       int ret;
-
-       ret = haptic_open(HAPTIC_DEVICE_ALL, &haptic_h);
-       dts_check_eq(API_NAME_HAPTIC_OPEN, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_open()
- */
-static void utc_system_deviced_haptic_open_n_1(void)
-{
-       int ret;
-
-       ret = haptic_open(-1, &haptic_h);
-       dts_check_ne(API_NAME_HAPTIC_OPEN, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_open()
- */
-static void utc_system_deviced_haptic_open_n_2(void)
-{
-       int ret;
-
-       ret = haptic_open(HAPTIC_DEVICE_ALL, NULL);
-       dts_check_ne(API_NAME_HAPTIC_OPEN, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_close()
- */
-static void utc_system_deviced_haptic_close_p(void)
-{
-       int ret;
-
-       ret = haptic_close(haptic_h);
-       dts_check_eq(API_NAME_HAPTIC_CLOSE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_close()
- */
-static void utc_system_deviced_haptic_close_n(void)
-{
-       int ret;
-
-       ret = haptic_close((haptic_device_h)-1);
-       dts_check_ne(API_NAME_HAPTIC_CLOSE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_monotone()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_p_1(void)
-{
-       haptic_effect_h eh;
-       int ret;
-
-       ret = haptic_vibrate_monotone(haptic_h, 1000, &eh);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_monotone()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_p_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone(haptic_h, 1000, NULL);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_monotone()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_n_1(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone((haptic_device_h)-1, 1000, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_monotone()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_n_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone(haptic_h, -1, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_monotone_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_1(void)
-{
-       haptic_effect_h eh;
-       int ret;
-
-       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
-                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &eh);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_monotone_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
-                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_monotone_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_1(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone_with_detail((haptic_device_h)-1, 1000,
-                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_monotone_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone_with_detail(haptic_h, -1,
-                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_monotone_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_3(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
-                       -1, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_monotone_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_4(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
-                       HAPTIC_FEEDBACK_5, -1, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_file()
- */
-static void utc_system_deviced_haptic_vibrate_file_p_1(void)
-{
-       haptic_effect_h eh;
-       int ret;
-
-       ret = haptic_vibrate_file(haptic_h, HAPTIC_FILE_PATH, &eh);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_file()
- */
-static void utc_system_deviced_haptic_vibrate_file_p_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file(haptic_h, HAPTIC_FILE_PATH, NULL);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_file()
- */
-static void utc_system_deviced_haptic_vibrate_file_n_1(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file((haptic_device_h)-1, HAPTIC_FILE_PATH, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_file()
- */
-static void utc_system_deviced_haptic_vibrate_file_n_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file(haptic_h, NULL, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_file_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_file_with_detail_p_1(void)
-{
-       haptic_effect_h eh;
-       int ret;
-
-       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &eh);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_file_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_file_with_detail_p_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_file_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_1(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file_with_detail((haptic_device_h)-1, HAPTIC_FILE_PATH,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_file_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file_with_detail(haptic_h, NULL,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_file_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_3(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
-                       -1, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_file_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_4(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
-                       HAPTIC_ITERATION_ONCE, -1, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_file_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_file_with_detail_n_5(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, -1, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_buffers()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_p_1(void)
-{
-       haptic_effect_h eh;
-       int ret;
-
-       ret = haptic_vibrate_buffers(haptic_h, haptic_buffer, haptic_buf_size, &eh);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_buffers()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_p_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers(haptic_h, haptic_buffer, haptic_buf_size, NULL);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_n_1(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers((haptic_device_h)-1, haptic_buffer, haptic_buf_size, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_n_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers(haptic_h, NULL, haptic_buf_size, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_n_3(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers(haptic_h, haptic_buffer, -1, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_1(void)
-{
-       haptic_effect_h eh;
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &eh);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_1(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail((haptic_device_h)-1, haptic_buffer, haptic_buf_size,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_2(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail(haptic_h, NULL, haptic_buf_size,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_3(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, -1,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_4(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
-                       -1, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_5(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
-                       HAPTIC_ITERATION_ONCE, -1, HAPTIC_PRIORITY_MIN, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_vibrate_buffers_with_detail()
- */
-static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_6(void)
-{
-       int ret;
-
-       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
-                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, -1, NULL);
-       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_stop_all_effects()
- */
-static void utc_system_deviced_haptic_stop_all_effects_p(void)
-{
-       int ret;
-
-       ret = haptic_stop_all_effects(haptic_h);
-       dts_check_eq(API_NAME_HAPTIC_STOP_ALL_EFFECTS, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_stop_all_effects()
- */
-static void utc_system_deviced_haptic_stop_all_effects_n(void)
-{
-       int ret;
-
-       ret = haptic_stop_all_effects((haptic_device_h)-1);
-       dts_check_ne(API_NAME_HAPTIC_STOP_ALL_EFFECTS, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_get_effect_state()
- */
-static void utc_system_deviced_haptic_get_effect_state_p(void)
-{
-       haptic_state_e val;
-       int ret;
-
-       ret = haptic_get_effect_state(haptic_h, (haptic_effect_h)0, &val);
-       dts_check_eq(API_NAME_HAPTIC_GET_EFFECT_STATE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_effect_state()
- */
-static void utc_system_deviced_haptic_get_effect_state_n_1(void)
-{
-       haptic_state_e val;
-       int ret;
-
-       ret = haptic_get_effect_state((haptic_device_h)NULL, (haptic_effect_h)0, &val);
-       dts_check_ne(API_NAME_HAPTIC_GET_EFFECT_STATE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_effect_state()
- */
-static void utc_system_deviced_haptic_get_effect_state_n_2(void)
-{
-       int ret;
-
-       ret = haptic_get_effect_state(haptic_h, 0, NULL);
-       dts_check_ne(API_NAME_HAPTIC_GET_EFFECT_STATE, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_create_effect()
- */
-static void utc_system_deviced_haptic_create_effect_p(void)
-{
-       int ret;
-       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
-
-       ret = haptic_create_effect(haptic_buffer, haptic_buf_size, elem, 3);
-       dts_check_eq(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_create_effect()
- */
-static void utc_system_deviced_haptic_create_effect_n_1(void)
-{
-       int ret;
-       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
-
-       ret = haptic_create_effect(NULL, haptic_buf_size, elem, 3);
-       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_create_effect()
- */
-static void utc_system_deviced_haptic_create_effect_n_2(void)
-{
-       int ret;
-       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
-
-       ret = haptic_create_effect(haptic_buffer, -1, elem, 3);
-       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_create_effect()
- */
-static void utc_system_deviced_haptic_create_effect_n_3(void)
-{
-       int ret;
-
-       ret = haptic_create_effect(haptic_buffer, haptic_buf_size, NULL, 3);
-       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_create_effect()
- */
-static void utc_system_deviced_haptic_create_effect_n_4(void)
-{
-       int ret;
-       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
-
-       ret = haptic_create_effect(haptic_buffer, haptic_buf_size, elem, -1);
-       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_save_effect()
- */
-static void utc_system_deviced_haptic_save_effect_p(void)
-{
-       int ret;
-
-       ret = haptic_save_effect(haptic_buffer, haptic_buf_size, HAPTIC_FILE_PATH);
-       dts_check_eq(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_save_effect()
- */
-static void utc_system_deviced_haptic_save_effect_n_1(void)
-{
-       int ret;
-
-       ret = haptic_save_effect(NULL, haptic_buf_size, HAPTIC_FILE_PATH);
-       dts_check_ne(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_save_effect()
- */
-static void utc_system_deviced_haptic_save_effect_n_2(void)
-{
-       int ret;
-
-       ret = haptic_save_effect(haptic_buffer, -1, HAPTIC_FILE_PATH);
-       dts_check_ne(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_save_effect()
- */
-static void utc_system_deviced_haptic_save_effect_n_3(void)
-{
-       int ret;
-
-       ret = haptic_save_effect(haptic_buffer, haptic_buf_size, NULL);
-       dts_check_ne(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_get_file_duration()
- */
-static void utc_system_deviced_haptic_get_file_duration_p(void)
-{
-       int val, ret;
-
-       ret = haptic_get_file_duration(haptic_h, HAPTIC_FILE_PATH, &val);
-       dts_check_eq(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_file_duration()
- */
-static void utc_system_deviced_haptic_get_file_duration_n_1(void)
-{
-       int val, ret;
-
-       ret = haptic_get_file_duration((haptic_device_h)-1, HAPTIC_FILE_PATH, &val);
-       dts_check_ne(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_file_duration()
- */
-static void utc_system_deviced_haptic_get_file_duration_n_2(void)
-{
-       int val, ret;
-
-       ret = haptic_get_file_duration(haptic_h, NULL, &val);
-       dts_check_ne(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_file_duration()
- */
-static void utc_system_deviced_haptic_get_file_duration_n_3(void)
-{
-       int ret;
-
-       ret = haptic_get_file_duration(haptic_h, HAPTIC_FILE_PATH, NULL);
-       dts_check_ne(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_get_buffer_duration()
- */
-static void utc_system_deviced_haptic_get_buffer_duration_p(void)
-{
-       int val, ret;
-
-       ret = haptic_get_buffer_duration(haptic_h, haptic_buffer, &val);
-       dts_check_eq(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_buffer_duration()
- */
-static void utc_system_deviced_haptic_get_buffer_duration_n_1(void)
-{
-       int val, ret;
-
-       ret = haptic_get_buffer_duration((haptic_device_h)-1, haptic_buffer, &val);
-       dts_check_ne(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_buffer_duration()
- */
-static void utc_system_deviced_haptic_get_buffer_duration_n_2(void)
-{
-       int val, ret;
-
-       ret = haptic_get_buffer_duration(haptic_h, NULL, &val);
-       dts_check_ne(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_get_buffer_duration()
- */
-static void utc_system_deviced_haptic_get_buffer_duration_n_3(void)
-{
-       int ret;
-
-       ret = haptic_get_buffer_duration(haptic_h, haptic_buffer, NULL);
-       dts_check_ne(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Positive test case of haptic_save_led()
- */
-static void utc_system_deviced_haptic_save_led_p(void)
-{
-       int ret;
-
-       ret = haptic_save_led(haptic_buffer, haptic_buf_size, BINARY_FILE_PATH);
-       dts_check_eq(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_save_led()
- */
-static void utc_system_deviced_haptic_save_led_n_1(void)
-{
-       int ret;
-
-       ret = haptic_save_led(NULL, haptic_buf_size, BINARY_FILE_PATH);
-       dts_check_ne(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_save_led()
- */
-static void utc_system_deviced_haptic_save_led_n_2(void)
-{
-       int ret;
-
-       ret = haptic_save_led(haptic_buffer, -1, BINARY_FILE_PATH);
-       dts_check_ne(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
-}
-
-/**
- * @brief Negative test case of haptic_save_led()
- */
-static void utc_system_deviced_haptic_save_led_n_3(void)
-{
-       int ret;
-
-       ret = haptic_save_led(haptic_buffer, haptic_buf_size, NULL);
-       dts_check_ne(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
-}
diff --git a/test/testcase/utc_system_deviced_led.c b/test/testcase/utc_system_deviced_led.c
deleted file mode 100644 (file)
index 0bb512f..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <dd-led.h>
-
-#define API_NAME_LED_GET_BRIGHTNESS "led_get_brightness"
-#define API_NAME_LED_GET_MAX_BRIGHTNESS "led_get_max_brightness"
-#define API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI "led_set_brightness_with_noti"
-#define API_NAME_LED_SET_IR_COMMAND "led_set_ir_command"
-#define API_NAME_LED_SET_MODE_WITH_COLOR "led_set_mode_with_color"
-#define API_NAME_LED_SET_MODE_WITH_PROPERTY "led_set_mode_with_property"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_led_get_brightness_p(void);
-static void utc_system_deviced_led_get_max_brightness_p(void);
-static void utc_system_deviced_led_set_brightness_with_noti_p_1(void);
-static void utc_system_deviced_led_set_brightness_with_noti_p_2(void);
-static void utc_system_deviced_led_set_brightness_with_noti_n(void);
-static void utc_system_deviced_led_set_ir_command_p(void);
-static void utc_system_deviced_led_set_ir_command_n(void);
-static void utc_system_deviced_led_set_mode_with_color_p_1(void);
-static void utc_system_deviced_led_set_mode_with_color_p_2(void);
-static void utc_system_deviced_led_set_mode_with_color_n(void);
-static void utc_system_deviced_led_set_mode_with_property_p_1(void);
-static void utc_system_deviced_led_set_mode_with_property_p_2(void);
-static void utc_system_deviced_led_set_mode_with_property_p_3(void);
-static void utc_system_deviced_led_set_mode_with_property_p_4(void);
-static void utc_system_deviced_led_set_mode_with_property_n(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_led_get_brightness_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_get_max_brightness_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_brightness_with_noti_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_brightness_with_noti_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_brightness_with_noti_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_led_set_ir_command_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_ir_command_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_color_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_color_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_color_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_property_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_property_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_property_p_3, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_property_p_4, POSITIVE_TC_IDX },
-       { utc_system_deviced_led_set_mode_with_property_n, NEGATIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of led_get_brightness()
- */
-static void utc_system_deviced_led_get_brightness_p(void)
-{
-       int ret;
-
-       ret = led_get_brightness();
-       dts_check_ge(API_NAME_LED_GET_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_get_max_brightness()
- */
-static void utc_system_deviced_led_get_max_brightness_p(void)
-{
-       int ret;
-
-       ret = led_get_max_brightness();
-       dts_check_ge(API_NAME_LED_GET_MAX_BRIGHTNESS, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_brightness_with_noti()
- */
-static void utc_system_deviced_led_set_brightness_with_noti_p_1(void)
-{
-       int max, ret;
-
-       max = led_get_max_brightness();
-
-       ret = led_set_brightness_with_noti(max, true);
-       dts_check_eq(API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI, ret, 0, "Turn on torchled");
-}
-
-/**
- * @brief Positive test case of led_set_brightness_with_noti()
- */
-static void utc_system_deviced_led_set_brightness_with_noti_p_2(void)
-{
-       int ret;
-
-       ret = led_set_brightness_with_noti(0, true);
-       dts_check_eq(API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI, ret, 0, "Turn off torchled");
-}
-
-/**
- * @brief Negative test case of led_set_brightness_with_noti()
- */
-static void utc_system_deviced_led_set_brightness_with_noti_n(void)
-{
-       int ret;
-
-       ret = led_set_brightness_with_noti(-1, true);
-       dts_check_ne(API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_ir_command()
- */
-static void utc_system_deviced_led_set_ir_command_p(void)
-{
-       int ret;
-
-       ret = led_set_ir_command("38000,173,171,24,1880");
-       dts_check_eq(API_NAME_LED_SET_IR_COMMAND, ret, 0);
-}
-
-/**
- * @brief Negative test case of led_set_ir_command()
- */
-static void utc_system_deviced_led_set_ir_command_n(void)
-{
-       int ret;
-
-       ret = led_set_ir_command(NULL);
-       dts_check_ne(API_NAME_LED_SET_IR_COMMAND, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_mode_with_color()
- */
-static void utc_system_deviced_led_set_mode_with_color_p_1(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_color(LED_MISSED_NOTI, true, 0xffff00ff);
-       dts_check_eq(API_NAME_LED_SET_MODE_WITH_COLOR, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_mode_with_color()
- */
-static void utc_system_deviced_led_set_mode_with_color_p_2(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_color(LED_MISSED_NOTI, false, 0xffff00ff);
-       dts_check_eq(API_NAME_LED_SET_MODE_WITH_COLOR, ret, 0);
-}
-
-/**
- * @brief Negative test case of led_set_mode_with_color()
- */
-static void utc_system_deviced_led_set_mode_with_color_n(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_color(-1, true, 0xffff00ff);
-       dts_check_ne(API_NAME_LED_SET_MODE_WITH_COLOR, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_mode_with_property()
- */
-static void utc_system_deviced_led_set_mode_with_property_p_1(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_property(LED_MISSED_NOTI, true, 500, 500, 0xffff00ff);
-       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_mode_with_property()
- */
-static void utc_system_deviced_led_set_mode_with_property_p_2(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_property(LED_MISSED_NOTI, false, 500, 500, 0xffff00ff);
-       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_mode_with_property()
- */
-static void utc_system_deviced_led_set_mode_with_property_p_3(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_property(LED_MISSED_NOTI, true, -1, 500, 0xffff00ff);
-       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
-}
-
-/**
- * @brief Positive test case of led_set_mode_with_property()
- */
-static void utc_system_deviced_led_set_mode_with_property_p_4(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_property(LED_MISSED_NOTI, true, 500, -1, 0xffff00ff);
-       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
-}
-
-/**
- * @brief Negative test case of led_set_mode_with_property()
- */
-static void utc_system_deviced_led_set_mode_with_property_n(void)
-{
-       int ret;
-
-       ret = led_set_mode_with_property(-1, true, 500, 500, 0xffff00ff);
-       dts_check_ne(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
-}
diff --git a/test/testcase/utc_system_deviced_mmc.c b/test/testcase/utc_system_deviced_mmc.c
deleted file mode 100644 (file)
index 8a326b9..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <dd-mmc.h>
-
-#define API_NAME_MMC_SECURE_MOUNT "mmc_secure_mount"
-#define API_NAME_MMC_SECURE_UNMOUNT "mmc_secure_unmount"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_mmc_secure_mount_p(void);
-static void utc_system_deviced_mmc_secure_mount_n(void);
-static void utc_system_deviced_mmc_secure_unmount_p(void);
-static void utc_system_deviced_mmc_secure_unmount_n(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_mmc_secure_mount_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_mmc_secure_mount_n, NEGATIVE_TC_IDX },
-       { utc_system_deviced_mmc_secure_unmount_p, POSITIVE_TC_IDX },
-       { utc_system_deviced_mmc_secure_unmount_n, NEGATIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-#define SECURE_MOUNT_POINT "/opt/storage/secure"
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of mmc_secure_mount()
- */
-static void utc_system_deviced_mmc_secure_mount_p(void)
-{
-       int ret;
-
-       dts_message("This testcase is only valid when mmc is inserted");
-
-       ret = mmc_secure_mount(SECURE_MOUNT_POINT);
-       dts_check_eq(API_NAME_MMC_SECURE_MOUNT, ret, 0);
-}
-
-/**
- * @brief Negative test case of mmc_secure_mount()
- */
-static void utc_system_deviced_mmc_secure_mount_n(void)
-{
-       int ret;
-
-       dts_message("This testcase is only valid when mmc is inserted");
-
-       ret = mmc_secure_mount(NULL);
-       dts_check_ne(API_NAME_MMC_SECURE_MOUNT, ret, 0);
-}
-
-/**
- * @brief Positive test case of mmc_secure_unmount()
- */
-static void utc_system_deviced_mmc_secure_unmount_p(void)
-{
-       int ret;
-
-       ret = mmc_secure_unmount(SECURE_MOUNT_POINT);
-       dts_check_eq(API_NAME_MMC_SECURE_UNMOUNT, ret, 0);
-}
-
-/**
- * @brief Negative test case of mmc_secure_unmount()
- */
-static void utc_system_deviced_mmc_secure_unmount_n(void)
-{
-       int ret;
-
-       ret = mmc_secure_unmount(NULL);
-       dts_check_ne(API_NAME_MMC_SECURE_UNMOUNT, ret, 0);
-}
diff --git a/test/testcase/utc_system_deviced_storage.c b/test/testcase/utc_system_deviced_storage.c
deleted file mode 100644 (file)
index 3eab765..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG
- * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
- * this software is owned by Samsung and you shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
- * make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied
- * warranties of merchantability, fitness for a particular purpose, or
- * non-infringement. SAMSUNG shall not be liable for any damages suffered by
- * licensee arising out of or related to this software.
- *
- */
-#include <tet_api.h>
-#include <dd-storage.h>
-
-#define API_NAME_STORAGE_GET_PATH "storage_get_path"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-
-static void utc_system_deviced_storage_get_path_p_1(void);
-static void utc_system_deviced_storage_get_path_p_2(void);
-static void utc_system_deviced_storage_get_path_p_3(void);
-static void utc_system_deviced_storage_get_path_n_1(void);
-static void utc_system_deviced_storage_get_path_n_2(void);
-static void utc_system_deviced_storage_get_path_n_3(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_system_deviced_storage_get_path_p_1, POSITIVE_TC_IDX },
-       { utc_system_deviced_storage_get_path_p_2, POSITIVE_TC_IDX },
-       { utc_system_deviced_storage_get_path_p_3, POSITIVE_TC_IDX },
-       { utc_system_deviced_storage_get_path_n_1, NEGATIVE_TC_IDX },
-       { utc_system_deviced_storage_get_path_n_2, NEGATIVE_TC_IDX },
-       { utc_system_deviced_storage_get_path_n_3, NEGATIVE_TC_IDX },
-       { NULL, 0 },
-};
-
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of storage_get_path()
- */
-static void utc_system_deviced_storage_get_path_p_1(void)
-{
-       char path[40];
-       int ret;
-
-       ret = storage_get_path(STORAGE_DEFAULT, path, sizeof(path));
-       dts_check_eq(API_NAME_STORAGE_GET_PATH, ret, 0, "Default storage");
-}
-
-/**
- * @brief Positive test case of storage_get_path()
- */
-static void utc_system_deviced_storage_get_path_p_2(void)
-{
-       char path[40];
-       int ret;
-
-       ret = storage_get_path(STORAGE_INTERNAL, path, sizeof(path));
-       dts_check_eq(API_NAME_STORAGE_GET_PATH, ret, 0, "Internal storage");
-}
-
-/**
- * @brief Positive test case of storage_get_path()
- */
-static void utc_system_deviced_storage_get_path_p_3(void)
-{
-       char path[40];
-       int ret;
-
-       ret = storage_get_path(STORAGE_EXTERNAL, path, sizeof(path));
-       dts_check_eq(API_NAME_STORAGE_GET_PATH, ret, 0, "External storage");
-}
-
-/**
- * @brief Negative test case of storage_get_path()
- */
-static void utc_system_deviced_storage_get_path_n_1(void)
-{
-       char path[40];
-       int ret;
-
-       ret = storage_get_path(-1, path, sizeof(path));
-       dts_check_ne(API_NAME_STORAGE_GET_PATH, ret, 0);
-}
-
-/**
- * @brief Negative test case of storage_get_path()
- */
-static void utc_system_deviced_storage_get_path_n_2(void)
-{
-       char path[40];
-       int ret;
-
-       ret = storage_get_path(STORAGE_DEFAULT, NULL, sizeof(path));
-       dts_check_ne(API_NAME_STORAGE_GET_PATH, ret, 0);
-}
-
-/**
- * @brief Negative test case of storage_get_path()
- */
-static void utc_system_deviced_storage_get_path_n_3(void)
-{
-       char path[40];
-       int ret;
-
-       ret = storage_get_path(STORAGE_DEFAULT, path, -1);
-       dts_check_ne(API_NAME_STORAGE_GET_PATH, ret, 0);
-}
diff --git a/test/tet_scen b/test/tet_scen
deleted file mode 100644 (file)
index 03f029a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-all
-       ^TEST
-##### Scenarios for TEST #####
-
-# Test scenario
-TEST
-       :include:/testcase/tslist
diff --git a/test/tetbuild.cfg b/test/tetbuild.cfg
deleted file mode 100644 (file)
index f7eda55..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-TET_OUTPUT_CAPTURE=True # capture option for build operation checking
-TET_BUILD_TOOL=make # build with using make command
-TET_BUILD_FILE=-f Makefile # execution file (Makefile) for build
-TET_API_COMPLIANT=True # use TET API in Test Case ?
-TET_PASS_TC_NAME=True # report passed TC name in Journal file?
diff --git a/test/tetclean.cfg b/test/tetclean.cfg
deleted file mode 100644 (file)
index 02d7030..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-TET_OUTPUT_CAPTURE=True # capture option
-TET_CLEAN_TOOL= make clean # clean tool
-TET_CLEAN_FILE= Makefile # file for clean
-TET_API_COMPLIANT=True # TET API useage 
-TET_PASS_TC_NAME=True # showing name , passed TC
diff --git a/test/tetexec.cfg b/test/tetexec.cfg
deleted file mode 100644 (file)
index ef3e452..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-TET_OUTPUT_CAPTURE=True # capturing execution or not
-TET_EXEC_TOOL=  # ex) exec : execution tool set up/ Optional
-TET_EXEC_FILE=   # ex) exectool : execution file/ Optional
-TET_API_COMPLIANT=True # Test case or Tool usesTET API?
-TET_PASS_TC_NAME=True # showing Passed TC name ?