SET(SRCS
./src/bt-hal-bluetooth.c
+./src/bt-hal-adapter-dbus-handler.c
+./src/bt-hal-dbus-common-utils.c
+./src/bt-hal-event-receiver.c
+./src/bt-hal-utils.c
)
SET(PREFIX ${CMAKE_INSTALL_PREFIX})
--- /dev/null
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+#include "bt-hal-utils.h"
+
+#include <bt-hal-adapter-dbus-handler.h>
+#include <bt-hal-dbus-common-utils.h>
+
+#define BT_MAX_PROPERTY_BUF_SIZE 1024
+#define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
+#define BT_CORE_NAME "org.projectx.bt_core"
+#define BT_CORE_PATH "/org/projectx/bt_core"
+#define BT_CORE_INTERFACE "org.projectx.btcore"
+#define BT_ADAPTER_INTERFACE "org.bluez.Adapter1"
+
+static GDBusProxy *core_proxy = NULL;
+static GDBusConnection *system_conn = NULL;
+static handle_stack_msg event_cb = NULL;
+
+handle_stack_msg _bt_get_adapter_event_cb(void)
+{
+ if (!event_cb)
+ return event_cb;
+ else
+ return NULL;
+}
+
+GDBusConnection *__bt_get_system_gconn(void)
+{
+ DBG("+");
+ if (system_conn == NULL)
+ system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+
+ DBG("-");
+ return system_conn;
+}
+
+GDBusProxy *_bt_init_core_proxy(void)
+{ GDBusProxy *proxy;
+ GDBusConnection *conn;
+
+ DBG("+");
+ conn = __bt_get_system_gconn();
+ if (!conn)
+ return NULL;
+
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ BT_CORE_NAME,
+ BT_CORE_PATH,
+ BT_CORE_INTERFACE,
+ NULL, NULL);
+
+ if (!proxy)
+ return NULL;
+
+ core_proxy = proxy;
+
+ DBG("-");
+ return proxy;
+}
+
+static GDBusProxy *__bt_get_core_proxy(void)
+{
+ return (core_proxy) ? core_proxy : _bt_init_core_proxy();
+}
+
+/* To send stack event to hal-bluetooth handler */
+void _bt_hal_dbus_store_stack_msg_cb(handle_stack_msg cb)
+{
+ event_cb = cb;
+}
+
+int _bt_hal_dbus_enable_adapter(void)
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ GVariant *result = NULL;
+
+ DBG("+");
+ proxy = __bt_get_core_proxy();
+
+ if (!proxy) {
+ DBG("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
+ return BT_STATUS_FAIL;
+ }
+
+ result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
+ NULL, &error);
+ if (error) {
+ DBG("EnableAdapter failed: %s", error->message);
+ g_clear_error(&error);
+ error = NULL;
+ result = g_dbus_proxy_call_sync(proxy,
+ "DisableAdapter",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error != NULL) {
+ DBG("Bt core call failed(Error: %s)", error->message);
+ g_clear_error(&error);
+ }
+ g_variant_unref(result);
+ //Terminate myself
+ /* TODO: Terminate bluetooth service or not, need to check */
+ //g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
+ return BT_STATUS_FAIL;
+ }
+
+ DBG("-");
+ g_variant_unref(result);
+ return BT_STATUS_SUCCESS;
+}
+
+int _bt_hal_dbus_disable_adapter(void)
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ GVariant *result = NULL;
+
+ DBG("+");
+ proxy = __bt_get_core_proxy();
+
+ if (!proxy) {
+ DBG("_bt_hal_dbus_enable_adapter: Core proxy get failed!!!");
+ return BT_STATUS_FAIL;
+ }
+
+ result = g_dbus_proxy_call_sync(proxy, "DisableAdapter",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &error);
+ if (error) {
+ DBG("DisableAdapter failed: %s", error->message);
+ g_clear_error(&error);
+ error = NULL;
+ g_variant_unref(result);
+ //Terminate myself
+ /* TODO: Terminate bluetooth service or not, need to check */
+ //g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
+ return BT_STATUS_FAIL;
+ }
+
+ DBG("-");
+ g_variant_unref(result);
+ return BT_STATUS_SUCCESS;
+}
--- /dev/null
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 _BT_HAL_ADAPTER_DBUS_HANDLER_H_
+#define _BT_HAL_ADAPTER_DBUS_HANDLER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+
+#include "bt-hal-event-receiver.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _bt_hal_dbus_store_stack_msg_cb(handle_stack_msg cb);
+
+int _bt_hal_dbus_enable_adapter(void);
+
+int _bt_hal_dbus_disable_adapter(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _BT_HAL_ADAPTER_DBUS_HANDLER_H_ */
#include "bt-hal-msg.h"
#include "bt-hal-utils.h"
+#include <bt-hal-adapter-dbus-handler.h>
+
#define enum_prop_to_hal(prop, hal_prop, type) do { \
static type e; \
prop.val = &e; \
static const bt_callbacks_t *bt_hal_cbacks = NULL;
+
+/* Forward declarations */
+static void __bt_adapter_props_to_hal(bt_property_t *send_props, struct hal_property *prop, uint8_t num_props, uint16_t len);
+static void __bt_hal_handle_adapter_state_changed(void *buf, uint16_t len);
+static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len);
+static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len);
+
static bool interface_ready(void)
{
return bt_hal_cbacks != NULL;
static int init(bt_callbacks_t *callbacks)
{
+ int ret;
DBG("HAL library Initialization..");
if (interface_ready())
else {
bt_hal_cbacks = callbacks;
DBG("Store HAL stack msg handler callback");
+ _bt_hal_dbus_store_stack_msg_cb(__bt_hal_handle_stack_messages);
+ ret = _bt_hal_initialize_event_receiver(__bt_hal_handle_stack_messages);
+
+ if (ret == BT_STATUS_SUCCESS)
+ return BT_STATUS_SUCCESS;
+ else
+ return BT_STATUS_FAIL;
+
}
return BT_STATUS_SUCCESS;
}
/* Enable Adapter */
static int enable(void)
{
- return BT_STATUS_UNSUPPORTED;
+ return _bt_hal_dbus_enable_adapter();
}
/* Disable Adapter */
static int disable(void)
{
- return BT_STATUS_UNSUPPORTED;
+ return _bt_hal_dbus_disable_adapter();
}
static void cleanup(void)
.author = "Intel Corporation",
.methods = &bluetooth_module_methods
};
+
+static void __bt_hal_handle_adapter_state_changed(void *buf, uint16_t len)
+{
+ struct hal_ev_adapter_state_changed *ev = buf;
+
+ DBG("Adapter State: %d", ev->state);
+
+ if (bt_hal_cbacks->adapter_state_changed_cb)
+ bt_hal_cbacks->adapter_state_changed_cb(ev->state);
+}
+
+static void __bt_adapter_props_to_hal(bt_property_t *send_props, struct hal_property *prop,
+ uint8_t num_props, uint16_t len)
+{
+ void *buf = prop;
+ uint8_t i;
+
+ for (i = 0; i < num_props; i++) {
+ if (sizeof(*prop) + prop->len > len) {
+ ERR("invalid adapter properties(%zu > %u), cant process further properties!!!",
+ sizeof(*prop) + prop->len, len);
+ return;
+ }
+
+ send_props[i].type = prop->type;
+
+ switch (prop->type) {
+ /* TODO: Add Adapter Properties */
+ default:
+ send_props[i].len = prop->len;
+ send_props[i].val = prop->val;
+ break;
+ }
+
+ DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
+
+ len -= sizeof(*prop) + prop->len;
+ buf += sizeof(*prop) + prop->len;
+ prop = buf;
+ }
+
+ if (!len)
+ return;
+}
+
+static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len)
+{
+ struct hal_ev_adapter_props_changed *ev = (struct hal_ev_adapter_props_changed *)buf;
+ bt_property_t props[ev->num_props];
+ DBG("+");
+
+ if (!bt_hal_cbacks->adapter_properties_cb)
+ return;
+
+ len -= sizeof(*ev);
+ __bt_adapter_props_to_hal(props, ev->props, ev->num_props, len);
+
+ if (bt_hal_cbacks->adapter_properties_cb)
+ bt_hal_cbacks->adapter_properties_cb(ev->status, ev->num_props, props);
+}
+
+static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len)
+{
+ DBG("+");
+ switch(message) {
+ case HAL_EV_ADAPTER_STATE_CHANGED:
+ DBG("Event: HAL_EV_ADAPTER_STATE_CHANGED");
+ __bt_hal_handle_adapter_state_changed(buf, len);
+ break;
+ case HAL_EV_ADAPTER_PROPS_CHANGED:
+ DBG("Event: HAL_EV_ADAPTER_PROPS_CHANGED");
+ __bt_hal_handle_adapter_property_changed(buf, len);
+ break;
+ default:
+ DBG("Event Currently not handled!!");
+ break;
+ }
+ DBG("-");
+}
--- /dev/null
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <dlog.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <sys/prctl.h>
+#include <gio/gio.h>
+
+#include "bt-hal-dbus-common-utils.h"
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+#include "bt-hal-utils.h"
+#include "bt-hal-internal.h"
+
+static GDBusConnection *system_conn;
+static GDBusConnection *session_conn;
+static GDBusProxy *manager_proxy;
+static GDBusProxy *adapter_proxy;
+
+static GDBusProxy *adapter_properties_proxy;
+
+static GDBusConnection *system_gconn = NULL;
+
+GDBusConnection *_bt_gdbus_init_system_gconn(void)
+{
+ GError *error = NULL;
+
+ if (system_gconn != NULL)
+ return system_gconn;
+
+ system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ if (!system_gconn) {
+ ERR("Unable to connect to dbus: %s", error->message);
+ g_clear_error(&error);
+ }
+
+ return system_gconn;
+}
+
+GDBusConnection *_bt_gdbus_get_system_gconn(void)
+{
+ GDBusConnection *local_system_gconn = NULL;
+ GError *error = NULL;
+
+ if (system_gconn == NULL) {
+ system_gconn = _bt_gdbus_init_system_gconn();
+ } else if (g_dbus_connection_is_closed(system_gconn)){
+
+ local_system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ if (!local_system_gconn) {
+ ERR("Unable to connect to dbus: %s", error->message);
+ g_clear_error(&error);
+ }
+
+ system_gconn = local_system_gconn;
+ }
+
+ return system_gconn;
+}
+
+static GDBusProxy *__bt_init_manager_proxy(void)
+{
+ GDBusProxy *proxy;
+
+ if (system_conn == NULL) {
+ system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+ if (system_conn == NULL)
+ return NULL;
+ }
+
+ proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_HAL_BLUEZ_NAME,
+ BT_HAL_MANAGER_PATH, BT_HAL_MANAGER_INTERFACE, NULL, NULL);
+
+ if (proxy == NULL)
+ return NULL;
+
+ manager_proxy = proxy;
+
+ return proxy;
+}
+
+static GDBusProxy *__bt_init_adapter_proxy(void)
+{
+ GDBusProxy *manager_proxy;
+ GDBusProxy *proxy;
+ char *adapter_path = NULL;
+
+ if (system_conn == NULL) {
+ system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+ if (system_conn == NULL)
+ return NULL;
+ }
+
+ manager_proxy = _bt_get_manager_proxy();
+ if (manager_proxy == NULL)
+ return NULL;
+
+ adapter_path = _bt_get_adapter_path();
+ if (adapter_path == NULL)
+ return NULL;
+
+ proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_HAL_BLUEZ_NAME,
+ adapter_path, BT_HAL_ADAPTER_INTERFACE, NULL, NULL);
+
+ g_free(adapter_path);
+
+ if (proxy == NULL)
+ return NULL;
+
+ adapter_proxy = proxy;
+
+ return proxy;
+}
+
+static GDBusProxy *__bt_init_adapter_properties_proxy(void)
+{
+ GDBusProxy *manager_proxy;
+ GDBusProxy *proxy;
+ char *adapter_path = NULL;
+
+ if (system_conn == NULL) {
+ system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+ if (system_conn == NULL)
+ return NULL;
+ }
+
+ manager_proxy = _bt_get_manager_proxy();
+ if (manager_proxy == NULL)
+ return NULL;
+
+ adapter_path = _bt_get_adapter_path();
+ if (adapter_path == NULL)
+ return NULL;
+
+ proxy = g_dbus_proxy_new_sync(system_conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_HAL_BLUEZ_NAME,
+ adapter_path, BT_HAL_PROPERTIES_INTERFACE, NULL, NULL);
+
+ g_free(adapter_path);
+
+ if (proxy == NULL)
+ return NULL;
+
+ adapter_properties_proxy = proxy;
+
+ return proxy;
+}
+
+GDBusConnection *__bt_init_system_gconn(void)
+{
+ if (system_conn == NULL)
+ system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
+
+ return system_conn;
+}
+
+GDBusConnection *__bt_init_session_conn(void)
+{
+ if (session_conn == NULL)
+ session_conn =g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
+
+ return session_conn;
+}
+
+GDBusConnection *_bt_get_session_gconn(void)
+{
+ return (session_conn) ? session_conn : __bt_init_session_conn();
+}
+
+GDBusConnection *_bt_get_system_gconn(void)
+{
+ return (system_conn) ? system_conn : __bt_init_system_gconn();
+}
+
+GDBusConnection *_bt_get_system_conn(void)
+{
+ GDBusConnection *g_conn;
+
+ if (system_conn == NULL) {
+ g_conn = __bt_init_system_gconn();
+ } else {
+ g_conn = system_conn;
+ }
+
+ if (g_conn == NULL)
+ return NULL;
+
+ return g_conn;
+}
+
+GDBusProxy *_bt_get_manager_proxy(void)
+{
+ if (manager_proxy) {
+ const gchar *path = g_dbus_proxy_get_object_path(manager_proxy);
+ if (path == NULL) {
+ ERR("Already proxy released hence creating new proxy");
+ return __bt_init_manager_proxy();
+ }
+ return manager_proxy;
+ }
+ return __bt_init_manager_proxy();
+}
+
+GDBusProxy *_bt_get_adapter_proxy(void)
+{
+ if (adapter_proxy) {
+ const char *path = g_dbus_proxy_get_object_path(adapter_proxy);
+ if (path == NULL) {
+ ERR("Already proxy released hence creating new proxy");
+ return __bt_init_adapter_proxy();
+ }
+
+ return adapter_proxy;
+ }
+ return __bt_init_adapter_proxy();
+
+}
+
+GDBusProxy *_bt_get_adapter_properties_proxy(void)
+{
+ return (adapter_properties_proxy) ? adapter_properties_proxy :
+ __bt_init_adapter_properties_proxy();
+}
+
+static char *__bt_extract_adapter_path(GVariantIter *iter)
+{
+ char *object_path = NULL;
+ GVariantIter *interface_iter;
+ GVariantIter *svc_iter;
+ char *interface_str = NULL;
+
+ /* Parse the signature: oa{sa{sv}}} */
+ while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
+ &interface_iter)) {
+
+ if (object_path == NULL)
+ continue;
+
+ while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
+ &interface_str, &svc_iter)) {
+ if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0)
+ continue;
+
+ DBG("Object Path: %s", object_path);
+ g_free(interface_str);
+ g_variant_iter_free(svc_iter);
+ g_variant_iter_free(interface_iter);
+ return g_strdup(object_path);
+ }
+ }
+ return NULL;
+}
+
+char *_bt_get_adapter_path(void)
+{
+ GDBusConnection *conn;
+ GDBusProxy *manager_proxy;
+ GVariant *result = NULL;
+ GVariantIter *iter = NULL;
+ char *adapter_path = NULL;
+
+ conn = _bt_get_system_conn();
+ if (conn == NULL)
+ return NULL;
+
+ manager_proxy = _bt_get_manager_proxy();
+ if (manager_proxy == NULL)
+ return NULL;
+
+ result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ if (!result) {
+ ERR("Can't get managed objects");
+ return NULL;
+ }
+
+ /* signature of GetManagedObjects: a{oa{sa{sv}}} */
+ g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
+
+ adapter_path = __bt_extract_adapter_path(iter);
+ g_variant_iter_free(iter);
+ g_variant_unref(result);
+ return adapter_path;
+}
+
+void _bt_deinit_bluez_proxy(void)
+{
+ if (manager_proxy) {
+ g_object_unref(manager_proxy);
+ manager_proxy = NULL;
+ }
+
+ if (adapter_proxy) {
+ g_object_unref(adapter_proxy);
+ adapter_proxy = NULL;
+ }
+ if (adapter_properties_proxy) {
+ g_object_unref(adapter_properties_proxy);
+ adapter_properties_proxy = NULL;
+ }
+}
+
+void _bt_deinit_proxys(void)
+{
+ _bt_deinit_bluez_proxy();
+
+ if (system_conn) {
+ g_object_unref(system_conn);
+ system_conn = NULL;
+ }
+
+ if (session_conn) {
+ g_object_unref(session_conn);
+ session_conn = NULL;
+ }
+}
+
+void _bt_convert_device_path_to_address(const char *device_path,
+ char *device_address)
+{
+ char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+ char *dev_addr;
+
+ if (device_path == NULL || device_address == NULL)
+ return;
+
+ dev_addr = strstr(device_path, "dev_");
+ if (dev_addr != NULL) {
+ char *pos = NULL;
+ dev_addr += 4;
+ g_strlcpy(address, dev_addr, sizeof(address));
+
+ while ((pos = strchr(address, '_')) != NULL) {
+ *pos = ':';
+ }
+
+ g_strlcpy(device_address, address, BT_HAL_ADDRESS_STRING_SIZE);
+ }
+}
+
+void _bt_convert_uuid_string_to_type(unsigned char *uuid,
+ const char *device_uuid)
+{
+ int i;
+ uint8_t temp[2];
+ uint8_t temp1[1];
+
+ if (uuid == NULL || device_uuid == NULL)
+ return;
+
+ int k=0;
+
+ for (i = 0; i < 36; ) {
+
+ if (device_uuid[i] != '\0') {
+ if (device_uuid[i] == '-') {
+ i = i+1;
+ continue;
+ }
+ temp[0] = device_uuid[i];
+ temp[1] = device_uuid[i+ 1];
+ sscanf((char*)temp, "%hhx", temp1); //hexadecimal scanf format for uint8_t
+ uuid[k] = temp1[0];
+ DBG("UUID[%d] = 0x%x", k, uuid[k]);
+ i = i + 2;
+ k++;
+ }
+
+ }
+}
+
+void _bt_convert_addr_string_to_type(unsigned char *addr,
+ const char *address)
+{
+ int i;
+ char *ptr = NULL;
+
+ if (address == NULL || addr == NULL)
+ return;
+
+ for (i = 0; i < BT_HAL_ADDRESS_LENGTH_MAX; i++) {
+ addr[i] = strtol(address, &ptr, 16);
+
+ if (ptr[0] != '\0') {
+ if (ptr[0] != ':')
+ return;
+
+ address = ptr + 1;
+ }
+ }
+}
+
+void _bt_convert_addr_type_to_string(char *address,
+ const unsigned char *addr)
+{
+ if (address == NULL || addr == NULL)
+ return;
+
+ snprintf(address, BT_HAL_ADDRESS_STRING_SIZE,
+ "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+ addr[0], addr[1], addr[2],
+ addr[3], addr[4], addr[5]);
+}
+
+void _bt_print_device_address_t(const bt_hal_device_address_t *addr)
+{
+ DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", addr->addr[0], addr->addr[1], addr->addr[2],
+ addr->addr[3], addr->addr[4], addr->addr[5]);
+}
+
+void _bt_divide_device_class(bt_hal_device_class_t *device_class,
+ unsigned int cod)
+{
+ if (device_class == NULL)
+ return;
+
+ device_class->major_class = (unsigned short)(cod & 0x00001F00) >> 8;
+ device_class->minor_class = (unsigned short)((cod & 0x000000FC));
+ device_class->service_class = (unsigned long)((cod & 0x00FF0000));
+
+ if (cod & 0x002000) {
+ device_class->service_class |=
+ BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE;
+ }
+}
+
+int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length)
+{
+ int i;
+ const char *p = src;
+ char *next;
+ int count;
+
+ if (dest == NULL || src == NULL)
+ return BT_HAL_ERROR_INVALID_PARAM;
+
+ DBG("+src : %s", src);
+ DBG("+dest : %s", dest);
+
+ i = 0;
+ while (*p != '\0' && i < length) {
+ next = g_utf8_next_char(p);
+ count = next - p;
+
+ while (count > 0 && ((i + count) < length)) {
+ dest[i++] = *p;
+ p++;
+ count --;
+ }
+ p = next;
+ }
+ return BT_HAL_ERROR_NONE;
+}
+
+gboolean _bt_utf8_validate(char *name)
+{
+ DBG("+");
+ gunichar2 *u16;
+ glong items_written = 0;
+
+ if (FALSE == g_utf8_validate(name, -1, NULL))
+ return FALSE;
+
+ u16 = g_utf8_to_utf16(name, -1, NULL, &items_written, NULL);
+ if (u16 == NULL)
+ return FALSE;
+
+ g_free(u16);
+
+ if (items_written != g_utf8_strlen(name, -1))
+ return FALSE;
+
+ DBG("-");
+ return TRUE;
+}
+
+int _bt_set_socket_non_blocking(int socket_fd)
+{
+ /* Set Nonblocking */
+ long arg;
+
+ arg = fcntl(socket_fd, F_GETFL);
+
+ if (arg < 0)
+ return -errno;
+
+ if (arg & O_NONBLOCK) {
+ ERR("Already Non-blocking \n");
+ }
+
+ arg |= O_NONBLOCK;
+
+ if (fcntl(socket_fd, F_SETFL, arg) < 0)
+ return -errno;
+
+ return BT_HAL_ERROR_NONE;
+}
+
+int _bt_set_non_blocking_tty(int sk)
+{
+ struct termios ti = {0,};
+ int err;
+
+ err = _bt_set_socket_non_blocking(sk);
+
+ if (err < 0) {
+ ERR("Error in set non blocking!\n");
+ return err;
+ }
+
+ tcflush(sk, TCIOFLUSH);
+
+ /* Switch tty to RAW mode */
+ cfmakeraw(&ti);
+ tcsetattr(sk, TCSANOW, &ti);
+
+ return BT_HAL_ERROR_NONE;
+}
+
+static char *__bt_extract_device_path(GVariantIter *iter, char *address)
+{
+ char *object_path = NULL;
+ char device_address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+
+ /* Parse the signature: oa{sa{sv}}} */
+ while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, NULL)) {
+ if (object_path == NULL)
+ return NULL;
+ _bt_convert_device_path_to_address(object_path, device_address);
+ if (g_strcmp0(address, device_address) == 0) {
+ return g_strdup(object_path);
+ }
+ }
+ return NULL;
+}
+
+char *_bt_get_device_object_path(char *address)
+{
+ char *object_path = NULL;
+ GDBusConnection *conn;
+ GDBusProxy *manager_proxy;
+ GVariant *result = NULL;
+ GVariantIter *iter = NULL;
+
+ conn = _bt_get_system_conn();
+ if (conn == NULL)
+ return NULL;
+
+ manager_proxy = _bt_get_manager_proxy();
+ if (manager_proxy == NULL)
+ return NULL;
+
+ result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL);
+ if (!result) {
+ ERR("Can't get managed objects");
+ return NULL;
+ }
+
+ /* signature of GetManagedObjects: a{oa{sa{sv}}} */
+ g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
+ object_path = __bt_extract_device_path(iter, address);
+ g_variant_iter_free(iter);
+ g_variant_unref(result);
+ return object_path;
+}
+
+char *_bt_convert_error_to_string(int error)
+{
+ switch (error) {
+ case BT_HAL_ERROR_CANCEL:
+ return "CANCELLED";
+ case BT_HAL_ERROR_INVALID_PARAM:
+ return "INVALID_PARAMETER";
+ case BT_HAL_ERROR_INVALID_DATA:
+ return "INVALID DATA";
+ case BT_HAL_ERROR_MEMORY_ALLOCATION:
+ case BT_HAL_ERROR_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case BT_HAL_ERROR_TIMEOUT:
+ return "TIMEOUT";
+ case BT_HAL_ERROR_NO_RESOURCES:
+ return "NO_RESOURCES";
+ case BT_HAL_ERROR_INTERNAL:
+ return "INTERNAL";
+ case BT_HAL_ERROR_NOT_SUPPORT:
+ return "NOT_SUPPORT";
+ case BT_HAL_ERROR_DEVICE_NOT_ENABLED:
+ return "NOT_ENABLED";
+ case BT_HAL_ERROR_DEVICE_ALREADY_ENABLED:
+ return "ALREADY_ENABLED";
+ case BT_HAL_ERROR_DEVICE_BUSY:
+ return "DEVICE_BUSY";
+ case BT_HAL_ERROR_ACCESS_DENIED:
+ return "ACCESS_DENIED";
+ case BT_HAL_ERROR_MAX_CLIENT:
+ return "MAX_CLIENT";
+ case BT_HAL_ERROR_NOT_FOUND:
+ return "NOT_FOUND";
+ case BT_HAL_ERROR_SERVICE_SEARCH_ERROR:
+ return "SERVICE_SEARCH_ERROR";
+ case BT_HAL_ERROR_PARING_FAILED:
+ return "PARING_FAILED";
+ case BT_HAL_ERROR_NOT_PAIRED:
+ return "NOT_PAIRED";
+ case BT_HAL_ERROR_SERVICE_NOT_FOUND:
+ return "SERVICE_NOT_FOUND";
+ case BT_HAL_ERROR_NOT_CONNECTED:
+ return "NOT_CONNECTED";
+ case BT_HAL_ERROR_ALREADY_CONNECT:
+ return "ALREADY_CONNECT";
+ case BT_HAL_ERROR_CONNECTION_BUSY:
+ return "CONNECTION_BUSY";
+ case BT_HAL_ERROR_CONNECTION_ERROR:
+ return "CONNECTION_ERROR";
+ case BT_HAL_ERROR_MAX_CONNECTION:
+ return "MAX_CONNECTION";
+ case BT_HAL_ERROR_NOT_IN_OPERATION:
+ return "NOT_IN_OPERATION";
+ case BT_HAL_ERROR_CANCEL_BY_USER:
+ return "CANCEL_BY_USER";
+ case BT_HAL_ERROR_REGISTRATION_FAILED:
+ return "REGISTRATION_FAILED";
+ case BT_HAL_ERROR_IN_PROGRESS:
+ return "IN_PROGRESS";
+ case BT_HAL_ERROR_AUTHENTICATION_FAILED:
+ return "AUTHENTICATION_FAILED";
+ case BT_HAL_ERROR_HOST_DOWN:
+ return "HOST_DOWN";
+ case BT_HAL_ERROR_END_OF_DEVICE_LIST:
+ return "END_OF_DEVICE_LIST";
+ case BT_HAL_ERROR_AGENT_ALREADY_EXIST:
+ return "AGENT_ALREADY_EXIST";
+ case BT_HAL_ERROR_AGENT_DOES_NOT_EXIST:
+ return "AGENT_DOES_NOT_EXIST";
+ case BT_HAL_ERROR_ALREADY_INITIALIZED:
+ return "ALREADY_INITIALIZED";
+ case BT_HAL_ERROR_PERMISSION_DEINED:
+ return "PERMISSION_DEINED";
+ case BT_HAL_ERROR_ALREADY_DEACTIVATED:
+ return "ALREADY_DEACTIVATED";
+ case BT_HAL_ERROR_NOT_INITIALIZED:
+ return "NOT_INITIALIZED";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+char * _bt_convert_disc_reason_to_string(int reason)
+{
+ switch(reason) {
+ case 1:
+ return "Link loss";
+ case 2:
+ return "Connection terminated by local host";
+ case 3:
+ return "Remote user terminated connection";
+ case 0:
+ default:
+ return "Unknown";
+ }
+}
+
+void _bt_logging_connection(gboolean connect, int addr_type)
+{
+ static int le_conn = 0;
+ static int le_disc = 0;
+ static int edr_conn = 0;
+ static int edr_disc = 0;
+
+ if (connect) {
+ if (addr_type)
+ le_conn++;
+ else
+ edr_conn++;
+ } else {
+ if (addr_type)
+ le_disc++;
+ else
+ edr_disc++;
+ }
+
+ INFO("[PM] Number of LE conn: %d disc: %d, Number of BR/EDR conn: %d disc: %d",
+ le_conn, le_disc, edr_conn, edr_disc);
+}
+
+void _bt_swap_byte_ordering(char *data, int data_len)
+{
+ char temp;
+ int i, j;
+
+ if (data == NULL)
+ return;
+ /* Swap to opposite endian */
+ for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
+ temp = data[i];
+ data[i] = data[j];
+ data[j] = temp;
+ }
+}
+
+int _bt_byte_arr_cmp(const char *data1, const char *data2, int data_len)
+{
+ int i;
+
+ if (data1 == NULL || data2 == NULL)
+ return -1;
+ for (i = 0; i < data_len; i++) {
+ if (data1[i] != data2[i])
+ return data1[i] - data2[i];
+ }
+ return 0;
+}
+int _bt_byte_arr_cmp_with_mask(const char *data1, const char *data2,
+ const char *mask, int data_len)
+{
+ int i;
+ char a, b;
+
+ if (data1 == NULL || data2 == NULL || mask == NULL);
+ return -1;
+ for (i = 0; i < data_len; i++) {
+ a = data1[i] & mask[i];
+ b = data2[i] & mask[i];
+ if (a != b)
+ return (int)(a - b);
+ }
+ return 0;
+}
+
+int _bt_connect_profile(char *address, char *uuid,
+ void *cb, gpointer func_data)
+{
+ char *object_path;
+ GDBusProxy *proxy;
+ GDBusConnection *conn;
+ GDBusProxy *adapter_proxy;
+ GError *error = NULL;
+
+ conn = _bt_get_system_gconn();
+ if (conn == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+ object_path = _bt_get_device_object_path(address);
+ if (object_path == NULL) {
+ ERR("No searched device");
+
+ adapter_proxy = _bt_get_adapter_proxy();
+ if (adapter_proxy == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+ g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice",
+ g_variant_new("(s)", address),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (error != NULL) {
+ ERR("CreateDevice Fail: %s", error->message);
+ g_error_free(error);
+ }
+
+ object_path = _bt_get_device_object_path(address);
+ }
+ if (object_path == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_HAL_BLUEZ_NAME,
+ object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
+ g_free(object_path);
+ if (proxy == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+
+ g_dbus_proxy_call(proxy, "ConnectProfile",
+ g_variant_new("(s)", uuid),
+ G_DBUS_CALL_FLAGS_NONE,
+ BT_HAL_MAX_DBUS_TIMEOUT,
+ NULL,
+ (GAsyncReadyCallback)cb,
+ func_data);
+
+ return BT_HAL_ERROR_NONE;
+}
+
+int _bt_disconnect_profile(char *address, char *uuid,
+ void *cb, gpointer func_data)
+{
+ char *object_path;
+ GDBusProxy *proxy;
+ GDBusConnection *conn;
+
+ conn = _bt_get_system_gconn();
+ if (conn == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+ object_path = _bt_get_device_object_path(address);
+ if (object_path == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+ proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_HAL_BLUEZ_NAME,
+ object_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
+ g_free(object_path);
+ if (proxy == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+ g_dbus_proxy_call(proxy, "DisconnectProfile",
+ g_variant_new("(s)", uuid),
+ G_DBUS_CALL_FLAGS_NONE,
+ BT_HAL_MAX_DBUS_TIMEOUT,
+ NULL,
+ (GAsyncReadyCallback)cb,
+ func_data);
+
+ return BT_HAL_ERROR_NONE;
+}
--- /dev/null
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 _BT_HAL_DBUS_COMMON_UTILS_H_
+#define _BT_HAL_DBUS_COMMON_UTILS_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <dlog.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <termios.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <dlog.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <termios.h>
+
+#define BT_HAL_MAX_DBUS_TIMEOUT 45000
+#define BT_HAL_TIMEOUT_MESSAGE "Did not receive a reply. Possible causes include: " \
+ "the remote application did not send a reply, " \
+ "the message bus security policy blocked the reply, " \
+ "the reply timeout expired, or the network connection " \
+ "was broken."
+
+#define BT_HAL_ADDRESS_LENGTH_MAX 6
+#define BT_HAL_ADDRESS_STRING_SIZE 18
+#define BT_HAL_LOWER_ADDRESS_LENGTH 9
+#define BT_HAL_AGENT_NEW_LINE "\r\n"
+
+#define BT_HAL_VERSION_LENGTH_MAX 30 /**< This specifies bluetooth device version length */
+#define BT_HAL_INTERFACE_NAME_LENGTH 16
+#define BT_HAL_DEVICE_NAME_LENGTH_MAX 248 /**< This specifies maximum device name length */
+#define BT_HAL_DEVICE_PASSKEY_LENGTH_MAX 50 /**< This specifies maximum length of the passkey */
+#define BT_HAL_ADVERTISING_DATA_LENGTH_MAX 31 /**< This specifies maximum AD data length */
+#define BT_HAL_SCAN_RESP_DATA_LENGTH_MAX 31 /**< This specifies maximum LE Scan response data length */
+#define BT_HAL_MANUFACTURER_DATA_LENGTH_MAX 240 /**< This specifies maximum manufacturer data length */
+#define BT_HAL_BLUEZ_NAME "org.bluez"
+#define BT_HAL_BLUEZ_PATH "/org/bluez"
+#define BT_HAL_MANAGER_PATH "/"
+#define BT_HAL_BLUEZ_HCI_PATH "/org/bluez/hci0"
+
+#define BT_HAL_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
+#define BT_HAL_ADAPTER_INTERFACE "org.bluez.Adapter1"
+#define BT_HAL_DEVICE_INTERFACE "org.bluez.Device1"
+#define BT_HAL_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
+
+#define BT_HAL_HARDWARE_ERROR "HardwareError"
+#define BT_HAL_TX_TIMEOUT_ERROR "TxTimeoutError"
+
+#define BT_HAL_FREEDESKTOP_INTERFACE "org.freedesktop.DBus"
+#define BT_HAL_FREEDESKTOP_PATH "/org/freedesktop/DBus"
+
+#define BT_HAL_SINK_INTERFACE "org.bluez.AudioSink"
+#define BT_HAL_AUDIO_INTERFACE "org.bluez.Audio"
+#define BT_HAL_INPUT_INTERFACE "org.bluez.Input1"
+#define BT_HAL_AGENT_INTERFACE "org.bluez.Agent1"
+#define BT_HAL_AGENT_MANAGER_INTERFACE "org.bluez.AgentManager1"
+#define BT_HAL_MEDIA_INTERFACE "org.bluez.Media1"
+#define BT_HAL_MEDIA_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
+#define BT_HAL_MEDIATRANSPORT_INTERFACE "org.bluez.MediaTransport1"
+#define BT_HAL_MEDIA_CONTROL_INTERFACE "org.bluez.MediaControl1"
+#define BT_HAL_PLAYER_CONTROL_INTERFACE "org.bluez.MediaPlayer1"
+#define BT_HAL_GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1"
+#define BT_HAL_NETWORK_INTERFACE "org.bluez.Network"
+#define BT_HAL_NETWORK_CLIENT_INTERFACE "org.bluez.Network1"
+#define BT_HAL_NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1"
+#define BT_HAL_MEDIA_INTERFACE "org.bluez.Media1"
+#define BT_HAL_MEDIA_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
+#define BT_HAL_OBEX_TRANSFER_INTERFACE "org.bluez.obex.Transfer1"
+#define BT_HAL_HEADSET_INTERFACE "org.bluez.Headset"
+
+
+#define BT_HAL_INTERFACES_ADDED "InterfacesAdded"
+#define BT_HAL_INTERFACES_REMOVED "InterfacesRemoved"
+#define BT_HAL_NAME_OWNER_CHANGED "NameOwnerChanged"
+#define BT_HAL_PROPERTIES_CHANGED "PropertiesChanged"
+
+
+/**
+ * This is Bluetooth error code
+ */
+#define BT_HAL_ERROR_BASE ((int)0) /**< Error code base */
+
+#define BT_HAL_ERROR_NONE ((int)0) /**< No error #0 */
+#define BT_HAL_ERROR_CANCEL ((int)BT_HAL_ERROR_BASE - 0x01)
+ /**< cancelled */
+#define BT_HAL_ERROR_INVALID_CALLBACK ((int)BT_HAL_ERROR_BASE - 0x02)
+ /**< Callback error */
+#define BT_HAL_ERROR_INVALID_PARAM ((int)BT_HAL_ERROR_BASE - 0x03)
+ /**< invalid paramerror */
+#define BT_HAL_ERROR_INVALID_DATA ((int)BT_HAL_ERROR_BASE - 0x04)
+ /**< invalid data error */
+#define BT_HAL_ERROR_MEMORY_ALLOCATION ((int)BT_HAL_ERROR_BASE - 0x05)
+ /**< Memory allocation error */
+#define BT_HAL_ERROR_OUT_OF_MEMORY ((int)BT_HAL_ERROR_BASE - 0x06)
+ /**< out of memory error */
+#define BT_HAL_ERROR_TIMEOUT ((int)BT_HAL_ERROR_BASE - 0x07)
+ /**< timeout error */
+#define BT_HAL_ERROR_NO_RESOURCES ((int)BT_HAL_ERROR_BASE - 0x08)
+ /**< No resource error */
+#define BT_HAL_ERROR_INTERNAL ((int)BT_HAL_ERROR_BASE - 0x09)
+ /**< internal error */
+#define BT_HAL_ERROR_NOT_SUPPORT ((int)BT_HAL_ERROR_BASE - 0x0a)
+ /**< Not supported error */
+#define BT_HAL_ERROR_DEVICE_NOT_ENABLED ((int)BT_HAL_ERROR_BASE - 0x0b)
+ /**< Operation is failed because
+ of not enabled BT Adapter */
+#define BT_HAL_ERROR_DEVICE_ALREADY_ENABLED ((int)BT_HAL_ERROR_BASE - 0x0c)
+ /**< Enabling is failed because of
+ already enabled BT Adapter */
+#define BT_HAL_ERROR_DEVICE_BUSY ((int)BT_HAL_ERROR_BASE - 0x0d)
+ /**< Operation is failed because of
+ other on going operation */
+#define BT_HAL_ERROR_ACCESS_DENIED ((int)BT_HAL_ERROR_BASE - 0x0e)
+ /**< access denied error */
+#define BT_HAL_ERROR_MAX_CLIENT ((int)BT_HAL_ERROR_BASE - 0x0f)
+ /**< max client error */
+#define BT_HAL_ERROR_NOT_FOUND ((int)BT_HAL_ERROR_BASE - 0x10)
+ /**< not found error */
+#define BT_HAL_ERROR_SERVICE_SEARCH_ERROR ((int)BT_HAL_ERROR_BASE - 0x11)
+ /**< service search fail */
+#define BT_HAL_ERROR_PARING_FAILED ((int)BT_HAL_ERROR_BASE - 0x12)
+ /**< pairing failed error */
+#define BT_HAL_ERROR_NOT_PAIRED ((int)BT_HAL_ERROR_BASE - 0x13)
+ /**< Not paired error */
+#define BT_HAL_ERROR_SERVICE_NOT_FOUND ((int)BT_HAL_ERROR_BASE - 0x14)
+ /**< no service error */
+#define BT_HAL_ERROR_NOT_CONNECTED ((int)BT_HAL_ERROR_BASE - 0x15)
+ /**< no connection error */
+#define BT_HAL_ERROR_ALREADY_CONNECT ((int)BT_HAL_ERROR_BASE - 0x16)
+ /**< alread connected error */
+#define BT_HAL_ERROR_CONNECTION_BUSY ((int)BT_HAL_ERROR_BASE - 0x17)
+ /**< connection busy error */
+#define BT_HAL_ERROR_CONNECTION_ERROR ((int)BT_HAL_ERROR_BASE - 0x18)
+ /**< connection error */
+#define BT_HAL_ERROR_MAX_CONNECTION ((int)BT_HAL_ERROR_BASE - 0x19)
+ /**< max connection error*/
+#define BT_HAL_ERROR_NOT_IN_OPERATION ((int)BT_HAL_ERROR_BASE - 0x1a)
+ /**< Not in operation */
+#define BT_HAL_ERROR_CANCEL_BY_USER ((int)BT_HAL_ERROR_BASE - 0x1b)
+ /**< Cancelled by user */
+#define BT_HAL_ERROR_REGISTRATION_FAILED ((int)BT_HAL_ERROR_BASE - 0x1c)
+ /**< Service record registration failed */
+#define BT_HAL_ERROR_IN_PROGRESS ((int)BT_HAL_ERROR_BASE - 0x1d)
+ /**< Operation in progress */
+#define BT_HAL_ERROR_AUTHENTICATION_FAILED ((int)BT_HAL_ERROR_BASE - 0x1e)
+ /**< authentication failed error when paring*/
+#define BT_HAL_ERROR_HOST_DOWN ((int)BT_HAL_ERROR_BASE - 0x1f)
+ /**< Remote host is down */
+#define BT_HAL_ERROR_END_OF_DEVICE_LIST ((int)BT_HAL_ERROR_BASE - 0x20)
+ /**< End of device list */
+
+#define BT_HAL_ERROR_AGENT_ALREADY_EXIST ((int)BT_HAL_ERROR_BASE - 0x21)
+ /**< Obex agent already exists */
+#define BT_HAL_ERROR_AGENT_DOES_NOT_EXIST ((int)BT_HAL_ERROR_BASE - 0x22)
+ /**< Obex agent does not exist */
+
+#define BT_HAL_ERROR_ALREADY_INITIALIZED ((int)BT_HAL_ERROR_BASE - 0x23)
+ /**< Already initialized */
+
+#define BT_HAL_ERROR_PERMISSION_DEINED ((int)BT_HAL_ERROR_BASE - 0x24)
+ /**< Permission deined */
+
+#define BT_HAL_ERROR_ALREADY_DEACTIVATED ((int)BT_HAL_ERROR_BASE - 0x25)
+ /**< Nap already done */
+
+#define BT_HAL_ERROR_NOT_INITIALIZED ((int)BT_HAL_ERROR_BASE - 0x26)
+ /**< Not initialized */
+
+#define BT_HAL_ERROR_DEVICE_POLICY_RESTRICTION ((int)BT_HAL_ERROR_BASE - 0x27)
+ /**< Device Policy Restricted */
+/**
+* Service class part of class of device returned from device discovery
+*/
+typedef enum {
+ BT_HAL_DEVICE_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE = 0x002000,
+ BT_HAL_DEVICE_SERVICE_CLASS_POSITIONING = 0x010000, /**< */
+ BT_HAL_DEVICE_SERVICE_CLASS_NETWORKING = 0x020000, /**< */
+ BT_HAL_DEVICE_SERVICE_CLASS_RENDERING = 0x040000, /**< */
+ BT_HAL_DEVICE_SERVICE_CLASS_CAPTURING = 0x080000, /**< */
+ BT_HAL_DEVICE_SERVICE_CLASS_OBJECT_TRANSFER = 0x100000, /**< */
+ BT_HAL_DEVICE_SERVICE_CLASS_AUDIO = 0x200000, /**< */
+ BT_HAL_DEVICE_SERVICE_CLASS_TELEPHONY = 0x400000, /**< */
+ BT_HAL_DEVICE_SERVICE_CLASS_INFORMATION = 0x800000, /**< */
+} bt_hal_device_service_class_t;
+
+/**
+ * Major device mask (For device discovery)
+ */
+typedef enum {
+ BT_HAL_DEVICE_MAJOR_MASK_MISC = 0x00,
+ BT_HAL_DEVICE_MAJOR_MASK_COMPUTER = 0x0001,
+ BT_HAL_DEVICE_MAJOR_MASK_PHONE = 0x0002,
+ BT_HAL_DEVICE_MAJOR_MASK_LAN_ACCESS_POINT = 0x0004,
+ BT_HAL_DEVICE_MAJOR_MASK_AUDIO = 0x0008,
+ BT_HAL_DEVICE_MAJOR_MASK_PERIPHERAL = 0x0010,
+ BT_HAL_DEVICE_MAJOR_MASK_IMAGING = 0x0020,
+ BT_HAL_DEVICE_MAJOR_MASK_WEARABLE = 0x0040,
+ BT_HAL_DEVICE_MAJOR_MASK_TOY = 0x0080,
+ BT_HAL_DEVICE_MAJOR_MASK_HEALTH = 0x0100,
+} bt_hal_device_major_mask_t;
+
+/**
+ * Major device class (part of Class of Device)
+ */
+typedef enum {
+ BT_HAL_DEVICE_MAJOR_CLASS_MISC = 0x00, /**< Miscellaneous major device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_COMPUTER = 0x01, /**< Computer major device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_PHONE = 0x02, /**< Phone major device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_LAN_ACCESS_POINT = 0x03, /**< LAN major device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_AUDIO = 0x04, /**< AUDIO major device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_PERIPHERAL = 0x05, /**< Peripheral major device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_IMAGING = 0x06, /**< Imaging major device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_WEARABLE = 0x07, /**< Wearable device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_TOY = 0x08, /**< Toy device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_HEALTH = 0x09, /**< Health device class*/
+ BT_HAL_DEVICE_MAJOR_CLASS_UNCLASSIFIED = 0x1F /**< Unknown major device class*/
+} bt_hal_device_major_class_t;
+
+
+typedef enum {
+ BT_HAL_DEVICE_MINOR_CLASS_UNCLASSIFIED = 0x00, /**< unclassified minor class */
+
+ /* About Computer Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_DESKTOP_WORKSTATION = 0x04, /**< desktop workstation
+ minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_SERVER_CLASS_COMPUTER = 0x08, /**< server minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_LAPTOP = 0x0C, /**< laptop minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HANDHELD_PC_OR_PDA = 0x10, /**< PDA minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_PALM_SIZED_PC_OR_PDA = 0x14, /**< PALM minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_WEARABLE_COMPUTER = 0x18, /**< Wearable PC minor class */
+
+ /* About Phone Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_CELLULAR = 0x04, /**< Cellular minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_CORDLESS = 0x08, /**< cordless minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_SMART_PHONE = 0x0C, /**< smart phone minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_WIRED_MODEM_OR_VOICE_GATEWAY = 0x10,
+ /**< voice gateway minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_COMMON_ISDN_ACCESS = 0x14, /**< ISDN minor class */
+
+ /* About LAN/Network Access Point Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_FULLY_AVAILABLE = 0x04, /**< Fully available minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_1_TO_17_PERCENT_UTILIZED = 0x20, /**< 1-17% utilized minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_17_TO_33_PERCENT_UTILIZED = 0x40, /**< 17-33% utilized minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_33_TO_50_PERCENT_UTILIZED = 0x60, /**< 33-50% utilized minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_50_to_67_PERCENT_UTILIZED = 0x80, /**< 50-67% utilized minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_67_TO_83_PERCENT_UTILIZED = 0xA0, /**< 67-83% utilized minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_83_TO_99_PERCENT_UTILIZED = 0xC0, /**< 83-99% utilized minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_NO_SERVICE_AVAILABLE = 0xE0, /**< No service available minor class */
+
+ /* About Audio/Video Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_HEADSET_PROFILE = 0x04, /**< Headset minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HANDSFREE = 0x08, /**< Handsfree minor class*/
+
+ BT_HAL_DEVICE_MINOR_CLASS_MICROPHONE = 0x10, /**< Microphone minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_LOUD_SPEAKER = 0x14, /**< Loud Speaker minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HEADPHONES = 0x18, /**< Headphones minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_PORTABLE_AUDIO = 0x1C, /**< Portable Audio minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_CAR_AUDIO = 0x20, /**< Car Audio minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_SET_TOP_BOX = 0x24, /**< Set top box minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HIFI_AUDIO_DEVICE = 0x28, /**< Hifi minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_VCR = 0x2C, /**< VCR minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_VIDEO_CAMERA = 0x30, /**< Video Camera minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_CAM_CORDER = 0x34, /**< CAM Corder minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_VIDEO_MONITOR = 0x38, /**<Video Monitor minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_VIDEO_DISPLAY_AND_LOUD_SPEAKER = 0x3C,
+ /**< Video Display and Loud
+ Speaker minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_VIDEO_CONFERENCING = 0x40, /**< Video Conferencing minor*/
+
+ BT_HAL_DEVICE_MINOR_CLASS_GAMING_OR_TOY = 0x48, /**< Gaming or toy minor class */
+
+ /* About Peripheral Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_KEY_BOARD = 0x40, /**< Key board minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_POINTING_DEVICE = 0x80, /**< Pointing Device minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_COMBO_KEYBOARD_OR_POINTING_DEVICE = 0xC0,
+ /**< Combo Keyboard or pointing
+ device minorclass */
+
+ BT_HAL_DEVICE_MINOR_CLASS_JOYSTICK = 0x04, /**< JoyStick minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_GAME_PAD = 0x08, /**< Game Pad minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_REMOTE_CONTROL = 0x0C, /**< Remote Control minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_SENSING_DEVICE = 0x10, /**< Sensing Device minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_DIGITIZER_TABLET = 0x14, /**< Digitizer minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_CARD_READER = 0x18, /**< Card Reader minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_DIGITAL_PEN = 0x1C, /**< Digital pen minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HANDHELD_SCANNER = 0x20, /**< Handheld scanner for bar-codes, RFID minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HANDHELD_GESTURAL_INPUT_DEVICE = 0x24, /**< Handheld gestural input device minor class */
+
+ /* About Imaging Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_DISPLAY = 0x10, /**< Display minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_CAMERA = 0x20, /**< Camera minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_SCANNER = 0x40, /**< Scanner minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_PRINTER = 0x80, /**< Printer minor class */
+
+ /* About Wearable Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_WRIST_WATCH = 0x04, /**< Wrist watch minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_PAGER = 0x08, /**< Pager minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_JACKET = 0x0C, /**< Jacket minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HELMET = 0x10, /**< Helmet minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_GLASSES = 0x14, /**< Glasses minor class */
+
+ /* About Toy Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_ROBOT = 0x04, /**< Robot minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_VEHICLE = 0x08, /**< Vehicle minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_DOLL_OR_ACTION = 0x0C, /**< Doll or Action minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_CONTROLLER = 0x10, /**< Controller minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_GAME = 0x14, /**< Game minor class */
+
+ /* About Health Major class */
+ BT_HAL_DEVICE_MINOR_CLASS_BLOOD_PRESSURE_MONITOR = 0x04, /**< Blood Pressure minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_THERMOMETER = 0x08, /**< Thermometer minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_WEIGHING_SCALE = 0x0C, /**< Weighing Scale minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_GLUCOSE_METER = 0x10, /**< Glucose minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_PULSE_OXIMETER = 0x14, /**< Pulse Oximeter minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_HEART_OR_PULSE_RATE_MONITOR = 0x18,/**< Heart or pulse rate monitor minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_MEDICAL_DATA_DISPLAY = 0x1C, /**< Medical minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_STEP_COUNTER = 0x20, /**< Step Counter minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_BODY_COMPOSITION_ANALYZER = 0x24, /**< Body composition analyzer minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_PEAK_FLOW_MONITOR = 0x28, /**< Peak flow monitor minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_MEDICATION_MONITOR = 0x2C, /**< Medication monitor minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_KNEE_PROSTHESIS = 0x30, /**< Knee prosthesis minor class */
+ BT_HAL_DEVICE_MINOR_CLASS_ANKLE_PROSTHESIS = 0x34, /**< Ankle prosthesis minor class */
+} bt_hal_device_minor_class_t;
+
+/**
+ * This is Bluetooth device address type, fixed to 6 bytes ##:##:##:##:##:##
+ */
+typedef struct {
+ unsigned char addr[BT_HAL_ADDRESS_LENGTH_MAX];
+} bt_hal_device_address_t;
+
+
+/**
+ * structure to hold the device information
+ */
+typedef struct {
+ bt_hal_device_major_class_t major_class; /**< major device class */
+ bt_hal_device_minor_class_t minor_class; /**< minor device class */
+ bt_hal_device_service_class_t service_class;
+ /**< service device class */
+} bt_hal_device_class_t;
+
+/**
+ * Connected state types
+ */
+typedef enum {
+ BT_HAL_CONNECTED_LINK_NONE = 0x00,
+ BT_HAL_CONNECTED_LINK_BREDR = 0x01,
+ BT_HAL_CONNECTED_LINK_LE = 0x02,
+ BT_HAL_CONNECTED_LINK_BREDR_LE = 0x03,
+} bt_hal_connected_link_t;
+
+GDBusProxy *_bt_get_adapter_proxy(void);
+
+GDBusProxy *_bt_get_adapter_properties_proxy(void);
+
+GDBusConnection *_bt_get_system_gconn(void);
+
+void _bt_convert_device_path_to_address(const char *device_path,
+ char *device_address);
+
+void _bt_convert_addr_string_to_type(unsigned char *addr, const char *address);
+
+void _bt_convert_addr_type_to_string(char *address, const unsigned char *addr);
+
+void _bt_convert_uuid_string_to_type(unsigned char *uuid, const char *device_uuid);
+
+int _bt_connect_profile(char *address, char *uuid, void *cb, gpointer func_data);
+
+int _bt_disconnect_profile(char *address, char *uuid, void *cb, gpointer func_data);
+
+GDBusProxy *_bt_get_manager_proxy(void);
+
+char *_bt_get_adapter_path(void);
+
+char *_bt_get_device_object_path(char *address);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _BT_HAL_DBUS_COMMON_UTILS_H_ */
--- /dev/null
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <vconf.h>
+
+/* BT HAL Headers */
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+#include "bt-hal-internal.h"
+#include "bt-hal-event-receiver.h"
+#include "bt-hal-dbus-common-utils.h"
+
+#define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
+ + sizeof(struct hal_property))
+
+/*TODO: Basic filters are currently added,
+ Need to add different event filters like HID,
+ Device etc in subsequent patches */
+
+/* Global variables and structures */
+static GDBusConnection *manager_conn;
+static handle_stack_msg event_cb = NULL;
+
+/* Forward declarations */
+int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
+static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
+static int __bt_hal_parse_event(GVariant *msg);
+static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current);
+static void __bt_hal_adapter_property_changed_event(GVariant *msg);
+void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path);
+static void __bt_hal_manager_event_filter(GDBusConnection *connection, const gchar *sender_name,
+ const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
+ GVariant *parameters, gpointer user_data);
+static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
+int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
+static int __bt_hal_initialize_manager_receiver(void);
+
+
+static int __bt_hal_parse_event(GVariant *msg)
+{
+ GVariantIter iter;
+ GVariant *child;
+ char *interface_name= NULL;
+ GVariant *inner_iter = NULL;
+
+ g_variant_iter_init(&iter, msg);
+
+ while ((child = g_variant_iter_next_value(&iter))) {
+ g_variant_get(child,"{&s@a{sv}}", &interface_name, &inner_iter);
+ if (g_strcmp0(interface_name,
+ BT_HAL_DEVICE_INTERFACE) == 0) {
+ DBG("__bt_hal_parse_event: Interface: BT_HAL_DEVICE_INTERFACE");
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ return BT_HAL_DEVICE_EVENT;
+ } else if (g_strcmp0(interface_name,
+ BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
+ DBG("__bt_hal_parse_event: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ return BT_HAL_MEDIA_TRANSFER_EVENT;
+ } else if (g_strcmp0(interface_name,
+ BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
+ DBG("__bt_hal_parse_event: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ return BT_HAL_AVRCP_CONTROL_EVENT;
+ }
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ }
+
+ return 0;
+}
+
+static int __bt_hal_get_owner_info(GVariant *msg, char **name, char **previous, char **current)
+{
+ g_variant_get(msg, "(sss)", name, previous, current);
+ return BT_HAL_ERROR_NONE;
+}
+
+int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val)
+{ struct hal_property *prop = buf;
+
+ prop->type = type;
+ prop->len = len;
+
+ if (len)
+ memcpy(prop->val, val, len);
+
+ return sizeof(*prop) + len;
+}
+
+handle_stack_msg _bt_hal_get_stack_message_handler(void)
+{
+ return event_cb;
+}
+
+static void __bt_hal_adapter_property_changed_event(GVariant *msg)
+{
+ GVariantIter value_iter;
+ GVariant *value = NULL;
+ char *key = NULL;
+ g_variant_iter_init (&value_iter, msg);
+
+ /* Buffer and propety count management */
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
+ struct hal_ev_adapter_props_changed *ev = (void*) buf;
+ size_t size = 0;
+ const gchar *address = NULL;
+ gchar *name = NULL;
+ unsigned int cod = 0;
+ gboolean discoverable;
+ gboolean connectable;
+ unsigned int scan_mode = BT_SCAN_MODE_NONE;
+ unsigned int disc_timeout;
+ const gchar *version;
+ const gboolean ipsp_initialized;
+ gboolean powered;
+ gboolean pairable;
+ unsigned int pairable_timeout;
+ gboolean scan_mode_property_update = FALSE;
+
+ memset(buf, 0, sizeof(buf));
+ size = sizeof(*ev);
+ ev->num_props = 0;
+ ev->status = BT_STATUS_SUCCESS;
+
+ DBG("+");
+
+ while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
+ if(!g_strcmp0(key, "Address")) {
+ uint8_t bdaddr[6];
+
+ address = g_variant_get_string(value, NULL);
+ DBG("##Address [%s]", address);
+ _bt_convert_addr_string_to_type(bdaddr, address);
+ size += __bt_insert_hal_properties(buf + size,
+ HAL_PROP_ADAPTER_ADDR, sizeof(bdaddr), bdaddr);
+ ev->num_props++;
+ } else if (!g_strcmp0(key, "Alias")) {
+ g_variant_get(value, "s", &name);
+ DBG("##Alias [%s] ", name);
+ size += __bt_insert_hal_properties(buf + size,
+ HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
+ ev->num_props++;
+ g_free(name);
+ } else if (!g_strcmp0(key, "Class")) {
+ cod = g_variant_get_uint32(value);
+ DBG("##Class [%d]", cod);
+ size += __bt_insert_hal_properties(buf + size,
+ HAL_PROP_ADAPTER_CLASS, sizeof(unsigned int), &cod);
+ ev->num_props++;
+ } else if (!g_strcmp0(key, "Discoverable")) {
+ discoverable = g_variant_get_boolean(value);
+ DBG("##Discoverable [%d]", discoverable);
+ if (discoverable)
+ scan_mode = BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE;
+ scan_mode_property_update = TRUE;
+ } else if (!g_strcmp0(key, "DiscoverableTimeout")) {
+ disc_timeout = g_variant_get_uint32(value);
+ DBG("##Discoverable Timeout [%d]", disc_timeout);
+ size += __bt_insert_hal_properties(buf + size,
+ HAL_PROP_ADAPTER_DISC_TIMEOUT, sizeof(unsigned int), &disc_timeout);
+ ev->num_props++;
+ } else if (!g_strcmp0(key, "Connectable")) {
+ connectable = g_variant_get_boolean(value);
+ DBG("##Connectable [%d]", connectable);
+ if (scan_mode == BT_SCAN_MODE_NONE)
+ scan_mode = BT_SCAN_MODE_CONNECTABLE;
+ scan_mode_property_update = TRUE;
+ } else if (!g_strcmp0(key, "Version")) {
+ version = g_variant_get_string(value, NULL);
+ DBG("##Version [%s]", version);
+ size += __bt_insert_hal_properties(buf + size,
+ HAL_PROP_ADAPTER_VERSION, strlen(version) + 1, version);
+ ev->num_props++;
+ } else if (!g_strcmp0(key, "Name")) {
+ g_variant_get(value, "s", &name);
+ DBG("##Name [%s]", name);
+ size += __bt_insert_hal_properties(buf + size,
+ HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
+ ev->num_props++;
+ g_free(name);
+ } else if (!g_strcmp0(key, "Powered")) {
+ powered = g_variant_get_boolean(value);
+ DBG("##Powered = %d", powered);
+ /* TODO: Need to check this operation!! */
+ if (powered == FALSE) {
+ DBG("###### Adapter Powered Down ######");
+ struct hal_ev_adapter_state_changed ev;
+ ev.state = HAL_POWER_OFF;
+ event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
+ /* Destroy Agent */
+ } else {
+ DBG("###### Adapter Powered Up ######");
+ struct hal_ev_adapter_state_changed ev;
+ ev.state = HAL_POWER_ON;
+ event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
+ /* Create Agent */
+ }
+
+ } else if (!g_strcmp0(key, "Pairable")) {
+ pairable = g_variant_get_boolean(value);
+ DBG("##Pairable [%d]", pairable);
+ } else if (!g_strcmp0(key, "PairableTimeout")) {
+ pairable_timeout = g_variant_get_uint32(value);
+ DBG("##Pairable Timeout = %d", pairable_timeout);
+ } else if (!g_strcmp0(key, "UUIDs")) {
+ char **uuid_value;
+ int uuid_count = 0;
+ gsize size1 = 0;
+ int i =0;
+ size1 = g_variant_get_size(value);
+ int num_props_tmp = ev->num_props;
+ if (size1 > 0) {
+ uuid_value = (char **)g_variant_get_strv(value, &size1);
+ for (i = 0; uuid_value[i] != NULL; i++)
+ uuid_count++;
+ /* UUID collection */
+ uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
+ for (i = 0; uuid_value[i] != NULL; i++) {
+ char *uuid_str = NULL;
+ uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
+ uuid_str = g_strdup(uuid_value[i]);
+ DBG("##UUID string [%s]\n", uuid_str);
+ _bt_convert_uuid_string_to_type(uuid, uuid_str);
+ memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
+ }
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
+ (BT_HAL_STACK_UUID_SIZE * uuid_count),
+ uuids);
+ ev->num_props = num_props_tmp + 1;
+ g_free(uuid_value);
+ }
+ } else if (!g_strcmp0(key, "Discovering")) {
+ } else if (!g_strcmp0(key, "LEDiscovering")) {
+ } else if (!g_strcmp0(key, "Modalias")) {
+ char *modalias = NULL;
+ g_variant_get(value, "s", &modalias);
+ DBG("##Adapter ModAlias [%s]", modalias);
+ } else if (!g_strcmp0(key, "SupportedLEFeatures")) {
+ DBG("##LE Supported features");
+ } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
+ g_variant_get(value, "b" ,&ipsp_initialized);
+ DBG("##IPSP Initialized = %d", ipsp_initialized);
+ } else {
+ ERR("Unhandled Property:[%s]", key);
+ }
+ }
+
+ if (scan_mode_property_update) {
+ size += __bt_insert_hal_properties(buf + size,
+ HAL_PROP_ADAPTER_SCAN_MODE, sizeof(int), &scan_mode);
+ ev->num_props++;
+ }
+
+
+ if (size > 2) {
+ DBG("Send Adapter properties changed event to HAL user, Num Prop [%d] total size [%d]",ev->num_props, size);
+ event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, buf, size);
+ }
+ g_variant_unref(value);
+ DBG("-");
+}
+
+void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
+{
+ char *interface_name = NULL;
+ GVariant *val = NULL;
+
+ DBG("+");
+
+ g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val,NULL);
+
+ if (strcasecmp(interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_ADAPTER_INTERFACE");
+ __bt_hal_adapter_property_changed_event(val);
+ } else if (strcasecmp(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_DEVICE_INTERFACE");
+ } else if (strcasecmp(interface_name, BT_HAL_OBEX_TRANSFER_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_OBEX_TRANSFER_INTERFACE");
+ /* TODO: Handle event */
+ } else if (strcasecmp(interface_name, BT_HAL_MEDIA_CONTROL_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_MEDIA_CONTROL_INTERFACE");
+ /* TODO: Handle event */
+ } else if (strcasecmp(interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
+ /* TODO: Handle event */
+ } else if (strcasecmp(interface_name, BT_HAL_NETWORK_CLIENT_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_NETWORK_CLIENT_INTERFACE");
+ /* TODO: Handle event */
+ } else if (strcasecmp(interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_GATT_CHAR_INTERFACE");
+ /* TODO: Handle event */
+ } else if (strcasecmp(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
+ DBG("Event: Property Changed: Interface: BT_HAL_INPUT_INTERFACE");
+ }
+ g_variant_unref(val);
+
+ DBG("-");
+}
+
+static void __bt_hal_manager_event_filter(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ bt_hal_event_type_t bt_event = 0x00;
+ GVariant *value;
+ char *obj_path = NULL;
+
+ DBG("+");
+
+ if (signal_name == NULL)
+ return;
+
+ if (strcasecmp(signal_name, "InterfacesAdded") == 0) {
+
+ /*TODO: Handle Interfaces Added Signal from stack */
+ DBG("Manager Event: Signal Name: InterfacesAdded");
+
+ g_variant_get(parameters, "(&o@a{sa{sv}})", &obj_path, &value);
+
+ if (strcasecmp(obj_path, BT_HAL_BLUEZ_HCI_PATH) == 0) {
+ /* TODO: Handle adapter added */
+ DBG("Manager Event: Signal Name: InterfiacesAdded: Adapter added in bluetoothd: path [hci0]");
+ } else {
+ bt_event = __bt_hal_parse_event(value);
+ if (bt_event == BT_HAL_DEVICE_EVENT) {
+ /*TODO: Handle device events from BlueZ */
+ DBG("Device path : %s ", obj_path);
+ } else if (bt_event == BT_HAL_AVRCP_CONTROL_EVENT) {
+ /*TODO: Handle AVRCP control events from BlueZ */
+ }
+ }
+ g_variant_unref(value);
+
+ } else if (strcasecmp(signal_name, "InterfacesRemoved") == 0) {
+ /*TODO: Handle Interfaces Removed Signal from stack */
+ DBG("Manager Event: Signal Name: InterfacesRemoved");
+ } else if (strcasecmp(signal_name, "NameOwnerChanged") == 0) {
+ char *name = NULL;
+ char *previous = NULL;
+ char *current = NULL;
+
+ /* TODO: Handle Name Owener changed Signal */
+ DBG("Manager Event: Signal Name: NameOwnerChanged");
+
+ if (__bt_hal_get_owner_info(parameters, &name, &previous, ¤t)) {
+ DBG("Fail to get the owner info");
+ return;
+ }
+ if (current && *current != '\0') {
+ g_free(name);
+ g_free(previous);
+ g_free(current);
+ return;
+ }
+ if (strcasecmp(name, BT_HAL_BLUEZ_NAME) == 0) {
+ DBG("Bluetoothd is terminated");
+
+ /* TODO: Handle Bluetoothd terminating scenario */
+ }
+
+ g_free(name);
+ g_free(previous);
+ g_free(current);
+
+ } else if (g_strcmp0(interface_name, BT_HAL_PROPERTIES_INTERFACE) == 0) {
+ DBG("Manager Event: Interface Name: BT_HAL_PROPERTIES_INTERFACE");
+ __bt_hal_handle_property_changed_event(parameters, object_path);
+ } else if (g_strcmp0(interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
+ /* TODO: Handle Adapter events from stack */
+ DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE");
+ } else if (g_strcmp0(interface_name, BT_HAL_INPUT_INTERFACE) == 0) {
+ DBG("Manager Event: Interface Name: BT_HAL_INPUT_INTERFACE");
+ } else if (g_strcmp0(interface_name, BT_HAL_NETWORK_SERVER_INTERFACE) == 0) {
+ /* TODO: Handle Network Server events from stack */
+ DBG("Manager Event: Interface Name: BT_HAL_NETWORK_SERVER_INTERFACE");
+ } else if (g_strcmp0(interface_name, BT_HAL_HEADSET_INTERFACE) == 0) {
+ DBG("Manager Event: Interface Name: BT_HAL_HEADSET_INTERFACE");
+ } else if (g_strcmp0(interface_name, BT_HAL_SINK_INTERFACE) == 0) {
+ /* TODO: Handle Sink interface events from stack */
+ DBG("Manager Event: Interface Name:BT_HAL_SINK_INTERFACE");
+ } else if (g_strcmp0(interface_name, BT_HAL_AGENT_INTERFACE) == 0) {
+ /* TODO: Handle Agent events from stack */
+ DBG("Manager Event: Interface Name:BT_HAL_AGENT_INTERFACE");
+ } else if (g_strcmp0(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
+ DBG("Manager Event: Interface Name:BT_HAL_DEVICE_INTERFACE");
+ }
+
+ DBG("-");
+ return;
+}
+
+static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn,
+ int subscribe)
+{
+ if (conn == NULL)
+ return -1;
+
+ static int subs_interface_added_id = -1;
+ static int subs_interface_removed_id = -1;
+ static int subs_name_owner_id = -1;
+ static int subs_property_id = -1;
+ static int subs_adapter_id = -1;
+
+ INFO_C("+");
+
+ if (subscribe) {
+ if (subs_interface_added_id == -1) {
+ subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_HAL_MANAGER_INTERFACE,
+ BT_HAL_INTERFACES_ADDED, NULL, NULL, 0,
+ __bt_hal_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_interface_removed_id == -1) {
+ subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_HAL_MANAGER_INTERFACE,
+ BT_HAL_INTERFACES_REMOVED, NULL, NULL, 0,
+ __bt_hal_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_name_owner_id == -1) {
+ subs_name_owner_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_HAL_FREEDESKTOP_INTERFACE,
+ BT_HAL_NAME_OWNER_CHANGED, NULL, NULL, 0,
+ __bt_hal_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_property_id == -1) {
+ subs_property_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_HAL_PROPERTIES_INTERFACE,
+ BT_HAL_PROPERTIES_CHANGED, NULL, NULL, 0,
+ __bt_hal_manager_event_filter,
+ NULL, NULL);
+ }
+ if (subs_adapter_id == -1) {
+ subs_adapter_id = g_dbus_connection_signal_subscribe(conn,
+ NULL, BT_HAL_ADAPTER_INTERFACE,
+ NULL, NULL, NULL, 0,
+ __bt_hal_manager_event_filter,
+ NULL, NULL);
+ }
+ } else {
+ if (subs_interface_added_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_interface_added_id);
+ subs_interface_added_id = -1;
+ }
+ if (subs_interface_removed_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_interface_removed_id);
+ subs_interface_removed_id = -1;
+ }
+ if (subs_name_owner_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_name_owner_id);
+ subs_name_owner_id = -1;
+ }
+ if (subs_property_id != -1) {
+ g_dbus_connection_signal_unsubscribe(conn,
+ subs_property_id);
+ subs_property_id = -1;
+ }
+ if (subs_adapter_id == -1) {
+ g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id);
+ subs_adapter_id = -1;
+ }
+ }
+
+ INFO_C("-");
+ return 0;
+}
+
+int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
+{
+ DBG("+");
+
+ if (g_conn == NULL)
+ return BT_HAL_ERROR_INTERNAL;
+
+ /* TODO: Add more events in subsequent patches */
+ switch (event_type) {
+ case BT_HAL_MANAGER_EVENT:
+ __bt_hal_register_manager_subscribe_signal(g_conn, TRUE);
+ break;
+ default:
+ INFO_C("Register Event: event_type [%d]", event_type);
+ return BT_HAL_ERROR_NOT_SUPPORT;
+ }
+
+ return BT_HAL_ERROR_NONE;
+}
+
+static int __bt_hal_initialize_manager_receiver(void)
+{
+ DBG("+");
+
+ GError *error = NULL;
+
+ if (manager_conn == NULL) {
+ manager_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (error != NULL) {
+ ERR_C("ERROR: Can't get on system bus [%s]", error->message);
+ g_clear_error(&error);
+ }
+ if (manager_conn == NULL)
+ goto fail;
+ }
+
+ if (__bt_hal_register_service_event(manager_conn,
+ BT_HAL_MANAGER_EVENT) != BT_HAL_ERROR_NONE)
+ goto fail;
+
+ return BT_HAL_ERROR_NONE;
+fail:
+ if (manager_conn) {
+ g_object_unref(manager_conn);
+ manager_conn = NULL;
+ }
+
+ DBG("-");
+
+ return BT_HAL_ERROR_INTERNAL;
+}
+
+/* To receive the event from bluez */
+int _bt_hal_initialize_event_receiver(handle_stack_msg cb)
+{
+ int result;
+ DBG("+");
+
+ if (!cb)
+ return BT_HAL_ERROR_INVALID_PARAM;
+
+ result = __bt_hal_initialize_manager_receiver();
+
+ DBG("Manager event receiver initialization result [%d]", result);
+ if (result != BT_HAL_ERROR_NONE)
+ return result;
+
+ /*TODO: Initialize Obexd Event receiver */
+
+ event_cb = cb;
+ DBG("-");
+
+ return BT_HAL_ERROR_NONE;
+}
--- /dev/null
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 _BT_HAL_EVENT_RECEIVER_H_
+#define _BT_HAL_EVENT_RECEIVER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DBUS_TIMEOUT 20 * 1000 /* 20 Sec */
+#define BT_HAL_MAX_PROPERTY_BUF_SIZE 1024
+#define BT_HAL_STACK_UUID_SIZE 16
+#define MAX_UUID_COUNT 50
+#define BT_HAL_DISCOVERY_FINISHED_DELAY 200
+
+/* This is the callback method which handles events from stack */
+typedef void (*handle_stack_msg) (int message, void *buf, uint16_t len);
+
+int _bt_hal_initialize_event_receiver(handle_stack_msg cb);
+
+handle_stack_msg _bt_hal_get_stack_message_handler(void);
+
+int __bt_insert_hal_properties(void *buf, uint8_t type, uint16_t len, const void *val);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _BT_HAL_EVENT_RECEIVER_H_ */
--- /dev/null
+/*
+ * BLUETOOTH HAL
+ *
+ * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 _BT_HAL_INTERNAL_H_
+#define _BT_HAL_INTERNAL_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ BT_HAL_MANAGER_EVENT = 0x01,
+ BT_HAL_ADAPTER_EVENT,
+ BT_HAL_LE_ADAPTER_EVENT,
+ BT_HAL_DEVICE_EVENT,
+ BT_HAL_HID_EVENT,
+ BT_HAL_NETWORK_EVENT,
+ BT_HAL_HEADSET_EVENT,
+ BT_HAL_AVRCP_EVENT,
+ BT_HAL_OPP_CLIENT_EVENT,
+ BT_HAL_OPP_SERVER_EVENT,
+ BT_HAL_PBAP_CLIENT_EVENT,
+ BT_HAL_RFCOMM_CLIENT_EVENT,
+ BT_HAL_RFCOMM_SERVER_EVENT,
+ BT_HAL_AGENT_EVENT,
+ BT_HAL_OBJECT_MANAGER_EVENT,
+ BT_HAL_MEDIA_TRANSFER_EVENT,
+ BT_HAL_HF_AGENT_EVENT,
+ BT_HAL_AVRCP_CONTROL_EVENT,
+ BT_HAL_A2DP_SOURCE_EVENT,
+ BT_HAL_HID_DEVICE_EVENT,
+ /* Will be added */
+} bt_hal_event_type_t;
+
+/* TODO More declarations to be added in subsequent patches */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _BT_HAL_INTERNAL_H_ */
--- /dev/null
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <dlog.h>
+
+#include "bt-hal-msg.h"
+#include "bt-hal.h"
+#include "bt-hal-utils.h"
+#include "bt-hal-log.h"
+
+#include <hardware/bluetooth.h>
+
+/*
+ * converts uuid to string
+ * buf should be at least 39 bytes
+ *
+ * returns string representation of uuid
+ */
+const char *bt_uuid_t2str(const uint8_t *uuid, char *buf)
+{
+ int shift = 0;
+ unsigned int i;
+ int is_bt;
+
+ if (!uuid)
+ return strcpy(buf, "NULL");
+
+ is_bt = !memcmp(&uuid[4], &BT_BASE_UUID[4], HAL_UUID_LEN - 4);
+
+ for (i = 0; i < HAL_UUID_LEN; i++) {
+ if (i == 4 && is_bt)
+ break;
+
+ if (i == 4 || i == 6 || i == 8 || i == 10) {
+ buf[i * 2 + shift] = '-';
+ shift++;
+ }
+ sprintf(buf + i * 2 + shift, "%02x", uuid[i]);
+ }
+
+ return buf;
+}
+
+const char *btuuid2str(const uint8_t *uuid)
+{
+ static char buf[MAX_UUID_STR_LEN];
+
+ return bt_uuid_t2str(uuid, buf);
+}
+
+/* Find first index of given value in table m */
+int int2str_findint(int v, const struct int2str m[])
+{
+ int i;
+
+ for (i = 0; m[i].str; ++i) {
+ if (m[i].val == v)
+ return i;
+ }
+ return -1;
+}
+
+/* Find first index of given string in table m */
+int int2str_findstr(const char *str, const struct int2str m[])
+{
+ int i;
+
+ for (i = 0; m[i].str; ++i) {
+ if (strcmp(m[i].str, str) == 0)
+ return i;
+ }
+ return -1;
+}
+
+/*
+ * convert bd_addr to string
+ * buf must be at least 18 char long
+ *
+ * returns buf
+ */
+const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf)
+{
+ const uint8_t *p;
+
+ if (!bd_addr)
+ return strcpy(buf, "NULL");
+
+ p = bd_addr->address;
+
+ snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+
+ return buf;
+}
+
+/* converts string to bt_bdaddr_t */
+void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr)
+{
+ uint8_t *p = bd_addr->address;
+
+ sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+ &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]);
+}
+
+/* converts string to uuid */
+void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
+{
+ int i = 0;
+
+ memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t));
+
+ while (*str && i < (int) sizeof(bt_uuid_t)) {
+ while (*str == '-')
+ str++;
+
+ if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1)
+ break;
+
+ i++;
+ str += 2;
+ }
+}
+
+const char *enum_defines(void *v, int i)
+{
+ const struct int2str *m = v;
+
+ return m[i].str != NULL ? m[i].str : NULL;
+}
+
+const char *enum_strings(void *v, int i)
+{
+ const char **m = v;
+
+ return m[i] != NULL ? m[i] : NULL;
+}
+
+const char *enum_one_string(void *v, int i)
+{
+ const char *m = v;
+
+ return (i == 0) && (m[0] != 0) ? m : NULL;
+}
+
+const char *bdaddr2str(const bt_bdaddr_t *bd_addr)
+{
+ static char buf[MAX_ADDR_STR_LEN];
+
+ return bt_bdaddr_t2str(bd_addr, buf);
+}
+
+static void bonded_devices2string(char *str, void *prop, int prop_len)
+{
+ int count = prop_len / sizeof(bt_bdaddr_t);
+ bt_bdaddr_t *addr = prop;
+
+ strcat(str, "{");
+
+ while (count--) {
+ strcat(str, bdaddr2str(addr));
+ if (count)
+ strcat(str, ", ");
+ addr++;
+ }
+
+ strcat(str, "}");
+}
+
+static void uuids2string(char *str, void *prop, int prop_len)
+{
+ int count = prop_len / sizeof(bt_uuid_t);
+ bt_uuid_t *uuid = prop;
+
+ strcat(str, "{");
+
+ while (count--) {
+ strcat(str, btuuid2str(uuid->uu));
+ if (count)
+ strcat(str, ", ");
+ uuid++;
+ }
+
+ strcat(str, "}");
+}
+
+const char* bt_property_type_t2str(bt_property_type_t prop_type)
+{
+ switch (prop_type) {
+
+ case BT_PROPERTY_BDNAME:
+ return "[Bluetooth Name]";
+ case BT_PROPERTY_BDADDR:
+ return "[Bluetooth Address]";
+ case BT_PROPERTY_UUIDS:
+ return "[UUIDS]";
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ return "[Class of Device]";
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ return "[Bluetooth Type of Device]";
+ case BT_PROPERTY_SERVICE_RECORD:
+ return "[Bluetooth Service record]";
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ return "[Bluetooth Adapter Scan Mode]";
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ return "[Bluetooth Bonded Devices]";
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ return "[Bluetooth Adapter Discovery Timeout]";
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ return "[Bluetooth Friendly Name]";
+ case BT_PROPERTY_REMOTE_RSSI:
+ return "[Bluetooth Rmote RSSI]";
+ case BT_PROPERTY_REMOTE_VERSION_INFO:
+ return "[Bluetooth Version Info]";
+ case BT_PROPERTY_LOCAL_LE_FEATURES:
+ return "[Bluetooth LE Features]";
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ return "[Bluetooth Remote Device Timestamp]";
+ default:
+ return "[Default Property]";
+ }
+}
+
+const char* bt_device_type_t2str(bt_device_type_t device_type)
+{
+ switch (device_type) {
+ case BT_DEVICE_DEVTYPE_BREDR:
+ return "BREDR Device";
+ break;
+ case BT_DEVICE_DEVTYPE_BLE:
+ return "BLE Device";
+ break;
+ case BT_DEVICE_DEVTYPE_DUAL:
+ return "Dual Device";
+ break;
+ default:
+ return "Unknown Device Type";
+ }
+}
+
+const char* bt_scan_mode_t2str(bt_scan_mode_t scan_mode)
+{
+ switch(scan_mode) {
+ case BT_SCAN_MODE_NONE:
+ return "Non Scannable";
+ case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
+ return "Connectable And Discoverable";
+ case BT_SCAN_MODE_CONNECTABLE:
+ return "Connectable";
+ default:
+ return "Unknown Scan Mode";
+ }
+
+}
+
+static void local_le_feat2string(char *str, const bt_local_le_features_t *f)
+{
+ uint16_t scan_num;
+
+ str += sprintf(str, "{\n");
+
+ str += sprintf(str, "Privacy supported: %s,\n",
+ f->local_privacy_enabled ? "TRUE" : "FALSE");
+
+ str += sprintf(str, "Num of advertising instances: %u,\n",
+ f->max_adv_instance);
+
+ str += sprintf(str, "PRA offloading support: %s,\n",
+ f->rpa_offload_supported ? "TRUE" : "FALSE");
+
+ str += sprintf(str, "Num of offloaded IRKs: %u,\n",
+ f->max_irk_list_size);
+
+ str += sprintf(str, "Num of offloaded scan filters: %u,\n",
+ f->max_adv_filter_supported);
+
+ scan_num = (f->scan_result_storage_size_hibyte << 8) +
+ f->scan_result_storage_size_lobyte;
+
+ str += sprintf(str, "Num of offloaded scan results: %u,\n", scan_num);
+
+ str += sprintf(str, "Activity & energy report support: %s\n",
+ f->activity_energy_info_supported ? "TRUE" : "FALSE");
+
+ sprintf(str, "}");
+}
+
+const char *btproperty2str(const bt_property_t *property)
+{
+ bt_service_record_t *rec;
+ static char buf[4096];
+ char *p;
+
+ p = buf + sprintf(buf, "type=%s len=%d val=",
+ bt_property_type_t2str(property->type),
+ property->len);
+
+ switch (property->type) {
+ case BT_PROPERTY_BDNAME:
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ snprintf(p, property->len + 1, "%s",
+ ((bt_bdname_t *) property->val)->name);
+ break;
+ case BT_PROPERTY_BDADDR:
+ sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val));
+ break;
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ sprintf(p, "%06x", *((unsigned int *) property->val));
+ break;
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ sprintf(p, "%s", bt_device_type_t2str(
+ *((bt_device_type_t *) property->val)));
+ break;
+ case BT_PROPERTY_REMOTE_RSSI:
+ sprintf(p, "%d", *((char *) property->val));
+ break;
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ sprintf(p, "%d", *((unsigned int *) property->val));
+ break;
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ sprintf(p, "%s",
+ bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val)));
+ break;
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ bonded_devices2string(p, property->val, property->len);
+ break;
+ case BT_PROPERTY_UUIDS:
+ uuids2string(p, property->val, property->len);
+ break;
+ case BT_PROPERTY_SERVICE_RECORD:
+ rec = property->val;
+ sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu),
+ rec->channel, rec->name);
+ break;
+ case BT_PROPERTY_LOCAL_LE_FEATURES:
+ local_le_feat2string(p, property->val);
+ break;
+ case BT_PROPERTY_REMOTE_VERSION_INFO:
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ default:
+ sprintf(p, "%p", property->val);
+ break;
+ }
+
+ return buf;
+}
oal_status_t convert_to_oal_status(bt_status_t status);
void parse_device_properties(int num_properties, bt_property_t *properties,
remote_device_t *dev_info, ble_adv_data_t * adv_info);
+static gboolean retry_enable_adapter(gpointer data);
oal_status_t oal_mgr_init_internal(void);
+
+/* Callback registered with Stack */
+static void cb_adapter_state_change(bt_state_t status);
+
static bt_callbacks_t callbacks = {
sizeof(callbacks),
- NULL, /* adapter_state_changed_callback */
+ cb_adapter_state_change,
NULL, /* adapter_properties_callback */
NULL, /* remote_device_properties_callback */
NULL, /* device_found_callback */
BT_DBG();
}
+oal_status_t adapter_enable(void)
+{
+ int ret = BT_STATUS_SUCCESS;
+
+ API_TRACE();
+ CHECK_OAL_INITIALIZED();
+ if (OAL_STATUS_SUCCESS != hw_is_module_ready()) {
+ g_timeout_add(200, retry_enable_adapter, NULL);
+ return OAL_STATUS_PENDING;
+ }
+
+ ret = blued_api->enable();
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BT_ERR("Enable failed: [%s]", status2string(ret));
+ return convert_to_oal_status(ret);
+ }
+
+ return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t adapter_disable(void)
+{
+ int ret;
+
+ API_TRACE();
+
+ CHECK_OAL_INITIALIZED();
+
+ ret = blued_api->disable();
+
+ if (ret != BT_STATUS_SUCCESS) {
+ BT_ERR("Disable failed: [%s]", status2string(ret));
+ return convert_to_oal_status(ret);
+ }
+ return OAL_STATUS_SUCCESS;
+}
+
+/* Callbacks from Stack */
+static void cb_adapter_state_change(bt_state_t status)
+{
+ BT_DBG("+");
+ oal_event_t event;
+
+ event = (BT_STATE_ON == status)?OAL_EVENT_ADAPTER_ENABLED:OAL_EVENT_ADAPTER_DISABLED;
+
+ send_event(event, NULL);
+}
+
+static gboolean retry_enable_adapter(gpointer data)
+{
+ adapter_enable();
+ return FALSE;
+}
/*This file will contain state machines related to adapter and remote device */
+/* Global variables */
+static guint timer_id = 0;
+
+/* Adapter default states */
+static bt_status_t adapter_state = BT_DEACTIVATED;
+static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
+
/* Forward declarations */
static void __bt_adapter_event_handler(int event_type, gpointer event_data);
static void __bt_post_oal_init(void);
static void __bt_handle_oal_initialisation(oal_event_t event);
+static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size);
+static gboolean __bt_adapter_post_set_enabled(gpointer user_data);
+static gboolean __bt_adapter_post_set_disabled(gpointer user_data);
+static void __bt_adapter_update_bt_enabled(void);
+static void __bt_adapter_update_bt_disabled(void);
+static void __bt_adapter_state_set_status(bt_status_t status);
+static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
+static void __bt_adapter_state_change_callback(int bt_status);
+static int __bt_adapter_state_handle_request(gboolean enable);
+
/* Initialize BT stack (Initialize OAL layer) */
int _bt_stack_init(void)
return BLUETOOTH_ERROR_NONE;
}
+int _bt_enable_adapter(void)
+{
+ return __bt_adapter_state_handle_request(TRUE);
+}
+
+int _bt_disable_adapter(void)
+{
+ return __bt_adapter_state_handle_request(FALSE);
+}
+
static void __bt_adapter_event_handler(int event_type, gpointer event_data)
{
BT_DBG("");
case OAL_EVENT_OAL_INITIALISED_FAILED:
__bt_handle_oal_initialisation(event_type);
break;
+ case OAL_EVENT_ADAPTER_ENABLED:
+ __bt_adapter_state_change_callback(BT_ACTIVATED);
+ break;
+ case OAL_EVENT_ADAPTER_DISABLED:
+ __bt_adapter_state_change_callback(BT_DEACTIVATED);
+ break;
default:
BT_ERR("Unhandled event..");
break;
break;
}
}
+
+/* Internal functions of core adapter service */
+static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
+{
+ GSList *l;
+ GArray *out_param;
+ invocation_info_t *req_info;
+ BT_INFO("+");
+
+ /* Get method invocation context */
+ for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
+ req_info = l->data;
+ if (req_info == NULL || req_info->service_function != service_function)
+ continue;
+
+ /* Create out param */
+ out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+
+ switch(service_function) {
+ case BT_ENABLE_ADAPTER:
+ case BT_DISABLE_ADAPTER:
+ {
+ gboolean done = TRUE;
+ g_array_append_vals(out_param, &done, sizeof(gboolean));
+ break;
+ }
+ default:
+ BT_ERR("Unknown service function[%d]", service_function);
+ }
+
+ _bt_service_method_return(req_info->context, out_param, req_info->result);
+ g_array_free(out_param, TRUE);
+ /* Now free invocation info for this request*/
+ _bt_free_info_from_invocation_list(req_info);
+ }
+}
+
+/* Request return handlings */
+static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
+{
+ BT_INFO("__bt_adapter_post_set_enabled>>");
+ /*TODO Get All properties */
+ /* Add Adapter enabled post processing codes */
+ return FALSE;
+}
+
+static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
+{
+ BT_INFO("_bt_adapter_post_set_disabled>>");
+ /* Add Adapter disabled post processing codes */
+ return FALSE;
+}
+
+static void __bt_adapter_update_bt_enabled(void)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ BT_INFO("_bt_adapter_update_bt_enabled>>");
+ /* Update Bluetooth Status to notify other modules */
+ if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
+ BT_ERR("Set vconf failed\n");
+
+ /* TODO:Add timer function to handle any further post processing */
+ g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
+
+ /*Return BT_ADAPTER_ENABLE Method invocation context */
+ __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
+ /*Send BT Enabled event to application */
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
+ g_variant_new("(i)", result));
+}
+
+static void __bt_adapter_update_bt_disabled(void)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ BT_INFO("_bt_adapter_update_bt_disabled>>");
+
+ int power_off_status = 0;
+ int ret;
+
+ /* Update the vconf BT status in normal Deactivation case only */
+ ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
+ BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
+
+ /* TODO:Add timer function to handle any further post processing */
+ g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
+
+ /* Return BT_ADAPTER_DISABLE Method invocation context */
+ __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
+
+ /* Send BT Disabled event to application */
+ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
+ g_variant_new("(i)", result));
+}
+
+
+static void __bt_adapter_state_set_status(bt_status_t status)
+{
+ BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
+ adapter_state = status;
+}
+
+static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
+{
+ BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
+ adapter_discovery_state = status;
+}
+
+static void __bt_adapter_state_change_callback(int bt_status)
+{
+ BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
+
+ switch (bt_status) {
+ case BT_DEACTIVATED:
+ __bt_adapter_state_set_status(bt_status);
+
+ /* Adapter is disabled, unregister event handlers */
+ _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
+ //_bt_deinit_device_event_handler();
+
+ /* Add Adapter disabled post processing codes */
+ __bt_adapter_update_bt_disabled();
+ break;
+ case BT_ACTIVATED:
+ __bt_adapter_state_set_status(bt_status);
+ /* Add Adapter enabled post processing codes */
+ if (timer_id > 0) {
+ BT_DBG("g_source is removed");
+ g_source_remove(timer_id);
+ timer_id = 0;
+ }
+ __bt_adapter_update_bt_enabled();
+ break;
+ default:
+ BT_ERR("Incorrect Bluetooth adapter state changed status");
+
+ }
+}
+
+static int __bt_adapter_state_handle_request(gboolean enable)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+ BT_DBG("");
+
+ switch (adapter_state) {
+ case BT_ACTIVATING:
+ {
+ BT_INFO("Adapter is currently in activating state, state [%d]",
+ adapter_state);
+ if (enable) {
+ return BLUETOOTH_ERROR_IN_PROGRESS;
+ } else {
+ if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
+ adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
+ /*TODO Stop Discovery*/
+ if (result != OAL_STATUS_SUCCESS)
+ BT_ERR("Discover stop failed: %d", result);
+ __bt_adapter_update_discovery_status(FALSE);
+ }
+ result = adapter_disable();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("adapter_enable failed: [%d]", result);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ /*TODO: perform if anything more needs to be done to handle failure */
+ } else {
+ /* TODO: To be handled */
+ __bt_adapter_state_set_status(BT_DEACTIVATING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
+ }
+ case BT_ACTIVATED:
+ {
+ BT_INFO("Adapter is currently in activated state, state [%d]",
+ adapter_state);
+ if (enable) {
+ return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
+ } else {
+ if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
+ adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
+ /*TODO Stop Discovery*/
+ if (result != OAL_STATUS_SUCCESS)
+ BT_ERR("Discover stop failed: %d", result);
+ __bt_adapter_update_discovery_status(FALSE);
+ }
+ result = adapter_disable();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("adapter_enable failed: [%d]", result);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ /*TODO: perform if anything more needs to be done to handle failure */
+ } else {
+ /* TODO: To be handled */
+ __bt_adapter_state_set_status(BT_DEACTIVATING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
+ }
+ case BT_DEACTIVATING:
+ {
+ BT_INFO("Adapter is currently in deactivating state, state [%d]",
+ adapter_state);
+ if (!enable) {
+ return BLUETOOTH_ERROR_IN_PROGRESS;
+
+ } else {
+ result = adapter_enable();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("adapter_enable failed: [%d]", result);
+ adapter_disable();
+ result = BLUETOOTH_ERROR_INTERNAL;
+ /*TODO: perform if anything more needs to be done to handle failure */
+ } else {
+ /* TODO: To be handled */
+ __bt_adapter_state_set_status(BT_ACTIVATING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
+ }
+ case BT_DEACTIVATED:
+ {
+ BT_INFO("Adapter is currently in deactivated state, state [%d]",
+ adapter_state);
+ if (!enable) {
+ return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
+ } else {
+ result = adapter_enable();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("adapter_enable failed: [%d]", result);
+ adapter_disable();
+ result = BLUETOOTH_ERROR_INTERNAL;
+ /*TODO: perform if anything more needs to be done to handle failure */
+ } else {
+ /* TODO: To be handled */
+ __bt_adapter_state_set_status(BT_ACTIVATING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
+ }
+ }
+ if (enable && result == BLUETOOTH_ERROR_NONE) {
+ /* Adapter enable request is successful, setup event handlers */
+ _bt_service_register_event_handler_callback(
+ BT_ADAPTER_MODULE, __bt_adapter_event_handler);
+ /*TODO Set Device Core Callbacks*/
+ }
+ return result;
+}
+
GArray **out_param1)
{
int result = BLUETOOTH_ERROR_NONE;
+ char *sender = NULL;
switch (function_name) {
+ case BT_ENABLE_ADAPTER: {
+ result = _bt_enable_adapter();
+ /* Save invocation */
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_DBG("_bt_enable_adapter scheduled successfully! save invocation context");
+ sender = (char*)g_dbus_method_invocation_get_sender(context);
+ _bt_save_invocation_context(context, result, sender,
+ function_name, NULL);
+ }
+ break;
+ }
+ case BT_DISABLE_ADAPTER: {
+ result = _bt_disable_adapter();
+ /* Save invocation */
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_DBG("_bt_disable_adapter scheduled successfully! save invocation context");
+ sender = (char*)g_dbus_method_invocation_get_sender(context);
+ _bt_save_invocation_context(context, result, sender,
+ function_name, NULL);
+ }
+ break;
+ }
default:
BT_INFO("UnSupported function [%d]", function_name);
result = BLUETOOTH_ERROR_NOT_SUPPORT;
switch(event_type) {
case OAL_EVENT_OAL_INITIALISED_SUCCESS:
case OAL_EVENT_OAL_INITIALISED_FAILED:
+ case OAL_EVENT_ADAPTER_ENABLED:
+ case OAL_EVENT_ADAPTER_DISABLED:
if (adapter_cb)
adapter_cb(event_type, event_data);
break;
extern "C" {
#endif
+typedef enum {
+ ADAPTER_DISCOVERY_STOPPED,
+ ADAPTER_DISCOVERY_STARTED,
+ ADAPTER_DISCOVERY_STARTING,
+ ADAPTER_DISCOVERY_STOPPING,
+} bt_adapter_discovery_state_t;
+
+typedef enum {
+ BT_DEACTIVATED,
+ BT_ACTIVATED,
+ BT_ACTIVATING,
+ BT_DEACTIVATING,
+} bt_status_t;
+
+int _bt_enable_adapter(void);
+
+int _bt_disable_adapter(void);
+
int _bt_stack_init(void);
#ifdef __cplusplus