diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 96b7b30..52dafa8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,14 @@ pkg_check_modules(GLIB2 REQUIRED glib-2.0) include_directories(${GLIB2_INCLUDE_DIRS}) webos_add_compiler_flags(ALL ${GLIB2_CFLAGS_OTHER}) +pkg_check_modules(GIO REQUIRED gio-2.0) +include_directories(${GIO_INCLUDE_DIRS}) +webos_add_compiler_flags(ALL ${GIO_CFLAGS_OTHER}) + +pkg_check_modules(UDEV REQUIRED libudev) +include_directories(${UDEV_INCLUDE_DIRS}) +webos_add_compiler_flags(ALL ${UDEV_CFLAGS_OTHER}) + pkg_check_modules(NYXLIB REQUIRED nyx) include_directories(${NYXLIB_INCLUDE_DIRS}) webos_add_compiler_flags(ALL ${NYXLIB_CFLAGS_OTHER}) @@ -69,7 +77,7 @@ endif() macro(nyx_create_module module) add_library(${module} MODULE ${ARGN}) - target_link_libraries(${module} ${GLIB2_LDFLAGS} ${NYXLIB_LDFLAGS} -lrt -lpthread) + target_link_libraries(${module} ${GLIB2_LDFLAGS} ${GIO_LDFLAGS} ${UDEV_LDFLAGS} ${NYXLIB_LDFLAGS} -lrt -lpthread) install(TARGETS ${module} DESTINATION ${NYX_MODULE_DIR}) endmacro() diff --git a/src/rockhopper/battery/CMakeLists.txt b/src/rockhopper/battery/CMakeLists.txt index 0e04c5f..ec141d0 100644 --- a/src/rockhopper/battery/CMakeLists.txt +++ b/src/rockhopper/battery/CMakeLists.txt @@ -18,6 +18,9 @@ include_directories(.) -nyx_create_module(BatteryMain batterylib.c emulator/fake_battery.c) -install(FILES emulator/fake_battery_values.sh DESTINATION "/usr/sbin") - +if(${WEBOS_TARGET_MACHINE_IMPL} STREQUAL emulator) + nyx_create_module(BatteryMain fileutils.c batterylib.c emulator/fake_battery.c) + install(FILES emulator/fake_battery_values.sh DESTINATION "/usr/sbin") +elseif(${WEBOS_TARGET_MACHINE_IMPL} STREQUAL device) + nyx_create_module(BatteryMain fileutils.c batterylib.c device/battery.c) +endif() diff --git a/src/rockhopper/battery/device/battery.c b/src/rockhopper/battery/device/battery.c new file mode 100644 index 0000000..5970e2f --- /dev/null +++ b/src/rockhopper/battery/device/battery.c @@ -0,0 +1,290 @@ +/* @@@LICENSE +* +* Copyright (c) 2010-2012 Hewlett-Packard Development Company, L.P. +* Copyright (c) 2012 Simon Busch +* +* 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. +* +* LICENSE@@@ */ + + +/** +* @file fake_battery.c +* +* @brief Interface for reading all the battery registers in case of qemux86 or using fake batteries. +* +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "batterylib.h" +#include "battery_read.h" +#include "fileutils.h" + +#include + +#include +#include + +#define LOG_DOMAIN "common_linux_battery: " + +#define CHARGE_MIN_TEMPERATURE_C 0 +#define CHARGE_MAX_TEMPERATURE_C 57 +#define BATTERY_MAX_TEMPERATURE_C 60 + +nyx_battery_ctia_t battery_ctia_params; + +GIOChannel *channel; + +struct udev *udev; +struct udev_monitor *mon; + +extern nyx_device_t *nyxDev; +extern void *battery_callback_context; +extern nyx_device_callback_function_t battery_callback; + +nyx_battery_ctia_t *get_battery_ctia_params(void) +{ + battery_ctia_params.charge_min_temp_c=0; + battery_ctia_params.charge_max_temp_c=CHARGE_MAX_TEMPERATURE_C; + battery_ctia_params.battery_crit_max_temp=BATTERY_MAX_TEMPERATURE_C; + battery_ctia_params.skip_battery_authentication=true; + + return &battery_ctia_params; +} + +/** + * @brief Read battery percentage + * + * @retval Battery percentage (integer) + */ +int battery_percent(void) +{ + int now, full; + int capacity; + + /* try capacity node first but keep in mind it's not supported by all power class + * devices */ + if (!g_file_test(BATTERY_SYSFS_PATH "capacity", G_FILE_TEST_EXISTS) || + FileGetInt(BATTERY_SYSFS_PATH "capacity", &capacity) < 0) + { + /* capacity node is not available so next try is energy_now/energy_full */ + if (g_file_test(BATTERY_SYSFS_PATH "energy_now", G_FILE_TEST_EXISTS) && + g_file_test(BATTERY_SYSFS_PATH "energy_full", G_FILE_TEST_EXISTS)) + { + if (FileGetInt(BATTERY_SYSFS_PATH "energy_now", &now) < 0) + return -1; + + if (FileGetInt(BATTERY_SYSFS_PATH "energy_full", &full) < 0) + return -1; + + capacity = (now / full); + } + /* as last try we can use charge_full or charge_now */ + else if (g_file_test(BATTERY_SYSFS_PATH "charge_full", G_FILE_TEST_EXISTS) && + g_file_test(BATTERY_SYSFS_PATH "charge_now", G_FILE_TEST_EXISTS)) + { + if (FileGetInt(BATTERY_SYSFS_PATH "charge_full", &full) < 0) + return -1; + + if (FileGetInt(BATTERY_SYSFS_PATH "charge_now", &now) < 0) + return -1; + + capacity = (now / full); + } + else + { + return -1; + } + } + + return capacity; +} +/** + * @brief Read battery temperature + * + * @retval Battery temperature (integer) + */ +int battery_temperature(void) +{ + int temp; + + if (!g_file_test(BATTERY_SYSFS_PATH "temp", G_FILE_TEST_EXISTS) || + FileGetInt(BATTERY_SYSFS_PATH "temp", &temp) < 0) + return -1; + + return temp; +} + +/** + * @brief Read battery voltage + * + * @retval Battery voltage (integer) + */ + +int battery_voltage(void) +{ + int voltage; + + if (!g_file_test(BATTERY_SYSFS_PATH "voltage_now", G_FILE_TEST_EXISTS) || + FileGetInt(BATTERY_SYSFS_PATH "voltage_now", &voltage) < 0) + return -1; + + return voltage; +} + +/** + * @brief Read the amount of current being drawn by the battery. + * + * @retval Current (integer) + */ +int battery_current(void) +{ + return -1; +} + +/** + * @brief Read average current being drawn by the battery. + * + * @retval Current (integer) + */ + +int battery_avg_current(void) +{ + return -1; +} + +/** + * @brief Read battery full capacity + * + * @retval Battery capacity (double) + */ +double battery_full40(void) +{ + int energy_full; + + if (g_file_test(BATTERY_SYSFS_PATH "energy_full", G_FILE_TEST_EXISTS) && + FileGetInt(BATTERY_SYSFS_PATH "energy_full", &energy_full) < 0) + return -1; + + return (double) energy_full; +} + +/** + * @brief Read battery current raw capacity + * + * @retval Battery capacity (double) + */ + +double battery_rawcoulomb(void) +{ + return -1; +} + +/** + * @brief Read battery current capacity + * + * @retval Battery capacity (double) + */ + +double battery_coulomb(void) +{ + return -1; +} + +/** + * @brief Read battery age + * + * @retval Battery age (double) + */ +double battery_age(void) +{ + return -1; +} + + +bool battery_is_present(void) +{ + int present; + + /* We can either take present or online property into account */ + if (!g_file_test(BATTERY_SYSFS_PATH "present", G_FILE_TEST_EXISTS) || + FileGetInt(BATTERY_SYSFS_PATH "present", &present) < 0) + { + if (!g_file_test(BATTERY_SYSFS_PATH "online", G_FILE_TEST_EXISTS) || + FileGetInt(BATTERY_SYSFS_PATH "online", &present) < 0) + { + return -1; + } + } + + return present == 1 ? true : false; +} + +gboolean _handle_event(GIOChannel *channel, GIOCondition condition, gpointer data) +{ + struct udev_device *dev; + + if ((condition & G_IO_IN) == G_IO_IN) { + dev = udev_monitor_receive_device(mon); + if (dev) { + battery_callback(nyxDev, NYX_CALLBACK_STATUS_DONE, battery_callback_context); + } + } + + return TRUE; +} + +void battery_read_init(void) +{ + int fd; + + udev = udev_new(); + if (!udev) { + nyx_error("Could not initialize udev component; battery status updates will not be available"); + return; + } + + mon = udev_monitor_new_from_netlink(udev, "kernel"); + udev_monitor_filter_add_match_subsystem_devtype(mon, "power_supply", NULL); + udev_monitor_enable_receiving(mon); + fd = udev_monitor_get_fd(mon); + + channel = g_io_channel_unix_new(fd); + g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_NVAL, _handle_event, NULL); +} + +bool battery_is_authenticated(const char *pair_challenge, const char *pair_response) +{ + /* not supported */ + return true; +} + +bool battery_authenticate(void) +{ + /* not supported */ + return true; +} + +void battery_set_wakeup_percent(int percentage) +{ + /* no supported */ + return; +} + diff --git a/src/rockhopper/battery/emulator/fake_battery.c b/src/rockhopper/battery/emulator/fake_battery.c index 0db0ba3..4a26f90 100644 --- a/src/rockhopper/battery/emulator/fake_battery.c +++ b/src/rockhopper/battery/emulator/fake_battery.c @@ -34,6 +34,7 @@ #include "batterylib.h" #include "battery_read.h" +#include "fileutils.h" #include @@ -55,96 +56,6 @@ #define CHARGE_MAX_TEMPERATURE_C 57 #define BATTERY_MAX_TEMPERATURE_C 60 -/** - * Returns string in pre-allocated buffer. - */ - -int -FileGetString(const char *path, char *ret_string, size_t maxlen) -{ - GError *gerror = NULL; - char *contents = NULL; - gsize len; - - if (!path || !g_file_get_contents(path, &contents, &len, &gerror)) { - if (gerror) { - nyx_critical( "%s: %s", __FUNCTION__, gerror->message); - g_error_free(gerror); - } - return -1; - } - - g_strstrip(contents); - g_strlcpy(ret_string, contents, maxlen); - - g_free(contents); - - return 0; -} - -int -FileGetInt(const char *path, int *ret_data) -{ - GError *gerror = NULL; - char *contents = NULL; - char *endptr; - gsize len; - long int val; - - if (!path || !g_file_get_contents(path, &contents, &len, &gerror)) { - if (gerror) { - nyx_critical( "%s: %s", __FUNCTION__, gerror->message); - g_error_free(gerror); - } - return -1; - } - - val = strtol(contents, &endptr, 10); - if (endptr == contents) { - nyx_critical( "%s: Invalid input in %s.", - __FUNCTION__, path); - goto end; - } - - if (ret_data) - *ret_data = val; -end: - g_free(contents); - return 0; -} - -int -FileGetDouble(const char *path, double *ret_data) -{ - GError *gerror = NULL; - char *contents = NULL; - char *endptr; - gsize len; - float val; - - if (!path || !g_file_get_contents(path, &contents, &len, &gerror)) { - if (gerror) { - nyx_critical( "%s: %s", __FUNCTION__, gerror->message); - g_error_free(gerror); - } - return -1; - } - - val = strtod(contents, &endptr); - if (endptr == contents) { - nyx_critical( "%s: Invalid input in %s.", - __FUNCTION__, path); - goto end; - } - - if (ret_data) - *ret_data = val; -end: - g_free(contents); - return 0; -} - - nyx_battery_ctia_t battery_ctia_params; nyx_battery_ctia_t *get_battery_ctia_params(void) diff --git a/src/rockhopper/battery/fileutils.c b/src/rockhopper/battery/fileutils.c new file mode 100644 index 0000000..84218cc --- /dev/null +++ b/src/rockhopper/battery/fileutils.c @@ -0,0 +1,123 @@ +/* @@@LICENSE +* +* Copyright (c) 2010-2012 Hewlett-Packard Development Company, L.P. +* +* 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. +* +* LICENSE@@@ */ + +/** +* @file fileutils.c +* +* @brief Common methods to read values from a file. +* +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * Returns string in pre-allocated buffer. + */ + +int +FileGetString(const char *path, char *ret_string, size_t maxlen) +{ + GError *gerror = NULL; + char *contents = NULL; + gsize len; + + if (!path || !g_file_get_contents(path, &contents, &len, &gerror)) { + if (gerror) { + nyx_critical( "%s: %s", __FUNCTION__, gerror->message); + g_error_free(gerror); + } + return -1; + } + + g_strstrip(contents); + g_strlcpy(ret_string, contents, maxlen); + + g_free(contents); + + return 0; +} + +int +FileGetInt(const char *path, int *ret_data) +{ + GError *gerror = NULL; + char *contents = NULL; + char *endptr; + gsize len; + long int val; + + if (!path || !g_file_get_contents(path, &contents, &len, &gerror)) { + if (gerror) { + nyx_critical( "%s: %s", __FUNCTION__, gerror->message); + g_error_free(gerror); + } + return -1; + } + + val = strtol(contents, &endptr, 10); + if (endptr == contents) { + nyx_critical( "%s: Invalid input in %s.", + __FUNCTION__, path); + goto end; + } + + if (ret_data) + *ret_data = val; +end: + g_free(contents); + return 0; +} + +int +FileGetDouble(const char *path, double *ret_data) +{ + GError *gerror = NULL; + char *contents = NULL; + char *endptr; + gsize len; + float val; + + if (!path || !g_file_get_contents(path, &contents, &len, &gerror)) { + if (gerror) { + nyx_critical( "%s: %s", __FUNCTION__, gerror->message); + g_error_free(gerror); + } + return -1; + } + + val = strtod(contents, &endptr); + if (endptr == contents) { + nyx_critical( "%s: Invalid input in %s.", + __FUNCTION__, path); + goto end; + } + + if (ret_data) + *ret_data = val; +end: + g_free(contents); + return 0; +} diff --git a/src/rockhopper/battery/fileutils.h b/src/rockhopper/battery/fileutils.h new file mode 100644 index 0000000..3aa65a4 --- /dev/null +++ b/src/rockhopper/battery/fileutils.h @@ -0,0 +1,30 @@ +/* @@@LICENSE +* +* Copyright (c) 2010-2012 Hewlett-Packard Development Company, L.P. +* +* 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. +* +* LICENSE@@@ */ + +/** + * @file fileutils.h + */ + +#ifndef FILEUTILS_H_ +#define FILEUTILS_H_ + +int FileGetString(const char *path, char *ret_string, size_t maxlen); +int FileGetInt(const char *path, int *ret_data); +int FileGetDouble(const char *path, double *ret_data); + +#endif