diff options
author | Taeyoung Kim <ty317.kim@samsung.com> | 2016-05-26 18:54:26 +0900 |
---|---|---|
committer | Taeyoung Kim <ty317.kim@samsung.com> | 2016-05-26 18:54:26 +0900 |
commit | 8f8644fe3b19598467d9091065fcf8533f21a9e5 (patch) | |
tree | ae87b44a62de899b7fdc7e62846df8952bf98d94 | |
parent | 49e0455022fa53242a0b4a5d3271ae1670212b62 (diff) | |
download | device-manager-plugin-emul-8f8644fe3b19598467d9091065fcf8533f21a9e5.tar.gz device-manager-plugin-emul-8f8644fe3b19598467d9091065fcf8533f21a9e5.tar.bz2 device-manager-plugin-emul-8f8644fe3b19598467d9091065fcf8533f21a9e5.zip |
external connection: add HAL for external connectionsubmit/tizen/20160527.033611accepted/tizen/wearable/20160527.052035accepted/tizen/tv/20160527.052129accepted/tizen/mobile/20160527.051808accepted/tizen/ivi/20160527.052259accepted/tizen/common/20160527.152801
- HAL is added for external connection such as usb cable
ans earjack. The HAL handles the signal from emuld.
Change-Id: I27624450dcd4ab40c34a473675615fd76d11c13c
Signed-off-by: Taeyoung Kim <ty317.kim@samsung.com>
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | hw/dbus.c | 75 | ||||
-rw-r--r-- | hw/dbus.h | 32 | ||||
-rw-r--r-- | hw/external_connection/CMakeLists.txt | 19 | ||||
-rw-r--r-- | hw/external_connection/external_connection.c | 209 | ||||
-rw-r--r-- | packaging/device-manager-plugin-emul.spec | 2 |
6 files changed, 338 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 27ed342..0f68485 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,3 +33,4 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) ADD_SUBDIRECTORY(hw/display) +ADD_SUBDIRECTORY(hw/external_connection) diff --git a/hw/dbus.c b/hw/dbus.c new file mode 100644 index 0000000..ca14f3f --- /dev/null +++ b/hw/dbus.c @@ -0,0 +1,75 @@ +/* + * device-node + * + * Copyright (c) 2016 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 "dbus.h" +#include "shared.h" + +int register_dbus_signal(const char *object, + const char *iface, const char *signal, + GDBusSignalCallback callback, void *data, int *id) +{ + GError *err = NULL; + GDBusConnection *conn; + int sid; + +#if !GLIB_CHECK_VERSION(2, 35, 0) + g_type_init(); +#endif + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!conn) { + _E("fail to get dbus connection : %s", err->message); + g_clear_error(&err); + return -EPERM; + } + + /* subscribe signal */ + sid = g_dbus_connection_signal_subscribe(conn, + NULL, iface, signal, object, + NULL, G_DBUS_SIGNAL_FLAGS_NONE, + callback, data, NULL); + if (sid == 0) { + _E("fail to connect %s signal", signal); + return -EPERM; + } + + if (id) + *id = sid; + + return 0; +} + +void unregister_dbus_signal(int *id) +{ + GError *err = NULL; + GDBusConnection *conn; + + if (!id || *id <= 0) + return; + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!conn) { + _E("fail to get dbus connection : %s", err->message); + g_clear_error(&err); + return; + } + + /* unsubscribe signal */ + g_dbus_connection_signal_unsubscribe(conn, *id); + *id = 0; +} diff --git a/hw/dbus.h b/hw/dbus.h new file mode 100644 index 0000000..98695d0 --- /dev/null +++ b/hw/dbus.h @@ -0,0 +1,32 @@ +/* + * libdevice-node + * + * Copyright (c) 2016 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 __HW_DEFAULT_DBUS_H__ +#define __HW_DEFAULT_DBUS_H__ + +#include <stdio.h> +#include <errno.h> +#include <gio/gio.h> + +int register_dbus_signal(const char *object, + const char *iface, const char *signal, + GDBusSignalCallback callback, void *data, int *id); +void unregister_dbus_signal(int *id); + +#endif diff --git a/hw/external_connection/CMakeLists.txt b/hw/external_connection/CMakeLists.txt new file mode 100644 index 0000000..913ceb4 --- /dev/null +++ b/hw/external_connection/CMakeLists.txt @@ -0,0 +1,19 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(external_connection C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(external_connection_pkgs REQUIRED hwcommon dlog glib-2.0 gio-2.0) + +FOREACH(flag ${external_connection_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_LIBRARY(${PROJECT_NAME} MODULE external_connection.c ../shared.c ../dbus.c) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${external_connection_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "") +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}/hw COMPONENT RuntimeLibraries) diff --git a/hw/external_connection/external_connection.c b/hw/external_connection/external_connection.c new file mode 100644 index 0000000..741cc77 --- /dev/null +++ b/hw/external_connection/external_connection.c @@ -0,0 +1,209 @@ +/* + * device-node + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> +#include <linux/limits.h> +#include <dirent.h> + +#include <hw/external_connection.h> +#include "../shared.h" +#include "../dbus.h" + +#define EXTCON_BUS "org.tizen.system.deviced" +#define EXTCON_OBJECT "/Org/Tizen/System/DeviceD/ExtCon" +#define EXTCON_IFACE EXTCON_BUS".ExtCon" +#define EXTCON_SIGNAL "device_changed" + +#define EXTCON_EARJACK "earjack" +#define EXTCON_USB "usb" + +#define EXTCON_EARJACK_PATH "/sys/devices/platform/jack/earjack_online" +#define EXTCON_USB_PATH "/sys/devices/platform/jack/usb_online" + +struct extcon_device { + char *name; + char *type; + char *path; +} extcon_devices[] = { + { EXTCON_USB, EXTERNAL_CONNECTION_USB, EXTCON_USB_PATH, }, + { EXTCON_EARJACK, EXTERNAL_CONNECTION_HEADPHONE, EXTCON_EARJACK_PATH, }, +}; + +static int id; /* signal handler id */ + +static struct signal_data { + ConnectionUpdated updated_cb; + void *data; +} sdata = { 0, }; + +static void signal_delivered(GDBusConnection *conn, + const gchar *sender, + const gchar *object, + const gchar *iface, + const gchar *signal, + GVariant *parameters, + gpointer user_data) +{ + struct connection_info info; + char *sig, *name, *state; + char st[32]; + int num, i; + size_t len; + bool found; + + if (strncmp(signal, EXTCON_SIGNAL, sizeof(EXTCON_SIGNAL))) + return; + + g_variant_get(parameters, "(siss)", &sig, &num, &name, &state); + + _I("extcon uevent is delivered: (%s) state (%s)", name, state); + + found = false; + len = strlen(name) + 1; + for (i = 0 ; i < ARRAY_SIZE(extcon_devices) ; i++) { + if (strncmp(name, extcon_devices[i].name, len)) + continue; + found = true; + break; + } + if (!found) + goto out; + + info.name = extcon_devices[i].type; + snprintf(st, sizeof(st), "%s", state); + info.state = st; + info.flags = 0; + + if (sdata.updated_cb) + sdata.updated_cb(&info, sdata.data); + else + _E("callback is NULL"); + +out: + free(sig); + free(name); + free(state); +} + +static int external_connection_register_changed_event( + ConnectionUpdated updated_cb, void *data) +{ + int ret; + + if (sdata.updated_cb) { + _E("update callback is already registered"); + return -EEXIST; + } + + ret = register_dbus_signal(EXTCON_OBJECT, + EXTCON_IFACE, EXTCON_SIGNAL, + signal_delivered, &sdata, &id); + if (ret < 0) { + _E("Failed to register signal"); + return -ENOMEM; + } + + sdata.updated_cb = updated_cb; + sdata.data = data; + + return 0; +} + +static void external_connection_unregister_changed_event( + ConnectionUpdated updated_cb) +{ + unregister_dbus_signal(&id); + sdata.updated_cb = NULL; + sdata.data = NULL; +} + +static int external_connection_get_current_state( + ConnectionUpdated updated_cb, void *data) +{ + int ret, i, val; + struct connection_info info; + char buf[8]; + + if (!updated_cb) + return -EINVAL; + + for (i = 0 ; i < ARRAY_SIZE(extcon_devices) ; i++) { + ret = sys_get_int(extcon_devices[i].path, &val); + if (ret < 0) { + _E("Failed to get value of (%s, ret:%d)", + extcon_devices[i].path, ret); + continue; + } + + info.name = extcon_devices[i].type; + snprintf(buf, sizeof(buf), "%d", val); + info.state = buf; + + updated_cb(&info, data); + } + + return 0; +} + +static int external_connection_open(struct hw_info *info, + const char *id, struct hw_common **common) +{ + struct external_connection_device *external_connection_dev; + + if (!info || !common) + return -EINVAL; + + external_connection_dev = calloc(1, sizeof(struct external_connection_device)); + if (!external_connection_dev) + return -ENOMEM; + + external_connection_dev->common.info = info; + external_connection_dev->register_changed_event + = external_connection_register_changed_event; + external_connection_dev->unregister_changed_event + = external_connection_unregister_changed_event; + external_connection_dev->get_current_state + = external_connection_get_current_state; + + *common = (struct hw_common *)external_connection_dev; + return 0; +} + +static int external_connection_close(struct hw_common *common) +{ + if (!common) + return -EINVAL; + + free(common); + return 0; +} + +HARDWARE_MODULE_STRUCTURE = { + .magic = HARDWARE_INFO_TAG, + .hal_version = HARDWARE_INFO_VERSION, + .device_version = EXTERNAL_CONNECTION_HARDWARE_DEVICE_VERSION, + .id = EXTERNAL_CONNECTION_HARDWARE_DEVICE_ID, + .name = "external_connection", + .open = external_connection_open, + .close = external_connection_close, +}; diff --git a/packaging/device-manager-plugin-emul.spec b/packaging/device-manager-plugin-emul.spec index c4fa050..e87110c 100644 --- a/packaging/device-manager-plugin-emul.spec +++ b/packaging/device-manager-plugin-emul.spec @@ -11,6 +11,8 @@ BuildRequires: cmake BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(devman_plugin) BuildRequires: pkgconfig(hwcommon) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) %description Emulator plugin for libdevice-node. |