summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaeyoung Kim <ty317.kim@samsung.com>2016-05-26 18:54:26 +0900
committerTaeyoung Kim <ty317.kim@samsung.com>2016-05-26 18:54:26 +0900
commit8f8644fe3b19598467d9091065fcf8533f21a9e5 (patch)
treeae87b44a62de899b7fdc7e62846df8952bf98d94
parent49e0455022fa53242a0b4a5d3271ae1670212b62 (diff)
downloaddevice-manager-plugin-emul-8f8644fe3b19598467d9091065fcf8533f21a9e5.tar.gz
device-manager-plugin-emul-8f8644fe3b19598467d9091065fcf8533f21a9e5.tar.bz2
device-manager-plugin-emul-8f8644fe3b19598467d9091065fcf8533f21a9e5.zip
- 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.txt1
-rw-r--r--hw/dbus.c75
-rw-r--r--hw/dbus.h32
-rw-r--r--hw/external_connection/CMakeLists.txt19
-rw-r--r--hw/external_connection/external_connection.c209
-rw-r--r--packaging/device-manager-plugin-emul.spec2
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.