From 96e3c420374a7f7ed8f9bbe43fe87246ae451ebe Mon Sep 17 00:00:00 2001 From: scott park Date: Sat, 22 Jul 2017 20:30:21 +0900 Subject: [PATCH 01/16] The Initial Haptic (drv2605l) HAL for RPI3 Implemented using PIO (Peripheral-io) - open_device, close_device, vibrate_monotone, stop_device Change-Id: Ifc26d9f1397bd38f92b2dccb3916ed1316dfd9bc Signed-off-by: scott park --- CMakeLists.txt | 2 + packaging/feedbackd.spec | 1 + src/haptic/gpio_haptic.c | 391 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 394 insertions(+) create mode 100755 src/haptic/gpio_haptic.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f39f17..00813c1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ SET(SRCS src/haptic/external.c src/haptic/emulator.c src/haptic/circle.c + src/haptic/gpio_haptic.c ) IF(STANDARD_MIX STREQUAL on) SET(SRCS ${SRCS} src/haptic/standard-mix.c) @@ -37,6 +38,7 @@ SET(PKG_MODULES capi-base-common gio-2.0 capi-system-info + capi-system-peripheral-io ) INCLUDE(FindPkgConfig) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 32b5c45..5e4ca81 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -24,6 +24,7 @@ BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(capi-system-peripheral-io) Requires(post): /usr/bin/vconftool diff --git a/src/haptic/gpio_haptic.c b/src/haptic/gpio_haptic.c new file mode 100755 index 0000000..a634f6c --- /dev/null +++ b/src/haptic/gpio_haptic.c @@ -0,0 +1,391 @@ +/* + * feedbackd + * + * Copyright (c) 2016 - 2017 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 +#include +#include + +#include "core/log.h" +#include "haptic.h" +#include "peripheral_io.h" +#include "peripheral_internal.h" +#include "standard-vibcore.h" + +#define GPIO_I2C_BUS_INDEX 1 +#define MAX_HAPIC 1 +#define DRV2605L_DEFAULT_ADDR 0x5A + +#define START_CMD_CODE 1 +#define STOP_CMD_CODE 0 + +#define DRV2605L_REGISTER_STATUS 0x00 +#define DRV2605L_REGISTER_MODE 0x01 +#define DRV2605L_REGISTER_RTPINPUT 0x02 +#define DRV2605L_REGISTER_LIBRARY 0x03 +#define DRV2605L_REGISTER_WAVESEQ1 0x04 +#define DRV2605L_REGISTER_WAVESEQ2 0x05 +#define DRV2605L_REGISTER_WAVESEQ3 0x06 +#define DRV2605L_REGISTER_WAVESEQ4 0x07 +#define DRV2605L_REGISTER_WAVESEQ5 0x08 +#define DRV2605L_REGISTER_WAVESEQ6 0x09 +#define DRV2605L_REGISTER_WAVESEQ7 0x0A +#define DRV2605L_REGISTER_WAVESEQ8 0x0B +#define DRV2605L_REGISTER_GO 0x0C + +/** + * Mode register + */ +#define MODE_INTERNAL_TRIGGER 0 +#define MODE_EXTERNAL_TRIGGER_EDGE 1 +#define MODE_EXTERNAL_TRIGGER_LEVEL 2 +#define MODE_PWM_INPUT_ANALOG_INPUT 3 +#define MODE_AUDIO_TO_VIBE 4 +#define MODE_REALTIME_PLAYBACK 5 +#define MODE_DIAGNOSTICS 6 +#define MODE_AUTO_CALIBRATION 7 +/** + * Library register + */ +#define EMPTY_LIBRARY 0 +#define TS2200_LIBRARY_A 1 +#define TS2200_LIBRARY_B 2 +#define TS2200_LIBRARY_C 3 +#define TS2200_LIBRARY_D 4 +#define TS2200_LIBRARY_E 5 +#define LRA_LIBRARY_E 6 +#define TS2200_LIBRARY_F 7 + +static peripheral_i2c_h device_handle = NULL; + +static dd_list *handle_list; +static int unique_number; + +static bool state = false; +//static bool is_playing = false; +static Ecore_Timer *stop_timer = NULL; + +static int gpio_haptic_stop_device(int handle); + +static bool find_from_list(int handle) +{ + dd_list *elem; + + elem = DD_LIST_FIND(handle_list, (gpointer)(long)handle); + if (elem) + return true; + + return false; +} + +/* START: Haptic Module APIs */ +static Eina_Bool gpio_haptic_timer_cb(void *data) +{ + int handle = (int)(long)data; + bool found; + + _I("stop vibration by timer"); + + found = find_from_list(handle); + if (!found) + return ECORE_CALLBACK_CANCEL; + + if (device_handle == NULL) { + if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to open I2C"); + return -EIO; + } + } + + /* stop playing */ + peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_INTERNAL_TRIGGER); + + stop_timer = NULL; + return ECORE_CALLBACK_CANCEL; +} + +static int gpio_haptic_get_device_count(int *count) +{ + _I("HAL: The max number of DRV2605L is %d", (int)MAX_HAPIC); + if (count) + *count = MAX_HAPIC; + + return 0; +} + +/** + * Only one handle + * return device_handle + */ +static int gpio_haptic_open_device(int device_index, int *handle) +{ + int n; + bool found = false; + dd_list *elem; + + if (!handle) + return -EINVAL; + + /* if it is the first element */ + n = DD_LIST_LENGTH(handle_list); + if (n == 0) { + _I("Peripheral Device Open"); + if (device_handle == NULL) { + if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to open I2C"); + return -EIO; + } + } + } + + if (unique_number == INT_MAX) + unique_number = 0; + + while (found != true) { + ++unique_number; + elem = DD_LIST_FIND(handle_list, (gpointer)(long)unique_number); + if (!elem) + found = true; + } + + /* add info to local list */ + DD_LIST_APPEND(handle_list, (gpointer)(long)unique_number); + + *handle = unique_number; + return 0; +} + +static int gpio_haptic_close_device(int handle) +{ + int r, n; + bool found; + + found = find_from_list(handle); + if (!found) + return -EINVAL; + + if (device_handle == NULL) { + if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to open I2C"); + return -EIO; + } + } + + /* stop vibration */ + r = gpio_haptic_stop_device(handle); + if (r < 0) + _I("already stopped or failed to stop effect : %d", r); + + /* unregister existing timer */ + if (r >= 0) { + if (stop_timer) { + ecore_timer_del(stop_timer); + stop_timer = NULL; + } + } + + standard_vibrate_close(); + + _D("handle %d is closed and timer deleted", handle); + DD_LIST_REMOVE(handle_list, (gpointer)(long)handle); + + /* if it is the last element */ + n = DD_LIST_LENGTH(handle_list); + if (n == 0) { + _I("Peripheral Device Close"); + if (device_handle != NULL) { + if (peripheral_i2c_close(device_handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to close peripheral I2C"); + return -EIO; + } + device_handle = NULL; + } + } + return 0; +} + +static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int priority, int *e_handle) +{ + bool found; + + found = find_from_list(handle); + if (!found) + return -EINVAL; + + if (device_handle == NULL) { + if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to open I2C"); + return -EIO; + } + } + + /* Zero(0) is the infinitely vibration value */ + if (duration == HAPTIC_MODULE_DURATION_UNLIMITED) + duration = 0; + + if (stop_timer) + gpio_haptic_stop_device(handle); + + /* play vibration */ + peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_LIBRARY, TS2200_LIBRARY_A); + /* continuously vibrate*/ + peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_REALTIME_PLAYBACK); + peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_RTPINPUT, (uint8_t)level); + + /* register timer */ + if (duration) { + stop_timer = ecore_timer_add(duration/1000.f, gpio_haptic_timer_cb, (void *)(long)handle); + if (!stop_timer) + _E("Failed to add timer callback"); + } + _D("device handle %d %dms", handle, duration); + + if (e_handle) + *e_handle = handle; + + return 0; +} + +static int gpio_haptic_stop_device(int handle) +{ + bool found; + + found = find_from_list(handle); + if (!found) + return -EINVAL; + + if (cur_h_data.handle > 0 && cur_h_data.handle != handle) { + _E("Only same handle can stop current vibration"); + return -EPERM; + } + + /* Remove duration_timer for vibrate_effect */ + standard_vibrate_close(); + + if (device_handle == NULL) { + if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to open I2C"); + return -EIO; + } + } + + /* stop playing */ + peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_INTERNAL_TRIGGER); + + if (stop_timer) { + ecore_timer_del(stop_timer); + stop_timer = NULL; + } + + return 0; +} + +static int gpio_haptic_get_device_state(int index, int *effect_state) +{ + if (!effect_state) + return -EINVAL; + + *effect_state = state; + return 0; +} + +static int gpio_haptic_vibrate_buffer(int handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle) +{ + _E("Not support feature"); + return -EACCES; +} + +static int gpio_haptic_create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt) +{ + _E("Not support feature"); + return -EACCES; +} + +static int gpio_haptic_get_buffer_duration(int handle, const unsigned char *vibe_buffer, int *buffer_duration) +{ + _E("Not support feature"); + return -EACCES; +} + +static int gpio_haptic_convert_binary(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path) +{ + _E("Not support feature"); + return -EACCES; +} +/* END: Haptic Module APIs */ + +static const struct haptic_plugin_ops default_plugin = { + .get_device_count = gpio_haptic_get_device_count, + .open_device = gpio_haptic_open_device, + .close_device = gpio_haptic_close_device, + .vibrate_monotone = gpio_haptic_vibrate_monotone, + .vibrate_buffer = gpio_haptic_vibrate_buffer, + .vibrate_effect = standard_vibrate_effect, + .is_supported = standard_is_supported, + .stop_device = gpio_haptic_stop_device, + .get_device_state = gpio_haptic_get_device_state, + .create_effect = gpio_haptic_create_effect, + .get_buffer_duration = gpio_haptic_get_buffer_duration, + .convert_binary = gpio_haptic_convert_binary, +}; + +static bool is_valid(void) +{ + uint8_t result; + peripheral_i2c_h handle; + int ret; + + if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to open I2C"); + state = false; + return false; + } + if(peripheral_i2c_read_register_byte(handle, DRV2605L_REGISTER_STATUS, &result) < PERIPHERAL_ERROR_NONE) { + _E("Failed to read peripheral I2C"); + if (peripheral_i2c_close(handle) < PERIPHERAL_ERROR_NONE) + _E("Failed to close peripheral I2C"); + state = false; + return false; + } + if (peripheral_i2c_close(handle) < PERIPHERAL_ERROR_NONE) { + _E("Failed to close peripheral I2C"); + state = false; + return false; + } + + ret = standard_config_parse(); + if (ret < 0) + _E("failed to load standard vibration configuration file : %d", ret); + + state = true; + _I("Support gpio haptic device"); + return true; +} + +static const struct haptic_plugin_ops *load(void) +{ + _I("gpio haptic device module loaded"); + standard_set_vib_function(&gpio_haptic_vibrate_monotone); + return &default_plugin; +} + +static const struct haptic_ops gpio_haptic_ops = { + .is_valid = is_valid, + .load = load, +}; + +HAPTIC_OPS_REGISTER(&gpio_haptic_ops) -- 2.7.4 From f813e843fc278807ffe71eafbde1110577cf331a Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Wed, 2 Aug 2017 17:30:02 +0900 Subject: [PATCH 02/16] Return valid handle in vibrate_monotone Change-Id: I513fc57e25782ff7a3d8153be7fb764f98efb1c6 Signed-off-by: pr.jung --- src/haptic/circle.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/haptic/circle.c b/src/haptic/circle.c index ec00101..2d99195 100644 --- a/src/haptic/circle.c +++ b/src/haptic/circle.c @@ -227,6 +227,8 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p } _D("device handle %d %dms", device_handle, duration); + if (effect_handle) + *effect_handle = device_handle; return 0; } -- 2.7.4 From 196cb33f1cbc29ba13edb5dd0b81d962964e5734 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Tue, 12 Sep 2017 11:33:56 +0900 Subject: [PATCH 03/16] Apply Tizen Coding Rule Change-Id: Ia7f9dc80a77e9a90df8f58219a568c56850ceff1 Signed-off-by: pr.jung --- src/haptic/gpio_haptic.c | 2 +- src/haptic/standard-vibcore.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/haptic/gpio_haptic.c b/src/haptic/gpio_haptic.c index a634f6c..d7ef955 100755 --- a/src/haptic/gpio_haptic.c +++ b/src/haptic/gpio_haptic.c @@ -354,7 +354,7 @@ static bool is_valid(void) state = false; return false; } - if(peripheral_i2c_read_register_byte(handle, DRV2605L_REGISTER_STATUS, &result) < PERIPHERAL_ERROR_NONE) { + if (peripheral_i2c_read_register_byte(handle, DRV2605L_REGISTER_STATUS, &result) < PERIPHERAL_ERROR_NONE) { _E("Failed to read peripheral I2C"); if (peripheral_i2c_close(handle) < PERIPHERAL_ERROR_NONE) _E("Failed to close peripheral I2C"); diff --git a/src/haptic/standard-vibcore.c b/src/haptic/standard-vibcore.c index df6278e..510b717 100644 --- a/src/haptic/standard-vibcore.c +++ b/src/haptic/standard-vibcore.c @@ -209,9 +209,9 @@ static Eina_Bool haptic_duration_play(void *data) duration_timer = ecore_timer_add((node->duration + node->wait)/1000.0f, haptic_duration_play, NULL); ret = real_vibrate_monotone(h_data->handle, node->duration, h_data->level, h_data->priority, NULL); - if (!next) { + if (!next) goto out; - } + break; } if (ret != 0) { -- 2.7.4 From 39af87ca3f3eaf5750c58bb31f4b0af840f4a909 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Fri, 29 Sep 2017 16:04:21 +0900 Subject: [PATCH 04/16] Coverity fixes. Signed-off-by: INSUN PYO Change-Id: If524dfd179eb01d40855e5e6570a488e759550c7 --- src/haptic/standard-mix.c | 4 ++-- src/haptic/standard.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/haptic/standard-mix.c b/src/haptic/standard-mix.c index 40bda76..800bb10 100644 --- a/src/haptic/standard-mix.c +++ b/src/haptic/standard-mix.c @@ -149,7 +149,7 @@ static bool check_fd(int *fd) return true; ffd = open(ff_path, O_RDWR); - if (ffd <= 0) + if (ffd < 0) return false; *fd = ffd; @@ -358,7 +358,7 @@ static int open_device(int device_index, int *device_handle) _I("First element: open ff driver"); /* open ff driver */ ff_fd = open(ff_path, O_RDWR); - if (!ff_fd) { + if (ff_fd < 0) { _E("Failed to open %s : %d", ff_path, errno); return -errno; } diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 21bd343..2a914ca 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -111,7 +111,7 @@ static bool check_fd(int *fd) return true; ffd = open(ff_path, O_RDWR); - if (ffd <= 0) + if (ffd < 0) return false; *fd = ffd; @@ -320,7 +320,7 @@ static int open_device(int device_index, int *device_handle) _I("First element: open ff driver"); /* open ff driver */ ff_fd = open(ff_path, O_RDWR); - if (!ff_fd) { + if (ff_fd < 0) { _E("Failed to open %s : %d", ff_path, errno); return -errno; } -- 2.7.4 From 83d62a90a4db7f4387cc9b826348c341426b4f63 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Fri, 13 Oct 2017 02:15:25 +0000 Subject: [PATCH 05/16] Coverity fixes. Signed-off-by: INSUN PYO Change-Id: I9201254a8076891148aadb9a6932bebaef4263a4 --- src/haptic/standard-vibcore.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/haptic/standard-vibcore.c b/src/haptic/standard-vibcore.c index 510b717..4e40c22 100644 --- a/src/haptic/standard-vibcore.c +++ b/src/haptic/standard-vibcore.c @@ -71,15 +71,14 @@ static int vibration_load_config(struct parse_result *result, void *user_data) } conf->pattern = strdup(result->name); - if (!conf->pattern) + if (!conf->pattern) { _E("fail to copy %s pattern data", result->name); + free(conf); + return -ENOMEM; + } value = result->value; - - if (!value) - len = 0; - else - len = strlen(value); + len = strlen(value); if (len == 0) { data = (struct duration_data *)malloc(sizeof(struct duration_data)); @@ -97,6 +96,7 @@ static int vibration_load_config(struct parse_result *result, void *user_data) return 0; } + /* value : 100D or 100D0W or 250D250W250D750W*/ do { data = (struct duration_data *)malloc(sizeof(struct duration_data)); if (!data) { @@ -112,26 +112,22 @@ static int vibration_load_config(struct parse_result *result, void *user_data) if (check) { *check = '\0'; data->duration = strtol(value, NULL, 10); - if (!value) - len = len - 1; - else - len = len - strlen(value) - 1; + len = len - strlen(value) - 1; value = check + 1; } + check = strchr(value, 'W'); if (check) { *check = '\0'; data->wait = strtol(value, NULL, 10); - if (!value) - len = len - 1; - else - len = len - strlen(value) - 1; + len = len - strlen(value) - 1; value = check + 1; } + DD_LIST_APPEND(conf->data, data); if (data->duration == 0 && data->wait == 0) break; - } while (value && len > 0); + } while (len > 0); DD_LIST_APPEND(vib_conf_list, conf); -- 2.7.4 From 5fd931604c9a453ebfae64f9f42d37fdd6e830ee Mon Sep 17 00:00:00 2001 From: Segwon Date: Thu, 21 Dec 2017 11:20:03 +0900 Subject: [PATCH 06/16] pio: can be included only peripheral-io.h Change-Id: I05cf2472f33c579182c39ca650d02016b0512747 Signed-off-by: Segwon --- src/haptic/gpio_haptic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/haptic/gpio_haptic.c b/src/haptic/gpio_haptic.c index d7ef955..314ca3b 100755 --- a/src/haptic/gpio_haptic.c +++ b/src/haptic/gpio_haptic.c @@ -23,7 +23,6 @@ #include "core/log.h" #include "haptic.h" #include "peripheral_io.h" -#include "peripheral_internal.h" #include "standard-vibcore.h" #define GPIO_I2C_BUS_INDEX 1 -- 2.7.4 From 96eabab73a6b18b94fe3e6e1766ed21e2527aa38 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Thu, 21 Dec 2017 17:17:14 +0900 Subject: [PATCH 07/16] Remove tizen_build_devel_mode in the spec Change-Id: Ie46190e2be39e83877e3f63eeaf72c38e700bd28 Signed-off-by: Hyotaek Shim --- packaging/feedbackd.spec | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 5e4ca81..6aa2e72 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -59,12 +59,6 @@ Deviced binaries targeting wearable profile. Required by main deviced package %prep %setup -q -%if 0%{?tizen_build_devel_mode} == 1 -%define engineer_mode on -%else -%define engineer_mode off -%endif - # Build per profile # if profile = mobile or common or undefined mkdir -p build_mobile -- 2.7.4 From 0e5510e30ead3eb786f582e54c744df54e833c27 Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Thu, 21 Dec 2017 15:20:28 +0900 Subject: [PATCH 08/16] Seperate iot profile - GPIO_HAPTIC is used on iot profile Change-Id: I755261b3248ed30cea41a2d02c1aff12f0623a47 Signed-off-by: pr.jung --- CMakeLists.txt | 14 +++++----- packaging/feedbackd.spec | 67 +++++++++++++++++++++++++++++++++++++++------- src/haptic/haptic-iot.conf | 24 +++++++++++++++++ 3 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 src/haptic/haptic-iot.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index 00813c1..63c0854 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,8 @@ SET(SRCS src/haptic/external.c src/haptic/emulator.c src/haptic/circle.c - src/haptic/gpio_haptic.c ) + IF(STANDARD_MIX STREQUAL on) SET(SRCS ${SRCS} src/haptic/standard-mix.c) ELSE() @@ -38,9 +38,13 @@ SET(PKG_MODULES capi-base-common gio-2.0 capi-system-info - capi-system-peripheral-io ) +IF(GPIO_HAPTIC STREQUAL on) + SET(SRCS ${SRCS} src/haptic/gpio_haptic.c) + SET(PKG_MODULES ${PKG_MODULES} capi-system-peripheral-io) +ENDIF() + INCLUDE(FindPkgConfig) pkg_check_modules(pkgs2 REQUIRED ${PKG_MODULES}) @@ -64,8 +68,4 @@ INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "feedbackd.service") -IF(PROFILE STREQUAL wearable) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/haptic-wearable.conf DESTINATION /etc/feedbackd) -ELSE() -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/haptic-mobile.conf DESTINATION /etc/feedbackd) -ENDIF() +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/haptic-${PROFILE}.conf DESTINATION /etc/feedbackd) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 6aa2e72..69e1a79 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -46,6 +46,7 @@ feedback daemon. Summary: Deviced binaries targeting mobile profile Provides: %{name}-compat = %{version}-%{release} Conflicts: %{name}-profile_wearable +Conflicts: %{name}-profile_iot %description profile_mobile Deviced binaries targeting mobile profile. Required by main deviced package # if profile = wearable or common or undefined @@ -53,8 +54,17 @@ Deviced binaries targeting mobile profile. Required by main deviced package Summary: Deviced binaries targeting wearable profile Provides: %{name}-compat = %{version}-%{release} Conflicts: %{name}-profile_mobile +Conflicts: %{name}-profile_iot %description profile_wearable Deviced binaries targeting wearable profile. Required by main deviced package +# if profile = iot or common or undefined +%package profile_iot +Summary: Deviced binaries targeting iot profile +Provides: %{name}-compat = %{version}-%{release} +Conflicts: %{name}-profile_mobile +Conflicts: %{name}-profile_wearable +%description profile_iot +Deviced binaries targeting iot profile. Required by main deviced package %prep %setup -q @@ -67,6 +77,7 @@ pushd build_mobile -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DPROFILE=mobile \ -DSTANDARD_MIX=%{standard_mix} \ + -DGPIO_HAPTIC=off \ #eol popd @@ -77,6 +88,19 @@ pushd build_wearable -DCMAKE_INSTALL_PREFIX=%{_prefix} \ -DPROFILE=wearable \ -DSTANDARD_MIX=%{standard_mix} \ + -DGPIO_HAPTIC=off \ + #eol +popd + +# Build per profile +# if profile = iot or common or undefined +mkdir -p build_iot +pushd build_iot +%cmake .. \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DPROFILE=iot \ + -DSTANDARD_MIX=%{standard_mix} \ + -DGPIO_HAPTIC=on \ #eol popd @@ -94,6 +118,11 @@ pushd build_wearable make %{?jobs:-j%jobs} popd +# if profile = iot or common or undefined +pushd build_iot +make %{?jobs:-j%jobs} +popd + %install rm -rf %{buildroot} # Build per profile @@ -109,17 +138,24 @@ pushd build_wearable mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.wearable popd -%install_service multi-user.target.wants feedbackd.service +# if profile = iot or common or undefined +pushd build_iot +%make_install +mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.iot +popd -%post profile_mobile -mv %{_bindir}/feedbackd.mobile %{_bindir}/feedbackd -mv %{_sysconfdir}/feedbackd/haptic-mobile.conf %{_sysconfdir}/feedbackd/haptic.conf +%install_service multi-user.target.wants feedbackd.service +%post systemctl daemon-reload if [ "$1" == "1" ]; then systemctl restart feedbackd.service fi +%post profile_mobile +mv %{_bindir}/feedbackd.mobile %{_bindir}/feedbackd +mv %{_sysconfdir}/feedbackd/haptic-mobile.conf %{_sysconfdir}/feedbackd/haptic.conf + %preun profile_mobile mv %{_bindir}/feedbackd %{_bindir}/feedbackd.mobile @@ -131,11 +167,6 @@ fi mv %{_bindir}/feedbackd.wearable %{_bindir}/feedbackd mv %{_sysconfdir}/feedbackd/haptic-wearable.conf %{_sysconfdir}/feedbackd/haptic.conf -systemctl daemon-reload -if [ "$1" == "1" ]; then - systemctl restart feedbackd.service -fi - %preun profile_wearable mv %{_bindir}/feedbackd %{_bindir}/feedbackd.wearable @@ -143,6 +174,17 @@ if [ "$1" == "0" ]; then systemctl stop feedbackd.service fi +%post profile_iot +mv %{_bindir}/feedbackd.iot %{_bindir}/feedbackd +mv %{_sysconfdir}/feedbackd/haptic-iot.conf %{_sysconfdir}/feedbackd/haptic.conf + +%preun profile_iot +mv %{_bindir}/feedbackd %{_bindir}/feedbackd.iot + +if [ "$1" == "0" ]; then + systemctl stop feedbackd.service +fi + %files -n feedbackd %manifest %{name}.manifest %license LICENSE @@ -161,3 +203,10 @@ fi %manifest %{name}.manifest %config %{_sysconfdir}/feedbackd/haptic-wearable.conf %{_bindir}/feedbackd.wearable + +%files profile_iot +%license LICENSE +%manifest %{name}.manifest +%config %{_sysconfdir}/feedbackd/haptic-iot.conf +%{_bindir}/feedbackd.iot + diff --git a/src/haptic/haptic-iot.conf b/src/haptic/haptic-iot.conf new file mode 100644 index 0000000..84271f1 --- /dev/null +++ b/src/haptic/haptic-iot.conf @@ -0,0 +1,24 @@ +[Haptic] +# level +# how much does the vibration level to subdivide. +# The max value of vibration level fixed at 100. +# The min value of vibration level fixed at 0. +level=6 + +[level0] +value=0 + +[level1] +value=20 + +[level2] +value=40 + +[level3] +value=60 + +[level4] +value=80 + +[level5] +value=100 -- 2.7.4 From 9adef843d11172a625a6e17b1688cf5a1ccff36e Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Fri, 19 Jan 2018 17:01:41 +0900 Subject: [PATCH 09/16] Seperate haptic driver rpms and configuration rpms Change-Id: I17321f88d8602c9d92071fd1bab8d203bb2fe1e0 Signed-off-by: pr.jung --- CMakeLists.txt | 23 +- packaging/feedbackd.spec | 277 +++++++++++++++------ .../haptic-level3.conf} | 0 .../haptic-level6.conf} | 0 src/haptic/haptic-iot.conf | 24 -- src/haptic/haptic.c | 2 + src/haptic/standard-vibcore.c | 2 - 7 files changed, 210 insertions(+), 118 deletions(-) rename src/haptic/{haptic-wearable.conf => conf/haptic-level3.conf} (100%) rename src/haptic/{haptic-mobile.conf => conf/haptic-level6.conf} (100%) delete mode 100644 src/haptic/haptic-iot.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index 63c0854..974f5a7 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,15 +16,20 @@ SET(SRCS src/core/log.c src/core/dbus.c src/haptic/haptic.c - src/haptic/external.c - src/haptic/emulator.c - src/haptic/circle.c ) -IF(STANDARD_MIX STREQUAL on) - SET(SRCS ${SRCS} src/haptic/standard-mix.c) -ELSE() +IF(DRIVER STREQUAL external) + SET(SRCS ${SRCS} src/haptic/external.c) +ELSEIF(DRIVER STREQUAL emulator) + SET(SRCS ${SRCS} src/haptic/emulator.c) +ELSEIF(DRIVER STREQUAL gpio) + SET(SRCS ${SRCS} src/haptic/gpio_haptic.c src/haptic/standard-vibcore.c) +ELSEIF(DRIVER STREQUAL standard) SET(SRCS ${SRCS} src/haptic/standard.c src/haptic/standard-vibcore.c) +ELSEIF(DRIVER STREQUAL circle) + SET(SRCS ${SRCS} src/haptic/circle.c src/haptic/standard-vibcore.c) +ELSEIF(DRIVER STREQUAL mix) + SET(SRCS ${SRCS} src/haptic/standard-mix.c) ENDIF() INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) @@ -40,8 +45,7 @@ SET(PKG_MODULES capi-system-info ) -IF(GPIO_HAPTIC STREQUAL on) - SET(SRCS ${SRCS} src/haptic/gpio_haptic.c) +IF(DRIVER STREQUAL gpio) SET(PKG_MODULES ${PKG_MODULES} capi-system-peripheral-io) ENDIF() @@ -68,4 +72,5 @@ INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "feedbackd.service") -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/haptic-${PROFILE}.conf DESTINATION /etc/feedbackd) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level3.conf DESTINATION /etc/feedbackd) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level6.conf DESTINATION /etc/feedbackd) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 69e1a79..8c2985e 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -29,7 +29,10 @@ BuildRequires: pkgconfig(capi-system-peripheral-io) Requires(post): /usr/bin/vconftool Requires: %{name}-compat = %{version}-%{release} -Recommends: %{name}-profile_mobile = %{version}-%{release} +Recommends: %{name}-driver-standard = %{version}-%{release} + +Requires: configuration-compat = %{version}-%{release} +Recommends: %{name}-conf-level6 = %{version}-%{release} %description feedback daemon @@ -41,107 +44,175 @@ Group: main %description feedbackd feedback daemon. -# if profile = mobile or common or undefined -%package profile_mobile -Summary: Deviced binaries targeting mobile profile +# if driver = external or undefined +%package driver-external +Summary: Feedbackd binaries targeting external plugin +Provides: %{name}-compat = %{version}-%{release} +Conflicts: %{name}-driver-emulator +Conflicts: %{name}-driver-gpio +Conflicts: %{name}-driver-standard +Conflicts: %{name}-driver-circle +%description driver-external +Feedbackd binaries with external plugin. Required by main feedbackd package +# if driver = emulator or undefined +%package driver-emulator +Summary: Feedbackd binaries targeting emulator plugin Provides: %{name}-compat = %{version}-%{release} -Conflicts: %{name}-profile_wearable -Conflicts: %{name}-profile_iot -%description profile_mobile -Deviced binaries targeting mobile profile. Required by main deviced package -# if profile = wearable or common or undefined -%package profile_wearable -Summary: Deviced binaries targeting wearable profile +Conflicts: %{name}-driver-external +Conflicts: %{name}-driver-gpio +Conflicts: %{name}-driver-standard +Conflicts: %{name}-driver-circle +%description driver-emulator +Feedbackd binaries with emulator plugin. Required by main feedbackd package +# if driver = gpio or undefined +%package driver-gpio +Summary: Feedbackd binaries targeting gpio plugin Provides: %{name}-compat = %{version}-%{release} -Conflicts: %{name}-profile_mobile -Conflicts: %{name}-profile_iot -%description profile_wearable -Deviced binaries targeting wearable profile. Required by main deviced package -# if profile = iot or common or undefined -%package profile_iot -Summary: Deviced binaries targeting iot profile +Conflicts: %{name}-driver-external +Conflicts: %{name}-driver-emulator +Conflicts: %{name}-driver-standard +Conflicts: %{name}-driver-circle +%description driver-gpio +Feedbackd binaries with gpio plugin. Required by main feedbackd package +# if driver = standard or undefined +%package driver-standard +Summary: Feedbackd binaries targeting emulator plugin Provides: %{name}-compat = %{version}-%{release} -Conflicts: %{name}-profile_mobile -Conflicts: %{name}-profile_wearable -%description profile_iot -Deviced binaries targeting iot profile. Required by main deviced package +Conflicts: %{name}-driver-external +Conflicts: %{name}-driver-emulator +Conflicts: %{name}-driver-gpio +Conflicts: %{name}-driver-circle +%description driver-standard +Feedbackd binaries with standard plugin. Required by main feedbackd package +# if driver = circle or undefined +%package driver-circle +Summary: Feedbackd binaries targeting circle plugin +Provides: %{name}-compat = %{version}-%{release} +Conflicts: %{name}-driver-external +Conflicts: %{name}-driver-emulator +Conflicts: %{name}-driver-gpio +Conflicts: %{name}-driver-standard +%description driver-circle +Feedbackd binaries with circle plugin. Required by main feedbackd package + +%package conf-level3 +Summary: Feedbackd configuration file +Provides: configuration-compat = %{version}-%{release} +Conflicts: %{name}-conf-level6 +%description conf-level3 +Feedbackd configuration file. + +%package conf-level6 +Summary: Feedbackd configuration file +Provides: configuration-compat = %{version}-%{release} +Conflicts: %{name}-conf-level3 +%description conf-level6 +Feedbackd configuration file. %prep %setup -q -# Build per profile -# if profile = mobile or common or undefined -mkdir -p build_mobile -pushd build_mobile +# Build per driver +# if driver = external or undefined +mkdir -p build_external +pushd build_external +%cmake .. \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DDRIVER=external \ + #eol +popd + +# if driver = emulator or undefined +mkdir -p build_emulator +pushd build_emulator +%cmake .. \ + -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DDRIVER=emulator \ + #eol +popd + +# if driver = gpio or undefined +mkdir -p build_gpio +pushd build_gpio %cmake .. \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ - -DPROFILE=mobile \ - -DSTANDARD_MIX=%{standard_mix} \ - -DGPIO_HAPTIC=off \ + -DDRIVER=gpio \ #eol popd -# if profile = wearable or common or undefined -mkdir -p build_wearable -pushd build_wearable +# if driver = standard or undefined +mkdir -p build_standard +pushd build_standard %cmake .. \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ - -DPROFILE=wearable \ - -DSTANDARD_MIX=%{standard_mix} \ - -DGPIO_HAPTIC=off \ + -DDRIVER=standard \ #eol popd -# Build per profile -# if profile = iot or common or undefined -mkdir -p build_iot -pushd build_iot +# if driver = circle or undefined +mkdir -p build_circle +pushd build_circle %cmake .. \ -DCMAKE_INSTALL_PREFIX=%{_prefix} \ - -DPROFILE=iot \ - -DSTANDARD_MIX=%{standard_mix} \ - -DGPIO_HAPTIC=on \ + -DDRIVER=circle \ #eol popd %build cp %{SOURCE1} . -# Build per profile -# if profile = mobile or common or undefined -pushd build_mobile +# Build per driver +# if driver = external or undefined +pushd build_external make %{?jobs:-j%jobs} popd -# if profile = wearable or common or undefined -pushd build_wearable +# if driver = emulator or undefined +pushd build_emulator make %{?jobs:-j%jobs} popd -# if profile = iot or common or undefined -pushd build_iot +# if driver = gpio or undefined +pushd build_gpio +make %{?jobs:-j%jobs} +popd + +# if driver = standard or undefined +pushd build_standard +make %{?jobs:-j%jobs} +popd + +# if driver = circle or undefined +pushd build_circle make %{?jobs:-j%jobs} popd %install rm -rf %{buildroot} -# Build per profile -# if profile = mobile or common or undefined -pushd build_mobile +# Build per driver +pushd build_external %make_install -mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.mobile +mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.external popd -# if profile = wearable or common or undefined -pushd build_wearable +pushd build_emulator %make_install -mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.wearable +mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.emulator popd -# if profile = iot or common or undefined -pushd build_iot +pushd build_gpio %make_install -mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.iot +mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.gpio +popd + +pushd build_standard +%make_install +mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.standard +popd + +pushd build_circle +%make_install +mv %{buildroot}%{_bindir}/feedbackd %{buildroot}%{_bindir}/feedbackd.circle popd %install_service multi-user.target.wants feedbackd.service @@ -152,39 +223,62 @@ if [ "$1" == "1" ]; then systemctl restart feedbackd.service fi -%post profile_mobile -mv %{_bindir}/feedbackd.mobile %{_bindir}/feedbackd -mv %{_sysconfdir}/feedbackd/haptic-mobile.conf %{_sysconfdir}/feedbackd/haptic.conf +%post driver-external +mv %{_bindir}/feedbackd.external %{_bindir}/feedbackd -%preun profile_mobile -mv %{_bindir}/feedbackd %{_bindir}/feedbackd.mobile +%preun driver-external +mv %{_bindir}/feedbackd %{_bindir}/feedbackd.external if [ "$1" == "0" ]; then systemctl stop feedbackd.service fi -%post profile_wearable -mv %{_bindir}/feedbackd.wearable %{_bindir}/feedbackd -mv %{_sysconfdir}/feedbackd/haptic-wearable.conf %{_sysconfdir}/feedbackd/haptic.conf +%post driver-emulator +mv %{_bindir}/feedbackd.emulator %{_bindir}/feedbackd -%preun profile_wearable -mv %{_bindir}/feedbackd %{_bindir}/feedbackd.wearable +%preun driver-emulator +mv %{_bindir}/feedbackd %{_bindir}/feedbackd.emulator if [ "$1" == "0" ]; then systemctl stop feedbackd.service fi -%post profile_iot -mv %{_bindir}/feedbackd.iot %{_bindir}/feedbackd -mv %{_sysconfdir}/feedbackd/haptic-iot.conf %{_sysconfdir}/feedbackd/haptic.conf +%post driver-gpio +mv %{_bindir}/feedbackd.gpio %{_bindir}/feedbackd -%preun profile_iot -mv %{_bindir}/feedbackd %{_bindir}/feedbackd.iot +%preun driver-gpio +mv %{_bindir}/feedbackd %{_bindir}/feedbackd.gpio if [ "$1" == "0" ]; then systemctl stop feedbackd.service fi +%post driver-standard +mv %{_bindir}/feedbackd.standard %{_bindir}/feedbackd + +%preun driver-standard +mv %{_bindir}/feedbackd %{_bindir}/feedbackd.standard + +if [ "$1" == "0" ]; then + systemctl stop feedbackd.service +fi + +%post driver-circle +mv %{_bindir}/feedbackd.circle %{_bindir}/feedbackd + +%preun driver-circle +mv %{_bindir}/feedbackd %{_bindir}/feedbackd.circle + +if [ "$1" == "0" ]; then + systemctl stop feedbackd.service +fi + +%post conf-level3 +mv %{_sysconfdir}/feedbackd/haptic-level3.conf %{_sysconfdir}/feedbackd/haptic.conf + +%post conf-level6 +mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.conf + %files -n feedbackd %manifest %{name}.manifest %license LICENSE @@ -192,21 +286,38 @@ fi %{_unitdir}/feedbackd.service %{_unitdir}/multi-user.target.wants/feedbackd.service -%files profile_mobile +%files driver-external +%license LICENSE +%manifest %{name}.manifest +%{_bindir}/feedbackd.external + +%files driver-emulator +%license LICENSE +%manifest %{name}.manifest +%{_bindir}/feedbackd.emulator + +%files driver-gpio +%license LICENSE +%manifest %{name}.manifest +%{_bindir}/feedbackd.gpio + +%files driver-standard +%license LICENSE +%manifest %{name}.manifest +%{_bindir}/feedbackd.standard + +%files driver-circle %license LICENSE %manifest %{name}.manifest -%config %{_sysconfdir}/feedbackd/haptic-mobile.conf -%{_bindir}/feedbackd.mobile +%{_bindir}/feedbackd.circle -%files profile_wearable +%files conf-level3 %license LICENSE %manifest %{name}.manifest -%config %{_sysconfdir}/feedbackd/haptic-wearable.conf -%{_bindir}/feedbackd.wearable +%config %{_sysconfdir}/feedbackd/haptic-level3.conf -%files profile_iot +%files conf-level6 %license LICENSE %manifest %{name}.manifest -%config %{_sysconfdir}/feedbackd/haptic-iot.conf -%{_bindir}/feedbackd.iot +%config %{_sysconfdir}/feedbackd/haptic-level6.conf diff --git a/src/haptic/haptic-wearable.conf b/src/haptic/conf/haptic-level3.conf similarity index 100% rename from src/haptic/haptic-wearable.conf rename to src/haptic/conf/haptic-level3.conf diff --git a/src/haptic/haptic-mobile.conf b/src/haptic/conf/haptic-level6.conf similarity index 100% rename from src/haptic/haptic-mobile.conf rename to src/haptic/conf/haptic-level6.conf diff --git a/src/haptic/haptic-iot.conf b/src/haptic/haptic-iot.conf deleted file mode 100644 index 84271f1..0000000 --- a/src/haptic/haptic-iot.conf +++ /dev/null @@ -1,24 +0,0 @@ -[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 diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index d9521a5..6741a58 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -95,6 +95,8 @@ static int haptic_stop(void); static int haptic_internal_init(void); static int remove_haptic_info(struct haptic_info *info); +struct haptic_data cur_h_data; + void add_haptic(const struct haptic_ops *ops) { DD_LIST_APPEND(h_head, (void *)ops); diff --git a/src/haptic/standard-vibcore.c b/src/haptic/standard-vibcore.c index 4e40c22..09ce668 100644 --- a/src/haptic/standard-vibcore.c +++ b/src/haptic/standard-vibcore.c @@ -44,8 +44,6 @@ static Ecore_Timer *duration_timer; static t_vibrate_monotone real_vibrate_monotone; -struct haptic_data cur_h_data; - static int vibration_load_config(struct parse_result *result, void *user_data) { struct vibration_config *conf; -- 2.7.4 From a8b8e0f0ee2ca2884b101f7943e489c8fcab01aa Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 1 Aug 2017 15:39:21 +0900 Subject: [PATCH 10/16] dbus: clean up dbus conf Change-Id: I43fb5b292b86631b0be981f946a0acf19679dbd2 Signed-off-by: sanghyeok.oh --- scripts/feedbackd.conf | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) mode change 100644 => 100755 scripts/feedbackd.conf diff --git a/scripts/feedbackd.conf b/scripts/feedbackd.conf old mode 100644 new mode 100755 index 5b70ebb..d17e13a --- a/scripts/feedbackd.conf +++ b/scripts/feedbackd.conf @@ -1,16 +1,9 @@ - - - - - - - - + + Date: Thu, 1 Feb 2018 11:43:25 +0900 Subject: [PATCH 11/16] dbus: change edbus/ecore to common dbus api Change-Id: I9f2c821acedc7f4bd1466058c6205ff881444d43 Signed-off-by: sanghyeok.oh --- CMakeLists.txt | 6 +- packaging/feedbackd.spec | 3 +- src/core/common.h | 2 +- src/core/dbus.c | 2521 +++++++++++++++++++++++++++++++++++++-- src/core/dbus.h | 162 ++- src/core/device-idler.c | 14 +- src/core/edbus-handler.c | 146 +-- src/core/main.c | 26 +- src/haptic/circle.c | 28 +- src/haptic/emulator.c | 2 +- src/haptic/gpio_haptic.c | 26 +- src/haptic/haptic-plugin-intf.h | 2 +- src/haptic/haptic.c | 378 +++--- src/haptic/standard-mix.c | 48 +- src/haptic/standard-vibcore.c | 19 +- src/haptic/standard.c | 41 +- 16 files changed, 2945 insertions(+), 479 deletions(-) mode change 100755 => 100644 CMakeLists.txt mode change 100755 => 100644 src/haptic/gpio_haptic.c diff --git a/CMakeLists.txt b/CMakeLists.txt old mode 100755 new mode 100644 index 974f5a7..0900516 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,6 @@ SET(VERSION 0.1.0) SET(SRCS src/core/main.c - src/core/edbus-handler.c src/core/common.c src/core/config-parser.c src/core/device-idler.c @@ -35,13 +34,12 @@ ENDIF() INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) SET(PKG_MODULES - ecore - edbus - dbus-1 vconf dlog capi-base-common + glib-2.0 gio-2.0 + gio-unix-2.0 capi-system-info ) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 8c2985e..1dca668 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -15,14 +15,13 @@ Source0: %{name}-%{version}.tar.gz Source1: feedbackd.manifest BuildRequires: cmake -BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(edbus) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(gio-2.0) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-unix-2.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-system-peripheral-io) diff --git a/src/core/common.h b/src/core/common.h index 9978bf4..e8086e5 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -20,8 +20,8 @@ #ifndef __FEEDBACKD_COMMON_H__ #define __FEEDBACKD_COMMON_H__ -#include #include +#include #include #include #include diff --git a/src/core/dbus.c b/src/core/dbus.c index c8845f0..2d22d15 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -30,115 +30,2470 @@ /* -1 is a default timeout value, it's converted to 25*1000 internally. */ #define DBUS_REPLY_TIMEOUT (-1) -int append_variant(DBusMessageIter *iter, const char *sig, char *param[]) +static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM; +pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; + +void dbus_handle_set_default_bus_type(GBusType bus_type) +{ + if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) + return ; + + pthread_mutex_lock(&g_mutex); + g_default_bus_type = bus_type; + pthread_mutex_unlock(&g_mutex); +} + +GBusType dbus_handle_get_default_bus_type(void) +{ + GBusType type; + + pthread_mutex_lock(&g_mutex); + type = g_default_bus_type; + pthread_mutex_unlock(&g_mutex); + + return type; +} + +typedef struct { + const char *bus_name; + guint id; +} dbus_name; + +/* basic information */ +typedef struct { + GDBusConnection *conn; + GBusType bus_type; + gboolean priv; + GList *list_names; // dbus_name + GList *list_object; /* dbus_object_handle_s */ + pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER; +} dbus_handle_s; + +/* path + interfaces */ +typedef struct { + dbus_handle_s *dh; /* dbus handle */ + const char *path; + GList *list_ifaces; /* dbus_interface_s */ +} dbus_object_handle_s; + +typedef struct { + dbus_object_handle_s *oh; + const char *name; + GList *list_methods; // const dbus_method_s; + guint reg_id; + int modified; +} dbus_interface_s; + +#define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh + +static dbus_handle_s g_dh[2]; + +static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type); + +dbus_handle_s * _dbus_handle_get_default_connection(void) +{ + return _dbus_handle_get_connection(dbus_handle_get_default_bus_type()); +} + +#define dbus_handle_lock(handle) do {\ + assert(handle);\ + pthread_mutex_lock(&((handle)->mutex));\ +} while (0); + +#define dbus_handle_unlock(handle) do {\ + assert(handle);\ + pthread_mutex_unlock(&(handle)->mutex);\ +} while (0); + +#define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle; +#define dcl_dbus_handle_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\ + if (!dh) {\ + _E("dbus handle is null\n");\ + return 0;\ + } + +dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path); +dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name); +dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name); +static GVariant* _append_variant(const char *signature, const char *param[]); + +dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u) +{ + dbus_interface_s *iface = NULL; + + if (!iface_u || !iface_u->methods) { + _E("param is null"); + return NULL; + } + + iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s)); + if (!iface) { + _E("failed to calloc"); + return NULL; + } + + iface->name = iface_u->name; + iface->modified = TRUE; + + for (int i = 0 ; i < iface_u->nr_methods; ++i) { + //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func); + iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i)); + } + + return iface; +} + +static GDBusConnection * _get_bus(GBusType bus_type) +{ + GDBusConnection *conn = NULL; + GError *err = NULL; + + if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { + _E("Wrong bus_type %d", bus_type); + return NULL; + } + + conn = g_bus_get_sync(bus_type, NULL, &err); + if (!conn || err) { + _E("failed to get bus:type:%d, %s\n", bus_type, err->message); + g_error_free(err); + return NULL; + } + + return conn; +} + +static GDBusConnection * _get_bus_private(GBusType bus_type) +{ + GError *err = NULL; + GDBusConnection *conn = NULL; + const char * address; + + if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { + _E("Wrong bus_type %d", bus_type); + return NULL; + } + + address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err); + if (!address || err) { + _E("failed to get bus address\n"); + g_error_free(err); + return NULL; + } + + conn = g_dbus_connection_new_for_address_sync(address, + (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), + NULL, /* GDBusAuthObserver */ + NULL, + &err); + if (!conn || err) { + _E("failed to get private bus\n"); + g_error_free(err); + return NULL; + } + + return conn; +} + +/* ref cout is 1 */ +static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type) +{ + int ibus = bus_type - 1; + dbus_handle_s *dh = NULL; + + if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { + _E("Unknown bus type %d", bus_type); + return NULL; + } + dh = &g_dh[ibus]; + + dbus_handle_lock(dh); + + if (!dh->conn) { + dh->conn = _get_bus(bus_type); + dh->priv = FALSE; + dh->bus_type = bus_type; + if (!dh->conn) + dh = NULL; + } + + dbus_handle_unlock(dh); + + return dh; +} + +/* ref cout is 1 */ +static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type) +{ + dbus_handle_s * dh; + + if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { + _E("Unknown bus type %d", bus_type); + return NULL; + } + + dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s)); + if (!dh) { + _E("failed to allocate memory for dbus handle"); + return NULL; + } + + dbus_handle_lock(dh); + + if (!dh->conn) { + dh->conn = _get_bus_private(bus_type); + dh->bus_type = bus_type; + if (!dh->conn) + goto err; + } + + dbus_handle_unlock(dh); + + return dh; +err: + if (dh) { + dbus_handle_unlock(dh); + free(dh); + } + return NULL; +} + +dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv) +{ + dbus_handle_s *dh = NULL; + + if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) { + _E("Wrong bus_type %d\n", bus_type); + return dh; + } + + /* private */ + if (priv) + dh = _dbus_handle_get_connection_private(bus_type); + /* shared */ + else + dh = _dbus_handle_get_connection(bus_type); + + return dh; +} + +static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id) +{ + dbus_name *dn = NULL; + int locked = 0; + + if (!handle || !name || !id) + return ; + + dn = (dbus_name*)calloc(1, sizeof(dbus_name)); + if (!dn) { + _E("failed to calloc"); + assert(0); + } + dn->bus_name = name; + dn->id = id; + + // todo : delete lock ? + locked = pthread_mutex_trylock(&handle->mutex); + if (locked != 0 && locked != EBUSY) { + _E("failed to lock %d\n", locked); + assert(0); + } + + handle->list_names = g_list_prepend(handle->list_names, dn); + + // todo : delete lock ? + if (locked != EBUSY) + dbus_handle_unlock(handle); +} + +static gint _compare_dbus_name(gconstpointer a, gconstpointer b) +{ + const char *bus_name = ((dbus_name *)a)->bus_name; + if (!bus_name || !b) + return -1; + return strcmp(bus_name, (const char *)b); +} + +dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name) +{ + if (!list_name || !bus_name) + return NULL; + + GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name); + if (!item) + return NULL; + + return (dbus_name *)item->data; +} + +#define dh_to_ds(x) ((dbus_handle_s*)x) + +/* remove dbus_name from dbus handle */ +static void _dbus_handle_remove_bus_name(dbus_handle_s *handle, const char *bus_name) +{ + dcl_dbus_handle(); + dbus_name *dn = NULL; + + if (!bus_name) { + _E("wrong bus_name %s", bus_name); + return ; + } + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return ; + } + } + + dbus_handle_lock(dh); + dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name); + if (!dn) { + _E("failed to find dbus name %s", bus_name); + goto out; + } + dh->list_names = g_list_remove(dh->list_names, dn); + free(dn); +out: + dbus_handle_unlock(dh); +} + +static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + dbus_handle_s *dh = (dbus_handle_s *)user_data; + + _D("name %s", name); + + if (!dh) { + _E("%s:%d:dbus handle is null\n", __func__, __LINE__); + return ; + } + // todo: add bus name? + //dh->bus_name = name; +} + +static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + _E("%s:%d:%s\n", __func__, __LINE__, name); + dbus_handle_s *dh = (dbus_handle_s *)user_data; + if (!dh) { + _E("%s:%d:dbus handle is null\n", __func__, __LINE__); + return ; + } + _dbus_handle_remove_bus_name(dh, name); +} + +int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name) +{ + dcl_dbus_handle(); + int id = -1; + GList *item = NULL; + + if (!bus_name) { + _E("bus_name is NULL"); + return -1; + } + + /* get shared connection */ + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + + dbus_handle_lock(dh); + if (!dh->conn) { + _E("failed to register name: connection is null\n"); + goto out; + } + + /* todo : search name on connection */ + item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name); + if (item) { + id = ((dbus_name*)(item->data))->id; + _E("name already exist:%u", id); + goto out; + } + + id = g_bus_own_name_on_connection(dh->conn, bus_name, G_BUS_NAME_OWNER_FLAGS_NONE, _name_acquired, _name_lost, dh, NULL); + if (!id) { + _E("failed to own name:%s\n", bus_name); + goto out; + } + + _dbus_handle_add_bus_name(dh, bus_name, id); + +out: + dbus_handle_unlock(dh); + return id; +} + +int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name) +{ + dcl_dbus_handle(); + dbus_name *dn = NULL; + + if (!bus_name) { + _E("Wrong bus name"); + return -1; + } + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + + dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name); + if (!dn) { + _E("failed to find bus_name %s on dbus handle", bus_name); + return -1; + } + + _E("unown name %d", dn->id); + /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */ + g_bus_unown_name(dn->id); + + dbus_handle_lock(dh); + dh->list_names = g_list_remove(dh->list_names, dn); + free(dn); + dbus_handle_unlock(dh); + + return 0; +} + +int dbus_handle_free_connection(dbus_handle_h handle) +{ + dcl_dbus_handle(); + dbus_handle_s *pdh = NULL; + GError *err = NULL; + GList *item = NULL; + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + + if (!dh->conn) { + _E("connection is NULL"); + return 0; + } + + pdh = dh; + + /* disable dbus handler */ + dbus_handle_lock(dh); + if (!pdh->conn) { + _E("conn is null"); + free(pdh); + return 0; + } + + /* flush everything */ + if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) { + _E("failed to flush %s\n", err->message); + g_error_free(err); + err = NULL; + } + + _D("list_names %u", g_list_length(pdh->list_names)); + + /* unown every well-knwon name */ + if (pdh->list_names) { + dbus_name *dn = NULL; + for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) { + dn = (dbus_name *)item->data; + if (!dn) + continue; + + /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */ + _D("unown name id : %u", dn->id); + g_bus_unown_name(dn->id); + free(dn); + } + g_list_free(pdh->list_names); + pdh->list_names = NULL; + } + + _D("list_object %u", g_list_length(pdh->list_object)); + + /* unregister every object */ + if (pdh->list_object) { + dbus_object_handle_s * oh = NULL; + //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data){}, NULL); + for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) { + oh = (dbus_object_handle_s *)item->data; + if (!oh || !oh->list_ifaces) + continue; + + _D("delete object path %s", oh->path); + + /* unregister every interface, method handles */ + for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) { + dbus_interface_s *ih = (dbus_interface_s *)iface->data; + if (!ih) + continue; + + _D("delete object iface %s", ih->name); + + if (ih->reg_id) + g_dbus_connection_unregister_object(pdh->conn, ih->reg_id); + } + } + } + + /* close connection */ + if (pdh->priv) { + _E("close private connection\n"); + + if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) { + _E("Error closing connection %s\n", err->message); + g_error_free(err); + err = NULL; + } + } + + /* _free_func_object callback free the data */ + //assert(g_list_length(pdh->list_names) == 0); + //assert(g_list_length(pdh->list_object) == 0); + + g_object_unref(pdh->conn); + + dbus_handle_unlock(dh); + + if (dh->priv) + free(dh); + + return 0; + + // todo: signal ? +} + +#define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0) +#define buf_block_size 8192 + +#define buf_check_space_realloc(buf, nwrite, buf_len) do {\ + if ((nwrite >= buf_len - 1024)) {\ + if (buf_len >= buf_block_size * 10) {\ + _E("buf is too big to allocate. %d", buf_len);\ + } else {\ + _E("buf_check_space_realloc");\ + char *tmp = NULL;\ + buf_len += buf_block_size;\ + tmp = (char *)realloc(buf, buf_len);\ + if (!tmp) {\ + _E("failed to realloc");\ + } else\ + buf = tmp;\ + } \ + } \ +} while (0); + +static int _check_brace(const char * expr) +{ + int len = 0; + char qu[128]; + int qucnt = 0; + + if (!expr) + return -1; + + len = strlen(expr); + + if (expr[0] != '(' && expr[0] != '{') + return -1; + + for (int i = 0 ; i < len; ++i) { + + if (expr[i] == '(' || expr[i] == '{') { + qu[qucnt++] = expr[i]; + if (qucnt >= sizeof(qu)) { + _E("queue is too large. %s", expr); + return -1; + } + continue; + } + + if (expr[i] == ')' || expr[i] == '}') { + char ch; + + if (qucnt > 0) + ch = qu[qucnt-1]; + else + return -1; + + if (expr[i] == ')') { + if (ch == '(') { + --qucnt; + } else + return -1; + } else if (expr[i] == '}') { + if (ch == '{') { + --qucnt; + } else + return -1; + } else + return -1; + + if (qucnt == 0) { + return i + 1; + } + } + } + + return -1; +} + +static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces) +{ + int nwrite = 0; + int len_args; + char *buf = NULL; + const dbus_method_s *pmethod; + int buf_len = buf_block_size; + + if (!interfaces) { + _E("interfaces is null"); + return -1; + } + + // todo : check dbus naming rule for interface name. ? + if (!interfaces->name) { + _E("wrong interface name"); + return -1; + } + if (!interfaces->list_methods) { + _E("no methods"); + return -1; + } + + buf = (char *)malloc(buf_len); + if (!buf) { + _E("buf is null. not enough memory\n"); + return -1; + } + + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), """\n""\t""""\n", interfaces->name); + + /* members */ + for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) { + pmethod = (const dbus_method_s *)item->data; + if (!pmethod) + continue; + + /* check free space of buf */ + buf_check_space_realloc(buf, nwrite, buf_len); + + if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) { + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n", pmethod->member); + continue; + } + + /* */ + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n", pmethod->member); + + /* in args */ + len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0; + for (int m = 0; m < len_args; ++m) { + // todo + // array a(), as, ay ? + if (pmethod->signature_in[m] == 'a') { + int ei; //end index + ei = _check_brace(pmethod->signature_in + m + 1); + if (ei > 0) { + char tmp[128] = {0,}; + strncpy(tmp, pmethod->signature_in + m, ei + 1); + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", tmp, m); + m += ei; + continue; + } else { + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_in[m], pmethod->signature_in[m+1], m); + m += 1; + continue; + } + } + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_in[m], m); + } + + /* out args */ + len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0; + for (int m = 0; m < len_args; ++m) { + // array + // todo: container type + if (pmethod->signature_out[m] == 'a') { + int ei; //end index + ei = _check_brace(pmethod->signature_out + m + 1); + if (ei > 0) { + char tmp[128] = {0,}; + strncpy(tmp, pmethod->signature_out + m, ei + 1); + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", tmp, m); + m += ei; + continue; + } else { + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_out[m], pmethod->signature_out[m+1], m); + m += 1; + continue; + } + } + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""""\n", pmethod->signature_out[m], m); + } + + /* */ + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""""\n"); + } + + nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""""\n"""""); + + *xml = buf; + + return 0; +} + +static gint _compare_dbus_object(gconstpointer a, gconstpointer b) +{ + dbus_object_handle_s * pa = (dbus_object_handle_s *)a; + if (!pa->path || !((const char*)b)) + return -1; + return strcmp(pa->path, (const char*)b); +} + +static gint _compare_dbus_interface(gconstpointer a, gconstpointer b) +{ + dbus_interface_s * pa = (dbus_interface_s *)a; + if (!pa->name || !((const char*)b)) + return -1; + return strcmp(pa->name, (const char*)b); +} + +static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b) +{ + dbus_interface_s * pa = (dbus_interface_s *)a; + if (!pa->reg_id || !((guint*)b)) + return -1; + return !(pa->reg_id == (guint)b); +} + +static gint _compare_dbus_method(gconstpointer a, gconstpointer b) +{ + dbus_method_s *pa = (dbus_method_s*)a; + if (!pa->member || !((const char*)b)) + return -1; + return strcmp(pa->member, (const char*)b); +} + +dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path) +{ + if (!list_obj || !obj_path) + return NULL; + + GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object); + if (!item) + return NULL; + + return (dbus_object_handle_s *)item->data; +} + +dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name) +{ + if (!list_iface || !iface_name) + return NULL; + + GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface); + if (!item) + return NULL; + + return (dbus_interface_s *)item->data; +} + +dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id) +{ + if (!list_iface || !id) + return NULL; + + GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id); + if (!item) + return NULL; + + return (dbus_interface_s *)item->data; +} + +dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name) +{ + if (!list_methods || !method_name) + return NULL; + + GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method); + if (!item) + return NULL; + + return (dbus_method_s *)item->data; +} + +static void _free_func_object(gpointer data) +{ + dbus_interface_s *ih = (dbus_interface_s *)data; + dbus_object_handle_s *oh = NULL; + + if (!ih) { + _E("interface handle is null"); + assert(0); // something wrong + return ; + } + + /* just free list, not data(static dbus_method_s) */ + g_list_free(ih->list_methods); + + oh = ih->oh; + if (!oh) { + _E("object handle is null"); + assert(0); // something wrong + return ; + } + + /* remove ih from list_ifaces */ + oh->list_ifaces = g_list_remove(oh->list_ifaces, ih); + + /* interface_s is copy of interface_u */ + free(ih); + + /* remove oh from list_object */ + if (!oh->list_ifaces) { + oh->dh->list_object = g_list_remove(oh->dh->list_object, oh); + free(oh); + } +} + +static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface) +{ + dbus_object_handle_s *oh = NULL; + + if (!dh || !obj_path || !iface) { + _E("failed to attache object. wrong parameter"); + return -1; + } + + /* find object handle */ + if (dh->list_object) + oh = _dbus_handle_lookup_object(dh->list_object, obj_path); + + if (!oh) { + oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s)); + if (!oh) { + _E("failed to calloc"); + return -1; + } + oh->dh = dh; + oh->path = obj_path; + + /* attach object */ + dh->list_object = g_list_prepend(dh->list_object, oh); + } + + iface->oh = oh; + /* attach interface */ + oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface); + + return 0; +} + +/* libgio verify path and interface */ +static void _method_call_handler(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) +{ + dbus_interface_s *iface_s = (dbus_interface_s *)user_data; + const dbus_method_s *methods; + GVariant *result = NULL; + + /* todo: ghash ? */ + methods = _dbus_handle_lookup_method(iface_s->list_methods, name); + if (methods) { + result = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh)); + + /* async, maybe they will reply...maybe.. */ + if (!result) { + _E("finish method handle : NULL"); + return ; + } + } else { + _E("no methods"); + } + + g_dbus_method_invocation_return_value(invocation, result); + //if (g_variant_is_of_type(result, G_VARIANT_TYPE_TUPLE)) { + // //_E("TUPLE %s", g_variant_get_type_string(result)); + // g_dbus_method_invocation_return_value(invocation, result); + //} + //else if (g_variant_is_container(result)) { + // /* todo: we don't have any plan to using variant type for reply */ + // _E("CONTAINER %s", g_variant_get_type_string(result)); + // g_dbus_method_invocation_return_value(invocation, result); + // //g_dbus_method_invocation_return_value(invocation, g_variant_new("(v)", result)); + //} else { + // _E("Type is not Container : %s", g_variant_get_type_string(result)); + //} +} + +static GDBusInterfaceVTable path_vtable = {_method_call_handler}; + + +/* +before register object, attach object into dbus handle +_dbus_handle_attach_object() +*/ +static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface) +{ + dcl_dbus_handle(); + int ret = 0; + char *buf = NULL; + GError *err = NULL; + GDBusNodeInfo * nodeinfo = NULL; + GDBusInterfaceInfo *ifaceinfo = NULL; + + if (!obj_path || !iface) { + _E("wrong parameter\n"); + return -1; + } + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + if (!dh->conn) { + _E("connection is null\n"); + return -1; + } + + ret = _get_xml_from_interfaces(&buf, iface); + if (ret < 0) { + _E("failed to make xml format"); + goto err; + } + + _E("%s", buf); + + nodeinfo = g_dbus_node_info_new_for_xml(buf, &err); + if (!nodeinfo || err) { + _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf); + ret = -1; + goto err; + } + + ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name); + if (!ifaceinfo) { + _E("failed to g_dbus_node_info_lookup_interface"); + ret = -1; + goto err; + } + + /* + path own single interface + if interface is already registered, then failed. + g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered + */ + ret = g_dbus_connection_register_object(dh->conn, obj_path, ifaceinfo/*ref 2*/, &path_vtable, (void*)iface, + _free_func_object, + &err); + if (err) { + _E("failed to register object:err:%s:\n", err->message); + ret = -1; + goto err; + } + + iface->reg_id = ret; + iface->modified = FALSE; + +err: + /* todo: detach object */ + //_dbus_handle_detach_object(dh, obj_path, iface); + /* attach interface before register object */ + /*ret = _dbus_handle_detach_object(dh, obj_path, iface); + if (ret < 0) { + _E("failed to attach object"); + goto err; + }*/ + + if (nodeinfo) + g_dbus_node_info_unref(nodeinfo); + if (buf) + free(buf); + if (err) + g_error_free(err); + + return ret; +} + +/* +register same interface at once + +if interface is constructed by multiple methods, +also it is not possible to make methods struct at once, + +use dbus_handle_add_dbus_object(), dbus_handle_register_dbus_object_all(). + +return reg_id +*/ +int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u) +{ + dcl_dbus_handle(); + int ret = 0; + dbus_interface_s *iface = NULL; + + if (!obj_path || !iface_u) { + _E("wrong parameter\n"); + return -1; + } + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + if (!dh->conn) { + _E("connection is null\n"); + return -1; + } + + /* check registered interface */ + if (dh->list_object) { + dbus_object_handle_s *oh = _dbus_handle_lookup_object(dh->list_object, obj_path); + if (oh) { + dbus_interface_s *ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name); + if (ih) { + _E("path %s, interface %s already registered", obj_path, iface_u->name); + return -1; + } + } + } + + iface = _iface_u_to_s(iface_u); + if (!iface) { + _E("failed to _iface_u_to_s"); + return -1; + } + + /* attach interface before register object */ + ret = _dbus_handle_attach_object(dh, obj_path, iface); + if (ret < 0) { + _E("failed to attach object"); + goto err; + } + + ret = _dbus_handle_register_dbus_object(dh, obj_path, iface); + if (ret <= 0) { + _E("failed to register dbus object%d", ret); + goto err; + } +err: + return ret; +} + +int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path) +{ + dcl_dbus_handle(); + dbus_object_handle_s *oh = NULL; + int ret = 0; + + if (!obj_path) { + return -1; + } + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + if (!dh->list_object) { + _E("list_object is empty"); + return 0; + } + + oh = _dbus_handle_lookup_object(dh->list_object, obj_path); + if (!oh) { + _E("no object with name %s", obj_path); + return -1; + } + + /* unregister every interface of object*/ + for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) { + dbus_interface_s *ih = item->data; + if (!ih) { + _E("this is error"); + assert(0); + } + + /* remove ih from list_ifaces */ + if (!ih->reg_id) { + item = g_list_previous(item); + + /* remove and free link */ + oh->list_ifaces = g_list_remove(oh->list_ifaces, ih); + + /* free list_methods */ + g_list_free(ih->list_methods); + + /* free data */ + free(ih); + continue; + } + + /* unregister object by id */ + ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id); + if (!ret) + _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id); + } + + return 0; +} + +/* +add object temporarily. +dbus_handle_register_dbus_object_all will register every objects on connection. + +return registered method count +*/ +int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u) +{ + dcl_dbus_handle(); + dbus_object_handle_s *oh = NULL; + dbus_interface_s *ih = NULL; + int cnt; + + if (!obj_path || !iface_u) { + _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u); + return -1; + } + if (iface_u && (!iface_u->name || !iface_u->methods)) { + _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u); + return -1; + } + + cnt = iface_u->nr_methods; + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + + if (!dh->conn) { + _E("failed to register method. connection is null\n"); + return -1; + } + + /* if there are no object list, just add */ + if (!dh->list_object) { + if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) { + _E("failed to attach object"); + return -1; + } + goto out; + } + + oh = _dbus_handle_lookup_object(dh->list_object, obj_path); + /* if there are no matched object, just add */ + if (!oh) { + if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) { + _E("failed to attach object"); + return -1; + } + goto out; + } + + /* this is an error, interface must have one or more item ? */ + if (!oh->list_ifaces) { + _E("error. list_ifaces is null\n"); + assert(0); + goto out; + } + + ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name); + /* if there are no matched interface, just add */ + if (!ih) { + if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) { + _E("failed to attach object"); + return -1; + } + goto out; + } + + /* todo: + 1. unregister interface + 2. update interface and methods + 3. register interface + */ + if (ih->reg_id) { + _E("interface already registered, ignore new interface"); + return -1; + } + + /* attach new methods */ + cnt = 0; + for (int i = 0; i < iface_u->nr_methods; ++i) { + GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method); + if (!item) { + //_D("attached %s", iface_u->methods[i].member); + ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i)); + ++cnt; + } + } + + if (cnt) + ih->modified = TRUE; + +out: + /*todo: delete debugging log */ + //if (dh && dh->list_object) + // _D("obj list len %d", g_list_length(dh->list_object)); + //if (oh && oh->list_ifaces) + // _D("iface list len %d", g_list_length(oh->list_ifaces)); + //if (ih && ih->list_methods) + // _D("method list len %d", g_list_length(ih->list_methods)); + + return cnt; +} + +int dbus_handle_register_dbus_object_all(dbus_handle_h handle) +{ + dcl_dbus_handle(); + dbus_object_handle_s *oh = NULL; + dbus_interface_s *ih = NULL; + int ret = 0; + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + if (!dh->conn) { + _E("connection is null\n"); + return -1; + } + + if (!dh->list_object) { + _E("obj list is empty"); + return -1; + } + + /*if (dh && dh->list_object) + _D("obj list len %d", g_list_length(dh->list_object));*/ + + for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) { + oh = (dbus_object_handle_s *)item->data; + + if (!oh) { + _E("something wrong"); + assert(0); + } + if (!oh->list_ifaces) { + _E("path %s: list_ifaces are null", oh->path); + goto err; + } + + //_D("iface list len %d", g_list_length(oh->list_ifaces)); + + for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) { + ih = (dbus_interface_s *)li->data; + + /* if there are no modification, goto next */ + if (!ih->modified) + continue; + + /* todo: if already registered interface, unregister first */ + + /*_E("interface %s:", ih->name); + if (ih && ih->list_methods) + _D("method list len %d", g_list_length(ih->list_methods));*/ + + ret = _dbus_handle_register_dbus_object(dh, oh->path, ih); + if (ret <= 0) + _E("failed to register dbus object%d", ret); + + } + } + return 0; +err: + + // todo: delete all updates + + return -1; +} + +static void _free_func_signal(gpointer data) +{ + //_D("free signal subscribe"); +} + +guint subscribe_dbus_signal(dbus_handle_h handle, const char *path, + const char *iface, const char *name, + GDBusSignalCallback cb, void *data, + destroy_notified free_func) +{ + dcl_dbus_handle(); + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return 0; + } + } + + if (!dh->conn) { + _E("connection is null. check bus status"); + return 0; + } + return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, _free_func_signal); +} + +void unsubscribe_dbus_signal(dbus_handle_h handle, guint id) +{ + dcl_dbus_handle(); + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return; + } + } + + if (!dh->conn) { + _E("connection is null. check bus status"); + return; + } + + g_dbus_connection_signal_unsubscribe(dh->conn, id); +} + +int _check_type_string_is_container(const char *signature) +{ + if (!signature) + return FALSE; + + switch (signature[0]) { + case 'a': + case 'm': + case 'r': + case '(': + case '{': + case 'v': + return TRUE; + default: + return FALSE; + } + + return TRUE; +} + +GVariant *dbus_handle_make_simple_array(const char *sig, int *param) +{ + GVariantBuilder *builder = NULL; + char format[256]; + int i = 0; + + builder = g_variant_builder_new(G_VARIANT_TYPE(sig)); + if (!builder) { + _E("failed to g_variant_builder_new"); + return NULL; + } + + while (param[i]) + g_variant_builder_add(builder, "i", param[i++]); + + snprintf(format, sizeof(format) - 1, "(%s)", sig); + return g_variant_new(format, builder); +} + +/* todo: looks like garbage... */ +static GVariant* _append_variant(const char *signature, const char *param[]) +{ + char *ch; + int i; + int pi; + int int_type; + gboolean bool_type; + unsigned long long int64_type; + GVariant *ret; + int len; + char container[255];// The maximum length of a signature is 255. + const char *sig = signature; + GVariantBuilder *builder = NULL; + + if (!signature || !param) + return 0; + + /* workaround for user fault "(i) != i" but we treat this as same signature */ + /* G_VARIANT_TYPE("si") return NULL */ + /* todo: actually user have to use correct signature */ + if (!_check_type_string_is_container(signature)) { + snprintf(container, sizeof(container) - 1, "(%s)", signature); + sig = container; + } + if (!g_variant_type_is_container(G_VARIANT_TYPE(sig))) { + _E("signature (%s) is not container type", signature); + } + + builder = g_variant_builder_new(G_VARIANT_TYPE(sig)); + len = strlen(sig); + pi = 0; + for (ch = (char *)sig, i = 0; i < len; ++i, ++ch) { + switch (*ch) { + case '(': + case ')': + continue; + case 'b': + bool_type = (atoi(param[pi++]) == 0 ? FALSE : TRUE); + g_variant_builder_add(builder, "b", bool_type); + break; + case 'i': + int_type = atoi(param[pi++]); + g_variant_builder_add(builder, "i", int_type); + break; + case 'u': + int_type = strtoul(param[pi++], NULL, 10); + g_variant_builder_add(builder, "u", int_type); + break; + case 't': + int64_type = atoll(param[pi++]); + g_variant_builder_add(builder, "t", int64_type); + break; + case 's': + g_variant_builder_add(builder, "s", param[pi++]); + break; + case 'a': + ++ch; + switch (*ch) { + case 'y': + g_variant_builder_add(builder, "^ay", param[pi++]); + ++i; + break; + default: + break; + } + break; + default: + break; + } + } + ret = g_variant_builder_end(builder); + g_variant_builder_clear(builder); + g_variant_builder_unref(builder); + + return ret; +} + +int dbus_handle_broadcast_dbus_signal(const char *path, + const char *iface, const char *name, + const char *signature, const char *param[]) +{ + dbus_handle_s *dh = NULL; + GError *err = NULL; + gboolean ret = 0; + GVariant *var = NULL; + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + + if (signature && param) + var = _append_variant(signature, param); + ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, var, &err); + if (err) { + _E("%d %s\n", ret, err ? err->message : NULL); + g_error_free(err); + } + + return ret; +} + +int dbus_handle_broadcast_dbus_signal_var(const char *path, + const char *iface, const char *name, + GVariant *param) +{ + dbus_handle_s *dh = NULL; + GError *err = NULL; + gboolean ret = 0; + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + + ret = g_dbus_connection_emit_signal(dh->conn, NULL, path, iface, name, param, &err); + if (err) { + _E("%d %s\n", ret, err ? err->message : NULL); + g_error_free(err); + } + + return ret; +} + +GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, + const char *iface, const char *method, + const char *signature, const char *param[]) +{ + GError *err = NULL; + GVariant * var = NULL; + GVariant * ret = NULL; + dbus_handle_s *dh = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return NULL; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return NULL; + } + + if (signature && param) + var = _append_variant(signature, param); + + ret = g_dbus_connection_call_sync(dh->conn, + dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); + if (!ret || err) { + if (err) { + _E("failed to g_dbus_connection_call_sync:%s", err->message); + g_error_free(err); + } else { + _E("failed to g_dbus_connection_call_sync"); + g_variant_unref(var); + } + return NULL; + } + + return ret; +} + +GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, + const char *iface, const char *method, GVariant *var) +{ + GError *err = NULL; + GVariant * ret = NULL; + dbus_handle_s *dh = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + if (var) + g_variant_unref(var); + return NULL; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + if (var) + g_variant_unref(var); + return NULL; + } + + ret = g_dbus_connection_call_sync(dh->conn, + dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); + if (!ret || err) { + if (err) { + _E("failed to g_dbus_connection_call_sync:%s", err->message); + g_error_free(err); + } else { + _E("failed to g_dbus_connection_call_sync"); + } + return NULL; + } + + return ret; +} + +gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size) +{ + GUnixFDList *fd_list = NULL; + int length = 0; + + fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation)); + + if (!fd_list) { + _E("failed to g_unix_fd_list_get_length: fd_list is null"); + return NULL; + } + + length = g_unix_fd_list_get_length(fd_list); + if (length == 0) { + _E("failed to g_unix_fd_list_get_length: list size is 0"); + return NULL; + } + if (size) + *size = length; + + return g_unix_fd_list_steal_fds(fd_list, NULL); +} + +GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path, + const char *iface, const char *method, + const char *signature, const char *param[], + int *in_fdlist, int in_size, + int **out_fdlist, int *out_size) +{ + GError *err = NULL; + GVariant * var = NULL; + GVariant * ret = NULL; + dbus_handle_s *dh = NULL; + GDBusProxy *proxy = NULL; + GUnixFDList *g_infdlist = NULL; + GUnixFDList *g_outfdlist = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return NULL; + } + if (in_fdlist && in_size == 0) { + _E("wrong in_fdlist is not null but in_size is 0"); + return NULL; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return NULL; + } + + if (signature && param) + var = _append_variant(signature, param); + + proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err); + if (!proxy) { + if (err) { + _E("failed to proxy_new_sync(%s)\n", err->message); + g_error_free(err); + } else { + _E("failed to proxy_new_sync\n"); + if (var) + g_variant_unref(var); + } + } + + /* append fd */ + if (in_fdlist) { + g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size); + if (!g_infdlist) { + _E("failed to g_unix_fd_list_new_from_array\n"); + goto out; + } + //g_infdlist = g_unix_fd_list_new(); + //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) { + } + + ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, var, G_DBUS_CALL_FLAGS_NONE, -1, + g_infdlist, &g_outfdlist, NULL, &err); + if (!ret || err) { + if (err) { + _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message); + g_error_free(err); + } else { + _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:"); + if (var) + g_variant_unref(var); + if (g_infdlist) + g_object_unref(g_infdlist); + } + goto out; + } + + /* fds to out array */ + if (g_outfdlist) { + *out_size = g_unix_fd_list_get_length(g_outfdlist); + if (*out_size == 0) + goto out; + + *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL); + } + +out: + if (g_outfdlist) + g_object_unref(g_outfdlist); + if (proxy) + g_object_unref(proxy); + + return ret; +} + +GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path, + const char *iface, const char *method, + GVariant *param, + int *in_fdlist, int in_size, + int **out_fdlist, int *out_size) { - char *ch; - int i; - int int_type; - dbus_bool_t bool_type; - uint64_t int64_type; - DBusMessageIter arr; - struct dbus_byte *byte; + GError *err = NULL; + GVariant * ret = NULL; + dbus_handle_s *dh = NULL; + GDBusProxy *proxy = NULL; + GUnixFDList *g_infdlist = NULL; + GUnixFDList *g_outfdlist = NULL; - if (!sig || !param) - return 0; + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return NULL; + } + if (in_fdlist && in_size == 0) { + _E("wrong in_fdlist is not null but in_size is 0"); + return NULL; + } - 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': - ++ch; - switch (*ch) { - case 'y': - ++i; - 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; + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return NULL; + } + + proxy = g_dbus_proxy_new_sync(dh->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, dest, path, iface, NULL, &err); + if (!proxy) { + if (err) { + _E("failed to proxy_new_sync(%s)\n", err->message); + g_error_free(err); + } else { + _E("failed to proxy_new_sync\n"); + if (param) + g_variant_unref(param); + } + goto out; + } + + /* append fd */ + if (in_fdlist) { + g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size); + if (!g_infdlist) { + _E("failed to g_unix_fd_list_new_from_array\n"); + goto out; + } + //g_infdlist = g_unix_fd_list_new(); + //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) { + } + + /* send message */ + ret = g_dbus_proxy_call_with_unix_fd_list_sync(proxy, method, param, G_DBUS_CALL_FLAGS_NONE, -1, + g_infdlist, &g_outfdlist, NULL, &err); + if (!ret || err) { + if (err) { + _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:%s", err->message); + g_error_free(err); + } else { + _E("failed to g_dbus_proxy_call_with_unix_fd_list_sync:"); + if (param) + g_variant_unref(param); + if (g_infdlist) + g_object_unref(g_infdlist); } + goto out; + } + + /* copy fds to out array */ + if (g_outfdlist) { + *out_size = g_unix_fd_list_get_length(g_outfdlist); + if (*out_size == 0) + goto out; + *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL); + } +out: + if (g_outfdlist) + g_object_unref(g_outfdlist); + if (proxy) + g_object_unref(proxy); + return ret; +} + +int dbus_method_sync(const char *dest, const char *path, + const char *iface, const char *method, + const char *signature, const char *param[]) +{ + int result; + gboolean result_bool; + GVariant *reply = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + reply = dbus_method_sync_with_reply(dest, path, iface, method, signature, param); + if (!reply) + return -ECOMM; + + if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) { + g_variant_get(reply, "(i)", &result); + } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) { + g_variant_get(reply, "(b)", &result_bool); + result = (int)result_bool; + } else { + result = -ENOMSG; + } + + g_variant_unref(reply); + + return result; +} + +int dbus_method_sync_var(const char *dest, const char *path, + const char *iface, const char *method, GVariant *param) +{ + int result; + gboolean result_bool; + GVariant *reply = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + reply = dbus_method_sync_with_reply_var(dest, path, iface, method, param); + if (!reply) + return -ECOMM; + + if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) { + g_variant_get(reply, "(i)", &result); + } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) { + g_variant_get(reply, "(b)", &result_bool); + result = (int)result_bool; + } else { + result = -ENOMSG; + } + + g_variant_unref(reply); + + return result; +} + +int dbus_method_sync_timeout(const char *dest, const char *path, + const char *iface, const char *method, + const char *signature, const char *param[], int timeout) +{ + dbus_handle_s *dh = NULL; + GError *err = NULL; + GVariant * var = NULL; + GVariant * reply = NULL; + int result = 0; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -EPERM; + } + + if (signature && param) + var = _append_variant(signature, param); + + reply = g_dbus_connection_call_sync(dh->conn, + dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err); + if (!reply || err) { + _E("failed to g_dbus_connection_call_sync:%s", err->message); + g_error_free(err); + return -1; + } + + if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) + g_variant_get(reply, "(i)", &result); + else + result = -ENOMSG; + + g_variant_unref(reply); + + return result; +} + +int dbus_method_sync_pairs(const char *dest, const char *path, + const char *iface, const char *method, + int num, va_list args) +{ + GError *err = NULL; + GVariant * reply = NULL; + char *key, *value; + int ret = 0; + GVariant *var; + GVariantBuilder *builder; + dbus_handle_s *dh = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); + + for (int i = 0 ; i < num ; i = i + 2) { + key = va_arg(args, char *); + value = va_arg(args, char *); + _I("key(%s), value(%s)", key, value); + g_variant_builder_add(builder, "{ss}", key, value); + } + + var = g_variant_new("(a{ss})", builder); + + reply = g_dbus_connection_call_sync(dh->conn, + dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); + if (!reply || err) { + _E("failed to g_dbus_connection_call_sync"); + return -1; + } + + if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) + g_variant_get(reply, "(i)", &ret); + else + ret = -ENOMSG; + + g_variant_unref(reply); + + return ret; +} + +int dbus_method_async_pairs(const char *dest, const char *path, + const char *iface, const char *method, + int num, va_list args) +{ + char *key, *value; + GVariant *var; + GVariantBuilder *builder; + dbus_handle_s *dh = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + + // dict + builder = g_variant_builder_new(G_VARIANT_TYPE("a{ss}")); + + for (int i = 0 ; i < num ; i = i + 2) { + key = va_arg(args, char *); + value = va_arg(args, char *); + _I("key(%s), value(%s)", key, value); + g_variant_builder_add(builder, "{ss}", key, value); + } + + var = g_variant_new("(a{ss})", builder); + + g_dbus_connection_call(dh->conn, dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + NULL, + NULL); + + return 0; +} + +int dbus_method_async(const char *dest, const char *path, + const char *iface, const char *method, + const char *signature, const char *param[]) +{ + GVariant * var = NULL; + dbus_handle_s *dh = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + + if (signature && param) + var = _append_variant(signature, param); + + g_dbus_connection_call(dh->conn, dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + NULL, + NULL); + + return 0; +} + +int dbus_method_async_var(const char *dest, const char *path, + const char *iface, const char *method, GVariant *param) +{ + dbus_handle_s *dh = NULL; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; } + g_dbus_connection_call(dh->conn, dest, path, iface, method, + param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + NULL, + NULL); + 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[]) +/* callback should free gvariant */ +static void _cb_pending(GDBusConnection *conn, + GAsyncResult *res, + gpointer user_data) +{ + GVariant *reply = NULL; + GError *err = NULL; + pending_call_data *data = (pending_call_data *)user_data; + + reply = g_dbus_connection_call_finish(conn, res, &err); + if (!reply || err) { + if (err) { + _E("no message : [%s]", err->message); + g_error_free(err); + } else { + _E("no message"); + } + + if (data && data->func) + data->func(NULL, data->data, err); + goto out; + } + + if (data && data->func) + data->func(reply, data->data, err); +out: + if (data) + free(data); +} + +int dbus_method_async_with_reply(const char *dest, + const char *path, + const char *iface, + const char *method, + const char *signature, + const char *param[], + dbus_pending_cb cb, + int timeout_msec, + void *data) +{ + dbus_handle_s *dh = NULL; + pending_call_data *pdata = NULL; + GVariant * var = NULL; + int ret = 0; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + if (timeout_msec < -1) { + _E("wrong timeout %d", timeout_msec); + return -1; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -EPERM; + } + + if (signature && param) + var = _append_variant(signature, param); + + if (cb) { + pdata = (pending_call_data*)malloc(sizeof(pending_call_data)); + if (!pdata) { + ret = -ENOMEM; + goto err; + } + + pdata->func = cb; + pdata->data = data; + } + g_dbus_connection_call(dh->conn, dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, + (GAsyncReadyCallback)_cb_pending, + pdata); + + return ret; +err: + if (var) + g_variant_unref(var); + return ret; +} + +int dbus_method_async_with_reply_var(const char *dest, + const char *path, + const char *iface, + const char *method, + GVariant *param, + dbus_pending_cb cb, + int timeout_msec, + void *data) { - DBusConnection *conn; - DBusMessage *msg; - DBusMessageIter iter; - DBusMessage *reply; - DBusError err; - int r; + dbus_handle_s *dh = NULL; + pending_call_data *pdata = NULL; + int ret = 0; + + if (!dest || !path || !iface || !method) { + _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method); + return -1; + } + + if (timeout_msec < -1) { + _E("wrong timeout %d", timeout_msec); + return -1; + } + + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -EPERM; + } + + if (cb) { + pdata = (pending_call_data*)malloc(sizeof(pending_call_data)); + if (!pdata) { + ret = -ENOMEM; + goto err; + } + + pdata->func = cb; + pdata->data = data; + } + g_dbus_connection_call(dh->conn, dest, path, iface, method, + param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, + (GAsyncReadyCallback)_cb_pending, + pdata); + + return ret; +err: + if (param) + g_variant_unref(param); + return ret; +} + +int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender) +{ + GError *err = NULL; + GVariant *vret = NULL; + pid_t pid = 0; - conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); if (!conn) { - _E("dbus_bus_get error"); - return NULL; + _E("connection is null"); + return -1; + } + if (!sender) { + _E("sender is null"); + return -1; + } + + vret = g_dbus_connection_call_sync(conn, + "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID", + g_variant_new("(s)", sender), + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + NULL, + &err); + if (!vret || err) { + _E("failed to g_dbus_connection_call_sync:%s", err->message); + g_error_free(err); + return -1; + } + + g_variant_get(vret, "(u)", &pid); + g_variant_unref(vret); + + return pid; +} + +int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender) +{ + dcl_dbus_handle(); + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + if (!dh->conn) { + _E("wrong dbus handle. connection is null"); + assert(0); + return -1; + } + + return dbus_connection_get_sender_pid(dh->conn, sender); +} + +int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds) +{ + dcl_dbus_handle(); + GVariant *vret = NULL; + GError *err = NULL; + GVariantIter *iter = NULL; + char * item; + GVariant *sub; + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return -1; + } + } + vret = g_dbus_connection_call_sync(dh->conn, DBUS_BUS_NAME, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME, + "GetConnectionCredentials", g_variant_new("(s)", name), NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); + if (!vret || err) { + _E("failed to g_dbus_connection_call_sync:%s", err->message); + return -1; + } + + g_variant_get(vret, "(a{sv})", &iter); + + while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) { + if (!g_strcmp0(item, "UnixUserID")) { + g_variant_get(sub, "u", &creds->uid); + _D("UnixUserID %u", creds->uid); + } else if (!g_strcmp0(item, "ProcessID")) { + g_variant_get(sub, "u", &creds->pid); + _D("ProcessID %u", creds->pid); + } else if (!g_strcmp0(item, "LinuxSecurityLabel")) { + g_variant_get(sub, "^ay", &creds->sec_label); + _D("%s", creds->sec_label); + } + } + + if (iter) + g_variant_iter_free(iter); + if (vret) + g_variant_unref(vret); + + return 0; +} + +void _destroy_notify_watch_name(gpointer data) +{ + /*if (data) + free(data);*/ +} + +int dbus_handle_watch_name(const char *name, + GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, + void *user_data) +{ + guint id = 0; + + if (!name) { + _E("wrong name name %s", name); + return -1; + } + if (!name_appeared_handler && !name_vanished_handler) { + _E("both function pointers are null"); + return -1; + } + + id = g_bus_watch_name(dbus_handle_get_default_bus_type(), name, G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared_handler, name_vanished_handler, user_data, _destroy_notify_watch_name); + if (!id) { + _E("failed to g_bus_watch_name"); + return -1; + } + + return id; +} + +void dbus_handle_unwatch_name(guint id) +{ + if (id == 0) { + _E("wrong id %d", id); + return; + } + g_bus_unwatch_name(id); +} + +int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size) +{ + int fd, ret; + char buf[PATH_MAX + 1]; + char *filename; + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); + fd = open(buf, O_RDONLY); + if (fd < 0) { + errno = ESRCH; + return -1; + } + + ret = read(fd, buf, PATH_MAX); + close(fd); + if (ret < 0) + return -1; + + buf[PATH_MAX] = '\0'; + + filename = strrchr(buf, '/'); + if (filename == NULL) + filename = buf; + else + filename = filename + 1; + + if (cmdline_size < strlen(filename) + 1) { + errno = EOVERFLOW; + return -1; } - msg = dbus_message_new_method_call(dest, path, interface, method); - if (!msg) { - _E("dbus_message_new_method_call(%s:%s-%s)", - path, interface, method); + strncpy(cmdline, filename, cmdline_size - 1); + cmdline[cmdline_size - 1] = '\0'; + return 0; +} + +// g_strfreev(strv) +char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name) +{ + dcl_dbus_handle(); + GError *err = NULL; + GVariant *vret = NULL; + GVariantIter *iter = NULL; + gchar **strv = NULL; + gchar *str = NULL; + int i = 0; + + if (!bus_name) { + _E("wrong parameter bus_name(%s)", bus_name); 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); + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return NULL; + } + } + + vret = g_dbus_connection_call_sync(dh->conn, + "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListQueuedOwners", + g_variant_new("(s)", bus_name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + NULL, + &err); + if (!vret || err) { + _E("failed to g_dbus_connection_call_sync:%s", err->message); + g_error_free(err); return NULL; } - dbus_error_init(&err); + g_variant_get(vret, "(as)", &iter); + strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1); + + i = 0; + while (g_variant_iter_loop(iter, "s", &str)) + strv[i++] = g_strdup(str); + strv[i] = NULL; + + g_variant_iter_free(iter); + g_variant_unref(vret); + + return strv; +} + +void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name) +{ + dcl_dbus_handle(); + char exe_name[PATH_MAX]; + int pid; + char **strv = NULL; + int i; + + if (!dh) { + dh = _dbus_handle_get_default_connection(); + if (!dh) { + _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type()); + return ; + } + } - 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); + strv = dbus_handle_get_owner_list(dh, owner_name); + if (!strv) { + _E("failed to get owner list of %s", owner_name); + return ; } - 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; + for (i = 0; strv[i] != NULL; ++i) { + pid = dbus_handle_get_sender_pid(dh, strv[i]); + if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0) + break; + _I("%s(%d)", exe_name, pid); } - dbus_message_unref(msg); - return reply; + g_strfreev(strv); } -static void __CONSTRUCTOR__ dbus_init(void) +dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name) { - dbus_threads_init_default(); + dbus_handle_h handle = NULL; + int i, ret = 0; + + if (!bus_name) { + _E("Wrong bus name, %s", bus_name); + return NULL; + } + + // todo: do we need retry ? - booting time + for (i = 0 ; i < 3; ++i) { + handle = dbus_handle_get_connection(type, FALSE); + if (handle) + break; + usleep(5000); + } + ret = dbus_handle_request_bus_name(handle, bus_name); + if (ret <= 0) + goto out; + + dbush_handle_check_owner_name(NULL, bus_name); + + return handle; + +out: + return NULL; } diff --git a/src/core/dbus.h b/src/core/dbus.h index 4fb1436..4d35471 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -20,8 +20,11 @@ #ifndef __DBUS_H__ #define __DBUS_H__ -#include +#include +#include +#include #include +#include /* * Template @@ -71,15 +74,162 @@ #define VIBRATOR_PATH_HAPTIC VIBRATOR_OBJECT_PATH"/Haptic" #define VIBRATOR_INTERFACE_HAPTIC VIBRATOR_INTERFACE_NAME".haptic" -struct dbus_byte { +typedef struct { const unsigned char *data; int size; -}; +} dbus_byte; -int append_variant(DBusMessageIter *iter, const char *sig, char *param[]); +GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, const char *param[]); + +GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *var); + +/* fd */ +gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size); + +GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path, + const char *iface, const char *method, + const char *signature, const char *param[], + int *in_fdlist, int in_size, + int **out_fdlist, int *out_size); +GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path, + const char *iface, const char *method, + GVariant *param, + int *in_fdlist, int in_size, + int **out_fdlist, int *out_size); + +int dbus_method_sync(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, const char *param[]); + +int dbus_method_sync_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *param); -DBusMessage *dbus_method_sync_with_reply(const char *dest, const char *path, +int dbus_method_sync_timeout(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, const char *param[], int timeout); + +int dbus_method_sync_pairs(const char *dest, const char *path, + const char *interface, const char *method, + int num, va_list args); +int dbus_method_async_pairs(const char *dest, const char *path, const char *interface, const char *method, - const char *sig, char *param[]); + int num, va_list args); +int dbus_method_async(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, const char *param[]); + +int dbus_method_async_var(const char *dest, const char *path, const char *iface, const char *method, GVariant *param); + +typedef void (*dbus_pending_cb)(GVariant *var, void *user_data, GError *err); + +int dbus_method_async_with_reply(const char *dest, + const char *path, + const char *iface, + const char *method, + const char *signature, + const char *param[], + dbus_pending_cb cb, + int timeout_msec, + void *data); + + +int dbus_method_async_with_reply_var(const char *dest, + const char *path, + const char *iface, + const char *method, + GVariant *param, + dbus_pending_cb cb, + int timeout_msec, + void *data); + +int check_systemd_active(void); + +/** + * @brief Dbus handler which is used to register and call methods + + * @since_tizen 4.0 + */ +typedef void *dbus_handle_h; + +/** + * @brief Dbus method handler which is used to unregister dbus methods + * @since_tizen 4.0 + */ +typedef void *dbus_object_handle_h; + +/** + * @brief Structure which contains the dbus method name and callback function. + * @since_tizen 4.0 + */ +typedef struct { + const char *member; + const char *signature_in; + const char *signature_out; + GVariant *(*func)(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data); +} dbus_method_s; + +/** + * @brief Structure which contains the dbus interface information and its methods.i + * @since_tizen 4.0 + */ +typedef struct { + dbus_object_handle_h oh; + const char *name; + const dbus_method_s *methods; + int nr_methods; +} dbus_interface_u; + +#define dh_get_param_from_var(gvar, signature, ...) ((g_strcmp0(signature, g_variant_get_type_string(gvar)) == 0) ? g_variant_get(gvar, signature, __VA_ARGS__), TRUE : FALSE) + +#define dbus_handle_new_g_variant_tuple() g_variant_new_tuple(NULL, 0) + +/** + * @brief Callback function which is called when the user data needs to be released. + * @since_tizen 4.0 + */ +typedef void (*destroy_notified)(void *data); + +typedef struct { + dbus_pending_cb func; + void *data; +} pending_call_data; + +int dbus_handle_request_bus_name(dbus_handle_h handle, const char *bus_name); + +dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv); + +int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface); +int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path); + +int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u); +int dbus_handle_register_dbus_object_all(dbus_handle_h handle); + +guint subscribe_dbus_signal(dbus_handle_h handle, const char *path, const char *iface, const char *name, GDBusSignalCallback cb, void *data, destroy_notified free_func); +void unsubscribe_dbus_signal(dbus_handle_h handle, guint id); + +GVariant *dbus_handle_make_simple_array(const char *sig, int *param); + +int dbus_handle_broadcast_dbus_signal(const char *path, const char *iface, const char *name, const char *signature, const char *param[]); +int dbus_handle_broadcast_dbus_signal_var(const char *path, const char *iface, const char *name, GVariant *param); + +typedef struct +{ + guint pid; + guint uid; + gchar *unique_name; + gchar *sec_label; +} GDBusCredentials; + +int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender); +int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender); +int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds); +int dbus_handle_watch_name(const char *name, GBusNameAppearedCallback name_appeared_handler, GBusNameVanishedCallback name_vanished_handler, void *user_data); +void dbus_handle_unwatch_name(guint id); +dbus_handle_h dbus_handle_init(GBusType type, const char* bus_name); +char** dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name); +void dbush_handle_check_owner_name(dbus_handle_h handle, const char *owner_name); #endif diff --git a/src/core/device-idler.c b/src/core/device-idler.c index 2d58b63..d3bbec9 100644 --- a/src/core/device-idler.c +++ b/src/core/device-idler.c @@ -17,7 +17,7 @@ */ -#include +#include #include #include @@ -29,7 +29,7 @@ struct device_request { }; static GQueue req_queue = G_QUEUE_INIT; -static Ecore_Idler *idler; +static guint idler; static int free_request(struct device_request *req) { @@ -40,7 +40,7 @@ static int free_request(struct device_request *req) return 0; } -static Eina_Bool idler_cb(void *data) +static gboolean idler_cb(void *data) { struct device_request *req; @@ -52,11 +52,11 @@ static Eina_Bool idler_cb(void *data) } if (g_queue_is_empty(&req_queue)) { - idler = NULL; - return ECORE_CALLBACK_CANCEL; + idler = 0; + return G_SOURCE_REMOVE; } - return ECORE_CALLBACK_RENEW; + return G_SOURCE_CONTINUE; } static void process_next_request_in_idle(void) @@ -67,7 +67,7 @@ static void process_next_request_in_idle(void) if (idler) return; - idler = ecore_idler_add(idler_cb, NULL); + idler = g_idle_add(idler_cb, NULL); /** * if idler is null, * it means whole system might be an abnormal state. diff --git a/src/core/edbus-handler.c b/src/core/edbus-handler.c index b1f62d3..fff5a4c 100644 --- a/src/core/edbus-handler.c +++ b/src/core/edbus-handler.c @@ -64,7 +64,7 @@ struct watch_info { }; static dd_list *edbus_object_list; -static dd_list *edbus_owner_list; +//static dd_list *edbus_owner_list; static dd_list *edbus_handler_list; static dd_list *edbus_watch_list; static int edbus_init_val; @@ -671,82 +671,82 @@ static void request_name_cb(void *data, DBusMessage *msg, DBusError *error) 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); - } +// 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, item; - char *pa[1]; - char *name; - char *entry; - - pa[0] = VIBRATOR_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); +// DBusError err; +// DBusMessage *msg; +// DBusMessageIter array, item; +// char *pa[1]; +// char *name; +// char *entry; +// +// pa[0] = VIBRATOR_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) diff --git a/src/core/main.c b/src/core/main.c index 8ae1fb9..f2e39cc 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -20,13 +20,15 @@ #include #include #include +#include #include "core/log.h" #include "core/common.h" -#include "core/edbus-handler.h" #include "core/dbus.h" #include "haptic/haptic.h" +static GMainLoop *mainloop = NULL; + static void sig_quit(int signo) { _D("received SIGTERM signal %d", signo); @@ -36,15 +38,23 @@ static void sig_usr1(int signo) { _D("received SIGUSR1 signal %d, feedbackd'll be finished!", signo); - ecore_main_loop_quit(); + if (mainloop) { + if (g_main_loop_is_running(mainloop)) + g_main_loop_quit(mainloop); + mainloop = NULL; + } } int main(int argc, char **argv) { int ret; - ecore_init(); - edbus_init(NULL); + mainloop = g_main_loop_new(NULL, FALSE); + + if (!dbus_handle_init(G_BUS_TYPE_SYSTEM, VIBRATOR_BUS_NAME)) { + _E("failed to init dbus connection"); + } + ret = haptic_probe(); if (ret != 0) { _E("[haptic] probe fail"); @@ -55,11 +65,13 @@ int main(int argc, char **argv) signal(SIGTERM, sig_quit); signal(SIGUSR1, sig_usr1); - ecore_main_loop_begin(); + /* g_main_loop */ + g_main_loop_run(mainloop); _D("[haptic] deinitialize"); haptic_exit(); - edbus_exit(NULL); - ecore_shutdown(); + g_main_loop_unref(mainloop); + mainloop = NULL; + return 0; } diff --git a/src/haptic/circle.c b/src/haptic/circle.c index 2d99195..6555d40 100644 --- a/src/haptic/circle.c +++ b/src/haptic/circle.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "core/log.h" @@ -39,7 +38,7 @@ static int fd_play = -1, fd_stop = -1; static dd_list *handle_list; -static Ecore_Timer *stop_timer; +static guint stop_timer; static int unique_number; static bool state = false; @@ -55,7 +54,7 @@ static bool find_from_list(int handle) return false; } -static Eina_Bool timer_cb(void *data) +static gboolean timer_cb(void *data) { int device_handle = (int)(long)data; int ret; @@ -66,22 +65,22 @@ static Eina_Bool timer_cb(void *data) found = find_from_list(device_handle); if (!found) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; /* stop previous vibration */ if (fd_stop < 0) { fd_stop = open(CIRCLE_OFF_PATH, O_RDONLY); if (fd_stop < 0) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } ret = read(fd_stop, buf, BUF_SIZE); if (ret < 0) { _E("failed to stop"); - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } - stop_timer = NULL; + stop_timer = 0; - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } static int get_device_count(int *count) @@ -163,8 +162,8 @@ static int close_device(int device_handle) if (r >= 0) { _D("device handle %d is closed and timer deleted", device_handle); if (stop_timer) { - ecore_timer_del(stop_timer); - stop_timer = NULL; + g_source_remove(stop_timer); + stop_timer = 0; } } @@ -221,7 +220,8 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* register timer */ if (duration) { - stop_timer = ecore_timer_add(duration/1000.f, timer_cb, (void *)(long)device_handle); + stop_timer = g_timeout_add_seconds(duration/1000, timer_cb, (void *)(long)device_handle); + if (!stop_timer) _E("Failed to add timer callback"); } @@ -268,8 +268,8 @@ static int stop_device(int device_handle) return -errno; } if (stop_timer) { - ecore_timer_del(stop_timer); - stop_timer = NULL; + g_source_remove(stop_timer); + stop_timer = 0; } return 0; @@ -284,7 +284,7 @@ static int get_device_state(int device_index, int *effect_state) return 0; } -static int create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt) +static int create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt) { _E("Not support feature"); return -EACCES; diff --git a/src/haptic/emulator.c b/src/haptic/emulator.c index db5492a..4548952 100644 --- a/src/haptic/emulator.c +++ b/src/haptic/emulator.c @@ -132,7 +132,7 @@ static int get_device_state(int device_index, int *effect_state) return 0; } -static int create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt) +static int create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt) { _E("Not support feature"); return -EACCES; diff --git a/src/haptic/gpio_haptic.c b/src/haptic/gpio_haptic.c old mode 100755 new mode 100644 index 314ca3b..c44e768 --- a/src/haptic/gpio_haptic.c +++ b/src/haptic/gpio_haptic.c @@ -18,7 +18,6 @@ #include #include -#include #include "core/log.h" #include "haptic.h" @@ -76,7 +75,7 @@ static int unique_number; static bool state = false; //static bool is_playing = false; -static Ecore_Timer *stop_timer = NULL; +static guint stop_timer = 0; static int gpio_haptic_stop_device(int handle); @@ -92,7 +91,7 @@ static bool find_from_list(int handle) } /* START: Haptic Module APIs */ -static Eina_Bool gpio_haptic_timer_cb(void *data) +static gboolean gpio_haptic_timer_cb(void *data) { int handle = (int)(long)data; bool found; @@ -101,7 +100,7 @@ static Eina_Bool gpio_haptic_timer_cb(void *data) found = find_from_list(handle); if (!found) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; if (device_handle == NULL) { if (peripheral_i2c_open(GPIO_I2C_BUS_INDEX, DRV2605L_DEFAULT_ADDR, &device_handle) < PERIPHERAL_ERROR_NONE) { @@ -113,8 +112,8 @@ static Eina_Bool gpio_haptic_timer_cb(void *data) /* stop playing */ peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_INTERNAL_TRIGGER); - stop_timer = NULL; - return ECORE_CALLBACK_CANCEL; + stop_timer = 0; + return G_SOURCE_REMOVE; } static int gpio_haptic_get_device_count(int *count) @@ -192,8 +191,9 @@ static int gpio_haptic_close_device(int handle) /* unregister existing timer */ if (r >= 0) { if (stop_timer) { - ecore_timer_del(stop_timer); - stop_timer = NULL; + //ecore_timer_del(stop_timer); + g_source_remove(stop_timer); + stop_timer = 0; } } @@ -247,7 +247,8 @@ static int gpio_haptic_vibrate_monotone(int handle, int duration, int level, int /* register timer */ if (duration) { - stop_timer = ecore_timer_add(duration/1000.f, gpio_haptic_timer_cb, (void *)(long)handle); + //stop_timer = ecore_timer_add(duration/1000.f, gpio_haptic_timer_cb, (void *)(long)handle); + stop_timer = g_timeout_add_seconds(duration/1000, gpio_haptic_timer_cb, (void *)(long)handle); if (!stop_timer) _E("Failed to add timer callback"); } @@ -286,8 +287,9 @@ static int gpio_haptic_stop_device(int handle) peripheral_i2c_write_register_byte(device_handle, DRV2605L_REGISTER_MODE, MODE_INTERNAL_TRIGGER); if (stop_timer) { - ecore_timer_del(stop_timer); - stop_timer = NULL; + //ecore_timer_del(stop_timer); + g_source_remove(stop_timer); + stop_timer = 0; } return 0; @@ -308,7 +310,7 @@ static int gpio_haptic_vibrate_buffer(int handle, const unsigned char *vibe_buff return -EACCES; } -static int gpio_haptic_create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt) +static int gpio_haptic_create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt) { _E("Not support feature"); return -EACCES; diff --git a/src/haptic/haptic-plugin-intf.h b/src/haptic/haptic-plugin-intf.h index c507397..3565d71 100644 --- a/src/haptic/haptic-plugin-intf.h +++ b/src/haptic/haptic-plugin-intf.h @@ -32,7 +32,7 @@ struct haptic_plugin_ops { int (*is_supported) (const char*); int (*stop_device) (int); int (*get_device_state) (int, int*); - int (*create_effect) (unsigned char*, int, haptic_module_effect_element*, int); + int (*create_effect) (unsigned char*, int, const haptic_module_effect_element*, int); int (*get_buffer_duration) (int, const unsigned char*, int*); int (*convert_binary) (const unsigned char*, int, const char*); }; diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 6741a58..4578fce 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -28,8 +28,8 @@ #include "core/list.h" #include "core/common.h" #include "core/device-idler.h" -#include "core/edbus-handler.h" #include "core/config-parser.h" +#include "core/dbus.h" #include "haptic.h" #define HAPTIC_CONF_PATH "/etc/feedbackd/haptic.conf" @@ -156,10 +156,11 @@ static int convert_magnitude_by_conf(int level) return DEFAULT_FEEDBACK_LEVEL * HAPTIC_FEEDBACK_STEP; } -static DBusMessage *edbus_get_count(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_get_count(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) + { - DBusMessageIter iter; - DBusMessage *reply; int ret, val; if (!CHECK_VALID_OPS(h_ops, ret)) @@ -170,19 +171,18 @@ static DBusMessage *edbus_get_count(E_DBus_Object *obj, DBusMessage *msg) 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; + return g_variant_new("(i)", ret); } -static void haptic_name_owner_changed(const char *sender, void *data) +void haptic_name_owner_changed(GDBusConnection *connection, + const gchar *name, + gpointer user_data) { dd_list *n; - struct haptic_info *info = data; + struct haptic_info *info = user_data; int handle; - _I("%s (sender:%s)", __func__, sender); + _I("%s (sender:%s)", __func__, name); if (!info) return; @@ -196,6 +196,7 @@ static void haptic_name_owner_changed(const char *sender, void *data) remove_haptic_info(info); } +static guint id_name_watch; static struct haptic_info *add_haptic_info(const char *sender) { struct haptic_info *info; @@ -209,7 +210,7 @@ static struct haptic_info *add_haptic_info(const char *sender) info->sender = strdup(sender); DD_LIST_APPEND(haptic_handle_list, info); - register_edbus_watch(sender, haptic_name_owner_changed, info); + id_name_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info); return info; } @@ -218,7 +219,7 @@ static int remove_haptic_info(struct haptic_info *info) { assert(info); - unregister_edbus_watch(info->sender, haptic_name_owner_changed); + dbus_handle_unwatch_name(id_name_watch); DD_LIST_REMOVE(haptic_handle_list, info); DD_LIST_FREE_LIST(info->handle_list); @@ -245,13 +246,13 @@ static struct haptic_info *get_matched_haptic_info(const char *sender) return NULL; } -static DBusMessage *edbus_open_device(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_open_device(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) + { - DBusMessageIter iter; - DBusMessage *reply; int index, handle, ret; struct haptic_info *info; - const char *sender; /* Load haptic module before booting done */ if (!CHECK_VALID_OPS(h_ops, ret)) { @@ -260,17 +261,12 @@ static DBusMessage *edbus_open_device(E_DBus_Object *obj, DBusMessage *msg) goto exit; } - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(i)", &index); ret = h_ops->open_device(index, &handle); if (ret < 0) goto exit; - - sender = dbus_message_get_sender(msg); if (!sender) { ret = -EPERM; h_ops->close_device(handle); @@ -293,31 +289,23 @@ static DBusMessage *edbus_open_device(E_DBus_Object *obj, DBusMessage *msg) ret = handle; 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; + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_close_device(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_close_device(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - DBusMessageIter iter; - DBusMessage *reply; unsigned int handle; int ret; struct haptic_info *info; - const char *sender; int cnt; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(u)", &handle); - sender = dbus_message_get_sender(msg); if (!sender) { _E("fail to get sender from dbus message"); ret = -EPERM; @@ -340,16 +328,13 @@ static DBusMessage *edbus_close_device(E_DBus_Object *obj, DBusMessage *msg) remove_haptic_info(info); 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; + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_vibrate_monotone(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_vibrate_monotone(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - DBusMessageIter iter; - DBusMessage *reply; unsigned int handle; int duration, level, priority, e_handle, ret = 0; @@ -359,13 +344,7 @@ static DBusMessage *edbus_vibrate_monotone(E_DBus_Object *obj, DBusMessage *msg) if (haptic_disabled) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, - DBUS_TYPE_INT32, &duration, - DBUS_TYPE_INT32, &level, - DBUS_TYPE_INT32, &priority, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(uiii)", &handle, &duration, &level, &priority); /* convert as per conf value */ level = convert_magnitude_by_conf(level); @@ -383,20 +362,18 @@ static DBusMessage *edbus_vibrate_monotone(E_DBus_Object *obj, DBusMessage *msg) ret = e_handle; 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; - + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_vibrate_buffer(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_vibrate_buffer(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - DBusMessageIter iter; - DBusMessage *reply; unsigned int handle; - unsigned char *data; - int size, iteration, level, priority, e_handle, ret = 0; + const unsigned char *data = NULL; + GVariant *pvar = NULL; + gsize size = 0; + int iteration, level, priority, e_handle, ret = 0; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; @@ -404,14 +381,9 @@ static DBusMessage *edbus_vibrate_buffer(E_DBus_Object *obj, DBusMessage *msg) if (haptic_disabled) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size, - DBUS_TYPE_INT32, &iteration, - DBUS_TYPE_INT32, &level, - DBUS_TYPE_INT32, &priority, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(u@ayiii)", &handle, &pvar, &iteration, &level, &priority); + data = g_variant_get_fixed_array(pvar, &size, sizeof(char)); + g_variant_unref(pvar); /* convert as per conf value */ level = convert_magnitude_by_conf(level); @@ -425,10 +397,7 @@ static DBusMessage *edbus_vibrate_buffer(E_DBus_Object *obj, DBusMessage *msg) ret = e_handle; 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; + return g_variant_new("(i)", ret); } static void vibrate_effect_idler_cb(void *data) @@ -441,13 +410,13 @@ static void vibrate_effect_idler_cb(void *data) free(vibrate_info); } -static DBusMessage *edbus_vibrate_effect(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_vibrate_effect(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - DBusMessageIter iter; - DBusMessage *reply; struct vibrate_effect_info *vibrate_info; unsigned int handle; - char *pattern; + char *pattern = NULL; int level, priority, ret = 0; if (!CHECK_VALID_OPS(h_ops, ret)) @@ -456,13 +425,7 @@ static DBusMessage *edbus_vibrate_effect(E_DBus_Object *obj, DBusMessage *msg) if (haptic_disabled) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, - DBUS_TYPE_STRING, &pattern, - DBUS_TYPE_INT32, &level, - DBUS_TYPE_INT32, &priority, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(usii)", &handle, &pattern, &level, &priority); /* convert as per conf value */ level = convert_magnitude_by_conf(level); @@ -482,7 +445,8 @@ static DBusMessage *edbus_vibrate_effect(E_DBus_Object *obj, DBusMessage *msg) goto exit; } vibrate_info->handle = handle; - vibrate_info->pattern = strdup(pattern); + vibrate_info->pattern = pattern; + pattern = NULL; if (!vibrate_info->pattern) { _E("failed to allocate memory for pattern"); ret = -errno; @@ -495,16 +459,14 @@ static DBusMessage *edbus_vibrate_effect(E_DBus_Object *obj, DBusMessage *msg) ret = add_idle_request(vibrate_effect_idler_cb, (void *)vibrate_info); 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; + g_free(pattern); + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_stop_device(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_stop_device(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - DBusMessageIter iter; - DBusMessage *reply; unsigned int handle; int ret = 0; @@ -514,63 +476,50 @@ static DBusMessage *edbus_stop_device(E_DBus_Object *obj, DBusMessage *msg) if (haptic_disabled) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(u)", &handle); ret = h_ops->stop_device(handle); 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; + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_get_state(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_get_state(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - DBusMessageIter iter; - DBusMessage *reply; int index, state, ret; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(i)", &index); ret = h_ops->get_device_state(index, &state); if (ret >= 0) ret = state; 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; + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_create_effect(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_create_effect(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { static unsigned char data[MAX_EFFECT_BUFFER]; - static unsigned char *p = data; - DBusMessageIter iter, arr; - DBusMessage *reply; - haptic_module_effect_element *elem_arr; - int i, size, cnt, ret, bufsize = sizeof(data); + //static unsigned char *p = data; + const haptic_module_effect_element *elem_arr; + int i, cnt, ret, bufsize = sizeof(data); + GVariant *pvar = NULL; + gsize size = 0; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &bufsize, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &elem_arr, &size, - DBUS_TYPE_INT32, &cnt, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(i@ayi)", &bufsize, &pvar, &cnt); + elem_arr = g_variant_get_fixed_array(pvar, &size, sizeof(char)); + g_variant_unref(pvar); if (bufsize > MAX_EFFECT_BUFFER) { ret = -ENOMEM; @@ -584,73 +533,64 @@ static DBusMessage *edbus_create_effect(E_DBus_Object *obj, DBusMessage *msg) ret = h_ops->create_effect(data, bufsize, elem_arr, cnt); exit: - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr); - dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &p, bufsize); - dbus_message_iter_close_container(&iter, &arr); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret); - return reply; + pvar = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, data, sizeof(data), sizeof(char)); + return g_variant_new("(@ayi)", pvar, ret); } -static DBusMessage *edbus_get_duration(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_get_duration(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { - DBusMessageIter iter; - DBusMessage *reply; unsigned int handle; - unsigned char *data; - int size, duration, ret; + const unsigned char *data; + int duration, ret; + GVariant *pvar = NULL; + gsize size = 0; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size, - DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(u@ay)", &handle, &pvar); + data = g_variant_get_fixed_array(pvar, &size, sizeof(char)); + g_variant_unref(pvar); ret = h_ops->get_buffer_duration(handle, data, &duration); if (ret >= 0) ret = duration; 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; + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_save_binary(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_save_binary(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) + { - DBusMessageIter iter; - DBusMessage *reply; - unsigned char *data; - char *path; - int size, ret; + const unsigned char *data = NULL; + char *file_path = NULL; + int ret; + GVariant *pvar; + gsize size = 0; if (!CHECK_VALID_OPS(h_ops, ret)) goto exit; - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size, - DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(@ays)", &pvar, &file_path); + data = g_variant_get_fixed_array(pvar, &size, sizeof(char)); + g_variant_unref(pvar); - _D("file path : %s", path); - ret = h_ops->convert_binary(data, size, path); + _D("file path : %s", file_path); + ret = h_ops->convert_binary(data, size, file_path); 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; + g_free(file_path); + return g_variant_new("(i)", ret); } -static DBusMessage *edbus_show_handle_list(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_show_handle_list(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { dd_list *n; dd_list *elem; @@ -662,14 +602,15 @@ static DBusMessage *edbus_show_handle_list(E_DBus_Object *obj, DBusMessage *msg) _D("%s %d", info->sender, (int)(long)elem->data); } - return dbus_message_new_method_return(msg); + return g_variant_new_tuple(NULL, 0); } -static DBusMessage *edbus_pattern_is_supported(E_DBus_Object *obj, DBusMessage *msg) +GVariant *hdbus_pattern_is_supported(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) + { - DBusMessageIter iter; - DBusMessage *reply; - char *data; + char *data = NULL; int ret = 0; if (!CHECK_VALID_OPS(h_ops, ret)) @@ -678,21 +619,15 @@ static DBusMessage *edbus_pattern_is_supported(E_DBus_Object *obj, DBusMessage * if (haptic_disabled) goto exit; - if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &data, - DBUS_TYPE_INVALID)) { - ret = -EINVAL; - goto exit; - } + g_variant_get(param, "(s)", &data); ret = h_ops->is_supported(data); _I("%s is supported : %d", data, ret); 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; + g_free(data); + return g_variant_new("(i)", ret); } static int haptic_internal_init(void) @@ -711,7 +646,13 @@ static int haptic_internal_exit(void) return h_ops->close_device(g_handle); } -static void haptic_hardkey_changed_cb(void *data, DBusMessage *msg) +static void haptic_hardkey_changed_cb(GDBusConnection *conn, + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *name, + GVariant *param, + gpointer data) { int level, status, e_handle, ret; @@ -751,7 +692,13 @@ static void haptic_hardkey_changed_cb(void *data, DBusMessage *msg) return; } -static void haptic_poweroff_cb(void *data, DBusMessage *msg) +static void haptic_poweroff_cb(GDBusConnection *conn, + const gchar *sender, + const gchar *path, + const gchar *iface, + const gchar *name, + GVariant *param, + gpointer data) { int e_handle, ret; struct timespec time = {0,}; @@ -864,23 +811,30 @@ out: return 0; } -static const struct edbus_method edbus_methods[] = { - { "GetCount", NULL, "i", edbus_get_count }, - { "OpenDevice", "i", "i", edbus_open_device }, - { "CloseDevice", "u", "i", edbus_close_device }, - { "StopDevice", "u", "i", edbus_stop_device }, - { "VibrateMonotone", "uiii", "i", edbus_vibrate_monotone }, - { "VibrateBuffer", "uayiii", "i", edbus_vibrate_buffer }, - { "VibrateEffect", "usii", "i", edbus_vibrate_effect }, - { "GetState", "i", "i", edbus_get_state }, - { "GetDuration", "uay", "i", edbus_get_duration }, - { "CreateEffect", "iayi", "ayi", edbus_create_effect }, - { "SaveBinary", "ays", "i", edbus_save_binary }, - { "ShowHandleList", NULL, NULL, edbus_show_handle_list }, - { "IsSupported", "s", "i", edbus_pattern_is_supported }, +static const dbus_method_s hdbus_methods[] = { + { "GetCount", NULL, "i", hdbus_get_count }, + { "OpenDevice", "i", "i", hdbus_open_device }, + { "CloseDevice", "u", "i", hdbus_close_device }, + { "StopDevice", "u", "i", hdbus_stop_device }, + { "VibrateMonotone", "uiii", "i", hdbus_vibrate_monotone }, + { "VibrateBuffer", "uayiii", "i", hdbus_vibrate_buffer }, + { "VibrateEffect", "usii", "i", hdbus_vibrate_effect }, + { "GetState", "i", "i", hdbus_get_state }, + { "GetDuration", "uay", "i", hdbus_get_duration }, + { "CreateEffect", "iayi", "ayi", hdbus_create_effect }, + { "SaveBinary", "ays", "i", hdbus_save_binary }, + { "ShowHandleList", NULL, NULL, hdbus_show_handle_list }, + { "IsSupported", "s", "i", hdbus_pattern_is_supported }, /* Add methods here */ }; +static const dbus_interface_u dbus_interface = { + .oh = NULL, + .name = VIBRATOR_INTERFACE_HAPTIC, + .methods = hdbus_methods, + .nr_methods = ARRAY_SIZE(hdbus_methods), +}; + int haptic_probe(void) { /** @@ -891,6 +845,9 @@ int haptic_probe(void) return haptic_module_load(); } +guint id_sig_change_hardkey; +guint id_sig_pwr_off_state; + void haptic_init(void) { int r; @@ -903,24 +860,24 @@ void haptic_init(void) } /* init dbus interface */ - r = register_edbus_interface_and_method(VIBRATOR_PATH_HAPTIC, - VIBRATOR_INTERFACE_HAPTIC, - edbus_methods, ARRAY_SIZE(edbus_methods)); + r = dbus_handle_register_dbus_object(NULL, VIBRATOR_PATH_HAPTIC, &dbus_interface); if (r < 0) - _E("fail to init edbus interface and method(%d)", r); + _E("fail to init hdbus interface and method(%d)", r); /* register notifier for below each event */ - register_edbus_signal_handler(DEVICED_PATH_KEY, - DEVICED_INTERFACE_KEY, - SIGNAL_CHANGE_HARDKEY, - haptic_hardkey_changed_cb); + id_sig_change_hardkey = subscribe_dbus_signal(NULL, DEVICED_PATH_KEY, DEVICED_INTERFACE_KEY, SIGNAL_CHANGE_HARDKEY, haptic_hardkey_changed_cb, NULL, NULL); + if (id_sig_change_hardkey <= 0) { + _E("Failed to register signal handler! %d", r); + return; + } - register_edbus_signal_handler(DEVICED_PATH_POWEROFF, - DEVICED_INTERFACE_POWEROFF, - SIGNAL_POWEROFF_STATE, - haptic_poweroff_cb); + id_sig_pwr_off_state = subscribe_dbus_signal(NULL, DEVICED_PATH_POWEROFF, DEVICED_INTERFACE_POWEROFF, SIGNAL_POWEROFF_STATE, haptic_poweroff_cb, NULL, NULL); + if (id_sig_pwr_off_state <= 0) { + _E("Failed to register signal handler! %d", r); + return; + } - broadcast_edbus_signal(VIBRATOR_PATH_HAPTIC, + dbus_handle_broadcast_dbus_signal(VIBRATOR_PATH_HAPTIC, VIBRATOR_INTERFACE_HAPTIC, SIGNAL_VIBRATOR_INITIATED, "", NULL); @@ -945,13 +902,8 @@ void haptic_exit(void) vconf_ignore_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb); /* unregister notifier for below each event */ - unregister_edbus_signal_handler(DEVICED_PATH_KEY, - DEVICED_INTERFACE_KEY, - SIGNAL_CHANGE_HARDKEY); - - unregister_edbus_signal_handler(DEVICED_PATH_POWEROFF, - DEVICED_INTERFACE_POWEROFF, - SIGNAL_POWEROFF_STATE); + unsubscribe_dbus_signal(NULL, id_sig_change_hardkey); + unsubscribe_dbus_signal(NULL, id_sig_pwr_off_state); /* release haptic data memory */ safe_free(haptic_conf.level_arr); diff --git a/src/haptic/standard-mix.c b/src/haptic/standard-mix.c index 800bb10..a234ec7 100644 --- a/src/haptic/standard-mix.c +++ b/src/haptic/standard-mix.c @@ -28,7 +28,6 @@ #include #include #include -#include #include "core/log.h" #include "core/list.h" @@ -74,7 +73,7 @@ struct ff_info_buffer { struct ff_info { int handle; - Ecore_Timer *timer; + guint timer; struct ff_effect effect; struct ff_info_buffer *ffinfobuffer; int currentindex; @@ -110,7 +109,7 @@ static dd_list *handle_list; static dd_list *vib_conf_list; static dd_list *vib_duration_conf_list; static dd_list *vib_waiting_conf_list; -static Ecore_Timer *duration_timer; +static guint duration_timer; static char ff_path[PATH_MAX]; static int unique_number; @@ -162,10 +161,10 @@ static Eina_Bool timer_cb(void *data) struct ff_info *info = (struct ff_info *)data; if (!info) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; if (!check_valid_handle(info)) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; _I("stop vibration by timer : id(%d)", info->effect.id); @@ -175,7 +174,7 @@ static Eina_Bool timer_cb(void *data) /* reset timer */ info->timer = NULL; - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } static int ff_find_device(void) @@ -417,7 +416,7 @@ static int close_device(int device_handle) /* unregister existing timer */ if (r >= 0 && info->timer) { _D("device handle %d is closed and timer deleted", device_handle); - ecore_timer_del(info->timer); + g_source_remove(info->timer); info->timer = NULL; } @@ -466,7 +465,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* unregister existing timer */ if (info->timer) { ff_stop(ff_fd, &info->effect); - ecore_timer_del(info->timer); + g_source_remove(info->timer); info->timer = NULL; } @@ -489,7 +488,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* register timer */ if (duration) { - info->timer = ecore_timer_add(duration/1000.f, timer_cb, info); + info->timer = g_timeout_add_seconds(duration/1000, timer_cb, info); if (!info->timer) _E("Failed to add timer callback"); } @@ -501,7 +500,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p return 0; } -static Eina_Bool _buffer_play(void *cbdata) +static gboolean _buffer_play(void *cbdata) { struct ff_info *info = (struct ff_info *)cbdata; struct ff_info_header *header = &info->ffinfobuffer->header; @@ -526,17 +525,17 @@ static Eina_Bool _buffer_play(void *cbdata) if (info->currentindex < header->ff_info_data_count) { info->currentindex++; - info->timer = ecore_timer_add(length/1000.0f, _buffer_play, info); + info->timer = g_timeout_add_seconds(length/1000, _buffer_play, info); } else { --header->iteration; if (header->iteration > 0) { info->currentindex = 0; - info->timer = ecore_timer_add(0.0, _buffer_play, info); + info->timer = g_timeout_add_seconds(0, _buffer_play, info); } else info->timer = NULL; } - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } static void print_buffer(const unsigned char *vibe_buffer) @@ -586,7 +585,7 @@ static int vibrate_custom_buffer(int device_handle, const unsigned char *vibe_bu info->currentindex = 0; if (info->timer) - ecore_timer_del(info->timer); + g_source_remove(info->timer); if (header->iteration > 0) _buffer_play(info); @@ -594,7 +593,7 @@ static int vibrate_custom_buffer(int device_handle, const unsigned char *vibe_bu return 0; } -static Eina_Bool haptic_duration_play(void *data) +static gboolean haptic_duration_play(void *data) { struct haptic_data *h_data; double time; @@ -607,18 +606,18 @@ static Eina_Bool haptic_duration_play(void *data) if (!data) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; if (duration_timer) { - ecore_timer_del(duration_timer); - duration_timer = NULL; + g_source_remove(duration_timer); + duration_timer = 0; } h_data = (struct haptic_data *)data; if (h_data->stop) { h_data->stop = false; free(h_data); - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } index = h_data->index; @@ -628,7 +627,7 @@ static Eina_Bool haptic_duration_play(void *data) if (!h_data->duration_config[index]) { free(h_data); - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } duration = h_data->duration_config[index]; @@ -642,7 +641,8 @@ static Eina_Bool haptic_duration_play(void *data) else time = duration + h_data->waiting_config[index]; - duration_timer = ecore_timer_add(time/1000.0f, haptic_duration_play, (void *)h_data); + /*duration_timer = ecore_timer_add(time/1000.0f, haptic_duration_play, (void *)h_data);*/ + duration_timer = g_timeout_add_seconds(time/1000, haptic_duration_play, (void *)h_data); _D("timer: %d", time); } @@ -654,7 +654,7 @@ static Eina_Bool haptic_duration_play(void *data) if (h_data) h_data->stop = true; } - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle) @@ -792,7 +792,7 @@ static int stop_device(int device_handle) /* unregister existing timer */ if (r >= 0 && info->timer) { - ecore_timer_del(info->timer); + g_source_remove(info->timer); info->timer = NULL; } @@ -820,7 +820,7 @@ static int get_device_state(int device_index, int *effect_state) return 0; } -static int create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt) +static int create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt) { _E("Not supported feature"); return -EACCES; diff --git a/src/haptic/standard-vibcore.c b/src/haptic/standard-vibcore.c index 09ce668..7361bb2 100644 --- a/src/haptic/standard-vibcore.c +++ b/src/haptic/standard-vibcore.c @@ -19,7 +19,6 @@ #include #include -#include #include "core/log.h" #include "core/list.h" @@ -40,7 +39,7 @@ struct duration_data { }; static dd_list *vib_conf_list; -static Ecore_Timer *duration_timer; +static guint duration_timer; static t_vibrate_monotone real_vibrate_monotone; @@ -161,7 +160,7 @@ int standard_is_supported(const char *pattern) return ret; } -static Eina_Bool haptic_duration_play(void *data) +static gboolean haptic_duration_play(void *data) { dd_list *head, *n, *next; struct haptic_data *h_data; @@ -169,8 +168,8 @@ static Eina_Bool haptic_duration_play(void *data) int ret = 0; if (duration_timer) { - ecore_timer_del(duration_timer); - duration_timer = NULL; + g_source_remove(duration_timer); + duration_timer = 0; } if (!data) { @@ -198,9 +197,9 @@ static Eina_Bool haptic_duration_play(void *data) if (next) { h_data->vibration_data = next; - duration_timer = ecore_timer_add((node->duration + node->wait)/1000.0f, haptic_duration_play, (void *)h_data); + duration_timer = g_timeout_add_seconds((node->duration + node->wait)/1000, haptic_duration_play, (void *)h_data); } else - duration_timer = ecore_timer_add((node->duration + node->wait)/1000.0f, haptic_duration_play, NULL); + duration_timer = g_timeout_add_seconds((node->duration + node->wait)/1000, haptic_duration_play, NULL); ret = real_vibrate_monotone(h_data->handle, node->duration, h_data->level, h_data->priority, NULL); if (!next) @@ -214,7 +213,7 @@ static Eina_Bool haptic_duration_play(void *data) h_data->stop = true; } out: - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } int standard_set_vib_function(t_vibrate_monotone func) @@ -265,8 +264,8 @@ int standard_vibrate_close() if (duration_timer) { _I("Remove duration_timer"); - ecore_timer_del(duration_timer); - duration_timer = NULL; + g_source_remove(duration_timer); + duration_timer = 0; } return 0; diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 2a914ca..8e77b20 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -28,7 +28,6 @@ #include #include #include -#include #include "core/log.h" #include "core/list.h" @@ -64,7 +63,7 @@ struct ff_info_buffer { struct ff_info { int handle; - Ecore_Timer *timer; + guint timer; struct ff_effect effect; struct ff_info_buffer *ffinfobuffer; int currentindex; @@ -119,15 +118,15 @@ static bool check_fd(int *fd) } static int ff_stop(int fd, struct ff_effect *effect); -static Eina_Bool timer_cb(void *data) +static gboolean timer_cb(void *data) { struct ff_info *info = (struct ff_info *)data; if (!info) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; if (!check_valid_handle(info)) - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; _I("stop vibration by timer : id(%d)", info->effect.id); @@ -135,9 +134,9 @@ static Eina_Bool timer_cb(void *data) ff_stop(ff_fd, &info->effect); /* reset timer */ - info->timer = NULL; + info->timer = 0; - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } static int ff_find_device(void) @@ -379,8 +378,8 @@ static int close_device(int device_handle) /* unregister existing timer */ if (r >= 0 && info->timer) { _D("device handle %d is closed and timer deleted", device_handle); - ecore_timer_del(info->timer); - info->timer = NULL; + g_source_remove(info->timer); + info->timer = 0; } standard_vibrate_close(); @@ -430,8 +429,8 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* unregister existing timer */ if (info->timer) { ff_stop(ff_fd, &info->effect); - ecore_timer_del(info->timer); - info->timer = NULL; + g_source_remove(info->timer); + info->timer = 0; } /* set effect as per arguments */ @@ -453,7 +452,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p /* register timer */ if (duration) { - info->timer = ecore_timer_add(duration/1000.f, timer_cb, info); + info->timer = g_timeout_add_seconds(duration/1000, timer_cb, info); if (!info->timer) _E("Failed to add timer callback"); } @@ -465,7 +464,7 @@ static int vibrate_monotone(int device_handle, int duration, int feedback, int p return 0; } -static Eina_Bool _buffer_play(void *cbdata) +static gboolean _buffer_play(void *cbdata) { struct ff_info *info = (struct ff_info *)cbdata; struct ff_info_header *header = &info->ffinfobuffer->header; @@ -490,17 +489,17 @@ static Eina_Bool _buffer_play(void *cbdata) if (info->currentindex < header->ff_info_data_count) { info->currentindex++; - info->timer = ecore_timer_add(length/1000.0f, _buffer_play, info); + info->timer = g_timeout_add_seconds(length/1000, _buffer_play, info); } else { --header->iteration; if (header->iteration > 0) { info->currentindex = 0; - info->timer = ecore_timer_add(0.0, _buffer_play, info); + info->timer = g_timeout_add_seconds(0, _buffer_play, info); } else - info->timer = NULL; + info->timer = 0; } - return ECORE_CALLBACK_CANCEL; + return G_SOURCE_REMOVE; } static void print_buffer(const unsigned char *vibe_buffer) @@ -550,7 +549,7 @@ static int vibrate_custom_buffer(int device_handle, const unsigned char *vibe_bu info->currentindex = 0; if (info->timer) - ecore_timer_del(info->timer); + g_source_remove(info->timer); if (header->iteration > 0) _buffer_play(info); @@ -605,8 +604,8 @@ static int stop_device(int device_handle) /* unregister existing timer */ if (r >= 0 && info->timer) { - ecore_timer_del(info->timer); - info->timer = NULL; + g_source_remove(info->timer); + info->timer = 0; } return 0; @@ -633,7 +632,7 @@ static int get_device_state(int device_index, int *effect_state) return 0; } -static int create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt) +static int create_effect(unsigned char *vibe_buffer, int max_bufsize, const haptic_module_effect_element *elem_arr, int max_elemcnt) { _E("Not support feature"); return -EACCES; -- 2.7.4 From 39452f1b0de2ff5f5de0aa273f2262b650fb9d8d Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Fri, 2 Feb 2018 19:47:34 +0900 Subject: [PATCH 12/16] Fix casting warning Change-Id: Ia0781461e5c6eaf5f01a4b1522eef852cfd5f415 Signed-off-by: pr.jung --- src/core/dbus.c | 211 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 113 insertions(+), 98 deletions(-) diff --git a/src/core/dbus.c b/src/core/dbus.c index 2d22d15..f21a073 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -182,11 +182,11 @@ static GDBusConnection * _get_bus_private(GBusType bus_type) } conn = g_dbus_connection_new_for_address_sync(address, - (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | - G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), - NULL, /* GDBusAuthObserver */ - NULL, - &err); + (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION), + NULL, /* GDBusAuthObserver */ + NULL, + &err); if (!conn || err) { _E("failed to get private bus\n"); g_error_free(err); @@ -779,7 +779,7 @@ static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b) dbus_interface_s * pa = (dbus_interface_s *)a; if (!pa->reg_id || !((guint*)b)) return -1; - return !(pa->reg_id == (guint)b); + return !(pa->reg_id == *((guint*)b)); } static gint _compare_dbus_method(gconstpointer a, gconstpointer b) @@ -907,8 +907,8 @@ static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, d /* libgio verify path and interface */ static void _method_call_handler(GDBusConnection *conn, - const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, - GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) { dbus_interface_s *iface_s = (dbus_interface_s *)user_data; const dbus_method_s *methods; @@ -1003,8 +1003,8 @@ static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *o g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered */ ret = g_dbus_connection_register_object(dh->conn, obj_path, ifaceinfo/*ref 2*/, &path_vtable, (void*)iface, - _free_func_object, - &err); + _free_func_object, + &err); if (err) { _E("failed to register object:err:%s:\n", err->message); ret = -1; @@ -1342,9 +1342,9 @@ static void _free_func_signal(gpointer data) } guint subscribe_dbus_signal(dbus_handle_h handle, const char *path, - const char *iface, const char *name, - GDBusSignalCallback cb, void *data, - destroy_notified free_func) + const char *iface, const char *name, + GDBusSignalCallback cb, void *data, + destroy_notified free_func) { dcl_dbus_handle(); @@ -1500,8 +1500,8 @@ static GVariant* _append_variant(const char *signature, const char *param[]) } int dbus_handle_broadcast_dbus_signal(const char *path, - const char *iface, const char *name, - const char *signature, const char *param[]) + const char *iface, const char *name, + const char *signature, const char *param[]) { dbus_handle_s *dh = NULL; GError *err = NULL; @@ -1526,8 +1526,8 @@ int dbus_handle_broadcast_dbus_signal(const char *path, } int dbus_handle_broadcast_dbus_signal_var(const char *path, - const char *iface, const char *name, - GVariant *param) + const char *iface, const char *name, + GVariant *param) { dbus_handle_s *dh = NULL; GError *err = NULL; @@ -1549,8 +1549,8 @@ int dbus_handle_broadcast_dbus_signal_var(const char *path, } GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[]) + const char *iface, const char *method, + const char *signature, const char *param[]) { GError *err = NULL; GVariant * var = NULL; @@ -1572,8 +1572,8 @@ GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, var = _append_variant(signature, param); ret = g_dbus_connection_call_sync(dh->conn, - dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); + dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); if (!ret || err) { if (err) { _E("failed to g_dbus_connection_call_sync:%s", err->message); @@ -1589,7 +1589,7 @@ GVariant *dbus_method_sync_with_reply(const char *dest, const char *path, } GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *var) + const char *iface, const char *method, GVariant *var) { GError *err = NULL; GVariant * ret = NULL; @@ -1611,8 +1611,8 @@ GVariant *dbus_method_sync_with_reply_var(const char *dest, const char *path, } ret = g_dbus_connection_call_sync(dh->conn, - dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); + dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); if (!ret || err) { if (err) { _E("failed to g_dbus_connection_call_sync:%s", err->message); @@ -1650,10 +1650,10 @@ gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size) } GVariant *dbus_method_with_unix_fd_list_sync_with_reply(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[], - int *in_fdlist, int in_size, - int **out_fdlist, int *out_size) + const char *iface, const char *method, + const char *signature, const char *param[], + int *in_fdlist, int in_size, + int **out_fdlist, int *out_size) { GError *err = NULL; GVariant * var = NULL; @@ -1739,10 +1739,10 @@ out: } GVariant *dbus_method_with_unix_fd_list_sync_with_reply_var(const char *dest, const char *path, - const char *iface, const char *method, - GVariant *param, - int *in_fdlist, int in_size, - int **out_fdlist, int *out_size) + const char *iface, const char *method, + GVariant *param, + int *in_fdlist, int in_size, + int **out_fdlist, int *out_size) { GError *err = NULL; GVariant * ret = NULL; @@ -1823,8 +1823,8 @@ out: } int dbus_method_sync(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[]) + const char *iface, const char *method, + const char *signature, const char *param[]) { int result; gboolean result_bool; @@ -1854,7 +1854,7 @@ int dbus_method_sync(const char *dest, const char *path, } int dbus_method_sync_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *param) + const char *iface, const char *method, GVariant *param) { int result; gboolean result_bool; @@ -1884,8 +1884,8 @@ int dbus_method_sync_var(const char *dest, const char *path, } int dbus_method_sync_timeout(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[], int timeout) + const char *iface, const char *method, + const char *signature, const char *param[], int timeout) { dbus_handle_s *dh = NULL; GError *err = NULL; @@ -1908,8 +1908,8 @@ int dbus_method_sync_timeout(const char *dest, const char *path, var = _append_variant(signature, param); reply = g_dbus_connection_call_sync(dh->conn, - dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err); + dest, path, iface, method, + var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout, NULL, &err); if (!reply || err) { _E("failed to g_dbus_connection_call_sync:%s", err->message); g_error_free(err); @@ -1927,8 +1927,8 @@ int dbus_method_sync_timeout(const char *dest, const char *path, } int dbus_method_sync_pairs(const char *dest, const char *path, - const char *iface, const char *method, - int num, va_list args) + const char *iface, const char *method, + int num, va_list args) { GError *err = NULL; GVariant * reply = NULL; @@ -1979,8 +1979,8 @@ int dbus_method_sync_pairs(const char *dest, const char *path, } int dbus_method_async_pairs(const char *dest, const char *path, - const char *iface, const char *method, - int num, va_list args) + const char *iface, const char *method, + int num, va_list args) { char *key, *value; GVariant *var; @@ -2011,16 +2011,16 @@ int dbus_method_async_pairs(const char *dest, const char *path, var = g_variant_new("(a{ss})", builder); g_dbus_connection_call(dh->conn, dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - NULL, - NULL); + var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + NULL, + NULL); return 0; } int dbus_method_async(const char *dest, const char *path, - const char *iface, const char *method, - const char *signature, const char *param[]) + const char *iface, const char *method, + const char *signature, const char *param[]) { GVariant * var = NULL; dbus_handle_s *dh = NULL; @@ -2040,15 +2040,15 @@ int dbus_method_async(const char *dest, const char *path, var = _append_variant(signature, param); g_dbus_connection_call(dh->conn, dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - NULL, - NULL); + var, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + NULL, + NULL); return 0; } int dbus_method_async_var(const char *dest, const char *path, - const char *iface, const char *method, GVariant *param) + const char *iface, const char *method, GVariant *param) { dbus_handle_s *dh = NULL; @@ -2064,17 +2064,17 @@ int dbus_method_async_var(const char *dest, const char *path, } g_dbus_connection_call(dh->conn, dest, path, iface, method, - param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - NULL, - NULL); + param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + NULL, + NULL); return 0; } /* callback should free gvariant */ static void _cb_pending(GDBusConnection *conn, - GAsyncResult *res, - gpointer user_data) + GAsyncResult *res, + gpointer user_data) { GVariant *reply = NULL; GError *err = NULL; @@ -2102,14 +2102,14 @@ out: } int dbus_method_async_with_reply(const char *dest, - const char *path, - const char *iface, - const char *method, - const char *signature, - const char *param[], - dbus_pending_cb cb, - int timeout_msec, - void *data) + const char *path, + const char *iface, + const char *method, + const char *signature, + const char *param[], + dbus_pending_cb cb, + int timeout_msec, + void *data) { dbus_handle_s *dh = NULL; pending_call_data *pdata = NULL; @@ -2146,9 +2146,9 @@ int dbus_method_async_with_reply(const char *dest, pdata->data = data; } g_dbus_connection_call(dh->conn, dest, path, iface, method, - var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, - (GAsyncReadyCallback)_cb_pending, - pdata); + var, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, + (GAsyncReadyCallback)_cb_pending, + pdata); return ret; err: @@ -2158,13 +2158,13 @@ err: } int dbus_method_async_with_reply_var(const char *dest, - const char *path, - const char *iface, - const char *method, - GVariant *param, - dbus_pending_cb cb, - int timeout_msec, - void *data) + const char *path, + const char *iface, + const char *method, + GVariant *param, + dbus_pending_cb cb, + int timeout_msec, + void *data) { dbus_handle_s *dh = NULL; pending_call_data *pdata = NULL; @@ -2197,9 +2197,9 @@ int dbus_method_async_with_reply_var(const char *dest, pdata->data = data; } g_dbus_connection_call(dh->conn, dest, path, iface, method, - param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, - (GAsyncReadyCallback)_cb_pending, - pdata); + param, NULL, G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, + (GAsyncReadyCallback)_cb_pending, + pdata); return ret; err: @@ -2224,13 +2224,13 @@ int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender) } vret = g_dbus_connection_call_sync(conn, - "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID", - g_variant_new("(s)", sender), - NULL, - G_DBUS_CALL_FLAGS_NONE, - DBUS_REPLY_TIMEOUT, - NULL, - &err); + "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID", + g_variant_new("(s)", sender), + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + NULL, + &err); if (!vret || err) { _E("failed to g_dbus_connection_call_sync:%s", err->message); g_error_free(err); @@ -2279,8 +2279,17 @@ int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, G return -1; } } - vret = g_dbus_connection_call_sync(dh->conn, DBUS_BUS_NAME, DBUS_OBJECT_PATH, DBUS_INTERFACE_NAME, - "GetConnectionCredentials", g_variant_new("(s)", name), NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, &err); + vret = g_dbus_connection_call_sync(dh->conn, + DBUS_BUS_NAME, + DBUS_OBJECT_PATH, + DBUS_INTERFACE_NAME, + "GetConnectionCredentials", + g_variant_new("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + NULL, + &err); if (!vret || err) { _E("failed to g_dbus_connection_call_sync:%s", err->message); return -1; @@ -2316,9 +2325,9 @@ void _destroy_notify_watch_name(gpointer data) } int dbus_handle_watch_name(const char *name, - GBusNameAppearedCallback name_appeared_handler, - GBusNameVanishedCallback name_vanished_handler, - void *user_data) + GBusNameAppearedCallback name_appeared_handler, + GBusNameVanishedCallback name_vanished_handler, + void *user_data) { guint id = 0; @@ -2331,7 +2340,13 @@ int dbus_handle_watch_name(const char *name, return -1; } - id = g_bus_watch_name(dbus_handle_get_default_bus_type(), name, G_BUS_NAME_WATCHER_FLAGS_NONE, name_appeared_handler, name_vanished_handler, user_data, _destroy_notify_watch_name); + id = g_bus_watch_name(dbus_handle_get_default_bus_type(), + name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + name_appeared_handler, + name_vanished_handler, + user_data, + _destroy_notify_watch_name); if (!id) { _E("failed to g_bus_watch_name"); return -1; @@ -2410,13 +2425,13 @@ char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name) } vret = g_dbus_connection_call_sync(dh->conn, - "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListQueuedOwners", - g_variant_new("(s)", bus_name), - NULL, - G_DBUS_CALL_FLAGS_NONE, - DBUS_REPLY_TIMEOUT, - NULL, - &err); + "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListQueuedOwners", + g_variant_new("(s)", bus_name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + NULL, + &err); if (!vret || err) { _E("failed to g_dbus_connection_call_sync:%s", err->message); g_error_free(err); -- 2.7.4 From d634bf6a2618fc460083022d57fd4b48117139eb Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Mon, 5 Feb 2018 20:52:03 +0900 Subject: [PATCH 13/16] haptic: watch/unwatch name with correct id multiple haptic_info struct can be added into haptic_handle_list, but abnormal name watching id is assigned to one global variable, fix this to use correct id for each haptic_info struct Change-Id: Ia2360120bdbd6ca6bdcc47ad6e071a90f7f462f9 Signed-off-by: sanghyeok.oh --- src/core/dbus.c | 9 ++++++++- src/haptic/haptic.c | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/core/dbus.c b/src/core/dbus.c index f21a073..42137a7 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -981,7 +981,14 @@ static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *o goto err; } - _E("%s", buf); + /* todo: delete this */ +#if 0 + if (strlen(buf) <= 512) { + _E("%s", buf); + } else { + _E("%s", buf + strlen(buf) - 512); + } +#endif nodeinfo = g_dbus_node_info_new_for_xml(buf, &err); if (!nodeinfo || err) { diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 4578fce..231e374 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -63,6 +63,7 @@ struct haptic_info { char *sender; dd_list *handle_list; + guint id_watch; }; struct vibrate_effect_info { @@ -196,7 +197,6 @@ void haptic_name_owner_changed(GDBusConnection *connection, remove_haptic_info(info); } -static guint id_name_watch; static struct haptic_info *add_haptic_info(const char *sender) { struct haptic_info *info; @@ -210,7 +210,7 @@ static struct haptic_info *add_haptic_info(const char *sender) info->sender = strdup(sender); DD_LIST_APPEND(haptic_handle_list, info); - id_name_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info); + info->id_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info); return info; } @@ -219,7 +219,7 @@ static int remove_haptic_info(struct haptic_info *info) { assert(info); - dbus_handle_unwatch_name(id_name_watch); + dbus_handle_unwatch_name(info->id_watch); DD_LIST_REMOVE(haptic_handle_list, info); DD_LIST_FREE_LIST(info->handle_list); -- 2.7.4 From b60487c9f5dac198ce16081961393090b57e9ef0 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Tue, 6 Feb 2018 14:03:27 +0900 Subject: [PATCH 14/16] Rename LICENSE file as LICENSE.Apache-2.0 Change-Id: I69d89d6fa27bdfeb1c9026a8aa190fd119421efe Signed-off-by: Hyotaek Shim --- LICENSE => LICENSE.Apache-2.0 | 0 packaging/feedbackd.spec | 16 ++++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) rename LICENSE => LICENSE.Apache-2.0 (100%) diff --git a/LICENSE b/LICENSE.Apache-2.0 similarity index 100% rename from LICENSE rename to LICENSE.Apache-2.0 diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index 1dca668..b01db16 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -280,43 +280,43 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %files -n feedbackd %manifest %{name}.manifest -%license LICENSE +%license LICENSE.Apache-2.0 %config %{_sysconfdir}/dbus-1/system.d/feedbackd.conf %{_unitdir}/feedbackd.service %{_unitdir}/multi-user.target.wants/feedbackd.service %files driver-external -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.external %files driver-emulator -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.emulator %files driver-gpio -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.gpio %files driver-standard -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.standard %files driver-circle -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %{_bindir}/feedbackd.circle %files conf-level3 -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %config %{_sysconfdir}/feedbackd/haptic-level3.conf %files conf-level6 -%license LICENSE +%license LICENSE.Apache-2.0 %manifest %{name}.manifest %config %{_sysconfdir}/feedbackd/haptic-level6.conf -- 2.7.4 From 29970885c0949d4c5421c73abae4b2c8d34bba10 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Tue, 6 Feb 2018 14:47:12 +0900 Subject: [PATCH 15/16] Enable systemd activiation on feedbackd.service Change-Id: Ifeb475d28740839f842a60a294d1df64b8115a11 Signed-off-by: Hyotaek Shim --- CMakeLists.txt | 2 +- packaging/feedbackd.spec | 1 + systemd/org.tizen.system.vibrator.service | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 systemd/org.tizen.system.vibrator.service diff --git a/CMakeLists.txt b/CMakeLists.txt index 0900516..a509c75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,6 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/scripts/feedbackd.conf DESTINATION /etc/dbus-1 INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "feedbackd.service") - +INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.vibrator.service DESTINATION /usr/share/dbus-1/system-services) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level3.conf DESTINATION /etc/feedbackd) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level6.conf DESTINATION /etc/feedbackd) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index b01db16..b74c9f6 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -284,6 +284,7 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %config %{_sysconfdir}/dbus-1/system.d/feedbackd.conf %{_unitdir}/feedbackd.service %{_unitdir}/multi-user.target.wants/feedbackd.service +%{_datadir}/dbus-1/system-services/org.tizen.system.vibrator.service %files driver-external %license LICENSE.Apache-2.0 diff --git a/systemd/org.tizen.system.vibrator.service b/systemd/org.tizen.system.vibrator.service new file mode 100644 index 0000000..d3c99bf --- /dev/null +++ b/systemd/org.tizen.system.vibrator.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.tizen.system.vibrator +Exec=/bin/false +User=system_fw +SystemdService=feedbackd.service -- 2.7.4 From 3dc4a167ed36965ff716bda109436ce20ffc82ee Mon Sep 17 00:00:00 2001 From: "pr.jung" Date: Thu, 8 Feb 2018 20:29:59 +0900 Subject: [PATCH 16/16] auto-test: Add auto-test for feedbackd Change-Id: Iee10703dc89bb94ecffc37424be259552c537f86 Signed-off-by: pr.jung --- CMakeLists.txt | 2 + packaging/feedbackd.spec | 11 ++ src/auto-test/CMakeLists.txt | 28 ++++ src/auto-test/haptic.c | 327 +++++++++++++++++++++++++++++++++++++++++++ src/auto-test/main.c | 74 ++++++++++ src/auto-test/result.c | 35 +++++ src/auto-test/test.c | 71 ++++++++++ src/auto-test/test.h | 99 +++++++++++++ src/core/dbus.h | 1 - src/haptic/haptic.c | 1 - src/haptic/standard.c | 2 + 11 files changed, 649 insertions(+), 2 deletions(-) create mode 100644 src/auto-test/CMakeLists.txt create mode 100755 src/auto-test/haptic.c create mode 100644 src/auto-test/main.c create mode 100644 src/auto-test/result.c create mode 100644 src/auto-test/test.c create mode 100644 src/auto-test/test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a509c75..55c3880 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,3 +72,5 @@ INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/org.tizen.system.vibrator.service DESTINATION /usr/share/dbus-1/system-services) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level3.conf DESTINATION /etc/feedbackd) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/haptic/conf/haptic-level6.conf DESTINATION /etc/feedbackd) + +ADD_SUBDIRECTORY(src/auto-test) diff --git a/packaging/feedbackd.spec b/packaging/feedbackd.spec index b74c9f6..fbffb0d 100644 --- a/packaging/feedbackd.spec +++ b/packaging/feedbackd.spec @@ -108,6 +108,13 @@ Conflicts: %{name}-conf-level3 %description conf-level6 Feedbackd configuration file. +%package auto-test +Summary: Feedbackd auto test tool +Group: System/Utilities +%description auto-test +Feedbackd helper programs. +This package can be installed optional for auto dbus test. + %prep %setup -q @@ -321,3 +328,7 @@ mv %{_sysconfdir}/feedbackd/haptic-level6.conf %{_sysconfdir}/feedbackd/haptic.c %manifest %{name}.manifest %config %{_sysconfdir}/feedbackd/haptic-level6.conf +%files auto-test +%license LICENSE +%manifest %{name}.manifest +%{_bindir}/feedbackd-auto-test diff --git a/src/auto-test/CMakeLists.txt b/src/auto-test/CMakeLists.txt new file mode 100644 index 0000000..5e40bd7 --- /dev/null +++ b/src/auto-test/CMakeLists.txt @@ -0,0 +1,28 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(feedbackd-auto-test C) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) + +SET(SRCS + test.c + main.c + result.c + ../core/dbus.c + haptic.c +) + +INCLUDE(FindPkgConfig) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs2_LDFLAGS} "-ldl" "-lm") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/src/auto-test/haptic.c b/src/auto-test/haptic.c new file mode 100755 index 0000000..7171d38 --- /dev/null +++ b/src/auto-test/haptic.c @@ -0,0 +1,327 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 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 requhapticed 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_HAPTIC_GETCOUNT "GetCount" +#define METHOD_HAPTIC_OPENDEVICE "OpenDevice" +#define METHOD_HAPTIC_CLOSEDEVICE "CloseDevice" +#define METHOD_HAPTIC_STOPDEVICE "StopDevice" +#define METHOD_HAPTIC_VIBRATEMONOTONE "VibrateMonotone" +#define METHOD_HAPTIC_VIBRATEEFFECT "VibrateEffect" +#define METHOD_HAPTIC_GETSTATE "GetState" +#define METHOD_HAPTIC_SHOWHANDLELIST "ShowHandleList" +#define METHOD_HAPTIC_ISSUPPORTED "IsSupported" + +static bool request_haptic_method(const char *method, GVariant *param) +{ + GVariant *msg; + int val; + bool ret = FALSE; + + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + method, param); + + if (!msg) { + _E("fail (%s): no reply", method); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &val)) + _E("fail (%s): no message", method); + else { + if ((val == -ENOTSUP) || (val == -ENOSYS)) { + _I("Not supported feature! (%s): %d", method, val); + ret = TRUE; + } else if (val == -ENODEV) { + _E("fail (%s): device open fail (%d)", method, val); + } else if (val < 0) { + _E("fail (%s): returned fail (%d)", method, val); + } else { + _I("success (%s): %d", method, val); + ret = TRUE; + } + } + + g_variant_unref(msg); + return ret; +} + +static bool haptic_getcount() +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_GETCOUNT, NULL); +} + +static bool haptic_opendevice(int index) +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_OPENDEVICE, g_variant_new("(i)", index)); +} + +static bool haptic_closedevice() +{ + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + return request_haptic_method(METHOD_HAPTIC_CLOSEDEVICE, g_variant_new("(u)", handle)); +} + +static bool haptic_vibratemonotone(int duration, int level, int priority) +{ + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + return request_haptic_method(METHOD_HAPTIC_VIBRATEMONOTONE, g_variant_new("(uiii)", handle, duration, level, priority)); +} + +static bool haptic_vibrateeffect(char *pattern, int level, int priority) +{ + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + return request_haptic_method(METHOD_HAPTIC_VIBRATEEFFECT, g_variant_new("(usii)", handle, pattern, level, priority)); +} + +static bool haptic_stopdevice() +{ + struct timespec time = {0,}; + GVariant *msg; + int handle; + bool ret = FALSE; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_OPENDEVICE, + g_variant_new("(i)", 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + + if (!dh_get_param_from_var(msg, "(i)", &handle)) { + _E("fail (%s): no message", METHOD_HAPTIC_OPENDEVICE); + return ret; + } + g_variant_unref(msg); + + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_VIBRATEMONOTONE, + g_variant_new("(uiii)", handle, 1000, 100, 0)); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_VIBRATEMONOTONE); + return ret; + } + + _D("sleep 300ms"); + time.tv_nsec = 300 * NANO_SECOND_MULTIPLIER; + nanosleep(&time, NULL); + _D("wakeup"); + + return request_haptic_method(METHOD_HAPTIC_STOPDEVICE, g_variant_new("(u)", handle)); +} + +static bool haptic_getstate(int index) +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_GETSTATE, g_variant_new("(i)", index)); +} + +static bool haptic_showhandlelist() +{ + GVariant *msg; + + _D("----------------------------------------------------------------------------------"); + msg = dbus_method_sync_with_reply_var(VIBRATOR_BUS_NAME, + VIBRATOR_PATH_HAPTIC, + VIBRATOR_INTERFACE_HAPTIC, + METHOD_HAPTIC_SHOWHANDLELIST, + NULL); + + if (!msg) { + _E("fail (%s): no reply", METHOD_HAPTIC_OPENDEVICE); + return FALSE; + } + g_variant_unref(msg); + return TRUE; +} + +static bool haptic_issupported(char *pattern) +{ + _D("----------------------------------------------------------------------------------"); + return request_haptic_method(METHOD_HAPTIC_ISSUPPORTED, g_variant_new("(s)", pattern)); +} + +void haptic_test_all(int *success, int *fail) +{ + struct timespec time = {0,}; + int s = 0; + int f = 0; + + time.tv_sec = 1; + + (haptic_getcount()) ? s++ : f++; + (haptic_opendevice(0)) ? s++ : f++; + (haptic_closedevice()) ? s++ : f++; + (haptic_stopdevice()) ? s++ : f++; + nanosleep(&time, NULL); + (haptic_vibratemonotone(300, 100, 0)) ? s++ : f++; + nanosleep(&time, NULL); + (haptic_vibrateeffect("FEEDBACK_PATTERN_SIP", 100, 0)) ? s++ : f++; + nanosleep(&time, NULL); + (haptic_getstate(0)) ? s++ : f++; + (haptic_showhandlelist()) ? s++ : f++; + (haptic_issupported("FEEDBACK_PATTERN_SIP")) ? s++ : f++; + + + if (NULL != success) *success = s; + if (NULL != fail) *fail = f; +} + +static void haptic_init(void *data) +{ + int success = 0; + int fail = 0; + + _I("start test"); + + haptic_test_all(&success, &fail); + + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); +} + +static void haptic_exit(void *data) +{ + _I("end test"); +} + +static int haptic_unit(int argc, char **argv) +{ + struct timespec time = {0,}; + + if (argc < 2) { + int success = 0; + int fail = 0; + + _I("start test"); + haptic_test_all(&success, &fail); + _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_GETCOUNT)) { + haptic_getcount(); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_OPENDEVICE)) { + haptic_opendevice(atoi(argv[2])); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_CLOSEDEVICE)) { + haptic_closedevice(); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_STOPDEVICE)) { + time.tv_sec = 1; + haptic_stopdevice(); + nanosleep(&time, NULL); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_VIBRATEMONOTONE)) { + haptic_vibratemonotone(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); + time.tv_sec = 1 + (atoi(argv[2]) / 1000); + nanosleep(&time, NULL); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_VIBRATEEFFECT)) { + haptic_vibrateeffect(argv[2], atoi(argv[3]), atoi(argv[4])); + time.tv_sec = 2; + nanosleep(&time, NULL); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_GETSTATE)) { + haptic_getstate(atoi(argv[2])); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_SHOWHANDLELIST)) { + haptic_showhandlelist(); + } else if (0 == strcasecmp(argv[1], METHOD_HAPTIC_ISSUPPORTED)) { + haptic_issupported(argv[2]); + } else { + _E("Unknown test case!!!"); + } + + return 0; +} + +static const struct test_ops haptic_test_ops = { + .priority = TEST_PRIORITY_NORMAL, + .name = "haptic", + .init = haptic_init, + .exit = haptic_exit, + .unit = haptic_unit, +}; + +TEST_OPS_REGISTER(&haptic_test_ops) diff --git a/src/auto-test/main.c b/src/auto-test/main.c new file mode 100644 index 0000000..85148c8 --- /dev/null +++ b/src/auto-test/main.c @@ -0,0 +1,74 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 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" + +static void test_main(int argc, char **argv) +{ + _I("auto test all"); + test_init((void *)NULL); + test_exit((void *)NULL); +} + +static void unit_test(int argc, char **argv) +{ + const struct test_ops *ops; + + ops = find_test("haptic"); + if (!ops) { + _E("there is no test ops : haptic"); + return; + } + ops->unit(argc, argv); +} + +void show_usage() +{ + printf("Usage: deviced-auto-test [UNIT-METHOD] [OPTS]\n\n"); + printf("Optional arguments\nIf you don't give any optional arguments, all supported modules will be tested.\n"); + printf("All module list is as below.\nAs per profile, supported modules are different.\n"); + printf("[UNIT-METHOD] [OPTS]\n"); + printf("GetCount 0\n"); + printf("OpenDevice 0\n"); + printf("CloseDevice 0\n"); + printf("StopDevice 0\n"); + printf("VibrateMonotone duration, level, priority\n"); + printf("VibrateEffect pattern string, level, priority\n"); + printf("GetState 0\n"); + printf("ShowHandleList 0\n"); + printf("IsSupported pattern string\n"); +} + +int main(int argc, char **argv) +{ + if (argc == 2) { + if (!strncmp(argv[1], "help", strlen("help") + 1)) { + show_usage(); + return 0; + } + } + + if (argc >= 2) + unit_test(argc, argv); + else + test_main(argc, argv); + + + return 0; +} + diff --git a/src/auto-test/result.c b/src/auto-test/result.c new file mode 100644 index 0000000..c0f07fb --- /dev/null +++ b/src/auto-test/result.c @@ -0,0 +1,35 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 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 + +#include "core/log.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); +} diff --git a/src/auto-test/test.c b/src/auto-test/test.c new file mode 100644 index 0000000..15f27be --- /dev/null +++ b/src/auto-test/test.c @@ -0,0 +1,71 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 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" + +static dd_list *dd_head; + +void add_test(const struct test_ops *d) +{ + if (d->priority == TEST_PRIORITY_HIGH) + DD_LIST_PREPEND(dd_head, d); + else + DD_LIST_APPEND(dd_head, d); +} + +void remove_test(const struct test_ops *d) +{ + DD_LIST_REMOVE(dd_head, d); +} + +const struct test_ops *find_test(const char *name) +{ + dd_list *elem; + const struct test_ops *d; + + DD_LIST_FOREACH(dd_head, elem, d) { + if (!strcasecmp(d->name, name)) + return d; + } + return NULL; +} + +void test_init(void *data) +{ + dd_list *elem; + const struct test_ops *d; + + _D("test module count(%d)", DD_LIST_LENGTH(dd_head)); + DD_LIST_FOREACH(dd_head, elem, d) { + _D("[%s] initialize", d->name); + if (d->init) + d->init(data); + } +} + +void test_exit(void *data) +{ + dd_list *elem; + const struct test_ops *d; + + DD_LIST_FOREACH(dd_head, elem, d) { + _D("[%s] deinitialize", d->name); + if (d->exit) + d->exit(data); + } +} diff --git a/src/auto-test/test.h b/src/auto-test/test.h new file mode 100644 index 0000000..e5d5801 --- /dev/null +++ b/src/auto-test/test.h @@ -0,0 +1,99 @@ +/* + * feedbackd auto-test + * + * Copyright (c) 2018 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 __TEST_H__ +#define __TEST_H__ +#include +#include + +#include "core/list.h" +#include "core/log.h" +#include "core/dbus.h" +#include "core/common.h" + +#ifdef ENABLE_TEST_DLOG +#define ENABLE_DLOG +#endif + +//#define LOG_TAG "AUTO_TEST" + +enum test_priority { + TEST_PRIORITY_NORMAL = 0, + TEST_PRIORITY_HIGH, +}; + +struct test_ops { + enum test_priority priority; + char *name; + void (*init) (void *data); + void (*exit) (void *data); + int (*start) (void); + int (*stop) (void); + int (*status) (void); + int (*unit) (int argc, char **argv); +}; + +enum test_ops_status { + TEST_OPS_STATUS_UNINIT, + TEST_OPS_STATUS_START, + TEST_OPS_STATUS_STOP, + TEST_OPS_STATUS_MAX, +}; + +void test_init(void *data); +void test_exit(void *data); + +static inline int test_start(const struct test_ops *c) +{ + if (c && c->start) + return c->start(); + + return -EINVAL; +} + +static inline int test_stop(const struct test_ops *c) +{ + if (c && c->stop) + return c->stop(); + + return -EINVAL; +} + +static inline int test_get_status(const struct test_ops *c) +{ + if (c && c->status) + return c->status(); + + return -EINVAL; +} + +#define TEST_OPS_REGISTER(c) \ +static void __CONSTRUCTOR__ module_init(void) \ +{ \ + add_test(c); \ +} \ +static void __DESTRUCTOR__ module_exit(void) \ +{ \ + remove_test(c); \ +} +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 diff --git a/src/core/dbus.h b/src/core/dbus.h index 4d35471..cca491a 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -176,7 +176,6 @@ typedef struct { * @since_tizen 4.0 */ typedef struct { - dbus_object_handle_h oh; const char *name; const dbus_method_s *methods; int nr_methods; diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c index 231e374..e1a64e6 100644 --- a/src/haptic/haptic.c +++ b/src/haptic/haptic.c @@ -829,7 +829,6 @@ static const dbus_method_s hdbus_methods[] = { }; static const dbus_interface_u dbus_interface = { - .oh = NULL, .name = VIBRATOR_INTERFACE_HAPTIC, .methods = hdbus_methods, .nr_methods = ARRAY_SIZE(hdbus_methods), diff --git a/src/haptic/standard.c b/src/haptic/standard.c index 8e77b20..39f6866 100644 --- a/src/haptic/standard.c +++ b/src/haptic/standard.c @@ -601,6 +601,8 @@ static int stop_device(int device_handle) r = ff_stop(ff_fd, &info->effect); if (r < 0) _E("failed to stop effect(id:%d) : %d", info->effect.id, r); + else + _D("succeed to stop effect"); /* unregister existing timer */ if (r >= 0 && info->timer) { -- 2.7.4