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
)
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
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)
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)
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)
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)
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)
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
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})
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}
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)
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)
+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>
SeungHun Pi <sh.pi@samsung.com>
Juho Son <juho80.son@samsung.com>
Jiyoung Yun <jy910.yun@samsung.com>
+
--- /dev/null
+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.
* : 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
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 *
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
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
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
+++ /dev/null
-[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
--- /dev/null
+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---- ------
<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>
+++ /dev/null
-# 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
[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]
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
%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
%build
cp %{SOURCE1001} .
cp %{SOURCE1002} .
-cp %{SOURCE1003} .
-cp %{SOURCE1004} .
make
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
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
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
%{_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
%{_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
%{_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
%{_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
+++ /dev/null
-<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>
+++ /dev/null
-<manifest>
- <define>
- <domain name="liblogd"/>
- </define>
- <request>
- <domain name="liblogd"/>
- </request>
- <assign>
- <filesystem path="/usr/lib/liblogd.so" label="_" exec_label="none"/>
- </assign>
-</manifest>
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;
}
#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) \
--- /dev/null
+/*
+ * 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)
#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;
};
static int lowbat_pid = 0;
+static int lowbat_popup = APPS_ENABLE;
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)) &&
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,
};
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);
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
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}")
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)
--- /dev/null
+ADD_SUBDIRECTORY(systemd)
+ADD_SUBDIRECTORY(dbus)
--- /dev/null
+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}
+)
--- /dev/null
+[D-BUS Service]
+Name=org.tizen.system.DevicedAutoTest
+Exec=/bin/false
+SystemdService=deviced-auto-test.service
+User=root
--- /dev/null
+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}
+)
--- /dev/null
+[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
--- /dev/null
+/*
+ * 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)
#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;
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;
} 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)
static int board_unit(int argc, char **argv)
{
- get_revision();
- get_serial();
+ board_revision();
+ board_serial();
+ board_numer();
return 0;
}
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;
_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();
}
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);
}
}
--- /dev/null
+/*
+ * 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)
#define METHOD_GET_REVISION "GetRevision"
-static void get_revision(void)
+static void cpuinfo_revision(void)
{
DBusError err;
DBusMessage *msg;
} 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)
static int cpuinfo_unit(int argc, char **argv)
{
- get_revision();
+ cpuinfo_revision();
return 0;
}
{
DBusError err;
DBusMessage *msg;
- int ret, level;
+ int ret, val;
msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
DEVICED_PATH_SYSNOTI,
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;
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)
if (strcmp(unit, device_change_types[index].name) != 0 ||
strcmp(status, device_change_types[index].status) != 0)
continue;
- test(index);
+ cradle(index);
test_cradle();
}
}
_I("start test");
for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
- test(index);
+ cradle(index);
}
static void cradle_exit(void *data)
if (argc != 4)
return -EAGAIN;
- unit(argv[2], argv[3]);
+ unit(argv[1], argv[2]);
out:
return 0;
}
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;
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)
if (strcmp(unit, device_change_types[index].name) != 0 ||
strcmp(status, device_change_types[index].status) != 0)
continue;
- test(index);
+ earjack(index);
}
}
_I("start test");
for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
- test(index);
+ earjack(index);
}
static void earjack_exit(void *data)
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;
}
{
DBusError err;
DBusMessage *msg;
- int ret, level;
+ int ret, val;
msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
DEVICED_PATH_SYSNOTI,
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,
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,
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;
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)
if (strcmp(unit, device_change_types[index].name) != 0 ||
strcmp(status, device_change_types[index].status) != 0)
continue;
- test(index);
+ hdmi(index);
}
}
_I("start test");
for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
- test(index);
+ hdmi(index);
test_hdmi();
test_hdcp();
test_hdmi_audio();
{"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;
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)
if (strcmp(unit, device_change_types[index].name) != 0 ||
strcmp(status, device_change_types[index].status) != 0)
continue;
- test(index);
+ keyboard(index);
}
}
_I("start test");
for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
- test(index);
+ keyboard(index);
}
static void keyboard_exit(void *data)
#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;
{"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)
e_dbus_shutdown();
return ret;
}
-static void test_signal(void)
+static void power_supply_signal(void)
{
_I("test");
register_charge_now_handler();
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;
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,
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)
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);
}
}
power_supply_types[index].status != status)
continue;
found = 1;
- test(index);
+ power_supply(index);
}
if (found)
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)
_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)
{
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;
}
--- /dev/null
+/*
+ * 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
return ret;
}
-static int test_storage(void)
+static int storage(void)
{
DBusError err;
DBusMessage *msg;
_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);
static void storage_init(void *data)
{
_I("start test");
- test_storage();
+ storage();
}
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;
}
#ifndef __TEST_H__
#define __TEST_H__
#include <stdio.h>
+#include <stdarg.h>
#include <errno.h>
#include <E_DBus.h>
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
{
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();
}
{"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;
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)
if (strcmp(unit, device_change_types[index].name) != 0 ||
strcmp(status, device_change_types[index].status) != 0)
continue;
- test(index);
+ tvout(index);
}
}
_I("start test");
for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
- test(index);
+ tvout(index);
}
static void tvout_exit(void *data)
{"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;
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)
if (strcmp(unit, device_change_types[index].name) != 0 ||
strcmp(status, device_change_types[index].status) != 0)
continue;
- test(index);
+ udev(index);
}
}
_I("start test");
for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
- test(index);
+ udev(index);
}
static void udev_exit(void *data)
{"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;
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)
if (strcmp(unit, device_change_types[index].name) != 0 ||
strcmp(status, device_change_types[index].status) != 0)
continue;
- test(index);
+ usb(index);
}
}
_I("start test");
for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
- test(index);
+ usb(index);
}
static void usb_exit(void *data)
+++ /dev/null
-/*
- * 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)
#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__ */
#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"
#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"
#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"
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;
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;
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;
#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;
}
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;
}
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);
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);
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)
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;
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;
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;
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);
}
}
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;
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;
_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;
}
.priority = DEVICE_PRIORITY_NORMAL,
.name = "lowbat",
.init = lowbat_init,
- .exit = lowbat_exit,
+ .exit = lowbat_exit,
};
DEVICE_OPS_REGISTER(&lowbat_device_ops)
#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;
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;
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;
}
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, ¶m);
+ 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, ¶m);
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)
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 = {
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)
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
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)
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);
}
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 = {
--- /dev/null
+/*
+ * 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, ¶m);
+ 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)
--- /dev/null
+/*
+ * 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, ¶m);
+ 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)
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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 */
+
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <dirent.h>
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);
+}
#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);
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__ */
+++ /dev/null
-/*
- * 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)
#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
#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"
char *value;
};
+struct siop_data {
+ int siop;
+ int rear;
+};
+
static int ss_flags = 0;
static int input_device_number;
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,
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;
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");
}
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)
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");
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;
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;
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)
{
char *args;
DBusError err;
- struct main_data *ad;
-
- ad = data;
dbus_error_init(&err);
if (dbus_message_get_args
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 *)¶ms);
+}
+
+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;
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;
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)) {
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;
}
continue;
DD_LIST_REMOVE(opt_uevent_list, handler);
- free(handler);
break;
}
}
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;
goto out;
}
- changed_device(argc, (char **)&argv);
+ changed_device(argv[0], argv[1]);
out:
reply = dbus_message_new_method_return(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);
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();
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();
"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)
#ifndef __DEVICE_HANDLER_H__
#define __DEVICE_HANDLER_H__
-#include "data.h"
+#include "common.h"
enum extcon_type {
EXTCON_TA = 0,
void sync_cradle_status(void);
+void internal_pm_change_state(unsigned int s_bits);
#endif /* __DEVICE_HANDLER_H__ */
#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;
};
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) \
}
}
+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;
static const struct device_ops notifier_device_ops = {
.priority = DEVICE_PRIORITY_NORMAL,
.name = "notifier",
+ .init = device_notifier_init,
.exit = device_notifier_exit,
};
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,
};
+++ /dev/null
-/*
- * 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;
-}
-
-
#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)
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)
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 {
static inline int device_start(const struct device_ops *dev)
{
if (dev && dev->start)
- return dev->start();
+ return dev->start(NORMAL_MODE);
return -EINVAL;
}
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;
}
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
#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"
{ 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;
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;
}
_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;
}
_D("add new obj for %s", edbus_objects[i].interface);
}
+ check_owner_list();
+ check_owner_name();
return;
out3:
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;
#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) \
* 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
#define LOG_TAG "DEVICED"
#include "shared/log-macro.h"
-
#endif
#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;
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;
}
{
writepid(PIDFILE_PATH);
ecore_init();
- return system_main(argc, argv);
+ return deviced_main(argc, argv);
}
+++ /dev/null
-/*
- * 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(¬i_device_ops)
#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);
static int old = -1;
if (old != bInserted) {
old = bInserted;
- predefine_pm_change_state(LCD_NORMAL);
+ internal_pm_change_state(LCD_NORMAL);
}
}
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));
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");
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);
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");
_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--) {
_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--) {
}
}
_E("Failed to call dbus method (err: %d)", ret);
-#endif
return ret;
}
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;
{
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;
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);
}
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();
}
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;
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)
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");
}
}
-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;
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)
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);
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;
#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);
+++ /dev/null
-/*
- * 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)
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__ */
#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"
+++ /dev/null
-/*
- * 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)
#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)
_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;
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();
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);
}
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)
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);
SET(SRCS
devicectl.c
+ usb.c
)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
#include <dbus/dbus.h>
#include <shared/dbus.h>
#include <core/common.h>
+#include "usb.h"
/*
* devicectl [device] [action]
DEVICE_DISPLAY,
DEVICE_LED,
DEVICE_PASS,
+ DEVICE_USB,
DEVICE_MAX,
DEVICE_ALL,
};
{ 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)
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;
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__*/
* 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,
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.
* @brief Enumerations of unlimited duration for the Haptic API.
*/
typedef enum {
- HAPTIC_DURATION_UNLIMITED = 0xFFFFFFFF,
+ HAPTIC_DURATION_UNLIMITED = 0x7FFFFFFF,
} haptic_duration_e;
/**
LED_CHARGING_ERROR,
LED_MISSED_NOTI,
LED_VOICE_RECORDING,
+ LED_REMOTE_CONTROLLER,
+ LED_AIR_WAKEUP,
LED_POWER_OFF,
LED_CUSTOM,
LED_MODE_MAX,
* 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
*/
/**
- * @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
* ...
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
* ...
} 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
#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)
{
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];
int alpm_set_state(int on)
{
+ if (!ambient_mode)
+ return 0;
+
if (!alpm_path)
return -ENODEV;
update_count = 0;
+ if (!on)
+ alpm_pid = 0;
+
_D("ALPM is %s", (on ? ON : OFF));
alpm_state = 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;
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");
#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)
#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;
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)
{
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);
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, "
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);
}
}
+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;
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!");
/*
* 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);
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]);
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) {
accel_handle = -1;
goto error;
}
+ sf_change_sensor_option(accel_handle, 1);
+success:
fault_count = 0;
return 0;
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;
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;
_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);
_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();
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;
}
return 0;
}
-static inline void update_brightness_direct(void)
+static void update_brightness_direct(void)
{
int ret, status;
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);
}
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);
}
#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;
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);
#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"
#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) \
.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 = {
_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;
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)
_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) {
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);
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);
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);
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);
states[pm_cur_state].trans(EVENT_TIMEOUT);
set_process_active(EINA_FALSE, (pid_t)data);
+
return EINA_FALSE;
}
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);
/* 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);
}
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;
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;
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)
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) {
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();
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);
_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) {
{
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;
(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;
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;
}
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 */
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);
}
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;
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;
/* 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;
}
}
- 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;
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;
}
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:
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) {
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;
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 */
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);
" 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) {
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,
[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);
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;
}
}
/* 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;
update_pm_setting(SETTING_HALLIC_OPEN, open);
+ if (display_info.update_auto_brightness)
+ display_info.update_auto_brightness(false);
+
return 0;
}
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));
} 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;
#ifdef ENABLE_PM_LOG
pm_history_init();
#endif
+ init_lcd_operation();
check_seed_status();
if (display_conf.lcd_always_on) {
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.
if (CHECK_OPS(keyfilter_ops, init))
keyfilter_ops->init();
}
- status = DEVICE_OPS_STATUS_START;
}
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();
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;
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;
int control_display;
int powerkey_doublepress;
int alpm_on;
+ int accel_sensor_on;
+ int continuous_sampling;
};
/*
#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;
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;
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);
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;
#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
}
}
+ 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)
#ifdef ENABLE_PM_LOG
pm_history_save(PM_LOG_LCD_OFF, pm_cur_state);
#endif
+ journal_display_off();
break;
} else {
#ifdef ENABLE_PM_LOG
{
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);
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;
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);
}
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;
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;
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;
#define __DEVICE_INTERFACE_H__
#include <stdbool.h>
+#include "core/devices.h"
#define FLAG_X_DPMS 0x2
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);
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);
};
extern struct _backlight_ops backlight_ops;
-extern struct _touch_ops touch_ops;
extern struct _power_ops power_ops;
#endif
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
+
#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);
}
int state;
int flag;
int ret;
+ unsigned int caps;
dbus_error_init(&err);
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;
pid_t pid;
int state;
int ret;
+ unsigned int caps;
dbus_error_init(&err);
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;
{
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);
{
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);
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);
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 },
{ "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 */
};
int ret, val;
static int state = false;
+ if (!find_display_feature("auto-brightness")) {
+ _D("auto brightness is not supported!");
+ return;
+ }
+
if (state)
return;
DBusError err;
int ret;
char *screen;
-
+ pid_t pid;
ret = dbus_message_is_signal(msg, DEVICED_INTERFACE_NAME,
SIGNAL_HOMESCREEN);
_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)
_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);
_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);
# 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
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
# 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
# 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
+
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;
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
--- /dev/null
+[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
+
#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"
#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,
}
}
+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];
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;
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;
_E("fail to set touch screen glove mode (%d)", val);
goto error;
}
+ broadcast_glove_mode(val);
error:
reply = dbus_message_new_method_return(msg);
#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;
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;
}
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);
}
{
/* 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 = {
--- /dev/null
+/*
+ * 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
#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>
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;
* 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)
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;
}
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;
}
}
_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);
#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
#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)
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;
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)) {
}
opt = POWEROFF_ACT;
entry_call:
- notify_action(opt, 0);
+ power_execute(opt);
}
static Eina_Bool longkey_pressed_cb(void *data)
*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())
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;
}
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;
}
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 */
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);
}
{
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:
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);
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;
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) {
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;
}
break;
case KEY_VOLUMEUP:
+ case KEY_VOLUMEDOWN:
case KEY_CAMERA:
case KEY_EXIT:
case KEY_CONFIG:
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;
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
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!!");
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!");
_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");
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");
/* 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) {
enum {
INTERNAL_LOCK_BASE = 100000,
+ INTERNAL_LOCK_ALPM,
INTERNAL_LOCK_BATTERY,
INTERNAL_LOCK_BOOTING,
INTERNAL_LOCK_DUMPMODE,
INTERNAL_LOCK_TA,
INTERNAL_LOCK_TIME,
INTERNAL_LOCK_USB,
+ INTERNAL_LOCK_POWEROFF,
+ INTERNAL_LOCK_COOL_DOWN,
};
#define SIGNAL_NAME_LCD_CONTROL "lcdcontol"
#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,
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!");
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)
}
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;
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,
#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
/* 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
--- /dev/null
+/*
+ * 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)
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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, ¤tFat);
+
+ 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#ifndef _FS_UTIL_H
+#define _FS_UTIL_H
+
+#define pwarn printf
+#define pfatal printf
+
+#endif
--- /dev/null
+/*
+ * 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';
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
#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;
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);
}
-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!!!");
{
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;
}
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)
#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__
--- /dev/null
+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.
}
static const struct haptic_ops ext_ops = {
+ .type = HAPTIC_EXTERNAL,
.is_valid = is_valid,
.load = load,
.release = release,
--- /dev/null
+[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
--- /dev/null
+[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
#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))
/* 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);
if (ops->is_valid && ops->is_valid()) {
if (ops->load)
h_ops = ops->load();
+ h_type = ops->type;
break;
}
}
}
/* 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;
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;
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,
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;
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,
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;
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;
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;
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;
}
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 },
{
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)
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;
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);
#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;
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;
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));
}
}
- /* 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;
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;
}
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;
}
{
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;
}
}
static const struct haptic_ops std_ops = {
+ .type = HAPTIC_STANDARD,
.is_valid = is_valid,
.load = load,
};
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * 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__ */
+
+
--- /dev/null
+/*
+ * 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);
+ }
+}
*/
-#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;
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
--- /dev/null
+[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
#include <vconf.h>
#include "deviced/dd-led.h"
-#include "xml.h"
#include "core/log.h"
#include "core/common.h"
#include "core/edbus-handler.h"
#include "core/device-notifier.h"
#include "core/device-handler.h"
#include "display/core.h"
+#include "conf.h"
#define BOOT_ANIMATION_FINISHED 1
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)
{
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;
}
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;
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);
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;
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)
_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;
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);
_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);
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 */
static void rgb_init(void *data)
{
- int ta_connected, boot;
+ int ta_connected, boot, psmode;
int ret;
struct led_mode *led;
/* 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)
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,
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);
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);
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",
+++ /dev/null
-/*
- * 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);
- }
-}
battery.c
control.c
display.c
+ dbus.c
haptic.c
led.c
mmc.c
vconf
dlog
dbus-1
+ dbus-glib-1
edbus)
FOREACH(flag ${libpkgs_CFLAGS})
# 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
--- /dev/null
+/*
+ * 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, ¶m[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();
+}
#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"
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;
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);
if (cmdline_size < strlen(filename) + 1) {
errno = EOVERFLOW;
- return -1;
+ return -EOVERFLOW;
}
strncpy(cmdline, filename, cmdline_size - 1);
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));
p = STR_NULL;
pa[2] = p;
- if (timeout < 0)
- return -EINVAL;
-
snprintf(str_timeout, sizeof(str_timeout), "%d", timeout);
pa[3] = str_timeout;
API int led_set_ir_command(char *value)
{
+ if (value == NULL) {
+ return -EINVAL;
+ }
+
DBusError err;
DBusMessage *msg;
char *arr[1];
#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,
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,
DEVICED_PATH_MMC,
DEVICED_INTERFACE_MMC,
METHOD_REQUEST_FORMAT,
- "i", arr, format_cb, -1, data);
+ "i", arr, format_cb, FORMAT_TIMEOUT, data);
}
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+#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;
+}
--- /dev/null
+#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");
+ }
+}
--- /dev/null
+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)
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
+
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
--- /dev/null
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_PROVIDED_LIBS@
+Cflags: @PC_CFLAGS@
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+#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);
+}
+
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
--- /dev/null
+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)
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+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)
--- /dev/null
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_PROVIDED_LIBS@
+Cflags: @PC_CFLAGS@
--- /dev/null
+#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;
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+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)
--- /dev/null
+#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;
+}
+
--- /dev/null
+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)
--- /dev/null
+/* 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
--- /dev/null
+#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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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_ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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)
+);
--- /dev/null
+#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;
+}
--- /dev/null
+#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__ */
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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__ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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__ */
--- /dev/null
+#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)
--- /dev/null
+#ifndef __LOGD_GRABBER_H__
+#define __LOGD_GRABBER_H__
+
+#include <logd.h>
+#include <time.h>
+
+#endif /* __LOGD_GRABBER_H__ */
--- /dev/null
+#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;
+}
--- /dev/null
+#ifndef __MMC_H__
+#define __MMC_H__
+
+int mmc_init();
+float mmc_power_cons();
+
+#endif /* __MMC_H__ */
--- /dev/null
+#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;
+}
--- /dev/null
+#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__ */
--- /dev/null
+#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);
+}
--- /dev/null
+#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__ */
+
--- /dev/null
+/*
+ * 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);
+}
+*/
#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;
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:
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);
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");
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);
#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,
static char *mmc_curpath;
static bool smack = false;
static bool mmc_disabled = false;
+static Ecore_Timer *smack_timer = NULL;
int __WEAK__ app2ext_unmount(void);
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");
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);
}
nbytes = ullbytes/512;
- _D("block size(64) : %d", nbytes);
+ _I("block size(64) : %d", nbytes);
return nbytes;
}
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;
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);
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 */
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);
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)
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;
if (r < 0)
_I("Faild to unmount app2ext : %s", strerror(-r));
+ ode_mmc_removed();
r = mmc_check_and_unmount(mount_point);
if (!r)
break;
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;
/* 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);
}
}
- _D("mount path : %s", path);
+ _I("mount path : %s", path);
ret = mmc_mount(mmc_curpath, path);
error:
goto error;
}
- _D("unmount path : %s", path);
+ _I("unmount path : %s", path);
ret = mmc_unmount(UNMOUNT_NORMAL, path);
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)
{ "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)
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;
}
#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
int mmc_uevent_start(void);
int mmc_uevent_stop(void);
int get_block_number(void);
+
+void mmc_mount_done(void);
#endif /* __MMC_HANDLER_H__ */
#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[] = {
return false;
}
- _D("MMC type : %s", vfat_info.name);
+ _I("MMC type : %s", vfat_info.name);
return true;
}
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);
/*
static void __DESTRUCTOR__ module_exit(void)
{
- _D("module exit");
+ _I("module exit");
remove_fs(&vfat_ops);
}
*/
--- /dev/null
+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})
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
*/
-#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
--- /dev/null
+/*
+ * 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)
*/
-#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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
* 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__ */
/*
- * 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__ */
--- /dev/null
+[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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
*/
-#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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+# 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]
--- /dev/null
+/*
+ * 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__ */
#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
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;
/* 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 },
{ "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 },
{ "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)
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)
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 = {
#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"
#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
#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;
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;
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);
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)
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;
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;
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;
}
{
int retry = 0;
sync();
+#ifdef MICRO_DD
if (!mount_check(UMOUNT_RW_PATH))
return;
+#endif
while (1) {
switch (retry++) {
case 0:
_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;
if (check_duration < 0)
break;
}
+#ifndef EMULATOR
unmount_rw_partition();
+#endif
}
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");
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);
void restart_ap(void *data)
{
_I("Restart %d", (int)data);
+ journal_system_device_reboot((int)data);
powerdown();
restart_by_mode((int)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 */
};
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);
}
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)
#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
#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"
#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"
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;
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,
_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;
}
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)
/* 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;
_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);
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)
--- /dev/null
+/*
+ * 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)
#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);
}
--- /dev/null
+/*
+ * 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__
#include "core/log.h"
#include "core/launch.h"
-#include "core/data.h"
#include "core/common.h"
#include "core/devices.h"
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)
{
_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;
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;
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];
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");
}
}
#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"
SIOP_POSITIVE = 1,
};
+struct siop_data {
+ int siop;
+ int rear;
+};
+
static int siop = 0;
static int mode = 0;
static int siop_domain = SIOP_POSITIVE;
static int siop_changed(int argc, char **argv)
{
-#ifdef MICRO_DD
- return 0;
-#else
int siop_level = 0;
int rear_level = 0;
int level;
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)
_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 },
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;
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)
#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);
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <stdint.h>
#include <errno.h>
char *ch;
int i;
int int_type;
+ dbus_bool_t bool_type;
uint64_t int64_type;
DBusMessageIter arr;
struct dbus_byte *byte;
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);
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[])
return -ECOMM;
}
+ dbus_message_unref(msg);
+
if (cb && pending) {
pdata = malloc(sizeof(struct pending_call_data));
if (!pdata)
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;
}
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();
#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
*/
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[]);
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
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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__ */
#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,
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;
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)
{
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");
{
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;
}
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;
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)
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);
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;
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);
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;
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));
--- /dev/null
+[LOWSTORAGE]
+#5%
+WARNING_LEVEL=5
+#0.1%
+CRITICAL_LEVEL=0.1
+#0.0%
+FULL_LEVEL=0
#include <device-node.h>
#include "core/log.h"
-#include "core/data.h"
#include "core/devices.h"
#include "display/poll.h"
#include "core/common.h"
#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>
#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"
return EINA_TRUE;
}
-static int telephony_start(void)
+static int telephony_start(enum device_flags flags)
{
int ready = 0;
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");
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);
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,
_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;
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;
}
if (tapi_handle == NULL) {
- if (telephony_start() != 0)
+ if (telephony_start(NORMAL_MODE) != 0)
_E("fail to get tapi handle");
}
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)
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 */
};
#include "core/common.h"
-#include "core/data.h"
enum ticker_type {
WITHOUT_QUEUE, /* for usb client */
--- /dev/null
+/*
+ * 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, ¶m[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);
+}
/*
- * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
#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"
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");
}
/* 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);
return 0;
}
-static int touch_start(void)
+static int touch_start(enum device_flags flags)
{
int i;
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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)
+
+++ /dev/null
-<?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>
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<usb-config>
- <config-nodes>
-
- <driver value="/sys/class/usb_mode/version"/>
-
- <usb-drv ver="1.1 ">
- <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 ">
- <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 ">
- <!-- 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 ">
- <!-- 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>
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+[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
--- /dev/null
+[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
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;
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)
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;
*/
#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;
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:
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));
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+[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
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;
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;
}
}
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)
_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;
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)
}
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);
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;
+++ /dev/null
-/*
- * 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;
-}
#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;
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;
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)
/*************************************************/
/* 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:
_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;
}
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;
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;
default:
break;
}
-
- release_supported_confs_list();
- release_configuration_list();
}
static int init_client(void)
if (ret < 0)
return ret;
- ret = init_client_values();
- if (ret < 0)
- return ret;
-
return 0;
}
return 0;
}
-#ifdef MICRO_DD
void act_usb_connected(void)
{
wait_configured = false;
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)
{
{
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)
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)
#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);
/* 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);
void change_client_setting(int options);
bool get_wait_configured(void);
+/* For SDK */
+void usb_state_changed(int state);
+
#endif /* __USB_CLIENT_H__ */
+++ /dev/null
-/*
- * 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)
remove_non_alphabet(name);
- change_to_short(name, strlen(name));
+ change_to_short(name, sizeof(name));
snprintf(buf, len, "%s", name);
return 0;
remove_non_alphabet(name);
- change_to_short(name, strlen(name));
+ change_to_short(name, sizeof(name));
remove_vendor(name, vendor);
--- /dev/null
+/*
+ * 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);
+}
};
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)
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");
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
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;
+++ /dev/null
-#!/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
+++ /dev/null
-#!/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
+++ /dev/null
-#!/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
+++ /dev/null
-#!/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
+++ /dev/null
-PKG_NAME=deviced
-TET_INSTALL_HOST_PATH=/var/tmp/dts_fw/TETware
-TET_INSTALL_TARGET_PATH=/opt/home/TETware
+++ /dev/null
-#!/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
+++ /dev/null
-#!/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
+++ /dev/null
-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)
+++ /dev/null
-/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
-
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-/*
- *
- * 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");
-}
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-/*
- *
- * 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);
-}
+++ /dev/null
-all
- ^TEST
-##### Scenarios for TEST #####
-
-# Test scenario
-TEST
- :include:/testcase/tslist
+++ /dev/null
-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?
+++ /dev/null
-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
+++ /dev/null
-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 ?