From 41bfe957df119c7d3693451fe94b950bccf70904 Mon Sep 17 00:00:00 2001 From: Taejin Woo Date: Fri, 8 Jan 2016 13:35:31 +0900 Subject: [PATCH] Merge the code from tizen_2.4 Change-Id: Id763ee7f503c8b0535b6d437f69d65710d98c011 Signed-off-by: Taejin Woo --- CMakeLists.txt | 2 + bt-api/CMakeLists.txt | 9 +- bt-api/bt-adapter.c | 4 +- bt-api/bt-common.c | 220 ++-- bt-api/bt-device.c | 131 +- bt-api/bt-event-handler.c | 174 ++- bt-api/bt-gatt-client.c | 162 +-- bt-api/bt-gatt-service.c | 1017 ++++++++++++---- bt-api/bt-hdp.c | 263 ++-- bt-api/bt-hid-device.c | 179 ++- bt-api/bt-ipsp.c | 104 ++ bt-api/bt-request-sender.c | 45 +- bt-api/bt-rfcomm-client.c | 10 +- bt-api/bt-rfcomm-server.c | 26 + bt-api/bt-scmst.c | 2 - bt-api/bt-telephony.c | 27 +- bt-api/include/bt-common.h | 10 +- bt-api/include/bt-request-sender.h | 6 +- bt-core/CMakeLists.txt | 7 +- bt-core/bt-core-adapter.c | 46 +- bt-core/bt-core-dbus-handler.c | 175 ++- bt-core/bt-core-main.c | 5 +- bt-core/bt-core-noti-handler.c | 17 +- bt-core/include/bt-core-dbus-handler.h | 3 + bt-httpproxy/CMakeLists.txt | 48 + bt-httpproxy/bt-httpproxy.c | 1759 +++++++++++++++++++++++++++ bt-httpproxy/bt-httpproxy.h | 102 ++ bt-httpproxy/org.projectx.httpproxy.service | 4 + bt-service/CMakeLists.txt | 4 + bt-service/bt-request-handler.c | 214 +++- bt-service/bt-service-adapter-le.c | 333 +++-- bt-service/bt-service-adapter.c | 76 +- bt-service/bt-service-agent.c | 93 +- bt-service/bt-service-audio.c | 1 + bt-service/bt-service-avrcp.c | 10 +- bt-service/bt-service-common.c | 27 +- bt-service/bt-service-device.c | 597 +++++++-- bt-service/bt-service-event-receiver.c | 175 ++- bt-service/bt-service-event-sender.c | 72 +- bt-service/bt-service-gap-agent.c | 66 +- bt-service/bt-service-main.c | 21 +- bt-service/bt-service-network.c | 7 +- bt-service/bt-service-obex-agent.c | 18 +- bt-service/bt-service-obex-server.c | 7 +- bt-service/bt-service-oob.c | 1 - bt-service/bt-service-opp-client.c | 6 +- bt-service/bt-service-pbap.c | 126 +- bt-service/bt-service-rfcomm-client.c | 3 +- bt-service/bt-service-rfcomm-server.c | 3 +- bt-service/include/bt-service-adapter-le.h | 17 + bt-service/include/bt-service-common.h | 4 +- bt-service/include/bt-service-device.h | 25 +- bt-service/include/bt-service-obex-server.h | 2 + bt-service/org.projectx.bt.service | 1 + include/bluetooth-api.h | 176 ++- include/bluetooth-audio-api.h | 2 - include/bluetooth-ipsp-api.h | 138 +++ include/bluetooth-telephony-api.h | 2 - include/bt-internal-types.h | 31 + packaging/bluetooth-frwk.spec | 21 +- test/CMakeLists.txt | 2 +- test/bluetooth-frwk-test.c | 70 +- test/gatt-test/CMakeLists.txt | 2 +- test/gatt-test/bluetooth-gatt-test.c | 5 +- test/handsfree/CMakeLists.txt | 2 +- test/handsfree/bluetooth-hf-test.c | 6 +- test/le-adv/CMakeLists.txt | 2 +- test/le-adv/bluetooth-advertising-test.c | 5 +- test/media-control/CMakeLists.txt | 2 +- test/telephony/bluetooth-telephony-test.c | 6 +- 70 files changed, 5716 insertions(+), 1222 deletions(-) create mode 100644 bt-api/bt-ipsp.c create mode 100644 bt-httpproxy/CMakeLists.txt create mode 100644 bt-httpproxy/bt-httpproxy.c create mode 100644 bt-httpproxy/bt-httpproxy.h create mode 100644 bt-httpproxy/org.projectx.httpproxy.service create mode 100644 include/bluetooth-ipsp-api.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bca208..6018a43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ ADD_SUBDIRECTORY(bt-api) ADD_SUBDIRECTORY(bt-service) +ADD_SUBDIRECTORY(bt-httpproxy) + ADD_SUBDIRECTORY(bt-core) ADD_SUBDIRECTORY(test) diff --git a/bt-api/CMakeLists.txt b/bt-api/CMakeLists.txt index 817d0d5..6ba8936 100644 --- a/bt-api/CMakeLists.txt +++ b/bt-api/CMakeLists.txt @@ -23,7 +23,8 @@ bt-scmst.c bt-gatt-service.c bt-pbap.c bt-hid-device.c -bt-gatt-client.c) +bt-gatt-client.c +bt-ipsp.c) SET(HEADERS bluetooth-api.h @@ -31,7 +32,8 @@ bluetooth-hid-api.h bluetooth-audio-api.h bluetooth-telephony-api.h bluetooth-media-control.h -bluetooth-scmst-api.h) +bluetooth-scmst-api.h +bluetooth-ipsp-api.h) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(EXEC_PREFIX "\${prefix}") @@ -56,6 +58,7 @@ SET(PKG_MODULES glib-2.0 gio-2.0 gio-unix-2.0 + dbus-1 ) INCLUDE(FindPkgConfig) @@ -77,6 +80,8 @@ IF("${ARCH}" STREQUAL "arm") MESSAGE("add -DTARGET") ENDIF("${ARCH}" STREQUAL "arm") +ADD_DEFINITIONS("-DHPS_FEATURE") + FIND_PROGRAM(MARSHALTOOL NAMES glib-genmarshal) EXEC_PROGRAM("${MARSHALTOOL}" ARGS "--prefix=marshal ${CMAKE_CURRENT_SOURCE_DIR}/marshal.list --header > ${CMAKE_CURRENT_SOURCE_DIR}/include/marshal.h") EXEC_PROGRAM("${MARSHALTOOL}" ARGS "--prefix=marshal ${CMAKE_CURRENT_SOURCE_DIR}/marshal.list --body > ${CMAKE_CURRENT_SOURCE_DIR}/marshal.c") diff --git a/bt-api/bt-adapter.c b/bt-api/bt-adapter.c index 6eb7fe7..4208fd8 100644 --- a/bt-api/bt-adapter.c +++ b/bt-api/bt-adapter.c @@ -295,7 +295,7 @@ BT_EXPORT_API int bluetooth_get_discoverable_mode(bluetooth_discoverable_mode_t if (bluetooth_check_adapter() == BLUETOOTH_ADAPTER_DISABLED) { if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0) { BT_ERR("Fail to get the timeout value"); - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; } if (timeout == -1) { @@ -306,6 +306,8 @@ BT_EXPORT_API int bluetooth_get_discoverable_mode(bluetooth_discoverable_mode_t return BLUETOOTH_ERROR_NONE; } +#else + BT_CHECK_ENABLED(return); #endif BT_INIT_PARAMS(); diff --git a/bt-api/bt-common.c b/bt-api/bt-common.c index 8535457..e69e230 100644 --- a/bt-api/bt-common.c +++ b/bt-api/bt-common.c @@ -37,63 +37,75 @@ #include "bluetooth-hid-api.h" #include "bluetooth-media-control.h" #include "bt-internal-types.h" +#include "bluetooth-ipsp-api.h" #include "bt-common.h" #include "bt-request-sender.h" #include "bt-event-handler.h" static bt_user_info_t user_info[BT_MAX_USER_INFO]; -static DBusGConnection *system_conn = NULL; +static DBusConnection *system_conn = NULL; static GDBusConnection *system_gdbus_conn = NULL; + static guint bus_id; static GDBusConnection *system_gconn = NULL; #define DBUS_TIMEOUT 20 * 1000 /* 20 Seconds */ -GDBusConnection *_bt_gdbus_init_system_gconn(void) +GDBusConnection *g_bus_get_private_conn(void) { GError *error = NULL; + char *address; + GDBusConnection *private_gconn = NULL; - if (!g_thread_supported()) { - g_thread_init(NULL); + address = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (address == NULL) { + if (error) { + BT_ERR ("Failed to get bus address: %s", error->message); + g_clear_error(&error); + } + return NULL; + } + + private_gconn = g_dbus_connection_new_for_address_sync (address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, + NULL, /* GDBusAuthObserver */ + NULL, + &error); + if (!private_gconn) { + if (error) { + BT_ERR("Unable to connect to dbus: %s", error->message); + g_clear_error(&error); + } + return NULL; } - dbus_g_thread_init(); + return private_gconn; +} + +GDBusConnection *_bt_gdbus_init_system_gconn(void) +{ + dbus_threads_init_default(); g_type_init(); if (system_gconn != NULL) return system_gconn; - system_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - - if (!system_gconn) { - BT_ERR("Unable to connect to dbus: %s", error->message); - g_clear_error(&error); - } + system_gconn = g_bus_get_private_conn(); 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) { - BT_ERR("Unable to connect to dbus: %s", error->message); - g_clear_error(&error); - } - - system_gconn = local_system_gconn; + system_gconn = g_bus_get_private_conn(); } return system_gconn; @@ -431,18 +443,8 @@ void __rfcomm_delete_id(int id) static GDBusConnection *__get_gdbus_connection() { - GError *err = NULL; - if (gconn == NULL) - gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); - - if (!gconn) { - if (err) { - BT_ERR("Unable to connect to dbus: %s", err->message); - g_clear_error(&err); - } - return NULL; - } + gconn = g_bus_get_private_conn(); return gconn; } @@ -688,6 +690,7 @@ int _bt_register_profile(bt_register_profile_info_t *info, gboolean use_default_ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); if (err) { + g_dbus_error_strip_remote_error(err); BT_ERR("RegisterProfile failed: %s", err->message); if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG)) @@ -756,6 +759,7 @@ int _bt_register_profile_ex(bt_register_profile_info_t *info, gboolean use_defau G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); if (err) { + g_dbus_error_strip_remote_error(err); BT_ERR("RegisterProfile failed: %s", err->message); if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG)) @@ -823,6 +827,7 @@ int _bt_register_profile_platform(bt_register_profile_info_t *info, gboolean use NULL, &err); if (err) { + g_dbus_error_strip_remote_error(err); BT_ERR("RegisterProfile failed: %s", err->message); if (g_strrstr(err->message, BT_ACCESS_DENIED_MSG)) @@ -923,6 +928,11 @@ int _bt_connect_profile(char *address, char *uuid, void *cb, BT_ERR("No searched device"); adapter_proxy = __bt_gdbus_get_adapter_proxy(); + if (adapter_proxy == NULL) { + BT_ERR("adapter proxy is NULL"); + return BLUETOOTH_ERROR_INTERNAL; + } + ret = g_dbus_proxy_call_sync(adapter_proxy, "CreateDevice", g_variant_new("(s)", address), G_DBUS_CALL_FLAGS_NONE, @@ -984,7 +994,9 @@ int _bt_discover_services(char *address, char *uuid, void *cb, } if (ret) g_variant_unref(ret); + g_object_unref(adapter_proxy); + object_path = _bt_get_device_object_path(address); if (object_path == NULL) return BLUETOOTH_ERROR_INTERNAL; @@ -1028,7 +1040,9 @@ int _bt_cancel_discovers(char *address) } if (ret) g_variant_unref(ret); + g_object_unref(adapter_proxy); + object_path = _bt_get_device_object_path(address); if (object_path == NULL) return BLUETOOTH_ERROR_INTERNAL; @@ -1057,7 +1071,7 @@ int _bt_discover_service_uuids(char *address, char *remote_uuid) GDBusConnection *gconn; GError *err = NULL; char **uuid_value = NULL; - gsize size; + gsize size = 0; int i =0; GVariant *value = NULL; GVariant *ret = NULL; @@ -1100,22 +1114,26 @@ int _bt_discover_service_uuids(char *address, char *remote_uuid) GVariant *temp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY); - size = g_variant_get_size(temp_value); - if (size > 0) { - uuid_value = (char **)g_variant_get_strv(temp_value, &size); - BT_DBG("Size items %d", size); - } - if (temp_value) - g_variant_unref(temp_value); - for (i = 0; uuid_value[i] != NULL; i++) { - BT_DBG("Remote uuids %s", uuid_value[i]); - if (strcasecmp(uuid_value[i], remote_uuid) == 0) { - result = BLUETOOTH_ERROR_NONE; - goto done; + if (temp_value) { + size = g_variant_get_size(temp_value); + if (size > 0) { + uuid_value = (char **)g_variant_get_strv(temp_value, &size); + BT_DBG("Size items %d", size); + + if (uuid_value) { + for (i = 0; uuid_value[i] != NULL; i++) { + BT_DBG("Remote uuids %s", uuid_value[i]); + if (strcasecmp(uuid_value[i], remote_uuid) == 0) { + result = BLUETOOTH_ERROR_NONE; + g_variant_unref(temp_value); + goto done; + } + } + } } + g_variant_unref(temp_value); } } - done: if (proxy) g_object_unref(proxy); @@ -1388,59 +1406,12 @@ char *_bt_get_device_object_path(char *address) fail: g_clear_error(&err); - if (result) - g_variant_unref(result); - if (proxy) g_object_unref(proxy); return object_path; } - -DBusGProxy *_bt_get_adapter_proxy(DBusGConnection *conn) -{ - GError *err = NULL; - DBusGProxy *manager_proxy = NULL; - DBusGProxy *adapter_proxy = NULL; - char *adapter_path = NULL; - - retv_if(conn == NULL, NULL); - - manager_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, - BT_MANAGER_PATH, BT_MANAGER_INTERFACE); - - retv_if(manager_proxy == NULL, NULL); - - if (!dbus_g_proxy_call(manager_proxy, "DefaultAdapter", &err, - G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH, - &adapter_path, - G_TYPE_INVALID)) { - if (err != NULL) { - BT_ERR("Getting DefaultAdapter failed: [%s]\n", err->message); - g_error_free(err); - } - g_object_unref(manager_proxy); - return NULL; - } - - if (adapter_path == NULL || strlen(adapter_path) >= BT_ADAPTER_OBJECT_PATH_MAX) { - BT_ERR("Adapter path is inproper\n"); - g_free(adapter_path); - g_object_unref(manager_proxy); - return NULL; - } - - adapter_proxy = dbus_g_proxy_new_for_name(conn, - BT_BLUEZ_NAME, - adapter_path, - BT_ADAPTER_INTERFACE); - g_free(adapter_path); - g_object_unref(manager_proxy); - - return adapter_proxy; -} - void _bt_device_path_to_address(const char *device_path, char *device_address) { char address[BT_ADDRESS_STRING_SIZE] = { 0 }; @@ -1463,53 +1434,34 @@ void _bt_device_path_to_address(const char *device_path, char *device_address) } } -DBusGConnection *__bt_init_system_gconn(void) +/* TODO : replace the dbus-glib APIs to gdbus APIs */ +DBusConnection *__bt_init_system_conn(void) { - g_type_init(); - if (system_conn == NULL) - system_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL); + system_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL); - return system_conn; -} - -DBusGConnection *_bt_get_system_gconn(void) -{ - return (system_conn) ? system_conn : __bt_init_system_gconn(); -} - -GDBusConnection *_bt_init_system_gdbus_conn(void) -{ - g_type_init(); - GError *error = NULL; - if (system_gdbus_conn == NULL) { - system_gdbus_conn = - g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (error) { - BT_ERR("GDBus connection Error : %s \n", - error->message); - g_clear_error(&error); - return NULL; - } + if (system_conn) { + dbus_connection_setup_with_g_main(system_conn, NULL); + dbus_connection_set_exit_on_disconnect(system_conn, FALSE); } - return system_gdbus_conn; + + return system_conn; } DBusConnection *_bt_get_system_conn(void) { - DBusGConnection *g_conn; + DBusConnection *conn = NULL; if (system_conn == NULL) { - g_conn = __bt_init_system_gconn(); + conn = __bt_init_system_conn(); } else { - g_conn = system_conn; + conn = system_conn; } - retv_if(g_conn == NULL, NULL); - - return dbus_g_connection_get_connection(g_conn); + return conn; } + int _bt_register_osp_server_in_agent(int type, char *uuid, char *path, int fd) { int ret; @@ -1661,7 +1613,7 @@ BT_EXPORT_API int bluetooth_register_callback(bluetooth_cb_func_ptr callback_ptr int ret; _bt_gdbus_init_system_gconn(); - __bt_init_system_gconn(); + __bt_init_system_conn(); ret = _bt_init_event_handler(); if (ret != BLUETOOTH_ERROR_NONE && @@ -1670,6 +1622,7 @@ BT_EXPORT_API int bluetooth_register_callback(bluetooth_cb_func_ptr callback_ptr return ret; } + _bt_set_user_data(BT_COMMON, (void *)callback_ptr, user_data); /* Register All events */ @@ -1688,6 +1641,11 @@ BT_EXPORT_API int bluetooth_register_callback(bluetooth_cb_func_ptr callback_ptr ret = _bt_register_event(BT_RFCOMM_SERVER_EVENT, (void *)callback_ptr, user_data); if (ret != BLUETOOTH_ERROR_NONE) goto fail; +#ifdef GATT_NO_RELAY + ret = _bt_register_event(BT_GATT_BLUEZ_EVENT, (void *)callback_ptr, user_data); + if (ret != BLUETOOTH_ERROR_NONE) + goto fail; +#endif _bt_register_name_owner_changed(); @@ -1702,6 +1660,7 @@ BT_EXPORT_API int bluetooth_unregister_callback(void) { int ret; + ret = _bt_deinit_event_handler(); if (ret != BLUETOOTH_ERROR_NONE) { BT_ERR("Fail to deinit the event handler"); @@ -1712,13 +1671,16 @@ BT_EXPORT_API int bluetooth_unregister_callback(void) _bt_set_user_data(BT_COMMON, NULL, NULL); if (system_conn) { - dbus_g_connection_unref(system_conn); + dbus_connection_flush(system_conn); + dbus_connection_close(system_conn); + dbus_connection_unref(system_conn); system_conn = NULL; } if (system_gconn) { g_object_unref(system_gconn); system_gconn = NULL; } + _bt_gdbus_deinit_proxys(); return BLUETOOTH_ERROR_NONE; } diff --git a/bt-api/bt-device.c b/bt-api/bt-device.c index 5897f49..ec4f0c1 100644 --- a/bt-api/bt-device.c +++ b/bt-api/bt-device.c @@ -320,6 +320,7 @@ BT_EXPORT_API int bluetooth_is_device_connected(const bluetooth_device_address_t BT_EXPORT_API int bluetooth_connect_le(const bluetooth_device_address_t *device_address, gboolean auto_connect) { int result; + bt_user_info_t *user_info; BT_CHECK_PARAMETER(device_address, return); BT_CHECK_ENABLED_ANY(return); @@ -330,8 +331,12 @@ BT_EXPORT_API int bluetooth_connect_le(const bluetooth_device_address_t *device_ g_array_append_vals(in_param1, device_address, sizeof(bluetooth_device_address_t)); g_array_append_vals(in_param2, &auto_connect, sizeof(gboolean)); - result = _bt_send_request(BT_BLUEZ_SERVICE, BT_CONNECT_LE, - in_param1, in_param2, in_param3, in_param4, &out_param); + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info == NULL, BLUETOOTH_ERROR_INTERNAL); + + result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_CONNECT_LE, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); @@ -341,6 +346,7 @@ BT_EXPORT_API int bluetooth_connect_le(const bluetooth_device_address_t *device_ BT_EXPORT_API int bluetooth_disconnect_le(const bluetooth_device_address_t *device_address) { int result; + bt_user_info_t *user_info; BT_CHECK_PARAMETER(device_address, return); BT_CHECK_ENABLED_ANY(return); @@ -350,8 +356,12 @@ BT_EXPORT_API int bluetooth_disconnect_le(const bluetooth_device_address_t *devi g_array_append_vals(in_param1, device_address, sizeof(bluetooth_device_address_t)); - result = _bt_send_request(BT_BLUEZ_SERVICE, BT_DISCONNECT_LE, - in_param1, in_param2, in_param3, in_param4, &out_param); + user_info = _bt_get_user_data(BT_COMMON); + retv_if(user_info == NULL, BLUETOOTH_ERROR_INTERNAL); + + result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_DISCONNECT_LE, + in_param1, in_param2, in_param3, in_param4, + user_info->cb, user_info->user_data); BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); @@ -399,7 +409,7 @@ BT_EXPORT_API int bluetooth_get_rssi_strength(const bluetooth_device_address_t * } BT_EXPORT_API int bluetooth_le_conn_update(const bluetooth_device_address_t *address, - const bluetooth_le_conn_update_t *parameters) + const bluetooth_le_connection_param_t *parameters) { int result; @@ -413,7 +423,7 @@ BT_EXPORT_API int bluetooth_le_conn_update(const bluetooth_device_address_t *add g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t)); g_array_append_vals(in_param2, parameters, - sizeof(bluetooth_le_conn_update_t)); + sizeof(bluetooth_le_connection_param_t)); result = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_CONN_UPDATE, in_param1, in_param2, in_param3, in_param4, &out_param); @@ -448,3 +458,112 @@ BT_EXPORT_API int bluetooth_get_connected_link_type( return result; } + +BT_EXPORT_API int bluetooth_set_pin_code( + const bluetooth_device_address_t *device_address, + const bluetooth_device_pin_code_t *pin_code) +{ + int result; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_PARAMETER(pin_code, return); + BT_CHECK_ENABLED(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, device_address, sizeof(bluetooth_device_address_t)); + g_array_append_vals(in_param2, pin_code, sizeof(bluetooth_device_pin_code_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_SET_PIN_CODE, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_unset_pin_code( + const bluetooth_device_address_t *device_address) +{ + int result; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_ENABLED(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, device_address, sizeof(bluetooth_device_address_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_UNSET_PIN_CODE, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_update_le_connection_mode(const bluetooth_device_address_t *address, + const bluetooth_le_connection_mode_t mode) +{ + int result; + + BT_CHECK_ENABLED(return); + BT_CHECK_PARAMETER(address, return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, address, + sizeof(bluetooth_device_address_t)); + g_array_append_vals(in_param2, &mode, + sizeof(bluetooth_le_connection_mode_t)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_UPDATE_LE_CONNECTION_MODE, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_passkey_reply(char *passkey, gboolean reply) +{ + int result; + + char str_passkey[BLUETOOTH_DEVICE_PASSKEY_LENGTH_MAX]; + + BT_CHECK_PARAMETER(passkey, return); + BT_CHECK_ENABLED(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_strlcpy(str_passkey, passkey, sizeof(str_passkey)); + g_array_append_vals(in_param1, str_passkey, BLUETOOTH_DEVICE_PASSKEY_LENGTH_MAX); + g_array_append_vals(in_param2, &reply, sizeof(gboolean)); + + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_PASSKEY_REPLY, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} + +BT_EXPORT_API int bluetooth_passkey_confirmation_reply(gboolean reply) +{ + int result; + + BT_CHECK_ENABLED(return); + BT_INIT_PARAMS(); + + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + g_array_append_vals(in_param1, &reply, sizeof(gboolean)); + result = _bt_send_request(BT_BLUEZ_SERVICE, BT_PASSKEY_CONFIRMATION_REPLY, + in_param1, in_param2, in_param3, in_param4, &out_param); + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return result; +} diff --git a/bt-api/bt-event-handler.c b/bt-api/bt-event-handler.c index 8cc2860..1cae341 100755 --- a/bt-api/bt-event-handler.c +++ b/bt-api/bt-event-handler.c @@ -22,8 +22,6 @@ */ #include -#include -#include #include #include #include @@ -55,6 +53,7 @@ static GSList *sending_list = NULL; static GSList *server_list = NULL; static GSList *event_list = NULL; static int owner_sig_id = -1; +static gboolean is_adapter_enabled = TRUE; void _bt_add_push_request_id(int request_id) { @@ -383,12 +382,15 @@ gboolean __bt_reliable_disable_cb(gpointer user_data) _bt_set_le_scan_status(FALSE); if (is_initialized != FALSE) { - _bt_common_event_cb(BLUETOOTH_EVENT_DISABLED, - BLUETOOTH_ERROR_NONE, NULL, - event_info->cb, event_info->user_data); - _bt_common_event_cb(BLUETOOTH_EVENT_LE_DISABLED, - BLUETOOTH_ERROR_NONE, NULL, - event_info->cb, event_info->user_data); + if (is_adapter_enabled == TRUE) { + is_adapter_enabled = FALSE; + _bt_common_event_cb(BLUETOOTH_EVENT_DISABLED, + BLUETOOTH_ERROR_NONE, NULL, + event_info->cb, event_info->user_data); + _bt_common_event_cb(BLUETOOTH_EVENT_LE_DISABLED, + BLUETOOTH_ERROR_NONE, NULL, + event_info->cb, event_info->user_data); + } } obex_server_id = BT_NO_SERVER; @@ -434,6 +436,8 @@ void __bt_adapter_event_filter(GDBusConnection *connection, BT_ERR("Set vconf failed"); } + is_adapter_enabled = TRUE; + _bt_common_event_cb(BLUETOOTH_EVENT_ENABLED, result, NULL, event_info->cb, event_info->user_data); @@ -458,6 +462,12 @@ void __bt_adapter_event_filter(GDBusConnection *connection, disable_timer_id = g_timeout_add(BT_RELIABLE_DISABLE_TIME, (GSourceFunc)__bt_reliable_disable_cb, event_info); + } else { + is_adapter_enabled = FALSE; + + _bt_common_event_cb(BLUETOOTH_EVENT_DISABLED, + result, NULL, + event_info->cb, event_info->user_data); } _bt_common_event_cb(BLUETOOTH_EVENT_DISABLED, @@ -629,6 +639,87 @@ void __bt_adapter_event_filter(GDBusConnection *connection, event_info->cb, event_info->user_data); g_free(device_info); + } else if (strcasecmp(signal_name, BT_IPSP_INITIALIZED) == 0) { + gboolean ipsp_intialized = FALSE; + g_variant_get(parameters, "(b)", &ipsp_intialized); + + BT_DBG("IPSP init state changed to : %d", ipsp_intialized); + + _bt_common_event_cb(BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED, + BLUETOOTH_ERROR_NONE, &ipsp_intialized, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_KBD_PASSKEY_DISPLAY_REQ_RECEIVED) == 0) { + const char *address = NULL; + const char *name = NULL; + const char *str_passkey = NULL; + + bluetooth_authentication_request_info_t auth_info; + memset(&auth_info, 0x00, sizeof(bluetooth_authentication_request_info_t)); + + g_variant_get(parameters, "(i&s&s&s)", &result, &address, &name, &str_passkey); + + g_strlcpy(auth_info.device_name.name, name, + BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1); + _bt_convert_addr_string_to_type(auth_info.device_address.addr, + address); + g_strlcpy(auth_info.str_passkey, str_passkey, strlen(str_passkey)+1); + + _bt_common_event_cb(BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, + result, &auth_info, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_PIN_REQ_RECEIVED) == 0) { + const char *address = NULL; + const char *name = NULL; + + bluetooth_authentication_request_info_t auth_info; + memset(&auth_info, 0x00, sizeof(bluetooth_authentication_request_info_t)); + + g_variant_get(parameters, "(i&s&s)", &result, &address, &name); + + g_strlcpy(auth_info.device_name.name, name, + BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1); + _bt_convert_addr_string_to_type(auth_info.device_address.addr, + address); + + _bt_common_event_cb(BLUETOOTH_EVENT_PIN_REQUEST, + result, &auth_info, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_PASSKEY_REQ_RECEIVED) == 0) { + const char *address = NULL; + const char *name = NULL; + + bluetooth_authentication_request_info_t auth_info; + memset(&auth_info, 0x00, sizeof(bluetooth_authentication_request_info_t)); + + g_variant_get(parameters, "(i&s&s)", &result, &address, &name); + + g_strlcpy(auth_info.device_name.name, name, + BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1); + _bt_convert_addr_string_to_type(auth_info.device_address.addr, + address); + + _bt_common_event_cb(BLUETOOTH_EVENT_PASSKEY_REQUEST, + result, &auth_info, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_PASSKEY_CFM_REQ_RECEIVED) == 0) { + const char *address = NULL; + const char *name = NULL; + const char *str_passkey = NULL; + + bluetooth_authentication_request_info_t auth_info; + memset(&auth_info, 0x00, sizeof(bluetooth_authentication_request_info_t)); + + g_variant_get(parameters, "(i&s&s&s)", &result, &address, &name, &str_passkey); + + g_strlcpy(auth_info.device_name.name, name, + BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1); + _bt_convert_addr_string_to_type(auth_info.device_address.addr, + address); + g_strlcpy(auth_info.str_passkey, str_passkey, strlen(str_passkey)+1); + + _bt_common_event_cb(BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, + result, &auth_info, + event_info->cb, event_info->user_data); } } @@ -700,10 +791,24 @@ void __bt_device_event_filter(GDBusConnection *connection, event_info = (bt_event_info_t *)user_data; ret_if(event_info == NULL); +#ifdef GATT_NO_RELAY + gboolean gatt_interface = FALSE; + + if (strcasecmp(interface_name, BT_GATT_CHARACTERISTIC_INTERFACE) == 0) + gatt_interface = TRUE; + + if (strcasecmp(object_path, BT_DEVICE_PATH) != 0 && + gatt_interface == FALSE) + return; + if (strcasecmp(interface_name, BT_EVENT_SERVICE) != 0 && + gatt_interface == FALSE) + return; +#else if (strcasecmp(object_path, BT_DEVICE_PATH) != 0) return; if (strcasecmp(interface_name, BT_EVENT_SERVICE) != 0) return; +#endif ret_if(signal_name == NULL); @@ -729,7 +834,11 @@ void __bt_device_event_filter(GDBusConnection *connection, _bt_common_event_cb(BLUETOOTH_EVENT_GATT_DISCONNECTED, result, &dev_address, event_info->cb, event_info->user_data); +#ifdef GATT_NO_RELAY + } else if (strcasecmp(signal_name, BT_GATT_BLUEZ_CHAR_VAL_CHANGED) == 0) { +#else } else if (strcasecmp(signal_name, BT_GATT_CHAR_VAL_CHANGED) == 0) { +#endif const char *char_handle = NULL; int len = 0; const char * value = NULL; @@ -752,6 +861,8 @@ void __bt_device_event_filter(GDBusConnection *connection, if (char_val.char_value == NULL) { BT_ERR("BLUETOOTH_ERROR_OUT_OF_MEMORY"); g_free(char_val.char_handle); + if (char_value_var) + g_variant_unref(char_value_var); return; } memcpy(char_val.char_value, value, len); @@ -759,6 +870,8 @@ void __bt_device_event_filter(GDBusConnection *connection, result, &char_val, event_info->cb, event_info->user_data); g_free(char_val.char_value); + if (char_value_var) + g_variant_unref(char_value_var); } g_free(char_val.char_handle); } else if (strcasecmp(signal_name, BT_DEVICE_CONNECTED) == 0) { @@ -889,6 +1002,30 @@ void __bt_device_event_filter(GDBusConnection *connection, _bt_common_event_cb(BLUETOOTH_EVENT_DEVICE_UNAUTHORIZED, result, &dev_address, event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_IPSP_CONNECTED) == 0) { + const char *address = NULL; + bluetooth_device_address_t dev_address = { {0} }; + + BT_DBG("BT_IPSP_CONNECTED"); + g_variant_get(parameters, "(i&s)", &result, &address); + + _bt_convert_addr_string_to_type(dev_address.addr, address); + + _bt_common_event_cb(BLUETOOTH_EVENT_IPSP_CONNECTED, + result, &dev_address, + event_info->cb, event_info->user_data); + } else if (strcasecmp(signal_name, BT_IPSP_DISCONNECTED) == 0) { + const char *address = NULL; + bluetooth_device_address_t dev_address = { {0} }; + BT_DBG("BT_IPSP_DISCONNECTED"); + + g_variant_get(parameters, "(i&s)", &result, &address); + + _bt_convert_addr_string_to_type(dev_address.addr, address); + + _bt_common_event_cb(BLUETOOTH_EVENT_IPSP_DISCONNECTED, + result, &dev_address, + event_info->cb, event_info->user_data); } else if (strcasecmp(signal_name, BT_LE_DATA_LENGTH_CHANGED) == 0) { const char *address = NULL; bluetooth_device_address_t dev_address = { {0} }; @@ -2378,7 +2515,6 @@ static void __bt_event_data_free(void *data) ret_if(cb_data == NULL); - g_object_unref(cb_data->conn); g_free(cb_data); } @@ -2468,24 +2604,26 @@ int _bt_register_event(int event_type, void *event_cb, void *user_data) event_func = __bt_hid_device_event_filter; path = BT_HID_DEVICE_PATH; break; +#ifdef GATT_NO_RELAY + case BT_GATT_BLUEZ_EVENT: + BT_DBG("BT_GATT_BLUEZ_EVENT"); + event_func = __bt_device_event_filter; + interface = BT_GATT_CHARACTERISTIC_INTERFACE; + path = NULL; + break; +#endif default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; } - connection_type = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (connection_type == NULL) { - if (error) { - BT_ERR("Unable to get the bus: %s", error->message); - g_clear_error(&error); - } + connection_type = _bt_gdbus_get_system_gconn(); + if (connection_type == NULL) return BLUETOOTH_ERROR_INTERNAL; - } cb_data = g_new0(bt_event_info_t, 1); cb_data->event_type = event_type; - cb_data->conn = connection_type; cb_data->cb = event_cb; cb_data->user_data = user_data; @@ -2520,7 +2658,7 @@ int _bt_unregister_event(int event_type) return BLUETOOTH_ERROR_INTERNAL; } - connection_type = cb_data->conn; + connection_type = _bt_gdbus_get_system_gconn(); event_list = g_slist_remove(event_list, (void *)cb_data); diff --git a/bt-api/bt-gatt-client.c b/bt-api/bt-gatt-client.c index 1d80967..8be742e 100644 --- a/bt-api/bt-gatt-client.c +++ b/bt-api/bt-gatt-client.c @@ -28,6 +28,8 @@ #include #include "bt-common.h" +#include "bt-internal-types.h" +#include "bt-request-sender.h" #define GATT_SERV_INTERFACE "org.bluez.GattService1" #define GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1" @@ -138,7 +140,7 @@ BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle BT_CHECK_PARAMETER(service_handle, return); BT_CHECK_PARAMETER(service, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); g_conn = _bt_gdbus_get_system_gconn(); retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -237,7 +239,7 @@ BT_EXPORT_API int bluetooth_gatt_get_primary_services( BT_INFO("+"); BT_CHECK_PARAMETER(address, return); BT_CHECK_PARAMETER(prim_svc, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); result = _bt_get_managed_objects(); if (result == NULL) @@ -307,7 +309,7 @@ BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_ BT_CHECK_PARAMETER(address, return); BT_CHECK_PARAMETER(service_uuid, return); BT_CHECK_PARAMETER(service, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); result = _bt_get_managed_objects(); if (result == NULL) @@ -367,7 +369,6 @@ static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy, GVariantIter *char_iter; GPtrArray *gp_array = NULL; bt_gatt_discovered_char_t svc_char = { 0, }; - int i; char *char_handle; GError *error = NULL; bt_user_info_t *user_info; @@ -400,20 +401,16 @@ static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy, g_variant_get(value, "(v)", &char_value); g_variant_get(char_value, "ao", &char_iter); - int len = g_variant_get_size((GVariant *)char_iter); - if (len > 0) { - gp_array = g_ptr_array_new(); - for (i = 0; i < len; i++) { - g_variant_iter_loop(char_iter, "&o", &char_handle); - g_ptr_array_add(gp_array, (gpointer)char_handle); - } - if (gp_array->len != 0) { - svc_char.handle_info.count = gp_array->len; - svc_char.handle_info.handle = - __get_string_array_from_gptr_array(gp_array); - } - g_ptr_array_free(gp_array, TRUE); + gp_array = g_ptr_array_new(); + while(g_variant_iter_loop(char_iter, "&o", &char_handle)); + g_ptr_array_add(gp_array, (gpointer)char_handle); + + if (gp_array->len != 0) { + svc_char.handle_info.count = gp_array->len; + svc_char.handle_info.handle = + __get_string_array_from_gptr_array(gp_array); } + g_ptr_array_free(gp_array, TRUE); if (user_info) { _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED, @@ -438,7 +435,7 @@ BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics( BT_DBG("+"); BT_CHECK_PARAMETER(service_handle, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); g_conn = _bt_gdbus_get_system_gconn(); retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -523,7 +520,7 @@ BT_EXPORT_API int bluetooth_gatt_get_characteristics_property( BT_CHECK_PARAMETER(char_handle, return); BT_CHECK_PARAMETER(characteristic, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); g_conn = _bt_gdbus_get_system_gconn(); retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -687,7 +684,7 @@ BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle, BT_CHECK_PARAMETER(service_handle, return); BT_CHECK_PARAMETER(char_uuid, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); g_conn = _bt_gdbus_get_system_gconn(); retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -734,7 +731,7 @@ BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property( BT_CHECK_PARAMETER(descriptor_handle, return); BT_CHECK_PARAMETER(descriptor, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); g_conn = _bt_gdbus_get_system_gconn(); retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -865,7 +862,7 @@ BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *character char *handle; BT_CHECK_PARAMETER(characteristic, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -901,7 +898,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value( BT_CHECK_PARAMETER(char_handle, return); BT_CHECK_PARAMETER(value, return); retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -983,7 +980,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type( BT_CHECK_PARAMETER(char_handle, return); BT_CHECK_PARAMETER(value, return); retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -995,36 +992,17 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type( } val = g_variant_new("ay", builder); - - if (write_type == - BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE) { - g_dbus_connection_call(conn, - BT_BLUEZ_NAME, - char_handle, - GATT_CHAR_INTERFACE, - "WriteValuebyType", - g_variant_new("(y@ay)", write_type, val), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, - (GAsyncReadyCallback)__bluetooth_internal_write_cb, - NULL); - } else if (write_type == - BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE) { - g_dbus_connection_call(conn, - BT_BLUEZ_NAME, - char_handle, - GATT_CHAR_INTERFACE, - "WriteValuebyType", - g_variant_new("(y@ay)", write_type, val), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, - (GAsyncReadyCallback)__bluetooth_internal_write_cb, - NULL); - } else - ret = BLUETOOTH_ERROR_INVALID_PARAM; - + g_dbus_connection_call(conn, + BT_BLUEZ_NAME, + char_handle, + GATT_CHAR_INTERFACE, + "WriteValuebyType", + g_variant_new("(y@ay)", write_type, val), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, + (GAsyncReadyCallback)__bluetooth_internal_write_cb, + NULL); g_variant_builder_unref(builder); return ret; @@ -1042,7 +1020,7 @@ BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request( BT_CHECK_PARAMETER(char_handle, return); BT_CHECK_PARAMETER(value, return); retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1195,7 +1173,6 @@ static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy, GVariant *value; GVariant *char_value; GVariantIter *char_iter; - int i; char *char_handle; GError *error = NULL; bt_user_info_t *user_info; @@ -1227,16 +1204,12 @@ static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy, g_variant_get(value, "(v)", &char_value); g_variant_get(char_value, "ao", &char_iter); - int len = g_variant_get_size((GVariant *)char_iter); - if (len > 0) { - for (i = 0; i < len; i++) { - g_variant_iter_loop(char_iter, "o", &char_handle); - BT_DBG("object path of descriptor = %s",char_handle); - if(char_handle) { + while(g_variant_iter_loop(char_iter, "&o", &char_handle)) { + BT_DBG("object path of descriptor = %s",char_handle); + if(char_handle) { ret = __bluetooth_gatt_descriptor_iter(char_handle, &characteristic); BT_DBG("Descriptor read status [%d]",ret); - } } } @@ -1260,7 +1233,7 @@ BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor( GError *error = NULL; BT_CHECK_PARAMETER(characteristic_handle, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); g_conn = _bt_gdbus_get_system_gconn(); retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1352,7 +1325,7 @@ BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descript BT_DBG("+"); BT_CHECK_PARAMETER(char_descriptor, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1421,7 +1394,7 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value( BT_CHECK_PARAMETER(desc_handle, return); BT_CHECK_PARAMETER(value, return); retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); conn = _bt_gdbus_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1452,6 +1425,26 @@ BT_EXPORT_API int bluetooth_gatt_write_descriptor_value( return BLUETOOTH_ERROR_NONE; } +#ifndef GATT_NO_RELAY +static int __bluetooth_gatt_watch_characteristics(void) +{ + int result = BLUETOOTH_ERROR_NONE; + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + result = _bt_send_request(BT_BLUEZ_SERVICE, + BT_GATT_WATCH_CHARACTERISTIC, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result != BLUETOOTH_ERROR_NONE) + BT_ERR("Watch Characteristic request failed !"); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + return result; +} +#endif + BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle) { @@ -1461,7 +1454,7 @@ BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle) BT_DBG("+"); BT_CHECK_PARAMETER(char_handle, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); BT_DBG("Entered characteristic handle:%s \n ", char_handle); @@ -1499,10 +1492,35 @@ BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle) g_clear_error(&error); } - BT_DBG("-"); +#ifndef GATT_NO_RELAY + else { + /* Register the client sender to bt-service */ + ret = __bluetooth_gatt_watch_characteristics(); + } +#endif + return ret; } +#ifndef GATT_NO_RELAY +static void __bluetooth_gatt_unwatch_characteristics(void) +{ + int result = BLUETOOTH_ERROR_NONE; + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + result = _bt_send_request(BT_BLUEZ_SERVICE, + BT_GATT_UNWATCH_CHARACTERISTIC, + in_param1, in_param2, in_param3, in_param4, &out_param); + + if (result != BLUETOOTH_ERROR_NONE) + BT_ERR("Unwatch Characteristic request failed !"); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); +} +#endif + BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle) { @@ -1512,7 +1530,7 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle BT_DBG("+"); BT_CHECK_PARAMETER(char_handle, return); - BT_CHECK_ENABLED(return); + BT_CHECK_ENABLED_ANY(return); BT_DBG("Entered characteristic handle:%s \n ", char_handle); @@ -1534,6 +1552,12 @@ BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle g_clear_error(&error); ret = BLUETOOTH_ERROR_INTERNAL; } +#ifndef GATT_NO_RELAY + else { + /* Unregister the client sender to bt-service */ + __bluetooth_gatt_unwatch_characteristics(); + } +#endif BT_DBG("-"); return ret; } diff --git a/bt-api/bt-gatt-service.c b/bt-api/bt-gatt-service.c index c027d40..1e6ff1b 100644 --- a/bt-api/bt-gatt-service.c +++ b/bt-api/bt-gatt-service.c @@ -37,15 +37,27 @@ guint manager_id; static gboolean new_service = FALSE; static gboolean new_char = FALSE; static int serv_id = 1; +static int register_pending_cnt = 0; /* Introspection data for the service we are exporting */ static const gchar service_introspection_xml[] = "" +" " +" " +" " +" " +" " " " " " " " -" " -" " +" " +" " +" " +" " +" " +" " +" " +" " " " ""; @@ -53,14 +65,42 @@ static const gchar service_introspection_xml[] = static const gchar characteristics_introspection_xml[] = "" " " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " " " " " " " " " +" " +" " " " " " +" " +" " +" " +" " " " ""; @@ -68,44 +108,31 @@ static const gchar characteristics_introspection_xml[] = static const gchar descriptor_introspection_xml[] = "" " " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " " " " " -" " +" " " " " " " " " " ""; -static const gchar manager_introspection_xml[] = -"" -" " -" " -" " -" " -" " -""; - -static const gchar properties_introspection_xml[] = -"" -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -""; - struct gatt_service_info { gchar *serv_path; guint serv_id; @@ -114,6 +141,7 @@ struct gatt_service_info { guint prop_id; GSList *char_data; gboolean is_svc_registered; + gboolean is_svc_primary; }; struct gatt_char_info { @@ -140,6 +168,7 @@ struct gatt_req_info { gchar *svc_path; guint request_id; guint offset; + GDBusMethodInvocation *context; }; static GSList *gatt_services = NULL; @@ -155,14 +184,80 @@ static GSList *gatt_requests = NULL; #define GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1" #define GATT_DESC_INTERFACE "org.bluez.GattDescriptor1" +#ifdef HPS_FEATURE +#define BT_HPS_OBJECT_PATH "/org/projectx/httpproxy" +#define BT_HPS_INTERFACE_NAME "org.projectx.httpproxy_service" +#define PROPERTIES_CHANGED "PropertiesChanged" +#define BT_HPS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" +#endif + static GDBusProxy *manager_gproxy = NULL; static struct gatt_char_info *__bt_gatt_find_gatt_char_info( const char *service_path, const char *char_path); +static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info( + const char *serv_path, const char *char_path, + const char *desc_path); static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id); -static void __bt_gatt_manager_method_call(GDBusConnection *connection, +#ifdef HPS_FEATURE +static int __bt_send_event_to_hps(int event, GVariant *var) +{ + GError *error = NULL; + GVariant *parameters; + GDBusMessage *msg = NULL; + + BT_DBG(" "); + + retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + if (event == BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED) { + GVariantBuilder *inner_builder; + GVariantBuilder *invalidated_builder; + + BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED"); + inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + + g_variant_builder_add(inner_builder, "{sv}", "WriteValue", var); + + invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as")); + + parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder); + g_variant_builder_unref(invalidated_builder); + g_variant_builder_unref(inner_builder); + } else if (BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED) { + GVariantBuilder *inner_builder; + GVariantBuilder *invalidated_builder; + + BT_DBG("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED"); + inner_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + + g_variant_builder_add(inner_builder, "{sv}", "ReadValue", var); + + invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as")); + + parameters = g_variant_new("(a{sv}as)", inner_builder, invalidated_builder); + g_variant_builder_unref(invalidated_builder); + g_variant_builder_unref(inner_builder); + } + + msg = g_dbus_message_new_signal(BT_HPS_OBJECT_PATH, BT_HPS_INTERFACE_NAME, PROPERTIES_CHANGED); + g_dbus_message_set_body(msg, parameters); + if (!g_dbus_connection_send_message(g_conn, msg,G_DBUS_SEND_MESSAGE_FLAGS_NONE, 0, NULL)) { + if (error != NULL) { + BT_ERR("D-Bus API failure: errCode[%x], \ + message[%s]", + error->code, error->message); + g_clear_error(&error); + } + return BLUETOOTH_ERROR_INTERNAL; + } + return BLUETOOTH_ERROR_NONE; +} +#endif + +static void __bt_gatt_serv_method_call(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, @@ -171,10 +266,15 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, GDBusMethodInvocation *invocation, gpointer user_data) { - if (g_strcmp0(method_name, "GetManagedObjects") == 0) { + GSList *l1; + if (g_strcmp0(method_name, "GetManagedObjects") == 0) { BT_DBG("Getting values for service, chars and descriptors"); + GVariantBuilder *builder; + GVariantBuilder *inner_builder1 = NULL; + GVariant *svc_char = NULL; + GSList *l4; /*Main Builder */ builder = g_variant_builder_new( G_VARIANT_TYPE("a{oa{sa{sv}}}")); @@ -184,7 +284,14 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, GVariantBuilder *svc_builder = NULL; GVariantBuilder *inner_builder = NULL; - GSList *l1 = g_slist_last(gatt_services); + if (register_pending_cnt > 1) { + int len = g_slist_length(gatt_services); + l1 = g_slist_nth(gatt_services, len - register_pending_cnt); + } else { + l1 = g_slist_last(gatt_services); + } + register_pending_cnt--; + struct gatt_service_info *serv_info = l1->data; if (serv_info == NULL) { BT_ERR("service info value is NULL"); @@ -201,6 +308,23 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, g_variant_builder_add(inner_builder, "{sv}", "UUID", g_variant_new_string(serv_info->service_uuid)); + g_variant_builder_add(inner_builder, "{sv}", "Primary", + g_variant_new_boolean(serv_info->is_svc_primary)); + + /*Characteristics*/ + inner_builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao")); + BT_DBG("Adding Charatarisitcs list"); + for (l4 = serv_info->char_data; l4 != NULL; l4 = l4->next) { + struct gatt_char_info *char_info = l4->data; + g_variant_builder_add(inner_builder1, "o", + char_info->char_path); + BT_DBG("%s", char_info->char_path); + } + + svc_char = g_variant_new("ao", inner_builder1); + g_variant_builder_add(inner_builder, "{sv}", "Characteristics", + svc_char); + g_variant_builder_add(svc_builder, "{sa{sv}}", GATT_SERV_INTERFACE, inner_builder); @@ -209,6 +333,8 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, serv_info->serv_path, svc_builder); + g_variant_builder_unref(inner_builder1); + /* Prepare inner builder for GattCharacteristic1 interface */ GSList *l2 = serv_info->char_data; @@ -223,8 +349,12 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, GVariantBuilder *inner_builder = NULL; GVariantBuilder *builder1 = NULL; GVariantBuilder *builder2 = NULL; + GVariantBuilder *builder3 = NULL; GVariant *char_val = NULL; GVariant *flags_val = NULL; + GVariant *char_desc = NULL; + char *unicast = NULL; + gboolean notify = FALSE; int i = 0; char_builder = g_variant_builder_new( @@ -270,6 +400,30 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, g_variant_builder_add(inner_builder, "{sv}", "Flags", flags_val); + /* Notifying */ + g_variant_builder_add(inner_builder, "{sv}", "Notifying", + g_variant_new("b", notify)); + + /* Unicast */ + unicast = g_strdup("00:00:00:00:00:00"); + g_variant_builder_add(inner_builder, "{sv}", "Unicast", + g_variant_new("s", unicast)); + + /*Descriptors*/ + builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao")); + BT_DBG("Adding Descriptors list"); + + for (l4 = char_info->desc_data; l4 != NULL; l4 = l4->next) { + struct gatt_desc_info *desc_info = l4->data; + g_variant_builder_add(builder3, "o", + desc_info->desc_path); + BT_DBG("%s", desc_info->desc_path); + } + + char_desc = g_variant_new("ao", builder3); + g_variant_builder_add(inner_builder, "{sv}", "Descriptors", + char_desc); + g_variant_builder_add(char_builder, "{sa{sv}}", GATT_CHAR_INTERFACE , inner_builder); g_variant_builder_add(builder, "{oa{sa{sv}}}", @@ -343,9 +497,12 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, g_variant_builder_unref(desc_builder); } + if (unicast) + g_free(unicast); /*unref char builder pointers*/ g_variant_builder_unref(builder1); g_variant_builder_unref(builder2); + g_variant_builder_unref(builder3); g_variant_builder_unref(inner_builder); g_variant_builder_unref(char_builder); } @@ -363,7 +520,72 @@ static void __bt_gatt_manager_method_call(GDBusConnection *connection, } } -static void __bt_gatt_prop_method_call(GDBusConnection *connection, +static struct gatt_service_info *__bt_gatt_find_gatt_service_from_char(const char *char_path) +{ + GSList *l1, *l2; + + for (l1 = gatt_services; l1 != NULL; l1 = l1->next) { + struct gatt_service_info *serv_info = l1->data; + + for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { + struct gatt_char_info *char_info = l2->data; + + if (g_strcmp0(char_info->char_path, char_path) + == 0) + return serv_info; + } + } + BT_ERR("Gatt service not found"); + return NULL; +} + +static struct gatt_service_info *__bt_gatt_find_gatt_service_from_desc(const char *desc_path) +{ + GSList *l1, *l2, *l3; + + for (l1 = gatt_services; l1 != NULL; l1 = l1->next) { + struct gatt_service_info *serv_info = l1->data; + + for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { + struct gatt_char_info *char_info = l2->data; + + for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) { + struct gatt_desc_info *desc_info = l3->data; + + if (g_strcmp0(desc_info->desc_path, desc_path) + == 0) + return serv_info; + } + } + } + BT_ERR("Gatt service not found"); + return NULL; +} + +static struct gatt_char_info *__bt_gatt_find_gatt_char_from_desc(const char *desc_path) +{ + GSList *l1, *l2, *l3; + + for (l1 = gatt_services; l1 != NULL; l1 = l1->next) { + struct gatt_service_info *serv_info = l1->data; + + for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { + struct gatt_char_info *char_info = l2->data; + + for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) { + struct gatt_desc_info *desc_info = l3->data; + + if (g_strcmp0(desc_info->desc_path, desc_path) + == 0) + return char_info; + } + } + } + BT_ERR("Gatt Characterisitc not found"); + return NULL; +} + +static void __bt_gatt_char_method_call(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, @@ -372,78 +594,360 @@ static void __bt_gatt_prop_method_call(GDBusConnection *connection, GDBusMethodInvocation *invocation, gpointer user_data) { - GVariantBuilder *inner_builder = NULL; - int i; if (g_strcmp0(method_name, "ReadValue") == 0) { gchar *addr = NULL; - gchar *attr_path = NULL; guint8 req_id = 1; guint16 offset = 0; bt_gatt_read_req_t read_req = {0, }; bt_user_info_t *user_info = NULL; struct gatt_req_info *req_info = NULL; + struct gatt_service_info *svc_info = NULL; - g_variant_get(parameters, "(&s&syq)", &addr, &attr_path, &req_id, &offset); + int i; + BT_DBG("ReadValue"); + + g_variant_get(parameters, "(&syq)", &addr, &req_id, &offset); BT_DBG("Application path = %s", object_path); - BT_DBG("Attribute path = %s", attr_path); BT_DBG("Remote Device address number = %s", addr); BT_DBG("Request id = %d, Offset = %d", req_id, offset); BT_DBG("Sender = %s", sender); - read_req.char_handle = g_strdup(attr_path); + read_req.att_handle = g_strdup(object_path); read_req.address = g_strdup(addr); read_req.req_id = req_id; read_req.offset = offset; - user_info = _bt_get_user_data(BT_COMMON); + svc_info = __bt_gatt_find_gatt_service_from_char(object_path); + if (svc_info != NULL) { + read_req.service_handle = g_strdup(svc_info->serv_path); + user_info = _bt_get_user_data(BT_COMMON); +#ifdef HPS_FEATURE + GVariant *param = NULL; +#endif + + /* Store requets information */ + req_info = g_new0(struct gatt_req_info, 1); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(read_req.service_handle); + req_info->request_id= req_id; + req_info->offset = offset; + req_info->context = invocation; + gatt_requests = g_slist_append(gatt_requests, req_info); + + if (user_info != NULL) { + struct gatt_char_info *char_info = NULL; + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, + BLUETOOTH_ERROR_NONE, &read_req, + user_info->cb, user_info->user_data); + } +#ifdef HPS_FEATURE + param = g_variant_new("(sssyq)", + read_req.att_handle, + read_req.service_handle, + read_req.address, + read_req.req_id, + read_req.offset); + __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, param); +#endif + } + + if (read_req.att_handle) + g_free(read_req.att_handle); + if (read_req.address) + g_free(read_req.address); + if (read_req.service_handle) + g_free(read_req.service_handle); + return; + } else if (g_strcmp0(method_name, "WriteValue") == 0) { + GVariant *var = NULL; + gchar *addr = NULL; + guint8 req_id = 0; + guint16 offset = 0; + bt_gatt_value_change_t value_change = {0, }; + bt_user_info_t *user_info = NULL; + int len = 0; + struct gatt_service_info *svc_info = NULL; + struct gatt_req_info *req_info = NULL; +#ifdef HPS_FEATURE + GVariant *param = NULL; +#endif + + BT_DBG("WriteValue"); + BT_DBG("Application path = %s", object_path); + BT_DBG("Sender = %s", sender); + + g_variant_get(parameters, "(&syq@ay)", &addr, &req_id, &offset, &var); + + value_change.att_handle = g_strdup(object_path); + value_change.address = g_strdup(addr); + svc_info = __bt_gatt_find_gatt_service_from_char(object_path); + if (svc_info == NULL) { + g_variant_unref(var); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + + value_change.service_handle = g_strdup(svc_info->serv_path); + value_change.offset = offset; + value_change.req_id = req_id; + + len = g_variant_get_size(var); + if (len > 0) { + char *data; + + value_change.att_value = (guint8 *)malloc(len); + if (!value_change.att_value) { + BT_ERR("att_value is NULL"); + g_variant_unref(var); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + + data = (char *)g_variant_get_data(var); + memcpy(value_change.att_value, data, len); + } + + value_change.val_len = len; /* Store requets information */ req_info = g_new0(struct gatt_req_info, 1); - req_info->attr_path = g_strdup(attr_path); - req_info->svc_path = g_strdup(object_path); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(value_change.service_handle); req_info->request_id= req_id; req_info->offset = offset; + req_info->context = invocation; gatt_requests = g_slist_append(gatt_requests, req_info); - inner_builder = g_variant_builder_new(G_VARIANT_TYPE ("ay")); - + user_info = _bt_get_user_data(BT_COMMON); if (user_info != NULL) { - struct gatt_char_info *char_info; - - read_req.service_handle = g_strdup(object_path); _bt_common_event_cb( - BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, - BLUETOOTH_ERROR_NONE, &read_req, + BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, + BLUETOOTH_ERROR_NONE, &value_change, user_info->cb, user_info->user_data); + } +#ifdef HPS_FEATURE + if (len > 0) { + gchar *svc_path; + svc_path = g_strdup(svc_info->serv_path); + param = g_variant_new("(sssyq@ay)", + object_path, + svc_path, + addr, + req_id, + offset, + var); + __bt_send_event_to_hps(BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, param); + if (svc_path) + g_free(svc_path); + } +#endif + g_variant_unref(var); + return; + } else if (g_strcmp0(method_name, "StartNotify") == 0) { + bt_user_info_t *user_info = NULL; + bt_gatt_char_notify_change_t notify_change = {0, }; + BT_DBG("StartNotify"); + user_info = _bt_get_user_data(BT_COMMON); + if (user_info != NULL) { + struct gatt_service_info *svc_info = NULL; + svc_info = __bt_gatt_find_gatt_service_from_char(object_path); + if (svc_info) { + notify_change.service_handle = g_strdup(svc_info->serv_path); + notify_change.att_handle = g_strdup(object_path); + notify_change.att_notify = TRUE; + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED, + BLUETOOTH_ERROR_NONE, ¬ify_change, + user_info->cb, user_info->user_data); + } + } + } else if (g_strcmp0(method_name, "StopNotify") == 0) { + bt_user_info_t *user_info = NULL; + bt_gatt_char_notify_change_t notify_change = {0, }; + BT_DBG("StopNotify"); + user_info = _bt_get_user_data(BT_COMMON); + if (user_info != NULL) { + struct gatt_service_info *svc_info = NULL; + svc_info = __bt_gatt_find_gatt_service_from_char(object_path); + if (svc_info) { + notify_change.service_handle = g_strdup(svc_info->serv_path); + notify_change.att_handle = g_strdup(object_path); + notify_change.att_notify = FALSE; + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED, + BLUETOOTH_ERROR_NONE, ¬ify_change, + user_info->cb, user_info->user_data); + } + } + } else if (g_strcmp0(method_name, "IndicateConfirm") == 0) { + gchar *addr = NULL; + bt_gatt_indicate_confirm_t confirm = {0, }; + bt_user_info_t *user_info = NULL; + gboolean complete = 0; + struct gatt_service_info *svc_info = NULL; + + BT_DBG("IndicateConfirm"); + BT_DBG("Application path = %s", object_path); + BT_DBG("Sender = %s", sender); + + g_variant_get(parameters, "(&sb)", &addr, &complete); - char_info = __bt_gatt_find_gatt_char_info(req_info->svc_path, req_info->attr_path); - if (char_info) { - for (i = req_info->offset; i < char_info->value_length; i++) - g_variant_builder_add(inner_builder, "y", char_info->char_value[i]); + BT_DBG("Remote Device address number = %s", addr); + confirm.att_handle = g_strdup(object_path); + confirm.address = g_strdup(addr); + confirm.complete = complete; + + svc_info = __bt_gatt_find_gatt_service_from_char(object_path); + if (svc_info != NULL) { + confirm.service_handle = g_strdup(svc_info->serv_path); + user_info = _bt_get_user_data(BT_COMMON); + + if (user_info != NULL) { + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_INDICATE_CONFIRMED, + BLUETOOTH_ERROR_NONE, &confirm, + user_info->cb, user_info->user_data); } } + } + g_dbus_method_invocation_return_value(invocation, NULL); +} - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(ay)", inner_builder)); - if (inner_builder) - g_variant_builder_unref(inner_builder); +static void __bt_gatt_desc_method_call(GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + GVariantBuilder *inner_builder = NULL; + int i; - if (read_req.char_handle) - g_free(read_req.char_handle); + if (g_strcmp0(method_name, "ReadValue") == 0) { + gchar *addr = NULL; + guint8 req_id = 1; + guint16 offset = 0; + bt_gatt_read_req_t read_req = {0, }; + bt_user_info_t *user_info = NULL; + struct gatt_req_info *req_info = NULL; + struct gatt_service_info *svc_info = NULL; + BT_DBG("ReadValue"); + + g_variant_get(parameters, "(&syq)", &addr, &req_id, &offset); + + BT_DBG("Application path = %s", object_path); + + BT_DBG("Remote Device address number = %s", addr); + BT_DBG("Request id = %d, Offset = %d", req_id, offset); + + BT_DBG("Sender = %s", sender); + + read_req.att_handle = g_strdup(object_path); + read_req.address = g_strdup(addr); + read_req.req_id = req_id; + read_req.offset = offset; + svc_info = __bt_gatt_find_gatt_service_from_desc(object_path); + if (svc_info != NULL) { + read_req.service_handle = g_strdup(svc_info->serv_path); + user_info = _bt_get_user_data(BT_COMMON); + + /* Store requets information */ + req_info = g_new0(struct gatt_req_info, 1); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(read_req.service_handle); + req_info->request_id= req_id; + req_info->offset = offset; + req_info->context = invocation; + gatt_requests = g_slist_append(gatt_requests, req_info); + + if (user_info != NULL) { + struct gatt_char_info *char_info = NULL; + + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED, + BLUETOOTH_ERROR_NONE, &read_req, + user_info->cb, user_info->user_data); + } + } + + if (read_req.att_handle) + g_free(read_req.att_handle); if (read_req.address) g_free(read_req.address); + if (read_req.service_handle) + g_free(read_req.service_handle); - gatt_requests = g_slist_remove(gatt_requests, req_info); - if (req_info->attr_path) - g_free(req_info->attr_path); - if (req_info->svc_path) - g_free(req_info->svc_path); + return; + } else if (g_strcmp0(method_name, "WriteValue") == 0) { + GVariant *var = NULL; + gchar *addr = NULL; + guint8 req_id = 0; + guint16 offset = 0; + bt_gatt_value_change_t value_change = {0, }; + bt_user_info_t *user_info = NULL; + int len = 0; + struct gatt_service_info *svc_info = NULL; + struct gatt_req_info *req_info = NULL; - g_free(req_info); + BT_DBG("WriteValue"); + BT_DBG("Application path = %s", object_path); + BT_DBG("Sender = %s", sender); + + g_variant_get(parameters, "(&syq@ay)", &addr, &req_id, &offset, &var); + + value_change.att_handle = g_strdup(object_path); + value_change.address = g_strdup(addr); + svc_info = __bt_gatt_find_gatt_service_from_desc(object_path); + if (svc_info == NULL) { + g_variant_unref(var); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + value_change.service_handle = g_strdup(svc_info->serv_path); + value_change.offset = offset; + value_change.req_id = req_id; + + len = g_variant_get_size(var); + if (len > 0) { + char *data; + + value_change.att_value = (guint8 *)malloc(len); + if (!value_change.att_value) { + BT_ERR("att_value is NULL"); + g_variant_unref(var); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } + data = (char *)g_variant_get_data(var); + memcpy(value_change.att_value, data, len); + } + g_variant_unref(var); + + value_change.val_len = len; + + /* Store requets information */ + req_info = g_new0(struct gatt_req_info, 1); + req_info->attr_path = g_strdup(object_path); + req_info->svc_path = g_strdup(value_change.service_handle); + req_info->request_id= req_id; + req_info->offset = offset; + req_info->context = invocation; + gatt_requests = g_slist_append(gatt_requests, req_info); + + user_info = _bt_get_user_data(BT_COMMON); + if (user_info != NULL) { + _bt_common_event_cb( + BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED, + BLUETOOTH_ERROR_NONE, &value_change, + user_info->cb, user_info->user_data); + } return; } g_dbus_method_invocation_return_value(invocation, NULL); @@ -479,126 +983,24 @@ gboolean __bt_gatt_emit_interface_removed(gchar *object_path, gchar *interface) return ret; } -static gboolean __bt_gatt_desc_set_property(GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GVariant *value, - GError **err, gpointer user_data) -{ - BT_DBG("+"); - - return TRUE; -} - -static gboolean __bt_gatt_char_set_property(GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GVariant *value, - GError **err, gpointer user_data) -{ - BT_DBG("+"); - - if (g_strcmp0(property_name, "Value") == 0) { - GVariantIter *var = NULL; - bt_gatt_char_value_t char_val = {0, }; - bt_user_info_t *user_info = NULL; - int len = 0, i; - - g_variant_get(value, "ay", &var); - len = g_variant_get_size((GVariant *)value); - BT_DBG("length of characteristic value = %d", len); - - char_val.char_handle = (char *)object_path; - if (len > 0) { - char_val.char_value = (guint8 *)malloc(len); - if (!char_val.char_value) { - g_variant_iter_free(var); - return FALSE; - } - } - for (i = 0; i < len; i++) - g_variant_iter_loop(var, "y", &char_val.char_value[i]); - char_val.val_len = len; - user_info = _bt_get_user_data(BT_COMMON); - if (user_info != NULL) - _bt_common_event_cb( - BLUETOOTH_EVENT_GATT_SERVER_CHARACTERISTIC_VALUE_CHANGED, - BLUETOOTH_ERROR_NONE, &char_val, - user_info->cb, user_info->user_data); - - bluetooth_gatt_update_characteristic(object_path, (const char *)char_val.char_value, - char_val.val_len); - - free(char_val.char_value); - g_variant_iter_free(var); - } - return TRUE; -} - -static GVariant *__bt_gatt_desc_get_property(GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GError **error, gpointer user_data) -{ - BT_DBG("+"); - - return NULL; -} - -static GVariant *__bt_gatt_char_get_property(GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GError **error, gpointer user_data) -{ - BT_DBG("+"); - - return NULL; -} - -static GVariant *__bt_gatt_serv_get_property(GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GError **error, gpointer user_data) -{ - BT_DBG("+"); - - return NULL; -} - static const GDBusInterfaceVTable desc_interface_vtable = { + __bt_gatt_desc_method_call, + NULL, NULL, - __bt_gatt_desc_get_property, - __bt_gatt_desc_set_property }; static const GDBusInterfaceVTable char_interface_vtable = { + __bt_gatt_char_method_call, + NULL, NULL, - __bt_gatt_char_get_property, - __bt_gatt_char_set_property, }; static const GDBusInterfaceVTable serv_interface_vtable = { + __bt_gatt_serv_method_call, NULL, - __bt_gatt_serv_get_property, - NULL, -}; - -static const GDBusInterfaceVTable manager_interface_vtable = { - __bt_gatt_manager_method_call, NULL, - NULL }; -static const GDBusInterfaceVTable properties_interface_vtable = { - __bt_gatt_prop_method_call, - NULL, - NULL -}; static GDBusNodeInfo *__bt_gatt_create_method_node_info( const gchar *introspection_data) @@ -711,10 +1113,18 @@ static int char_info_cmp(gconstpointer a1, gconstpointer a2) return g_strcmp0(attrib1->char_path, attrib2->char_path); } -static void __bt_gatt_update_attribute_info(struct gatt_req_info *req_info, +static int desc_info_cmp(gconstpointer a1, gconstpointer a2) +{ + const struct gatt_desc_info *attrib1 = a1; + const struct gatt_desc_info *attrib2 = a2; + + return g_strcmp0(attrib1->desc_path, attrib2->desc_path); +} + +static gboolean __bt_gatt_update_attribute_info(struct gatt_req_info *req_info, char *value, int value_length) { - GSList *l1, *l2; + GSList *l1, *l2, *l3; int found = 0; for (l1 = gatt_services; l1 != NULL; l1 = l1->next) { struct gatt_service_info *serv_info = l1->data; @@ -724,21 +1134,35 @@ static void __bt_gatt_update_attribute_info(struct gatt_req_info *req_info, for (l2 = serv_info->char_data; l2 != NULL; l2 = l2->next) { struct gatt_char_info *char_info = l2->data; - if (char_info && g_strcmp0(char_info->char_path, req_info->attr_path) - == 0) { - memcpy(&char_info->char_value[req_info->offset], value, value_length); - serv_info->char_data = g_slist_insert_sorted (serv_info->char_data, char_info, char_info_cmp); - found = 1; - break; + if (char_info) { + if (g_strcmp0(char_info->char_path, req_info->attr_path) == 0) { + memcpy(&char_info->char_value[req_info->offset], value, value_length); + serv_info->char_data = g_slist_insert_sorted (serv_info->char_data, char_info, char_info_cmp); + found = 1; + break; + } else { + for (l3 = char_info->desc_data; l3 != NULL; l3 = l3->next) { + struct gatt_desc_info *desc_info = l3->data; + + if (desc_info && g_strcmp0(desc_info->desc_path, req_info->attr_path) + == 0) { + memcpy(&desc_info->desc_value[req_info->offset], value, value_length); + char_info->desc_data = g_slist_insert_sorted (char_info->desc_data, desc_info, desc_info_cmp); + found = 1; + break; + } + } + } } } } - if (found) - break; + if (found) { + return TRUE;; + } } + return FALSE; } - static GDBusProxy *__bt_gatt_gdbus_init_manager_proxy(const gchar *service, const gchar *path, const gchar *interface) { @@ -782,45 +1206,6 @@ static GDBusProxy *__bt_gatt_gdbus_get_manager_proxy(const gchar *service, path, interface); } -static gboolean __bt_gatt_export_properties_method(const char *svc_path) -{ - guint prop_id; - GDBusNodeInfo *prop_info; - GError *error = NULL; - struct gatt_service_info *svc_info; - - BT_DBG("svc_path %s", svc_path); - svc_info = __bt_gatt_find_gatt_service_info(svc_path); - - if (!svc_info) { - BT_ERR("Unable to find service info"); - return FALSE; - } - - /* Register ObjectManager interface */ - prop_info = __bt_gatt_create_method_node_info( - properties_introspection_xml); - - if (prop_info == NULL) { - BT_ERR("failed to get node info"); - return FALSE; - } - - prop_id = g_dbus_connection_register_object(g_conn, svc_path, - prop_info->interfaces[0], - &properties_interface_vtable, - NULL, NULL, &error); - - if (prop_id == 0) { - BT_ERR("failed to register: %s", error->message); - g_error_free(error); - return FALSE; - } - svc_info->prop_id = prop_id; - - return TRUE; -} - int bluetooth_gatt_convert_prop2string( bt_gatt_characteristic_property_t properties, char *char_properties[]) @@ -954,6 +1339,8 @@ void register_service_cb(GObject *object, GAsyncResult *res, gpointer user_data) GError *error = NULL; GVariant *result; + register_pending_cnt = 0; + result = g_dbus_proxy_call_finish(manager_gproxy, res, &error); if (result == NULL) { @@ -1002,7 +1389,7 @@ static int __bt_gatt_unregister_service(const char *service_path) GDBusProxy *proxy = NULL; proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez", - "/org/bluez", GATT_MNGR_INTERFACE); + "/org/bluez/hci0", GATT_MNGR_INTERFACE); if (proxy == NULL) return BLUETOOTH_ERROR_INTERNAL; @@ -1053,8 +1440,6 @@ static GDBusConnection *__bt_gatt_get_gdbus_connection(void) BT_EXPORT_API int bluetooth_gatt_init(void) { GDBusConnection *conn; - GDBusNodeInfo *obj_info; - GError *error = NULL; owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, BT_GATT_SERVICE_NAME, @@ -1071,26 +1456,6 @@ BT_EXPORT_API int bluetooth_gatt_init(void) return BLUETOOTH_ERROR_INTERNAL; } - /* Register ObjectManager interface */ - obj_info = __bt_gatt_create_method_node_info( - manager_introspection_xml); - - if (obj_info == NULL) { - BT_ERR("failed to get node info"); - return BLUETOOTH_ERROR_INTERNAL; - } - - manager_id = g_dbus_connection_register_object(g_conn, "/", - obj_info->interfaces[0], - &manager_interface_vtable, - NULL, NULL, &error); - - if (manager_id == 0) { - BT_ERR("failed to register: %s", error->message); - g_error_free(error); - return BLUETOOTH_ERROR_INTERNAL; - } - return BLUETOOTH_ERROR_NONE; } @@ -1105,10 +1470,6 @@ BT_EXPORT_API int bluetooth_gatt_deinit() g_bus_unown_name(owner_id); - /* unregister the exported interface for object manager */ - g_dbus_connection_unregister_object(g_conn, - manager_id); - BT_DBG("Gatt service deinitialized \n"); g_slist_free(gatt_services); @@ -1128,7 +1489,9 @@ BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid, GDBusNodeInfo *node_info; gchar *path = NULL; GVariantBuilder *builder = NULL; + GVariantBuilder *builder1 = NULL; GVariantBuilder *inner_builder = NULL; + gboolean svc_primary = TRUE; struct gatt_service_info *serv_info = NULL; node_info = __bt_gatt_create_method_node_info( @@ -1162,6 +1525,7 @@ BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid, serv_info->serv_id = object_id; serv_info->service_uuid = g_strdup(svc_uuid); serv_info->is_svc_registered = FALSE; + serv_info->is_svc_primary = svc_primary; gatt_services = g_slist_append(gatt_services, serv_info); @@ -1172,6 +1536,14 @@ BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid, g_variant_builder_add(inner_builder, "{sv}", "UUID", g_variant_new_string(svc_uuid)); + g_variant_builder_add(inner_builder, "{sv}", + "Primary", g_variant_new_boolean(svc_primary)); + + builder1 = g_variant_builder_new(G_VARIANT_TYPE("ao")); + + g_variant_builder_add(inner_builder, "{sv}", "Characteristics", + g_variant_new("ao", builder1)); + g_variant_builder_add(builder, "{sa{sv}}", GATT_SERV_INTERFACE, inner_builder); @@ -1189,6 +1561,7 @@ BT_EXPORT_API int bluetooth_gatt_add_service(const char *svc_uuid, g_free(path); g_variant_builder_unref(inner_builder); g_variant_builder_unref(builder); + g_variant_builder_unref(builder1); return BLUETOOTH_ERROR_NONE; } @@ -1208,6 +1581,7 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic( struct gatt_service_info *serv_info = NULL; struct gatt_char_info *char_info = NULL; GVariantBuilder *builder2 = NULL; + GVariantBuilder *builder3 = NULL; GVariant *flags_val = NULL; int i = 0; char *char_flags[NUMBER_OF_FLAGS]; @@ -1279,6 +1653,11 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic( g_variant_builder_add(inner_builder, "{sv}", "Flags", flags_val); + builder3 = g_variant_builder_new(G_VARIANT_TYPE("ao")); + + g_variant_builder_add(inner_builder, "{sv}", "Descriptors", + g_variant_new("ao", builder3)); + g_variant_builder_add(builder, "{sa{sv}}", GATT_CHAR_INTERFACE, inner_builder); @@ -1299,6 +1678,7 @@ BT_EXPORT_API int bluetooth_gatt_add_new_characteristic( g_variant_builder_unref(inner_builder); g_variant_builder_unref(builder); g_variant_builder_unref(builder2); + g_variant_builder_unref(builder3); return BLUETOOTH_ERROR_NONE; } @@ -1540,7 +1920,7 @@ int bluetooth_gatt_get_service(const char *svc_uuid) gchar *uuid = NULL; proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez", - "/org/bluez", GATT_MNGR_INTERFACE); + "/org/bluez/hci0", GATT_MNGR_INTERFACE); if (proxy == NULL) return BLUETOOTH_ERROR_INTERNAL; @@ -1566,18 +1946,15 @@ BT_EXPORT_API int bluetooth_gatt_register_service( GDBusProxy *proxy = NULL; gchar *path = NULL; + register_pending_cnt++; + if (__bt_gatt_get_service_state(svc_path)) { BT_DBG("service already registered \n"); return BLUETOOTH_ERROR_NONE; } - if (!__bt_gatt_export_properties_method(svc_path)) { - BT_ERR("Failed to export Object manager method"); - return BLUETOOTH_ERROR_INTERNAL; - } - proxy = __bt_gatt_gdbus_get_manager_proxy("org.bluez", - "/org/bluez", GATT_MNGR_INTERFACE); + "/org/bluez/hci0", GATT_MNGR_INTERFACE); if (proxy == NULL) return BLUETOOTH_ERROR_INTERNAL; @@ -1688,6 +2065,22 @@ BT_EXPORT_API int bluetooth_gatt_update_characteristic( g_clear_error(&error); } err = BLUETOOTH_ERROR_INTERNAL; + } else { + struct gatt_char_info *char_info = NULL; + + char_info = __bt_gatt_find_gatt_char_info(serv_path, char_path); + if (char_info == NULL) { + return BLUETOOTH_ERROR_INVALID_DATA; + } + + char_info->value_length = value_length; + + char_info->char_value = (char *)realloc(char_info->char_value, value_length); + if (char_info->char_value) { + for (i = 0; i < value_length; i++) { + char_info->char_value[i] = char_value[i]; + } + } } g_strfreev(line_argv); @@ -1774,17 +2167,119 @@ BT_EXPORT_API int bluetooth_gatt_unregister_service(const char *svc_path) return err; } -BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, - int offset, char *value, int value_length) +BT_EXPORT_API int bluetooth_gatt_send_response(int request_id, guint req_type, + int resp_state, int offset, char *value, int value_length) { struct gatt_req_info *req_info = NULL; req_info = __bt_gatt_find_request_info(request_id); if (req_info) { - __bt_gatt_update_attribute_info(req_info, value, value_length); - } else + if (resp_state != BLUETOOTH_ERROR_NONE) { + + GQuark quark = g_quark_from_string("gatt-server"); + GError *err = g_error_new(quark, 0, "Application Error"); + g_dbus_method_invocation_return_gerror(req_info->context, err); + g_error_free(err); + + gatt_requests = g_slist_remove(gatt_requests, req_info); + + req_info->context = NULL; + if (req_info->attr_path) + g_free(req_info->attr_path); + if (req_info->svc_path) + g_free(req_info->svc_path); + g_free(req_info); + + return BLUETOOTH_ERROR_NONE; + } + if (req_type == BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ) { + int i; + GVariantBuilder *inner_builder = NULL; + inner_builder = g_variant_builder_new(G_VARIANT_TYPE ("ay")); + if (value_length > 0 && value != NULL) { + for (i = 0; i < value_length; i++) + g_variant_builder_add(inner_builder, "y", value[i]); + } + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(ay)", inner_builder)); + g_variant_builder_unref(inner_builder); + } else { + g_dbus_method_invocation_return_value(req_info->context, NULL); + } + gatt_requests = g_slist_remove(gatt_requests, req_info); + + req_info->context = NULL; + if (req_info->attr_path) + g_free(req_info->attr_path); + if (req_info->svc_path) + g_free(req_info->svc_path); + g_free(req_info); + } else { return BLUETOOTH_ERROR_INTERNAL; + } return BLUETOOTH_ERROR_NONE; } + +BT_EXPORT_API int bluetooth_gatt_server_set_notification(const char *char_path, + bluetooth_device_address_t *unicast_address) +{ + GVariantBuilder *outer_builder; + GVariantBuilder *invalidated_builder; + GError *error = NULL; + gboolean notify = TRUE; + gboolean ret = TRUE; + int err = BLUETOOTH_ERROR_NONE; + gchar **line_argv = NULL; + gchar *serv_path = NULL; + char addr[20] = { 0 }; + + line_argv = g_strsplit_set(char_path, "/", 0); + serv_path = g_strdup_printf("/%s", line_argv[1]); + + if (!__bt_gatt_get_service_state(serv_path)) { + BT_DBG("service not registered for this characteristic \n"); + g_strfreev(line_argv); + return BLUETOOTH_ERROR_INTERNAL; + } + + outer_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + invalidated_builder = g_variant_builder_new(G_VARIANT_TYPE("as")); + + g_variant_builder_add(outer_builder, "{sv}", "Notifying", + g_variant_new("b", notify)); + + if (unicast_address) { + _bt_convert_addr_type_to_string(addr, + (unsigned char *)unicast_address->addr); + } + g_variant_builder_add(outer_builder, "{sv}", "Unicast", + g_variant_new("s", addr)); + + BT_DBG("Set characteristic Notification \n"); + ret = g_dbus_connection_emit_signal(g_conn, NULL, + char_path, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new("(sa{sv}as)", + "org.bluez.GattCharacteristic1", + outer_builder, invalidated_builder), + &error); + + if (!ret) { + if (error != NULL) { + BT_ERR("D-Bus API failure: errCode[%x], \ + message[%s]", + error->code, error->message); + g_clear_error(&error); + } + err = BLUETOOTH_ERROR_INTERNAL; + } + + g_strfreev(line_argv); + g_variant_builder_unref(outer_builder); + g_variant_builder_unref(invalidated_builder); + + return err; +} diff --git a/bt-api/bt-hdp.c b/bt-api/bt-hdp.c index 3a9e145..0984c82 100644 --- a/bt-api/bt-hdp.c +++ b/bt-api/bt-hdp.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "bluetooth-api.h" @@ -36,6 +35,8 @@ #define BLUEZ_HDP_DEVICE_INTERFACE "org.bluez.HealthDevice1" #define BLUEZ_HDP_CHANNEL_INTERFACE "org.bluez.HealthChannel1" +gboolean interface_exist = FALSE; + typedef struct { char *obj_channel_path; int fd; @@ -165,7 +166,7 @@ static int __bt_hdp_internal_create_application(unsigned int data_type, BLUEZ_HDP_MANAGER_INTERFACE, "CreateApplication"); - retv_if(msg == NULL, BLUETOOTH_ERROR_NO_RESOURCES); + retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL); dbus_message_iter_init_append(msg, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, @@ -271,6 +272,13 @@ static int __bt_hdp_internal_create_application(unsigned int data_type, BT_DBG("Created health application: %s", (char *)app_path); + list = g_new0(hdp_app_list_t, 1); + list->app_handle = (void *)g_strdup(app_path); + *app_handle = (char *)list->app_handle; + g_app_list = g_slist_append(g_app_list, list); + + BT_DBG("app_handle: %s", (char *)list->app_handle); + ret = __bt_hdp_internal_add_filter(); if (ret != BLUETOOTH_ERROR_NONE) { @@ -278,12 +286,6 @@ static int __bt_hdp_internal_create_application(unsigned int data_type, return ret; } - list = g_new0(hdp_app_list_t, 1); - list->app_handle = (void *)g_strdup(app_path); - *app_handle = list->app_handle; - - g_app_list = g_slist_append(g_app_list, list); - return BLUETOOTH_ERROR_NONE; } @@ -312,6 +314,14 @@ static int __bt_hdp_internal_add_filter(void) "type='signal',interface=" BLUEZ_HDP_DEVICE_INTERFACE, &dbus_error); + dbus_bus_add_match(g_hdp_dus_conn, + "type='signal',interface=" BT_MANAGER_INTERFACE, + &dbus_error); + + dbus_bus_add_match(g_hdp_dus_conn, + "type='signal',interface=" BT_PROPERTIES_INTERFACE, + &dbus_error); + if (dbus_error_is_set(&dbus_error)) { BT_ERR("Fail to add dbus filter signal\n"); dbus_error_free(&dbus_error); @@ -325,6 +335,9 @@ done: } +static void __bt_hdp_internal_handle_connected(DBusMessage *msg); + + static DBusHandlerResult __bt_hdp_internal_event_filter(DBusConnection *sys_conn, DBusMessage *msg, void *data) { @@ -334,24 +347,97 @@ static DBusHandlerResult __bt_hdp_internal_event_filter(DBusConnection *sys_conn return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; BT_DBG("Path = %s\n", path); - if (path == NULL || g_strcmp0(path, "/") == 0) + if (path == NULL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE, "ChannelConnected")) __bt_hdp_internal_handle_connect(msg); - else if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE, "ChannelDeleted")) __bt_hdp_internal_handle_disconnect(msg); - else if (dbus_message_is_signal(msg, BLUEZ_HDP_DEVICE_INTERFACE, "PropertyChanged")) __bt_hdp_internal_handle_property_changed(msg); + else if (dbus_message_is_signal(msg, BT_MANAGER_INTERFACE, + "InterfacesAdded")) { + interface_exist = TRUE; + BT_DBG("InterfaceAdded"); + } else if (dbus_message_is_signal(msg, BT_MANAGER_INTERFACE, + "InterfacesRemoved")) { + interface_exist = FALSE; + __bt_hdp_internal_handle_disconnect(msg); + BT_DBG("InterfaceRemoved"); + } else if (dbus_message_is_signal(msg, BT_PROPERTIES_INTERFACE, + "PropertiesChanged")) { + BT_DBG("PropertyChanged"); + if(interface_exist) + __bt_hdp_internal_handle_connected(msg); + } return DBUS_HANDLER_RESULT_HANDLED; } +static void __bt_hdp_internal_handle_connected(DBusMessage *msg) +{ + DBusMessageIter iter, dict, entry, var; + const char *path = NULL; + const char *obj_channel_path = NULL; + bt_user_info_t *user_info; + int ret; + + if (dbus_message_iter_init(msg, &iter) == FALSE) + return; + + dbus_message_iter_get_basic(&iter, &path); + + BT_DBG("object path: %s", path); + + if(!g_strcmp0(path, "org.bluez.HealthDevice1")) { + dbus_message_iter_next(&iter); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) + return; + + dbus_message_iter_recurse(&iter, &dict); + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + const char *interface; + + dbus_message_iter_recurse(&dict, &entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) + break; + + dbus_message_iter_get_basic(&entry, &interface); + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &var); + + if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_OBJECT_PATH) + break; + + dbus_message_iter_get_basic(&var, &obj_channel_path); + + BT_DBG("interface: %s", interface); + BT_DBG("object_path: %s", obj_channel_path); + + dbus_message_iter_next(&dict); + } + + BT_INFO("Channel connected, Path = %s", obj_channel_path); + + user_info = _bt_get_user_data(BT_COMMON); + if (user_info == NULL || user_info->cb == NULL) + return; + + ret = __bt_hdp_internal_acquire_fd(obj_channel_path); + if (ret != BLUETOOTH_ERROR_NONE) { + _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED, + BLUETOOTH_ERROR_CONNECTION_ERROR, NULL, + user_info->cb, user_info->user_data); + } + } +} + static void __bt_hdp_internal_handle_connect(DBusMessage *msg) { const char *path = dbus_message_get_path(msg); @@ -746,6 +832,7 @@ static gboolean __bt_hdp_internal_data_received(GIOChannel *gio, BT_DBG("Received data of %d\n", act_read); } else { BT_ERR("Read failed.....\n"); + __bt_hdp_internal_handle_disconnect_cb(sk, path); return FALSE; } @@ -788,6 +875,7 @@ static hdp_app_list_t *__bt_hdp_internal_gslist_find_app_handler(void *app_handl hdp_app_list_t *list = l->data; if (list) { + BT_DBG("found app_handle=%s\n", (char *)list->app_handle); if (0 == g_strcmp0((char *)list->app_handle, (char *)app_handle)) return list; @@ -996,23 +1084,25 @@ BT_EXPORT_API int bluetooth_hdp_send_data(unsigned int channel_id, return BLUETOOTH_ERROR_NONE; } - -static void __bt_hdp_connect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall *call, - gpointer user_data) +static void __bt_hdp_connect_request_cb(GDBusProxy *hdp_proxy, + GAsyncResult *res, gpointer user_data) { - GError *g_error = NULL; + GError *err = NULL; char *obj_connect_path = NULL; bt_hdp_connected_t *conn_ind = user_data; bt_user_info_t *user_info; + GVariant *reply = NULL; + int ret = BLUETOOTH_ERROR_NONE; - dbus_g_proxy_end_call(hdp_proxy, call, &g_error, - DBUS_TYPE_G_OBJECT_PATH, &obj_connect_path, G_TYPE_INVALID); + reply = g_dbus_proxy_call_finish(hdp_proxy, res, &err); g_object_unref(hdp_proxy); - if (g_error != NULL) { - BT_ERR("HDP connection Dbus Call Error: %s\n", g_error->message); - g_error_free(g_error); + if (!reply) { + if (err) { + BT_ERR("HDP connection Dbus Call Error: %s\n", err->message); + g_clear_error(&err); + } user_info = _bt_get_user_data(BT_COMMON); @@ -1022,15 +1112,21 @@ static void __bt_hdp_connect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall *c user_info->cb, user_info->user_data); } } else { + g_variant_get(reply, "(&o)", &obj_connect_path); + BT_DBG("Obj Path returned = %s\n", obj_connect_path); user_info = _bt_get_user_data(BT_COMMON); - if (user_info->cb) { - _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED, - BLUETOOTH_ERROR_NONE, conn_ind, - user_info->cb, user_info->user_data); + ret = __bt_hdp_internal_acquire_fd(obj_connect_path); + if (ret != BLUETOOTH_ERROR_NONE) { + user_info = _bt_get_user_data(BT_COMMON); + if (user_info->cb) { + _bt_common_event_cb(BLUETOOTH_EVENT_HDP_CONNECTED, + BLUETOOTH_ERROR_CONNECTION_ERROR, NULL, + user_info->cb, user_info->user_data); + } } - g_free(obj_connect_path); + g_variant_unref(reply); } g_free((void *)conn_ind->app_handle); g_free(conn_ind); @@ -1042,8 +1138,8 @@ BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, const bluetooth_device_address_t *device_address) { GError *err = NULL; - DBusGConnection *conn = NULL; - DBusGProxy *hdp_proxy = NULL; + GDBusConnection *conn = NULL; + GDBusProxy *hdp_proxy = NULL; bt_hdp_connected_t *param; char address[BT_ADDRESS_STRING_SIZE] = { 0 }; char default_adapter_path[BT_ADAPTER_OBJECT_PATH_MAX + 1] = { 0 }; @@ -1073,11 +1169,11 @@ BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, return BLUETOOTH_ERROR_ACCESS_DENIED; } - conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err); + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); - if (err != NULL) { + if (err) { BT_ERR("ERROR: Can't get on system bus [%s]", err->message); - g_error_free(err); + g_clear_error(&err); return BLUETOOTH_ERROR_INTERNAL; } @@ -1085,7 +1181,7 @@ BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, if (_bt_get_adapter_path(_bt_gdbus_get_system_gconn(), default_adapter_path) < 0) { BT_ERR("Could not get adapter path\n"); - dbus_g_connection_unref(conn); + g_object_unref(conn); return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; } @@ -1097,7 +1193,7 @@ BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, dev_path = g_strdup_printf("%s/dev_%s", default_adapter_path, address); if (dev_path == NULL) { - dbus_g_connection_unref(conn); + g_object_unref(conn); return BLUETOOTH_ERROR_MEMORY_ALLOCATION; } @@ -1105,9 +1201,11 @@ BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, BT_DBG("path: %s", dev_path); - hdp_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, dev_path, - BLUEZ_HDP_DEVICE_INTERFACE); - dbus_g_connection_unref(conn); + hdp_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, + dev_path, BLUEZ_HDP_DEVICE_INTERFACE, + NULL, NULL); + g_object_unref(conn); if (hdp_proxy == NULL) { BT_ERR("Failed to get the HDP server proxy\n"); @@ -1122,47 +1220,46 @@ BT_EXPORT_API int bluetooth_hdp_connect(const char *app_handle, memcpy(¶m->device_address, device_address, BLUETOOTH_ADDRESS_LENGTH); param->type = channel_type; - if (!dbus_g_proxy_begin_call(hdp_proxy, "CreateChannel", - (DBusGProxyCallNotify) __bt_hdp_connect_request_cb, - param, /* user_data */ - NULL, /* destroy */ - DBUS_TYPE_G_OBJECT_PATH, app_handle, - G_TYPE_STRING, role, - G_TYPE_INVALID)) { - BT_ERR("HDP connection Dbus Call Error"); - g_free(dev_path); - g_free((void *)param->app_handle); - g_free(param); - g_object_unref(hdp_proxy); - return BLUETOOTH_ERROR_INTERNAL; - } + g_dbus_proxy_call(hdp_proxy, "CreateChannel", + g_variant_new("(os)", app_handle, role), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, + (GAsyncReadyCallback)__bt_hdp_connect_request_cb, + param); g_free(dev_path); + return BLUETOOTH_ERROR_NONE; + } -static void __bt_hdp_disconnect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall *call, - gpointer user_data) +static void __bt_hdp_disconnect_request_cb(GDBusProxy *hdp_proxy, + GAsyncResult *res, gpointer user_data) { - GError *g_error = NULL; + GError *err = NULL; bt_hdp_disconnected_t *disconn_ind = user_data; bt_user_info_t *user_info; + GVariant *reply = NULL; - dbus_g_proxy_end_call(hdp_proxy, call, &g_error, G_TYPE_INVALID); - + reply = g_dbus_proxy_call_finish(hdp_proxy, res, &err); g_object_unref(hdp_proxy); user_info = _bt_get_user_data(BT_COMMON); if (user_info == NULL || user_info->cb == NULL) { g_free(disconn_ind); - if (g_error) - g_error_free(g_error); + if (err) { + g_clear_error(&err); + return; + } + g_variant_unref(reply); return; } - if (g_error != NULL) { - BT_ERR("HDP disconnection Dbus Call Error: %s\n", g_error->message); - g_error_free(g_error); + if (!reply) { + if (err) { + BT_ERR("HDP disconnection Dbus Call Error: %s\n", + err->message); + g_clear_error(&err); + } _bt_common_event_cb(BLUETOOTH_EVENT_HDP_DISCONNECTED, BLUETOOTH_ERROR_CONNECTION_ERROR, disconn_ind, @@ -1172,17 +1269,19 @@ static void __bt_hdp_disconnect_request_cb(DBusGProxy *hdp_proxy, DBusGProxyCall BLUETOOTH_ERROR_NONE, disconn_ind, user_info->cb, user_info->user_data); BT_INFO("HDP disconnection Dbus Call is done\n"); + g_variant_unref(reply); } g_free(disconn_ind); + } BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, const bluetooth_device_address_t *device_address) { GError *err = NULL; - DBusGConnection *conn = NULL; - DBusGProxy *hdp_proxy = NULL; + GDBusConnection *conn = NULL; + GDBusProxy *hdp_proxy = NULL; char address[BT_ADDRESS_STRING_SIZE] = { 0 }; char default_adapter_path[BT_ADAPTER_OBJECT_PATH_MAX + 1] = { 0 }; char *dev_path = NULL; @@ -1199,17 +1298,19 @@ BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, return BLUETOOTH_ERROR_PERMISSION_DEINED; } - hdp_obj_info_t *info = __bt_hdp_internal_gslist_obj_find_using_fd(channel_id); + hdp_obj_info_t *info = + __bt_hdp_internal_gslist_obj_find_using_fd(channel_id); if (NULL == info) { - BT_ERR("*** Could not locate the list for %d*****\n", channel_id); + BT_ERR("*** Could not locate the list for %d*****\n", + channel_id); return BLUETOOTH_ERROR_INVALID_PARAM; } - conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &err); + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); - if (err != NULL) { + if (err) { BT_ERR("ERROR: Can't get on system bus [%s]", err->message); - g_error_free(err); + g_clear_error(&err); return BLUETOOTH_ERROR_INTERNAL; } @@ -1217,7 +1318,7 @@ BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, if (_bt_get_adapter_path(_bt_gdbus_get_system_gconn(), default_adapter_path) < 0) { BT_ERR("Could not get adapter path\n"); - dbus_g_connection_unref(conn); + g_object_unref(conn); return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; } @@ -1229,7 +1330,7 @@ BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, dev_path = g_strdup_printf("%s/dev_%s", default_adapter_path, address); if (dev_path == NULL) { - dbus_g_connection_unref(conn); + g_object_unref(conn); return BLUETOOTH_ERROR_MEMORY_ALLOCATION; } @@ -1237,10 +1338,12 @@ BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, BT_DBG("path %s\n", dev_path); - hdp_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, dev_path, - BLUEZ_HDP_DEVICE_INTERFACE); + hdp_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, + dev_path, BLUEZ_HDP_DEVICE_INTERFACE, + NULL, NULL); - dbus_g_connection_unref(conn); + g_object_unref(conn); if (hdp_proxy == NULL) { BT_ERR("Failed to get the HDP proxy\n"); @@ -1252,20 +1355,14 @@ BT_EXPORT_API int bluetooth_hdp_disconnect(unsigned int channel_id, param->channel_id = channel_id; memcpy(¶m->device_address, device_address, BLUETOOTH_ADDRESS_LENGTH); - if (!dbus_g_proxy_begin_call(hdp_proxy, "DestroyChannel", - (DBusGProxyCallNotify) __bt_hdp_disconnect_request_cb, - param, /* user_data */ - NULL, /* destroy */ - DBUS_TYPE_G_OBJECT_PATH, info->obj_channel_path, - G_TYPE_INVALID)) { - BT_ERR("HDP connection Dbus Call Error"); - g_free(dev_path); - g_free(param); - g_object_unref(hdp_proxy); - return BLUETOOTH_ERROR_INTERNAL; - } + g_dbus_proxy_call(hdp_proxy, "DestroyChannel", + g_variant_new("o", info->obj_channel_path), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, + (GAsyncReadyCallback)__bt_hdp_disconnect_request_cb, + param); g_free(dev_path); return BLUETOOTH_ERROR_NONE; + } diff --git a/bt-api/bt-hid-device.c b/bt-api/bt-hid-device.c index 2631e12..a623fea 100644 --- a/bt-api/bt-hid-device.c +++ b/bt-api/bt-hid-device.c @@ -35,32 +35,32 @@ #define REPORTID_MOUSE 1 #define BT_HID_BUFFER_LEN 100 -/* HIDP header masks */ -#define HIDP_HEADER_TRANS_MASK 0xf0 -#define HIDP_HEADER_PARAM_MASK 0x0f - -/* HIDP transaction types */ -#define HIDP_TRANS_HANDSHAKE 0x00 -#define HIDP_TRANS_HID_CONTROL 0x10 -#define HIDP_TRANS_GET_REPORT 0x40 -#define HIDP_TRANS_SET_REPORT 0x50 -#define HIDP_TRANS_GET_PROTOCOL 0x60 -#define HIDP_TRANS_SET_PROTOCOL 0x70 -#define HIDP_TRANS_GET_IDLE 0x80 -#define HIDP_TRANS_SET_IDLE 0x90 -#define HIDP_TRANS_DATA 0xa0 -#define HIDP_TRANS_DATC 0xb0 - -#define HIDP_DATA_RTYPE_INPUT 0x01 -#define HIDP_DATA_RTYPE_OUTPUT 0x02 - -#define HIDP_HSHK_SUCCESSFUL 0x00 -#define HIDP_HSHK_NOT_READY 0x01 -#define HIDP_HSHK_ERR_INVALID_REPORT_ID 0x02 -#define HIDP_HSHK_ERR_UNSUPPORTED_REQUEST 0x03 -#define HIDP_HSHK_ERR_INVALID_PARAMETER 0x04 -#define HIDP_HSHK_ERR_UNKNOWN 0x0E -#define HIDP_HSHK_ERR_FATAL 0x0F +/* The types of HIDP transaction */ +#define BT_HIDP_TRANSACTION_SET_PROTOCOL 0x70 +#define BT_HIDP_TRANSACTION_GET_IDLE 0x80 +#define BT_HIDP_TRANSACTION_SET_IDLE 0x90 +#define BT_HIDP_TRANSACTION_DATA 0xa0 +#define BT_HIDP_TRANSACTION_DATC 0xb0 +#define BT_HIDP_TRANSACTION_HANDSHAKE 0x00 +#define BT_HIDP_TRANSACTION_HID_CONTROL 0x10 +#define BT_HIDP_TRANSACTION_GET_REPORT 0x40 +#define BT_HIDP_TRANSACTION_SET_REPORT 0x50 +#define BT_HIDP_TRANSACTION_GET_PROTOCOL 0x60 + +#define BT_HIDP_DATA_OUT_RTYPE 0x02 +#define BT_HIDP_DATA_IN_RTYPE 0x01 + +#define BT_HIDP_HSHK_ERROR_UNSUPPORTED_REQUEST 0x03 +#define BT_HIDP_HSHK_ERROR_INVALID_PARAM 0x04 +#define BT_HIDP_HSHK_ERROR_UNKNOWN 0x0E +#define BT_HIDP_HSHK_ERROR_FATAL 0x0F +#define BT_HIDP_HSHK_OK_SUCCESSFUL 0x00 +#define BT_HIDP_HSHK_NOT_AVAILABLE 0x01 +#define BT_HIDP_HSHK_ERROR_INVALID_REPORT_ID 0x02 + +/* The masks of BT_HIDP header */ +#define BT_HIDP_HEADER_PARAMETER_MASK 0x0f +#define BT_HIDP_HEADER_TRANSACTION_MASK 0xf0 typedef struct { guint object_id; @@ -234,72 +234,52 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, BT_INFO("Parsing Data"); bluetooth_hid_received_data_t data = {0}; header = buffer[0]; - type = header & HIDP_HEADER_TRANS_MASK; - param = header & HIDP_HEADER_PARAM_MASK; + type = header & BT_HIDP_HEADER_TRANSACTION_MASK; + param = header & BT_HIDP_HEADER_PARAMETER_MASK; BT_INFO("type %d , param %d", type, param); BT_INFO("Data Reveived from %s" , info->address); data.address = g_strdup(info->address); switch (type) { - case HIDP_TRANS_HANDSHAKE: + case BT_HIDP_TRANSACTION_HANDSHAKE: BT_INFO("TRANS HANDSHAKE"); data.type = HTYPE_TRANS_HANDSHAKE; data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } break; - case HIDP_TRANS_HID_CONTROL: + case BT_HIDP_TRANSACTION_HID_CONTROL: BT_INFO("HID CONTROL"); data.type = HTYPE_TRANS_HID_CONTROL; data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } break; - case HIDP_TRANS_DATA: + case BT_HIDP_TRANSACTION_DATA: BT_INFO("TRANS DATA"); data.type = HTYPE_TRANS_DATA; - if ( param & HIDP_DATA_RTYPE_INPUT) { + if ( param & BT_HIDP_DATA_IN_RTYPE) { BT_INFO("Input Report"); data.param = PTYPE_DATA_RTYPE_INPUT; data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } } else { BT_INFO("Out Report"); data.param = PTYPE_DATA_RTYPE_OUTPUT; data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } } break; - case HIDP_TRANS_GET_REPORT: { + case BT_HIDP_TRANSACTION_GET_REPORT: { BT_INFO("Get Report"); data.type = HTYPE_TRANS_GET_REPORT; - if (param & HIDP_DATA_RTYPE_INPUT) { + if (param & BT_HIDP_DATA_IN_RTYPE) { BT_INFO("Input Report"); data.param = PTYPE_DATA_RTYPE_INPUT; } else { @@ -308,19 +288,14 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, } data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } break; } - case HIDP_TRANS_SET_REPORT: { + case BT_HIDP_TRANSACTION_SET_REPORT: { BT_INFO("Set Report"); data.type = HTYPE_TRANS_SET_REPORT; - if (param & HIDP_DATA_RTYPE_INPUT) { + if (param & BT_HIDP_DATA_IN_RTYPE) { BT_INFO("Input Report"); data.param = PTYPE_DATA_RTYPE_INPUT; } else { @@ -329,50 +304,35 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, } data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } break; } - case HIDP_TRANS_GET_PROTOCOL:{ + case BT_HIDP_TRANSACTION_GET_PROTOCOL:{ BT_INFO("Get_PROTOCOL"); data.type = HTYPE_TRANS_GET_PROTOCOL; data.param = PTYPE_DATA_RTYPE_INPUT; data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } break; } - case HIDP_TRANS_SET_PROTOCOL:{ + case BT_HIDP_TRANSACTION_SET_PROTOCOL:{ BT_INFO("Set_PROTOCOL"); data.type = HTYPE_TRANS_SET_PROTOCOL; data.param = PTYPE_DATA_RTYPE_INPUT; data.buffer_size = len; data.buffer = (char *) malloc(sizeof(char) * len); - /* Fix : NULL_RETURNS */ - if (NULL == data.buffer) { - BT_ERR("Failed to allocate memory"); - data.buffer_size = 0; - } else { + if (data.buffer) memcpy(data.buffer, buffer, len); - } break; } default: { BT_INFO("unsupported HIDP control message"); BT_ERR("Send Handshake Message"); - guint8 type = HIDP_TRANS_HANDSHAKE | - HIDP_HSHK_ERR_UNSUPPORTED_REQUEST; + guint8 type = BT_HIDP_TRANSACTION_HANDSHAKE | + BT_HIDP_HSHK_ERROR_UNSUPPORTED_REQUEST; data.type = HTYPE_TRANS_UNKNOWN; int fd = g_io_channel_unix_get_fd(chan); int bytes = write(fd, &type, sizeof(type)); @@ -381,16 +341,18 @@ static gboolean __received_cb(GIOChannel *chan, GIOCondition cond, } } event_info = _bt_event_get_cb_data(BT_HID_DEVICE_EVENT); - if (event_info == NULL) + if (event_info == NULL) { + g_free(data.buffer); + g_free((char *)data.address); return FALSE; + } _bt_common_event_cb(BLUETOOTH_HID_DEVICE_DATA_RECEIVED, BLUETOOTH_ERROR_NONE, &data, event_info->cb, event_info->user_data); - if (data.buffer) - g_free(data.buffer); - if (data.address) - g_free((char *)data.address); + + g_free(data.buffer); + g_free((char *)data.address); } else { BT_INFO("Error while reading data"); } @@ -413,6 +375,11 @@ int new_hid_connection(const char *path, int fd, bluetooth_device_address_t *add if (dev_info == NULL) { dev_info = (hid_connected_device_info_t *) g_malloc0(sizeof(hid_connected_device_info_t)); + if (dev_info == NULL) { + BT_ERR("Fail to allocation memory"); + return -1; + } + dev_info->intr_fd = -1; dev_info->ctrl_fd = -1; dev_info->intr_fd = fd; @@ -553,6 +520,7 @@ BT_EXPORT_API int bluetooth_hid_device_connect(const char *remote_addr) { char device_address[BT_ADDRESS_STRING_SIZE] = {0}; hid_connected_device_info_t *info = NULL; + int ret; BT_DBG("+"); BT_CHECK_PARAMETER(remote_addr, return); @@ -568,9 +536,9 @@ BT_EXPORT_API int bluetooth_hid_device_connect(const char *remote_addr) } memcpy(device_address, remote_addr, BT_ADDRESS_STRING_SIZE); - _bt_connect_profile(device_address, HID_UUID, NULL, NULL); + ret = _bt_connect_profile(device_address, HID_UUID, NULL, NULL); - return BLUETOOTH_ERROR_NONE; + return ret; } BT_EXPORT_API int bluetooth_hid_device_disconnect(const char *remote_addr) { @@ -597,6 +565,7 @@ BT_EXPORT_API int bluetooth_hid_device_send_mouse_event(const char *remote_addr, { int result; int written = 0; + int socket_fd; hid_connected_device_info_t *info = NULL; switch (privilege_token_send_mouse) { @@ -627,10 +596,6 @@ BT_EXPORT_API int bluetooth_hid_device_send_mouse_event(const char *remote_addr, BT_ERR("Connection Information not found"); return BLUETOOTH_ERROR_INVALID_PARAM; } - int socket_fd; - - if (info == NULL) - return -1; if (info->intr_fd != -1 && info->ctrl_fd == -1) socket_fd = info->intr_fd; @@ -647,6 +612,7 @@ BT_EXPORT_API int bluetooth_hid_device_send_key_event(const char *remote_addr, { int result; int written = 0; + int socket_fd; hid_connected_device_info_t *info = NULL; switch (privilege_token_send_key) { @@ -679,11 +645,6 @@ BT_EXPORT_API int bluetooth_hid_device_send_key_event(const char *remote_addr, return BLUETOOTH_ERROR_INVALID_PARAM; } - int socket_fd; - - if (info == NULL) - return -1; - if (info->intr_fd != -1 && info->ctrl_fd == -1) socket_fd = info->intr_fd; else @@ -738,8 +699,8 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, case HTYPE_TRANS_GET_REPORT: { switch(ptype) { case PTYPE_DATA_RTYPE_INPUT: { - output_report.type = HIDP_TRANS_DATA | - HIDP_DATA_RTYPE_INPUT; + output_report.type = BT_HIDP_TRANSACTION_DATA | + BT_HIDP_DATA_IN_RTYPE; memcpy(output_report.rep_data, data, data_len); bytes = write(info->intr_fd, &output_report, sizeof(output_report)); @@ -753,7 +714,7 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, break; case HTYPE_TRANS_GET_PROTOCOL: { BT_DBG("Replying to Get_PROTOCOL"); - output_report.type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUTPUT; + output_report.type = BT_HIDP_TRANSACTION_DATA | BT_HIDP_DATA_OUT_RTYPE; output_report.rep_data[0] = data[0]; bytes = write(info->intr_fd, &output_report, 2); BT_DBG("Bytes Written %d", bytes); @@ -761,7 +722,7 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, } case HTYPE_TRANS_SET_PROTOCOL: { BT_DBG("Reply to Set_Protocol"); - output_report.type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT; + output_report.type = BT_HIDP_TRANSACTION_DATA | BT_HIDP_DATA_IN_RTYPE; memcpy(output_report.rep_data, data, data_len); bytes = write(info->ctrl_fd, &output_report, sizeof(output_report)); @@ -770,7 +731,7 @@ BT_EXPORT_API int bluetooth_hid_device_reply_to_report(const char *remote_addr, } case HTYPE_TRANS_HANDSHAKE: { BT_DBG("Replying Handshake"); - output_report.type = HIDP_TRANS_HANDSHAKE | data[0]; + output_report.type = BT_HIDP_TRANSACTION_HANDSHAKE | data[0]; memset(output_report.rep_data, 0, sizeof(output_report.rep_data)); bytes = write(info->intr_fd, &output_report.type, sizeof(output_report.type)); diff --git a/bt-api/bt-ipsp.c b/bt-api/bt-ipsp.c new file mode 100644 index 0000000..8b4717d --- /dev/null +++ b/bt-api/bt-ipsp.c @@ -0,0 +1,104 @@ +/* + * Bluetooth-frwk + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Paras Kumar + * + * 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 "bluetooth-api.h" +#include "bluetooth-ipsp-api.h" +#include "bt-internal-types.h" + +#include "bt-common.h" +#include "bt-request-sender.h" +#include "bt-event-handler.h" + +BT_EXPORT_API int bluetooth_le_ipsp_init(void) +{ + int ret = IPSP_ERROR_NONE; + + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_IPSP_INIT, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return ret; +} + +BT_EXPORT_API int bluetooth_le_ipsp_deinit(void) +{ + int ret = IPSP_ERROR_NONE; + + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_IPSP_DEINIT, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return ret; +} + +BT_EXPORT_API int bluetooth_le_ipsp_connect(const ipsp_device_address_t *device_address) +{ + int ret = IPSP_ERROR_NONE; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, device_address, sizeof(ipsp_device_address_t)); + + ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_IPSP_CONNECT, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return ret; +} + +BT_EXPORT_API int bluetooth_le_ipsp_disconnect(const ipsp_device_address_t *device_address) +{ + int ret = IPSP_ERROR_NONE; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_ENABLED_LE(return); + + BT_INIT_PARAMS(); + BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + g_array_append_vals(in_param1, device_address, sizeof(ipsp_device_address_t)); + + ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_IPSP_DISCONNECT, + in_param1, in_param2, in_param3, in_param4, &out_param); + + BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); + + return ret; +} diff --git a/bt-api/bt-request-sender.c b/bt-api/bt-request-sender.c index 982412c..202bdf0 100755 --- a/bt-api/bt-request-sender.c +++ b/bt-api/bt-request-sender.c @@ -21,7 +21,6 @@ * */ -#include #include #include #include @@ -30,6 +29,7 @@ #include "bluetooth-hid-api.h" #include "bluetooth-audio-api.h" #include "bt-internal-types.h" +#include "bluetooth-ipsp-api.h" #include "bt-common.h" #include "bt-request-sender.h" @@ -41,30 +41,20 @@ static GSList *sending_requests; -DBusGConnection *service_conn; -DBusGConnection *system_conn; -DBusGProxy *service_proxy; - -static GDBusConnection *service_gconn; static GDBusProxy *service_gproxy; static GDBusProxy *__bt_gdbus_init_service_proxy(void) { + GDBusConnection *service_gconn; GDBusProxy *proxy; GError *err = NULL; g_type_init(); - if (service_gconn == NULL) - service_gconn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + service_gconn = _bt_gdbus_get_system_gconn(); - if (!service_gconn) { - if (err) { - BT_ERR("Unable to connect to dbus: %s", err->message); - g_clear_error(&err); - } + if (!service_gconn) return NULL; - } proxy = g_dbus_proxy_new_sync(service_gconn, G_DBUS_PROXY_FLAGS_NONE, NULL, @@ -78,8 +68,6 @@ static GDBusProxy *__bt_gdbus_init_service_proxy(void) g_clear_error(&err); } - g_object_unref(service_gconn); - service_gconn = NULL; return NULL; } @@ -96,13 +84,8 @@ static GDBusProxy *__bt_gdbus_get_service_proxy(void) void _bt_gdbus_deinit_proxys(void) { if (service_gproxy) { - g_object_unref(service_proxy); - service_proxy = NULL; - } - - if (service_gconn) { - g_object_unref(service_gconn); - service_gconn = NULL; + g_object_unref(service_gproxy); + service_gproxy = NULL; } } @@ -232,6 +215,20 @@ static void __bt_get_event_info(int service_function, GArray *output, ret_if(output == NULL); *param_data = &g_array_index(output, char, 0); break; + case BT_CONNECT_LE: + *event_type = BT_DEVICE_EVENT; + *event = BLUETOOTH_EVENT_GATT_CONNECTED; + ret_if(output == NULL); + *param_data = &g_array_index(output, + bluetooth_device_address_t, 0); + break; + case BT_DISCONNECT_LE: + *event_type = BT_DEVICE_EVENT; + *event = BLUETOOTH_EVENT_GATT_DISCONNECTED; + ret_if(output == NULL); + *param_data = &g_array_index(output, + bluetooth_device_address_t, 0); + break; default: BT_ERR("Unknown function"); return; @@ -406,6 +403,8 @@ int _bt_sync_send_request(int service_type, int service_function, in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar)); + + param1 = g_variant_new_from_data((const GVariantType *)"ay", in_param1->data, in_param1->len, TRUE, NULL, NULL); diff --git a/bt-api/bt-rfcomm-client.c b/bt-api/bt-rfcomm-client.c index 6a8a5d1..7681704 100644 --- a/bt-api/bt-rfcomm-client.c +++ b/bt-api/bt-rfcomm-client.c @@ -459,7 +459,7 @@ static void __bt_connect_response_cb(GDBusProxy *proxy, GAsyncResult *res, if (!g_dbus_proxy_call_finish(proxy, res, &error)) { int result; - + g_dbus_error_strip_remote_error(error); BT_ERR("Error : %s \n", error->message); if (g_strcmp0(error->message, "In Progress") == 0) @@ -504,6 +504,7 @@ static void __bt_discover_service_response_cb(GDBusProxy *proxy, g_object_unref(proxy); if (err != NULL) { + g_dbus_error_strip_remote_error(err); BT_ERR("Error occured in Proxy call [%s]\n", err->message); if (!strcmp("Operation canceled", err->message)) { result = BLUETOOTH_ERROR_CANCEL_BY_USER; @@ -809,6 +810,13 @@ BT_EXPORT_API int bluetooth_rfcomm_write(int fd, const char *buf, int length) int result; BT_CHECK_PARAMETER(buf, return); + if (fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + + BT_DBG("FD : %d", fd); + #ifndef RFCOMM_DIRECT BT_CHECK_ENABLED(return); #endif diff --git a/bt-api/bt-rfcomm-server.c b/bt-api/bt-rfcomm-server.c index 3028291..1c5a221 100644 --- a/bt-api/bt-rfcomm-server.c +++ b/bt-api/bt-rfcomm-server.c @@ -470,6 +470,11 @@ BT_EXPORT_API int bluetooth_rfcomm_remove_socket(int socket_fd) return BLUETOOTH_ERROR_PERMISSION_DEINED; } + if (socket_fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + #ifdef RFCOMM_DIRECT BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, fd=[%d] >>>>>>>>>>>", socket_fd); @@ -544,6 +549,10 @@ BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd) char address[20]; BT_INFO(">>>>>>>>RFCOMM server disconnect request from APP>>>>>>>>>"); + if (socket_fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } info = __find_rfcomm_info_with_fd(socket_fd); if (info == NULL) @@ -658,6 +667,10 @@ BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int socket_fd, int max_pend #endif BT_CHECK_ENABLED(return); + if (socket_fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } #ifdef RFCOMM_DIRECT BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>"); @@ -741,6 +754,10 @@ BT_EXPORT_API int bluetooth_rfcomm_listen(int socket_fd, int max_pending_connect #endif BT_CHECK_ENABLED(return); + if (socket_fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } #ifdef RFCOMM_DIRECT BT_INFO("<<<<<<<<< RFCOMM Listen >>>>>>>>>>>"); @@ -795,6 +812,10 @@ BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd) int result; BT_CHECK_ENABLED(return); + if (server_fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } BT_INIT_PARAMS(); BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param); @@ -817,6 +838,11 @@ BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd) BT_CHECK_ENABLED(return); + if (server_fd < 0) { + BT_ERR("Invalid FD"); + return BLUETOOTH_ERROR_INVALID_PARAM; + } + BT_INFO("+"); BT_INIT_PARAMS(); diff --git a/bt-api/bt-scmst.c b/bt-api/bt-scmst.c index 61d2285..3e98d97 100644 --- a/bt-api/bt-scmst.c +++ b/bt-api/bt-scmst.c @@ -23,8 +23,6 @@ #include #include -#include -#include #include "bt-common.h" #include "bt-internal-types.h" diff --git a/bt-api/bt-telephony.c b/bt-api/bt-telephony.c index e8db5cf..4b1ec99 100644 --- a/bt-api/bt-telephony.c +++ b/bt-api/bt-telephony.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -278,6 +277,7 @@ static int __bt_telephony_check_privilege(void) if (!reply) { BT_ERR("Error returned in method call"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -375,6 +375,7 @@ static int __bluetooth_telephony_send_call_status( if (!reply) { BT_ERR("Error returned in method call"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -758,6 +759,7 @@ static int __bluetooth_telephony_register(void) if (!reply) { BT_ERR("Error returned in method call"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); BT_ERR("Error here %d\n", ret); g_error_free(err); @@ -792,6 +794,7 @@ static int __bluetooth_telephony_unregister(void) if (!reply) { BT_ERR("Error returned in method call"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -825,7 +828,7 @@ static void __bluetooth_telephony_init_headset_state(void) if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { - __bt_telephony_get_error(err->message); + BT_ERR("Error message = %s", err->message); g_error_free(err); } return; @@ -951,6 +954,7 @@ static int __bluetooth_telephony_get_connected_device(void) BT_ERR("Unable to allocate new proxy \n"); ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -967,6 +971,7 @@ static int __bluetooth_telephony_get_connected_device(void) BT_ERR("Can't get managed objects"); ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1003,6 +1008,7 @@ static int __bluetooth_telephony_get_connected_device(void) BT_ERR("Unable to allocate new proxy \n"); ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1021,6 +1027,7 @@ static int __bluetooth_telephony_get_connected_device(void) BT_ERR("Can't get managed objects"); ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1069,6 +1076,7 @@ static int __bluetooth_telephony_get_connected_device(void) BT_ERR("Unable to allocate new headset_agent_proxy"); ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1085,6 +1093,7 @@ static int __bluetooth_telephony_get_connected_device(void) BT_ERR("Can't get managed objects"); ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1107,6 +1116,7 @@ static int __bluetooth_telephony_get_connected_device(void) BT_ERR("Can't get managed objects"); ret = BLUETOOTH_TELEPHONY_ERROR_INTERNAL; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1166,6 +1176,7 @@ static GDBusProxy *__bluetooth_telephony_get_connected_device_proxy(void) if (proxy == NULL) { BT_ERR("Unable to allocate new proxy"); if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1344,6 +1355,7 @@ BT_EXPORT_API int bluetooth_telephony_init(bt_telephony_func_ptr cb, telephony_dbus_info.conn = NULL; is_initialized = FALSE; if (error) { + g_dbus_error_strip_remote_error(error); ret = __bt_telephony_get_error(error->message); BT_ERR("Error here %d\n", ret); g_error_free(error); @@ -1477,7 +1489,7 @@ BT_EXPORT_API gboolean bluetooth_telephony_is_sco_connected(void) if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { - __bt_telephony_get_error(err->message); + BT_ERR("Error message = %s", err->message); g_error_free(err); } return FALSE; @@ -1658,6 +1670,7 @@ BT_EXPORT_API int bluetooth_telephony_start_voice_recognition(void) if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -1691,6 +1704,7 @@ BT_EXPORT_API int bluetooth_telephony_stop_voice_recognition(void) if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -1760,6 +1774,7 @@ BT_EXPORT_API int bluetooth_telephony_audio_open(void) if (proxy == NULL) { BT_ERR("Unable to allocate new proxy"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); BT_ERR("Error here %d\n", ret); g_error_free(err); @@ -1830,6 +1845,7 @@ BT_EXPORT_API int bluetooth_telephony_audio_close(void) if (proxy == NULL) { BT_ERR("Unable to allocate new proxy"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); BT_ERR("Error here %d\n", ret); g_error_free(err); @@ -2094,6 +2110,7 @@ BT_EXPORT_API int bluetooth_telephony_indicate_outgoing_call( if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -2145,6 +2162,7 @@ BT_EXPORT_API int bluetooth_telephony_indicate_incoming_call( if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -2182,6 +2200,7 @@ BT_EXPORT_API int bluetooth_telephony_set_speaker_gain( if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -2214,6 +2233,7 @@ BT_EXPORT_API int bluetooth_telephony_get_headset_volume( if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; @@ -2246,6 +2266,7 @@ BT_EXPORT_API int bluetooth_telephony_is_connected(gboolean *ag_connected) if (!reply) { BT_ERR("Error returned in method call\n"); if (err) { + g_dbus_error_strip_remote_error(err); ret = __bt_telephony_get_error(err->message); g_error_free(err); return ret; diff --git a/bt-api/include/bt-common.h b/bt-api/include/bt-common.h index e72304b5..9897e07 100644 --- a/bt-api/include/bt-common.h +++ b/bt-api/include/bt-common.h @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -333,21 +332,18 @@ int _bt_register_new_conn(const char *path, bt_new_connection_cb cb); int _bt_register_new_conn_ex(const char *path, const char *bus_name,bt_new_connection_cb cb); void _bt_swap_addr(unsigned char *dst, const unsigned char *src); -DBusGProxy *_bt_get_adapter_proxy(DBusGConnection *conn); - void _bt_device_path_to_address(const char *device_path, char *device_address); -DBusGConnection *__bt_init_system_gconn(void); +GDBusConnection *g_bus_get_private_conn(void); -DBusGConnection *_bt_get_system_gconn(void); +DBusConnection *__bt_init_system_conn(void); DBusConnection *_bt_get_system_conn(void); -GDBusConnection *_bt_init_system_gdbus_conn(void); - int _bt_register_osp_server_in_agent(int type, char *uuid, char *path, int fd); int _bt_unregister_osp_server_in_agent(int type, char *uuid); + int _bt_check_privilege(int service_type, int service_function); GDBusConnection *_bt_gdbus_init_system_gconn(void); diff --git a/bt-api/include/bt-request-sender.h b/bt-api/include/bt-request-sender.h index 069a923..56dd571 100644 --- a/bt-api/include/bt-request-sender.h +++ b/bt-api/include/bt-request-sender.h @@ -26,7 +26,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -34,13 +33,12 @@ extern "C" { typedef struct { int service_function; - DBusGProxy *proxy; - DBusGProxyCall *proxy_call; + GDBusProxy *proxy; void *cb; void *user_data; } bt_req_info_t; -void _bt_deinit_proxys(void); +void _bt_gdbus_deinit_proxys(void); int _bt_sync_send_request(int service_type, int service_function, GArray *in_param1, GArray *in_param2, diff --git a/bt-core/CMakeLists.txt b/bt-core/CMakeLists.txt index 319913a..1be04c3 100644 --- a/bt-core/CMakeLists.txt +++ b/bt-core/CMakeLists.txt @@ -22,7 +22,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED dbus-glib-1 dlog vconf gio-2.0 gio-unix-2.0) +pkg_check_modules(pkgs REQUIRED dbus-1 dbus-glib-1 dlog vconf gio-2.0 gio-unix-2.0 eventsystem) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") @@ -39,15 +39,12 @@ IF("${ARCH}" STREQUAL "arm") MESSAGE("add -DTARGET") ENDIF("${ARCH}" STREQUAL "arm") -FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool) -EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=bt ${CMAKE_CURRENT_SOURCE_DIR}/bt-request-service.xml --mode=glib-client --output=${CMAKE_CURRENT_SOURCE_DIR}/include/bt-request-service.h") -EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=bt_core ${CMAKE_CURRENT_SOURCE_DIR}/bt-core-adapter.xml --mode=glib-server --output=${CMAKE_CURRENT_SOURCE_DIR}/include/bt-core-adapter-method.h") - ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") ADD_DEFINITIONS("-DVENDOR=\"${APP_VENDOR}\"") ADD_DEFINITIONS("-DAPPNAME=\"${APP_NAME}\"") ADD_DEFINITIONS("-DAPP_DIR=\"${APP_DIR}\"") ADD_DEFINITIONS("-DAPP_SYSCONFDIR=\"${APP_SYSCONFDIR}\"") +ADD_DEFINITIONS("-DHPS_FEATURE") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") diff --git a/bt-core/bt-core-adapter.c b/bt-core/bt-core-adapter.c index 1e447fb..6f09ca1 100644 --- a/bt-core/bt-core-adapter.c +++ b/bt-core/bt-core-adapter.c @@ -24,9 +24,7 @@ #include #include #include -#if 0 #include -#endif #include "bt-core-main.h" #include "bt-core-adapter.h" @@ -43,9 +41,7 @@ static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED; static gboolean is_recovery_mode = FALSE; static int bt_status_before[BT_MODE_MAX] = { VCONFKEY_BT_STATUS_OFF, }; -static int bt_le_status_before[BT_MODE_MAX] = { 0, }; - -static DBusGConnection *conn = NULL; +static int bt_le_status_before[BT_MODE_MAX] = { VCONFKEY_BT_LE_STATUS_OFF, }; static void __bt_core_set_status(bt_status_t status) { @@ -182,7 +178,12 @@ int _bt_enable_adapter(void) #endif if (ret < 0) { BT_ERR("running script failed"); +#ifdef USB_BLUETOOTH + char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL}; + ret = __execute_command("/usr/bin/hciconfig", argv_down); +#else ret = __execute_command("/usr/etc/bluetooth/bt-dev-end.sh", NULL); +#endif __bt_core_set_status(BT_DEACTIVATED); return -1; } @@ -199,6 +200,7 @@ int _bt_disable_adapter(void) le_status = _bt_core_get_le_status(); BT_DBG("le_status : %d", le_status); +#if 0 /* only the concept of private */ if (le_status == BT_LE_ACTIVATED) { /* Turn off PSCAN, (ISCAN if needed) */ /* Return with 0 for the Disabled response. */ @@ -207,6 +209,7 @@ int _bt_disable_adapter(void) g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL); return 0; } +#endif status = _bt_core_get_status(); if (status == BT_ACTIVATING) { @@ -262,7 +265,12 @@ int _bt_enable_adapter_le(void) #endif if (ret < 0) { BT_ERR("running script failed"); +#ifdef USB_BLUETOOTH + char *argv_down[] = {"/usr/bin/hciconfig", "/usr/bin/hciconfig", "hci0", "down", NULL}; + ret = __execute_command("/usr/bin/hciconfig", argv_down); +#else ret = __execute_command("/usr/etc/bluetooth/bt-dev-end.sh &", NULL); +#endif __bt_core_set_status(BT_DEACTIVATED); __bt_core_set_le_status(BT_LE_DEACTIVATED); return -1; @@ -271,6 +279,12 @@ int _bt_enable_adapter_le(void) __bt_core_set_le_status(BT_LE_ACTIVATED); g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL); } +#ifdef HPS_FEATURE + ret = _bt_core_start_httpproxy(); + if (ret < 0) { + BT_ERR("_bt_core_start_httpproxy() failed"); + } +#endif return 0; } @@ -286,6 +300,10 @@ int _bt_disable_adapter_le(void) retv_if(le_status == BT_LE_DEACTIVATED, 0); retv_if(le_status == BT_LE_DEACTIVATING, -1); +#ifdef HPS_FEATURE + _bt_core_stop_httpproxy(); +#endif + status = _bt_core_get_status(); BT_DBG("status : %d", status); @@ -302,7 +320,7 @@ int _bt_disable_adapter_le(void) return -1; } } else { - g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL); + g_timeout_add(BT_CORE_IDLE_TERM_TIME, __bt_core_idle_terminate, NULL); } __bt_core_set_le_status(BT_LE_DEACTIVATED); @@ -420,9 +438,9 @@ void _bt_core_update_status(void) BT_INFO("bt_status = %d, bt_le_status = %d", bt_status, bt_le_status); - if(bt_status == VCONFKEY_BT_STATUS_ON) + if(bt_status & VCONFKEY_BT_STATUS_ON) __bt_core_set_status(BT_ACTIVATED); - if(bt_le_status == VCONFKEY_BT_LE_STATUS_ON) + if(bt_le_status & VCONFKEY_BT_LE_STATUS_ON) __bt_core_set_le_status(BT_ACTIVATED); } } @@ -707,7 +725,7 @@ static gboolean __bt_core_disable_timeout_cb(gpointer data) return FALSE; } -#if 0 + static int __bt_eventsystem_set_value(const char *event, const char *key, const char *value) { int ret; @@ -717,15 +735,15 @@ static int __bt_eventsystem_set_value(const char *event, const char *key, const bundle_add_str(b, key, value); - ret = eventsystem_request_sending_system_event(event, b); + ret = eventsystem_send_system_event(event, b); - BT_DBG("request_sending_system_event result: %d", ret); + BT_DBG("eventsystem_send_system_event result: %d", ret); bundle_free(b); return ret; } -#endif + void _bt_core_adapter_added_cb(void) { bt_status_t status; @@ -768,11 +786,9 @@ void _bt_core_adapter_removed_cb(void) __bt_core_set_le_status(BT_LE_DEACTIVATED); if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0) BT_ERR("Set vconf failed"); - if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0) BT_ERR("Set vconf failed"); -#if 0 if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE, EVT_VAL_BT_OFF) != ES_R_OK) BT_ERR("Fail to set value"); @@ -780,7 +796,7 @@ void _bt_core_adapter_removed_cb(void) if (__bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE, EVT_VAL_BT_LE_OFF) != ES_R_OK) BT_ERR("Fail to set value"); -#endif + if (is_recovery_mode == TRUE) { if (timer_id < 0) diff --git a/bt-core/bt-core-dbus-handler.c b/bt-core/bt-core-dbus-handler.c index 292b128..5e6b500 100644 --- a/bt-core/bt-core-dbus-handler.c +++ b/bt-core/bt-core-dbus-handler.c @@ -35,8 +35,17 @@ #define BT_SERVICE_NAME "org.projectx.bt" #define BT_SERVICE_PATH "/org/projectx/bt_service" +#ifdef HPS_FEATURE +#define BT_HPS_SERVICE_NAME "org.projectx.httpproxy" +#define BT_HPS_OBJECT_PATH "/org/projectx/httpproxy" +#define BT_HPS_INTERFACE_NAME "org.projectx.httpproxy_service" +#endif + static GDBusConnection *service_gconn; static GDBusProxy *service_gproxy; +#ifdef HPS_FEATURE +static GDBusProxy *hps_gproxy; +#endif void _bt_core_fill_garray_from_variant(GVariant *var, GArray *param) { @@ -107,6 +116,90 @@ GDBusProxy *_bt_core_gdbus_get_service_proxy(void) return (service_gproxy) ? service_gproxy : __bt_core_gdbus_init_service_proxy(); } +#ifdef HPS_FEATURE +int _bt_core_start_httpproxy(void) +{ + GVariant *variant = NULL; + unsigned char enabled; + + BT_DBG(" "); + + hps_gproxy = _bt_core_gdbus_get_hps_proxy(); + if (!hps_gproxy) { + BT_DBG("Couldn't get service proxy"); + return -1; + } + + variant = g_dbus_proxy_call_sync(hps_gproxy, "enable", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (variant) { + g_variant_get(variant, "(y)", &enabled); + BT_ERR("HPS enabled status 0x%x", enabled); + } + return 0; +} + +int _bt_core_stop_httpproxy(void) +{ + GVariant *variant = NULL; + unsigned char enabled; + + BT_DBG(" "); + + hps_gproxy = _bt_core_gdbus_get_hps_proxy(); + if (!hps_gproxy) { + BT_DBG("Couldn't get service proxy"); + return -1; + } + + variant = g_dbus_proxy_call_sync(hps_gproxy, "disable", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (variant) { + g_variant_get(variant, "(y)", &enabled); + BT_ERR("HPS disabled status 0x%x", enabled); + } + return 0; +} + +static GDBusProxy *_bt_core_gdbus_init_hps_proxy(void) +{ + GDBusProxy *proxy; + GError *err = NULL; + GDBusConnection *conn; + + g_type_init(); + + BT_DBG(" "); + + conn = _bt_core_get_gdbus_connection(); + if (!conn) + return NULL; + + proxy = g_dbus_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + BT_HPS_SERVICE_NAME, + BT_HPS_OBJECT_PATH, + BT_HPS_INTERFACE_NAME, + NULL, &err); + if (proxy == NULL) { + if (err) { + BT_ERR("Unable to create proxy: %s", err->message); + g_clear_error(&err); + } + return NULL; + } + + hps_gproxy = proxy; + + return proxy; +} + +GDBusProxy *_bt_core_gdbus_get_hps_proxy(void) +{ + return (hps_gproxy) ? hps_gproxy : _bt_core_gdbus_init_hps_proxy(); +} +#endif + void _bt_core_gdbus_deinit_proxys(void) { BT_DBG(""); @@ -116,6 +209,13 @@ void _bt_core_gdbus_deinit_proxys(void) service_gproxy = NULL; } +#ifdef HPS_FEATURE + if (hps_gproxy) { + g_object_unref(hps_gproxy); + hps_gproxy = NULL; + } +#endif + if (service_gconn) { g_object_unref(service_gconn); service_gconn = NULL; @@ -138,37 +238,49 @@ int _bt_core_service_request(int service_type, int service_function, int result = BLUETOOTH_ERROR_NONE; GError *error = NULL; GArray *in_param5 = NULL; - GArray *out_param2 = NULL; + + int retry = 5; proxy = _bt_core_gdbus_get_service_proxy(); if (!proxy) return BLUETOOTH_ERROR_INTERNAL; in_param5 = g_array_new(TRUE, TRUE, sizeof(gchar)); - param1 = g_variant_new_from_data((const GVariantType *)"ay", - in_param1->data, in_param1->len, - TRUE, NULL, NULL); - param2 = g_variant_new_from_data((const GVariantType *)"ay", - in_param2->data, in_param2->len, - TRUE, NULL, NULL); - param3 = g_variant_new_from_data((const GVariantType *)"ay", - in_param3->data, in_param3->len, - TRUE, NULL, NULL); - param4 = g_variant_new_from_data((const GVariantType *)"ay", - in_param4->data, in_param4->len, - TRUE, NULL, NULL); - param5 = g_variant_new_from_data((const GVariantType *)"ay", - in_param5->data, in_param5->len, - TRUE, NULL, NULL); - - ret = g_dbus_proxy_call_sync(proxy, "service_request", - g_variant_new("(iii@ay@ay@ay@ay@ay)", - service_type, service_function, - BT_SYNC_REQ, param1, - param2, param3, - param4, param5), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, &error); + while (--retry >= 0) { + param1 = g_variant_new_from_data((const GVariantType *)"ay", + in_param1->data, in_param1->len, + TRUE, NULL, NULL); + param2 = g_variant_new_from_data((const GVariantType *)"ay", + in_param2->data, in_param2->len, + TRUE, NULL, NULL); + param3 = g_variant_new_from_data((const GVariantType *)"ay", + in_param3->data, in_param3->len, + TRUE, NULL, NULL); + param4 = g_variant_new_from_data((const GVariantType *)"ay", + in_param4->data, in_param4->len, + TRUE, NULL, NULL); + param5 = g_variant_new_from_data((const GVariantType *)"ay", + in_param5->data, in_param5->len, + TRUE, NULL, NULL); + + ret = g_dbus_proxy_call_sync(proxy, "service_request", + g_variant_new("(iii@ay@ay@ay@ay@ay)", + service_type, service_function, + BT_SYNC_REQ, param1, + param2, param3, + param4, param5), + G_DBUS_CALL_FLAGS_NONE, 2000, + NULL, &error); + if (ret == NULL && error != NULL) { + if (error->code == G_IO_ERROR_TIMED_OUT) { + BT_ERR("D-Bus Timed out."); + g_clear_error(&error); + continue; + } + } + + break; + } g_array_free(in_param5, TRUE); @@ -191,9 +303,8 @@ int _bt_core_service_request(int service_type, int service_function, } param1 = NULL; - param2 = NULL; - g_variant_get(ret, "(@ay@ay)", ¶m1, ¶m2); + g_variant_get(ret, "(iv)", &result, ¶m1); if (param1) { *out_param1 = g_array_new(TRUE, TRUE, sizeof(gchar)); @@ -201,16 +312,6 @@ int _bt_core_service_request(int service_type, int service_function, g_variant_unref(param1); } - if (param2) { - out_param2 = g_array_new(TRUE, TRUE, sizeof(gchar)); - _bt_core_fill_garray_from_variant(param2, out_param2); - result = g_array_index(out_param2, int, 0); - g_variant_unref(param2); - g_array_free(out_param2, TRUE); - } else { - result = BLUETOOTH_ERROR_INTERNAL; - } - g_variant_unref(ret); return result; diff --git a/bt-core/bt-core-main.c b/bt-core/bt-core-main.c index 0d70d04..6b9c33b 100644 --- a/bt-core/bt-core-main.c +++ b/bt-core/bt-core-main.c @@ -80,12 +80,13 @@ static void __bt_core_sigterm_handler(int signo) static gboolean __bt_check_bt_core(void *data) { int bt_status = VCONFKEY_BT_STATUS_OFF; - int bt_le_status = 0; + int bt_le_status = VCONFKEY_BT_LE_STATUS_OFF; bt_status_t status = BT_DEACTIVATED; bt_le_status_t le_status = BT_LE_DEACTIVATED; int flight_mode_deactivation = 0; int bt_off_due_to_timeout = 0; int ps_mode_deactivation = 0; + int ret; status = _bt_core_get_status(); le_status = _bt_core_get_le_status(); @@ -128,7 +129,7 @@ static gboolean __bt_check_bt_core(void *data) _bt_core_set_bt_status(BT_POWER_SAVING_MODE, ps_mode_deactivation); } - if ((bt_le_status == 1) && (le_status == BT_LE_DEACTIVATED)) { + if ((bt_le_status == VCONFKEY_BT_LE_STATUS_ON) && (le_status == BT_LE_DEACTIVATED)) { BT_DBG("Previous session was le enabled. Turn BT LE on automatically."); /* Enable the BT LE */ diff --git a/bt-core/bt-core-noti-handler.c b/bt-core/bt-core-noti-handler.c index 3c5e618..dfa59e5 100644 --- a/bt-core/bt-core-noti-handler.c +++ b/bt-core/bt-core-noti-handler.c @@ -267,7 +267,11 @@ static void __bt_core_power_saving_mode_cb(keynode_t *node, void *data) void _bt_core_init_vconf_value(void) { gboolean flight_mode = FALSE; +#ifndef ENABLE_TIZEN_2_4 int power_saving_mode = 0; +#endif + int bt_flight_mode = 0; + int bt_ps_mode = 0; _bt_core_handle_flight_mode_noti(); _bt_core_handle_power_saving_mode_noti(); @@ -275,17 +279,28 @@ void _bt_core_init_vconf_value(void) flight_mode = _bt_core_is_flight_mode_enabled(); #ifndef TIZEN_WEARABLE -#ifdef ENABLE_TIZEN_2_4 +#ifndef ENABLE_TIZEN_2_4 if (vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &power_saving_mode) != 0) BT_ERR("Fail to get the power_saving_mode status value"); + BT_DBG("flight_mode = %d, power_saving_mode = %d", flight_mode, power_saving_mode); #endif #endif BT_DBG("flight_mode = %d, power_saving_mode = %d", flight_mode, power_saving_mode); + if (vconf_get_int(BT_OFF_DUE_TO_FLIGHT_MODE, &bt_flight_mode)) + BT_ERR("Fail get flight mode value"); + _bt_core_set_bt_status(BT_FLIGHT_MODE, bt_flight_mode); + + if (vconf_get_int(BT_OFF_DUE_TO_POWER_SAVING_MODE, &bt_ps_mode)) + BT_ERR("Fail get power saving mode value"); + _bt_core_set_bt_status(BT_POWER_SAVING_MODE, bt_ps_mode); + if (flight_mode == TRUE) __bt_core_handle_adapter_with_flight_mode(flight_mode); +#ifndef ENABLE_TIZEN_2_4 else if (power_saving_mode > 0) __bt_core_handle_adapter_with_power_saving_mode(power_saving_mode); +#endif else BT_ERR(""); } diff --git a/bt-core/include/bt-core-dbus-handler.h b/bt-core/include/bt-core-dbus-handler.h index 56c2406..ffb94f7 100644 --- a/bt-core/include/bt-core-dbus-handler.h +++ b/bt-core/include/bt-core-dbus-handler.h @@ -57,6 +57,9 @@ int _bt_core_service_request(int service_type, int service_function, GArray **out_param1); void _bt_core_fill_garray_from_variant(GVariant *var, GArray *param); GDBusProxy *_bt_core_gdbus_get_service_proxy(void); +#ifdef HPS_FEATURE +GDBusProxy *_bt_core_gdbus_get_hps_proxy(void); +#endif void _bt_core_gdbus_deinit_proxys(void); GDBusConnection * _bt_core_get_gdbus_connection(void); diff --git a/bt-httpproxy/CMakeLists.txt b/bt-httpproxy/CMakeLists.txt new file mode 100644 index 0000000..7aa5bc8 --- /dev/null +++ b/bt-httpproxy/CMakeLists.txt @@ -0,0 +1,48 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(bt-httpproxy C) + +SET(SRCS bt-httpproxy.c) + +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") + +MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +SET(PKG_MODULES + dbus-glib-1 + gio-2.0 + pkgmgr + eventsystem + libsoup-2.4 + dbus-1 +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(hps_pkgs REQUIRED ${PKG_MODULES}) + +FOREACH(flag ${hps_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag} -Wall") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") +SET(APP_SYSCONFDIR /opt/var/lib/bluetooth) + +FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool) + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") + +ADD_DEFINITIONS("-DHPS_FEATURE") +ADD_DEFINITIONS("-DHPS_GATT_DB") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${hps_pkgs_LDFLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/../bt-api -lbluetooth-api) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.projectx.httpproxy.service DESTINATION share/dbus-1/system-services) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) diff --git a/bt-httpproxy/bt-httpproxy.c b/bt-httpproxy/bt-httpproxy.c new file mode 100644 index 0000000..b161a48 --- /dev/null +++ b/bt-httpproxy/bt-httpproxy.c @@ -0,0 +1,1759 @@ +/* + * Bluetooth-httpproxy-service + * + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: C S Bhargava + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include + +#include "bt-httpproxy.h" +#include "bluetooth-api.h" + +#include + +#ifdef HPS_FEATURE + +#undef LOG_TAG +#define LOG_TAG "BLUETOOTH_HPS" + +#define BT_INFO(fmt, arg...) SLOGI(fmt, ##arg) +#define BT_ERR(fmt, arg...) SLOGE(fmt, ##arg) +#define BT_DBG(fmt, arg...) SLOGD(fmt, ##arg) + +char *hps_obj_path = NULL; +char *http_uri_obj_path = NULL; +char *http_hdr_obj_path = NULL; +char *http_entity_obj_path = NULL; +char *http_cp_obj_path = NULL; +char *http_status_obj_path = NULL; +char *http_status_desc_obj_path = NULL; +char *http_security_obj_path = NULL; + +static GMainLoop *main_loop; +static int property_sub_id = -1; +static int adapter_sub_id = -1; +static http_request_state req_state; + +#ifdef HPS_GATT_DB +struct hps_notify_read_info { + gchar *char_path; + guint read_status; + guint offset_status; + int https_status; +}; + +struct hps_char_info { + gchar *char_path; + gchar *char_value; + int value_length; +}; + +static GSList *hps_notify_read_list = NULL; +static GSList *hps_char_list = NULL; +#endif + +static GDBusConnection *conn; +static GDBusConnection *g_conn; +static guint g_owner_id = 0; +GDBusNodeInfo *hps_node_info = NULL; + +char *g_uri = NULL; +char *g_header = NULL; +char *g_entity = NULL; + +static SoupSession *hps_soup_session = NULL; +static SoupMessage *hps_soup_msg = NULL; + + +static const gchar hps_introspection_xml[] = +"" +" " +" " +" " +" " +" " +" " +" " +" " +""; + +#ifdef HPS_GATT_DB +static void _bt_hps_set_char_value(const char *obj_path, const char* value, int value_length); + +static void _hps_convert_address_to_hex(bluetooth_device_address_t *addr_hex, const char *addr_str) +{ + int i = 0; + unsigned int addr[BLUETOOTH_ADDRESS_LENGTH] = { 0, }; + + if (addr_str == NULL || addr_str[0] == '\0') + return; + + i = sscanf(addr_str, "%X:%X:%X:%X:%X:%X", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]); + if (i != BLUETOOTH_ADDRESS_LENGTH) { + BT_ERR("Invalid format string - [%s]", addr_str); + } + + for (i = 0; i < BLUETOOTH_ADDRESS_LENGTH; i++) { + addr_hex->addr[i] = (unsigned char)addr[i]; + } +} + +static void _bt_hps_send_status_notification(unsigned short http_status, + unsigned char data_status, + bluetooth_device_address_t *unicast_address) +{ + char status[3] = {0x00}; + int ret = BLUETOOTH_ERROR_NONE; + + BT_DBG(""); + + status[0] = http_status & 0xFF; + status[1] = (http_status >> 8 )& 0xFF; + status[2] = data_status; + BT_DBG("Status %d %04x", http_status, http_status); + + /* Store the status value */ + _bt_hps_set_char_value(http_status_obj_path, status, 3); + + /* Send unicast notification */ + ret = bluetooth_gatt_server_set_notification(http_status_obj_path, unicast_address); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("_bt_hps_send_status_notification failed"); + return; + } + ret = bluetooth_gatt_update_characteristic(http_status_obj_path, status, 3); + if (ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("_bt_hps_send_status_notification failed"); + return; + } +} +#endif + +static void _bt_httpproxy_method(GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + int status = 0; + + BT_DBG("Method[%s] Object Path[%s] Interface Name[%s]", + method_name, object_path, interface_name); + + if (g_strcmp0(method_name, "enable") == 0) { + g_dbus_method_invocation_return_value(invocation, g_variant_new("(y)", status)); + } else if (g_strcmp0(method_name, "disable") == 0) { + _bt_hps_exit(); + g_dbus_method_invocation_return_value(invocation, g_variant_new("(y)", status)); + } + + return; +} + +static const GDBusInterfaceVTable hps_method_table = { + _bt_httpproxy_method, + NULL, + NULL, +}; + +static void _bt_hps_on_bus_acquired (GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + guint object_id; + GError *error = NULL; + + BT_DBG(""); + + g_conn = connection; + + object_id = g_dbus_connection_register_object(connection, BT_HPS_OBJECT_PATH, + hps_node_info->interfaces[0], + &hps_method_table, + NULL, NULL, &error); + if (object_id == 0) { + BT_ERR("Failed to register method table: %s", error->message); + g_error_free(error); + g_dbus_node_info_unref(hps_node_info); + } + + return; +} + +static void _bt_hps_on_name_acquired (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + BT_DBG(""); + return; +} + +static void _bt_hps_on_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + BT_DBG(""); + g_object_unref(g_conn); + g_conn = NULL; + g_dbus_node_info_unref(hps_node_info); + g_bus_unown_name(g_owner_id); + + return; +} + +int _bt_hps_register_interface(void) +{ + GError *error = NULL; + guint owner_id; + + BT_DBG(""); + + hps_node_info = g_dbus_node_info_new_for_xml (hps_introspection_xml, &error); + if (!hps_node_info) { + BT_ERR("Failed to install: %s", error->message); + return BLUETOOTH_ERROR_INTERNAL; + } + + owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + BT_HPS_SERVICE_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + _bt_hps_on_bus_acquired, _bt_hps_on_name_acquired, _bt_hps_on_name_lost, + NULL, NULL); + g_owner_id = owner_id; + BT_DBG("owner_id is [%d]\n", owner_id); + + return BLUETOOTH_ERROR_NONE; +} + +void _bt_hps_unregister_interface(void) +{ + BT_DBG(""); + + g_object_unref(g_conn); + g_conn = NULL; + g_dbus_node_info_unref(hps_node_info); + g_bus_unown_name(g_owner_id); + + return; +} + +#ifdef HPS_GATT_DB +static struct hps_char_info *hps_get_char_value(const char *path) +{ + GSList *tmp = NULL; + + for (tmp = hps_char_list; tmp != NULL; tmp = tmp->next) { + if (tmp->data) { + struct hps_char_info *char_info = tmp->data; + if(!g_strcmp0(char_info->char_path, path)) + return char_info; + } + } + return NULL; +} + +static int char_info_cmp(gconstpointer a1, gconstpointer a2) +{ + const struct hps_char_info *attrib1 = a1; + const struct hps_char_info *attrib2 = a2; + + return g_strcmp0(attrib1->char_path, attrib2->char_path); +} + +static int notify_info_cmp(gconstpointer a1, gconstpointer a2) +{ + const struct hps_notify_read_info *attrib1 = a1; + const struct hps_notify_read_info *attrib2 = a2; + + return g_strcmp0(attrib1->char_path, attrib2->char_path); +} + +static void _bt_hps_set_char_value(const char *obj_path, const char* value, int value_length) +{ + GSList *tmp = NULL; + if (!value) + return; + + for (tmp = hps_char_list; tmp != NULL; tmp = tmp->next) { + if (tmp->data) { + struct hps_char_info *char_info = tmp->data; + if(!g_strcmp0(char_info->char_path, obj_path)) { + char_info->char_value = g_try_realloc(char_info->char_value, value_length); + if (char_info->char_value) { + memcpy(char_info->char_value, value, value_length); + char_info->value_length = value_length; + hps_char_list = g_slist_insert_sorted (hps_char_list, + char_info, char_info_cmp); + } + return; + } + } + } + return; +} + +static void _bt_hps_set_notify_read_status(const char *obj_path, + guint offset_status, guint read_status, int https_status) +{ + struct hps_notify_read_info *notify_read_info = NULL; + GSList *tmp = NULL; + + for (tmp = hps_notify_read_list; tmp != NULL; tmp = tmp->next) { + if (tmp->data) { + notify_read_info = tmp->data; + if(!g_strcmp0(notify_read_info->char_path, obj_path)) { + notify_read_info->read_status = read_status; + notify_read_info->offset_status = offset_status; + notify_read_info->https_status = https_status; + hps_notify_read_list = g_slist_insert_sorted (hps_notify_read_list, + notify_read_info, notify_info_cmp); + return; + } + } + } + + if (!hps_notify_read_list) { + /* Store Notification information */ + notify_read_info = g_new0(struct hps_notify_read_info, 1); + if (notify_read_info) { + notify_read_info->char_path = g_strdup(obj_path); + notify_read_info->read_status = read_status; + notify_read_info->offset_status = offset_status; + notify_read_info->https_status = https_status; + hps_notify_read_list = g_slist_append(hps_notify_read_list, notify_read_info); + } + return; + } else { + /* Store Notification information */ + notify_read_info = g_new0(struct hps_notify_read_info, 1); + if (notify_read_info) { + notify_read_info->char_path = g_strdup(obj_path); + notify_read_info->read_status = read_status; + notify_read_info->offset_status = offset_status; + notify_read_info->https_status = https_status; + hps_notify_read_list = g_slist_append(hps_notify_read_list, notify_read_info); + } + return; + } +} + +static struct hps_notify_read_info *_bt_hps_get_notify_read_status(const char *obj_path) +{ + GSList *tmp = NULL; + + for (tmp = hps_notify_read_list; tmp != NULL; tmp = tmp->next) { + if (tmp->data) { + struct hps_notify_read_info *notify_read_info = tmp->data; + if(!g_strcmp0(notify_read_info->char_path, obj_path)) { + return notify_read_info; + } + } + } + + return NULL; +} + +static void delete_all_characterisitc(void) +{ + GSList *tmp = NULL; + for (tmp = hps_char_list; tmp != NULL; tmp = tmp->next) { + if (tmp->data) { + struct hps_char_info *char_info = tmp->data; + if (char_info->char_path) + g_free(char_info->char_path); + if (char_info->char_value) + g_free(char_info->char_value); + hps_char_list = g_slist_delete_link(hps_char_list, tmp->data); + } + } + g_slist_free(hps_char_list); + hps_char_list = NULL; +} + +static void delete_all_notify_read_status(void) +{ + GSList *tmp = NULL; + for (tmp = hps_notify_read_list; tmp != NULL; tmp = tmp->next) { + if (tmp->data) { + struct hps_notify_read_info *notify_read_info = tmp->data; + if (notify_read_info->char_path) + g_free(notify_read_info->char_path); + hps_notify_read_list = g_slist_delete_link(hps_notify_read_list, tmp->data); + } + } + g_slist_free(hps_notify_read_list); + hps_notify_read_list = NULL; +} + +static void delete_notify_read_status(const char *obj_path) +{ + GSList *tmp = NULL; + for (tmp = hps_notify_read_list; tmp != NULL; tmp = tmp->next) { + if (tmp->data) { + struct hps_notify_read_info *notify_read_info = tmp->data; + if(!g_strcmp0(notify_read_info->char_path, obj_path)) { + if (notify_read_info->char_path) + g_free(notify_read_info->char_path); + hps_notify_read_list = g_slist_delete_link(hps_notify_read_list, tmp->data); + return; + } + } + } +} +#endif + +int _bt_hps_uri_write_cb(char *uri, int len) +{ + if((len < 1) || (len > MAX_URI_LENGTH)) { + BT_ERR("Wrong URI length %d", len); + return BLUETOOTH_ERROR_INTERNAL; + } + + /* g_uri will be used commonly for all HTTP methods whereever applicable */ + if (g_uri) + g_free(g_uri); + g_uri = g_strndup(uri, len); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_uri_obj_path, g_uri, len); +#endif + return BLUETOOTH_ERROR_NONE; +} + +int _bt_hps_http_header_write_cb(char *header, int len) +{ + if((len < 1) || (len > MAX_HEADER_LENGTH)) { + BT_ERR("Wrong Header length %d", len); + return BLUETOOTH_ERROR_INTERNAL; + } + + /* g_header will be used commonly for all HTTP methods where ever applicable + general-header, request-header, entity-header + */ + if (g_header) + g_free(g_header); + g_header = g_strndup(header, len); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_hdr_obj_path, g_header, len); +#endif + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_hps_entity_body_write_cb(char *entity, int len) +{ + if((len < 1) || (len > MAX_ENTITY_LENGTH)) { + BT_ERR("Wrong Entity length %d", len); + return BLUETOOTH_ERROR_INTERNAL; + } + + /* g_entity will be used commonly for all HTTP methods whereever applicable */ + if (g_entity) + g_free(g_entity); + g_entity = g_strndup(entity, len); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_entity_obj_path, g_entity, len); +#endif + + return BLUETOOTH_ERROR_NONE; +} + +#ifdef HPS_GATT_DB +int _bt_hps_read_cb(const char *obj_path, char **value, int *len) +{ + struct hps_char_info *info = NULL; + struct hps_notify_read_info *notify_read_info = NULL; + guint data_status = -1; + guint offset = 0; + gboolean is_header = FALSE; + + if(!obj_path) { + BT_ERR("Wrong Obj path"); + return FALSE; + } + + if (!g_strcmp0(http_hdr_obj_path, obj_path)) + is_header = TRUE; + + info = hps_get_char_value(obj_path); + if (info) { + + if (info->char_value == NULL || info->value_length == 0) + return data_status; + + notify_read_info = _bt_hps_get_notify_read_status(obj_path); + if (notify_read_info && notify_read_info->read_status != DS_BODY_RECEIVED && + notify_read_info->read_status != DS_HEADER_RECEIVED) { + offset = notify_read_info->offset_status; + if ((info->value_length - offset) > 0 && + (info->value_length - offset) > MAX_ENTITY_LENGTH) { + if (is_header) + data_status = DS_HEADER_TRUNCATED; + else + data_status = DS_BODY_TRUNCATED; + _bt_hps_set_notify_read_status(obj_path, offset + MAX_ENTITY_LENGTH, + data_status, notify_read_info->https_status); + *value = g_strdup(&info->char_value[offset]); + *len = info->value_length; + } else if ((info->value_length - offset) > 0 && + (info->value_length - offset) <= MAX_ENTITY_LENGTH) { + if (is_header) + data_status = DS_HEADER_RECEIVED; + else + data_status = DS_BODY_RECEIVED; + _bt_hps_set_notify_read_status(obj_path, offset, data_status, notify_read_info->https_status); + *value = g_strdup(&info->char_value[offset]); + *len = info->value_length; + } + } else if (notify_read_info && (notify_read_info->read_status == DS_BODY_RECEIVED || + notify_read_info->read_status == DS_HEADER_RECEIVED)) { + if (is_header) + data_status = DS_HEADER_RECEIVED; + else + data_status = DS_BODY_RECEIVED; + delete_notify_read_status(obj_path); + *value = g_strdup(&info->char_value[offset]); + *len = info->value_length; + } + } + + return data_status; +} +#endif + +void _bt_hps_head_response_cb(SoupSession *session, + SoupMessage *msg, gpointer user_data) +{ + unsigned short http_status = 0x00; +#ifndef HPS_GATT_DB + unsigned char status[3] = {0x00}; +#else + const char *device_address = user_data; + bluetooth_device_address_t addr_hex = { {0,} }; + unsigned char data_status = DS_NONE; + _hps_convert_address_to_hex(&addr_hex, device_address); +#endif + + if(hps_soup_session != session) { + BT_ERR("Wrong Session"); + return; + } + + if(msg == NULL) { + BT_ERR("Wrong Message"); + return; + } + hps_soup_msg = NULL; + + req_state = HTTP_REQ_STATE_EXECUTED; + + http_status = msg->status_code; + + // Process Header in Response Body + if(msg->response_headers) { + + const char *content = NULL; + const char *length = NULL; + guint hdr_len = 0; + + length = soup_message_headers_get_one (msg->request_headers, + "Content-Length"); + // Check "Content-MD5" is the right name to get header content + content = soup_message_headers_get_one (msg->response_headers, + "Content-MD5"); + if (content == NULL || length == NULL) { + BT_ERR("Wrong Response Header"); + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); + return; + } + + hdr_len = soup_message_headers_get_content_length(msg->response_headers); + + // Write Data to Header Characteristic +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_hdr_obj_path, content, hdr_len); +#else + bluetooth_gatt_set_characteristic_value(http_hdr_obj_path, content, hdr_len); +#endif + // TODO : Handle Truncated Header + + // Write Data to Status Code Characteristic +#ifdef HPS_GATT_DB + data_status = (hdr_len > MAX_ENTITY_LENGTH ) ? DS_HEADER_TRUNCATED : DS_HEADER_RECEIVED; + if (data_status == DS_BODY_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) { + _bt_hps_set_notify_read_status(http_hdr_obj_path, data_status, 0, http_status); + } + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); +#else + status[0] = http_status & 0x0F; + status[1] = (http_status >> 8 )& 0x0F; + status[2] = (hdr_len > MAX_HEADER_LENGTH ) ? DS_HEADER_TRUNCATED : DS_HEADER_RECEIVED; + + bluetooth_gatt_set_characteristic_value(http_status_obj_path, status, 3); +#endif + }else { + BT_ERR("HEAD Response is NULL"); + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); + } + + return; +} + +void _bt_hps_http_response_cb(SoupSession *session, + SoupMessage *msg, gpointer user_data) +{ + unsigned short http_status = 0x00; +#ifndef HPS_GATT_DB + unsigned char status[3] = {0x00}; +#else + const char *device_address = user_data; + bluetooth_device_address_t addr_hex = { {0,} }; + unsigned char data_status = DS_NONE; + _hps_convert_address_to_hex(&addr_hex, device_address); +#endif + + if(hps_soup_session != session) { + BT_ERR("Wrong Session"); + return; + } + + if(msg == NULL) { + BT_ERR("Wrong Message"); + return; + } + + hps_soup_msg = NULL; + + req_state = HTTP_REQ_STATE_EXECUTED; + + http_status = msg->status_code; + + // Write Data to Status Code Characteristic +#ifndef HPS_GATT_DB + status[0] = http_status & 0x0F; + status[1] = (http_status >> 8 )& 0x0F; + status[2] = DS_HEADER_RECEIVED; + bluetooth_gatt_set_characteristic_value(http_status_obj_path, status, 3); +#else + data_status = DS_HEADER_RECEIVED; + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); +#endif + + return; +} + +void _bt_hps_get_response_cb(SoupSession *session, + SoupMessage *msg, gpointer user_data) +{ + SoupBuffer *body = NULL; + unsigned short http_status = 0x00; +#ifndef HPS_GATT_DB + unsigned char status[3] = {0x00}; +#else + const char *device_address = user_data; + bluetooth_device_address_t addr_hex = { {0,} }; + unsigned char data_status = DS_NONE; + _hps_convert_address_to_hex(&addr_hex, device_address); +#endif + + if(hps_soup_session != session) { + BT_ERR("Wrong Session"); + return; + } + + if(msg == NULL) { + BT_ERR("Wrong Message"); + return; + } + + hps_soup_msg = NULL; + + req_state = HTTP_REQ_STATE_EXECUTED; + + http_status = msg->status_code; + + // Process Entity Body in Response Message + if(msg->response_body) { + + body = soup_message_body_flatten (msg->response_body); + if (body == NULL) { + BT_ERR("Wrong Response Body"); +#ifdef HPS_GATT_DB + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); +#endif + return; + } + if (body->data == NULL || body->length <= 0) { + BT_ERR("Wrong Response"); + soup_buffer_free(body); +#ifdef HPS_GATT_DB + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); +#endif + return; + } + // Write Data to Entity Body Characteristic +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_entity_obj_path, body->data, body->length); +#else + bluetooth_gatt_set_characteristic_value(http_entity_obj_path, body->data, body->length); +#endif + // TODO : Handle Truncated Entiry Body + + // Write Data to Status Code Characteristic +#ifdef HPS_GATT_DB + data_status = (body->length > MAX_ENTITY_LENGTH ) ? DS_BODY_TRUNCATED : DS_BODY_RECEIVED; + if (data_status == DS_BODY_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) { + _bt_hps_set_notify_read_status(http_entity_obj_path, data_status, 0, http_status); + } + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); + +#else + status[0] = http_status & 0x0F; + status[1] = (http_status >> 8 )& 0x0F; + status[2] = (body->length > MAX_HEADER_LENGTH ) ? DS_BODY_TRUNCATED : DS_BODY_TRUNCATED; + + bluetooth_gatt_set_characteristic_value(http_status_obj_path, status, 3); +#endif + soup_buffer_free(body); + }else { + BT_ERR("GET Response Body is NULL"); +#ifdef HPS_GATT_DB + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); +#endif + } + + // Process Header in Response Body + if(msg->response_headers) { + + const char *content = NULL; + const char *length = NULL; + guint hdr_len = 0; + + length = soup_message_headers_get_one (msg->request_headers, + "Content-Length"); + // Check "Content-MD5" is the right name to get header content + content = soup_message_headers_get_one (msg->response_headers, + "Content-MD5"); + if (content == NULL || length == NULL) { + BT_ERR("Wrong Response Header"); + data_status = DS_NONE; + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); + return; + } + + hdr_len = soup_message_headers_get_content_length(msg->response_headers); + // Write Data to Header Characteristic +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_hdr_obj_path, content, hdr_len); +#else + bluetooth_gatt_set_characteristic_value(http_hdr_obj_path, content, hdr_len); +#endif + // TODO : Handle Truncated Header + + // Write Data to Status Code Characteristic +#ifdef HPS_GATT_DB + data_status = (hdr_len > MAX_HEADER_LENGTH ) ? DS_HEADER_TRUNCATED : DS_HEADER_RECEIVED; + if (data_status == DS_HEADER_TRUNCATED && SOUP_STATUS_IS_SUCCESSFUL(http_status)) { + _bt_hps_set_notify_read_status(http_hdr_obj_path, data_status, 0, http_status); + } + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); +#else + status[0] = http_status & 0x0F; + status[1] = (http_status >> 8 )& 0x0F; + status[2] = (hdr_len > MAX_HEADER_LENGTH ) ? DS_HEADER_TRUNCATED : DS_HEADER_RECEIVED; + + bluetooth_gatt_set_characteristic_value(http_status_obj_path, status, 3); +#endif + }else { + BT_ERR("GET Response Header is NULL"); +#ifdef HPS_GATT_DB + _bt_hps_send_status_notification(http_status, data_status, &addr_hex); +#endif + } + + return; +} + +#ifdef HPS_GATT_DB +int _bt_hps_control_point_write_cb(const char *value, int len, char *addr) +#else +int _bt_hps_control_point_write_cb(char *value, int len) +#endif +{ + int opcode = *value; + GTlsCertificate *cert = NULL; + GTlsCertificateFlags flags; + gboolean https_status = FALSE; + int result = BLUETOOTH_ERROR_NONE; + BT_INFO("Opcode %0x", opcode); + +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_cp_obj_path, value, len); +#endif + + switch(opcode) { + case HTTP_GET_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("GET", g_uri); +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_get_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_get_response_cb, NULL); +#endif + } else { + BT_ERR("HTTP GET request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTP_POST_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("POST", g_uri); + if(hps_soup_msg == NULL || g_entity == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } + soup_message_set_request (hps_soup_msg, "text/xml", SOUP_MEMORY_COPY, + g_entity, strlen (g_entity)); +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, NULL); +#endif + } else { + BT_ERR("HTTP POST request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTP_HEAD_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("HEAD", g_uri); + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_head_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_head_response_cb, NULL); +#endif + } else { + BT_ERR("HTTP HEAD request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTP_PUT_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + SoupBuffer *buf; + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("PUT", g_uri); + if(hps_soup_msg == NULL || g_entity == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } + buf = soup_buffer_new (SOUP_MEMORY_TAKE, g_entity, strlen (g_entity)); + soup_message_body_append_buffer (hps_soup_msg->request_body, buf); + soup_message_body_set_accumulate (hps_soup_msg->request_body, FALSE); +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, NULL); +#endif + + } else { + BT_ERR("HTTP PUT request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTP_DELETE_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("DELETE", g_uri); + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, NULL); +#endif + } else { + BT_ERR("HTTP DELETE request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTPS_GET_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("GET", g_uri); + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_get_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_get_response_cb, NULL); +#endif + https_status = soup_message_get_https_status (hps_soup_msg, &cert, &flags); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_security_obj_path, (const char *)&https_status, 1); +#else + bluetooth_gatt_set_characteristic_value(http_security_obj_path, (char *)&https_status, 1); +#endif + } else { + BT_ERR("HTTPS GET request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTPS_HEAD_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("HEAD", g_uri); + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_head_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_head_response_cb, NULL); +#endif + https_status = soup_message_get_https_status (hps_soup_msg, &cert, &flags); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_security_obj_path, (const char *)&https_status, 1); +#else + bluetooth_gatt_set_characteristic_value(http_security_obj_path, (char *)&https_status, 1); +#endif + } else { + BT_ERR("HTTPS HEAD request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTPS_POST_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("POST", g_uri); + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } + soup_message_set_request (hps_soup_msg, "text/xml", SOUP_MEMORY_STATIC, + g_entity, strlen (g_entity)); +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, NULL); + +#endif + https_status = soup_message_get_https_status (hps_soup_msg, &cert, &flags); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_security_obj_path, (const char *)&https_status, 1); +#else + bluetooth_gatt_set_characteristic_value(http_security_obj_path, (char *)&https_status, 1); +#endif + } else { + BT_ERR("HTTPS POST request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTPS_PUT_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + SoupBuffer *buf; + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("PUT", g_uri); + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } + buf = soup_buffer_new (SOUP_MEMORY_TAKE, g_entity, strlen (g_entity)); + soup_message_body_append_buffer (hps_soup_msg->request_body, buf); + soup_message_body_set_accumulate (hps_soup_msg->request_body, FALSE); +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, NULL); +#endif + https_status = soup_message_get_https_status (hps_soup_msg, &cert, &flags); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_security_obj_path, (const char *)&https_status, 1); +#else + bluetooth_gatt_set_characteristic_value(http_security_obj_path, (char *)&https_status, 1); +#endif + } else { + BT_ERR("HTTPS PUT request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTPS_DELETE_REQUEST: + if(req_state == HTTP_REQ_STATE_EXECUTED) { + req_state = HTTP_REQ_STATE_INPROGRESS; + hps_soup_msg = soup_message_new("DELETE", g_uri); + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } +#ifdef HPS_GATT_DB + g_object_ref (hps_soup_msg); + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, addr); +#else + soup_session_queue_message(hps_soup_session, hps_soup_msg, _bt_hps_http_response_cb, NULL); +#endif + + https_status = soup_message_get_https_status (hps_soup_msg, &cert, &flags); +#ifdef HPS_GATT_DB + _bt_hps_set_char_value(http_security_obj_path, (const char *)&https_status, 1); +#else + bluetooth_gatt_set_characteristic_value(http_security_obj_path, (char *)&https_status, 1); +#endif + } else { + BT_ERR("HTTPS DELETE request in progress, message dropped"); + result = BLUETOOTH_ERROR_INTERNAL; + } + break; + + case HTTP_REQUEST_CANCEL: + /* Cancel the outstanding request */ + if(req_state == HTTP_REQ_STATE_INPROGRESS) { + req_state = HTTP_REQ_STATE_IDLE; + if(hps_soup_msg == NULL) { + BT_ERR("Soup Message NULL"); + result = BLUETOOTH_ERROR_INTERNAL; + req_state = HTTP_REQ_STATE_EXECUTED; + break; + } + soup_session_cancel_message (hps_soup_session, hps_soup_msg, SOUP_STATUS_CANCELLED); + hps_soup_msg = NULL; + } + break; + + default: + BT_ERR("Unknown opcode %0x", opcode); + result = BLUETOOTH_ERROR_INTERNAL; + break; + } + + return result; +} + +void _bt_hps_security_read_cb (char *value, int len) +{ + BT_INFO("HPS Client Read the value"); + return; +} + +#ifdef HPS_GATT_DB +void _bt_hps_gatt_char_property_changed_event(GVariant *msg, + const char *path) +{ + int result = BLUETOOTH_ERROR_NONE; + GVariantIter value_iter; + const char *property = NULL; + const char * char_path = NULL; + const char * svc_handle = NULL; + GVariant *var = NULL; + GVariant *val = NULL; + g_variant_iter_init (&value_iter, msg); + + while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &var))) { + + if(property == NULL) { + BT_ERR("Property NULL"); + return; + } + + if (!g_strcmp0(property, "WriteValue")) { + int len = 0; + BT_INFO("WriteValue"); + BT_INFO("Type '%s'\n", g_variant_get_type_string (var)); + + if (var) { + gchar *addr = NULL; + guint8 req_id = 1; + guint16 offset = 0; + char *value = NULL; + g_variant_get(var, "(&s&s&syq@ay)", &char_path, + &svc_handle, &addr, &req_id, &offset, &val); + + len = g_variant_get_size(val); + + BT_DBG("Len = %d", len); + + value = (char *) g_variant_get_data(val); + + if (len != 0) { + if(!g_strcmp0(char_path, http_uri_obj_path)) { + /* Retrive URI */ + result = _bt_hps_uri_write_cb(value, len); + } else if(!g_strcmp0(char_path, http_hdr_obj_path)) { + /* Retrive HEADER */ + result = _bt_hps_http_header_write_cb(value, len); + } else if(!g_strcmp0(char_path, http_entity_obj_path)) { + /* Retrive ENTITY BODY */ + result = _bt_hps_entity_body_write_cb(value, len); + } else if(!g_strcmp0(char_path, http_cp_obj_path)) { + result = _bt_hps_control_point_write_cb(value, len, addr); + } else { + BT_ERR("Wrong Object Path %s", char_path); + result = BLUETOOTH_ERROR_INTERNAL; + } + bluetooth_gatt_send_response(req_id, BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE, result, 0, NULL, 0); + } else { + BT_ERR("Array Len 0"); + } + } else { + BT_ERR("var==NULL"); + } + } else if (!g_strcmp0(property, "ReadValue")) { + gchar *addr = NULL; + guint8 req_id = 1; + guint16 offset = 0; + char *value = NULL; + int len = 0; + int data_status = -1; + BT_INFO("ReadValue"); + BT_INFO("Type '%s'\n", g_variant_get_type_string (var)); + + g_variant_get(var, "(&s&s&syq)", &char_path, &svc_handle, + &addr, &req_id, &offset); + + data_status = _bt_hps_read_cb(char_path, &value, &len); + if (data_status >= DS_NONE) { + struct hps_notify_read_info *notify_read_info = NULL; + bluetooth_device_address_t addr_hex = { {0,} }; + _hps_convert_address_to_hex(&addr_hex, addr); + bluetooth_gatt_send_response(req_id, BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ, + BLUETOOTH_ERROR_NONE, offset, value, len); + notify_read_info = _bt_hps_get_notify_read_status(char_path); + if (notify_read_info) { + _bt_hps_send_status_notification(notify_read_info->https_status, + data_status, &addr_hex); + } else { + if (data_status == DS_BODY_RECEIVED || + data_status == DS_HEADER_RECEIVED) { + _bt_hps_set_char_value(char_path, NULL, 0); + } + } + if (value) + g_free(value); + } else { + BT_ERR("ReadValue failed %s", char_path); + bluetooth_gatt_send_response(req_id, BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ, + BLUETOOTH_ERROR_INTERNAL, offset, NULL, 0); + } + } + } + return; +} +#else +void _bt_hps_gatt_char_property_changed_event(GVariant *msg, + const char *path) +{ + GVariantIter value_iter; + char *property = NULL; + char * char_handle = NULL; + GVariant *val = NULL; + int result = BLUETOOTH_ERROR_NONE; + GVariant *param = NULL; + g_variant_iter_init (&value_iter, msg); + char_handle = g_strdup(path); + + while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val))) { + + if(property == NULL) { + BT_ERR("Property NULL"); + return; + } + + if (strcasecmp(property, "ChangedValue") == 0) { + + int len = 0; + GByteArray *gp_byte_array = NULL; + BT_INFO("Type '%s'\n", g_variant_get_type_string (val)); + + if (val) { + gp_byte_array = g_byte_array_new(); + len = g_variant_get_size(val); + BT_DBG("Len = %d", len); + g_byte_array_append (gp_byte_array, + (const guint8 *) g_variant_get_data(val), len); + if (gp_byte_array->len != 0) { + GVariant *byte_array = NULL; + byte_array = g_variant_new_from_data( + G_VARIANT_TYPE_BYTESTRING, + gp_byte_array->data, + gp_byte_array->len, + TRUE, NULL, NULL); + param = g_variant_new("(is@ay)", result, char_handle, + byte_array); + + if(strcmp(path, http_uri_obj_path)) { + //Retrive URI + _bt_hps_uri_write_cb(NULL, len); + } else if(strcmp(path, http_hdr_obj_path)) { + //Retrive HEADER + _bt_hps_http_header_write_cb(NULL, len); + } else if(strcmp(path, http_entity_obj_path)) { + //Retrive ENTITY BODY + _bt_hps_entity_body_write_cb(NULL, len); + } else if(strcmp(path, http_cp_obj_path)) { + _bt_hps_control_point_write_cb(NULL, len); + } else if(strcmp(path, http_security_obj_path)) { + _bt_hps_security_read_cb(NULL, len); + } else { + BT_ERR("Wrong Object Path %s", path); + } + } else { + BT_ERR("Array Len 0"); + } + g_byte_array_free(gp_byte_array, TRUE); + }else { + BT_ERR("val==NULL"); + } + } + } + g_free(char_handle); + + return; +} +#endif + +void _bt_hps_property_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) +{ + GVariant *value; + + if (signal_name == NULL) { + BT_ERR("Wrong Signal"); + return; + } + +#ifdef HPS_GATT_DB + if (g_strcmp0(signal_name, PROPERTIES_CHANGED) == 0) { + + g_variant_get(parameters, "(@a{sv}@as)", &value, NULL); + + _bt_hps_gatt_char_property_changed_event(value, object_path); +#else + if (g_strcmp0(interface_name, BT_HPS_PROPERTIES_INTERFACE) == 0) { + + g_variant_get(parameters, "(&s@a{sv}@as)", &interface_name, &value, NULL); + + _bt_hps_gatt_char_property_changed_event(value, object_path); +#endif + } else { + //BT_ERR("Wrong Interface %s", interface_name); + } + + return; +} + + +void _bt_hps_adapter_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) +{ + int result = BLUETOOTH_ERROR_NONE; + GVariant *value; + + if (signal_name == NULL) { + BT_ERR("Wrong Signal"); + return; + } + + BT_INFO("Interface %s, Signal %s", interface_name, signal_name); + + if (g_strcmp0(interface_name, BT_HPS_INTERFACE_NAME) == 0) { + + g_variant_get(parameters, "(&s@a{sv}@as)", &interface_name, &value, NULL); + + if (strcasecmp(signal_name, BLE_ENABLED) == 0) { + g_variant_get(parameters, "(i)", &result); + + if (_bt_hps_prepare_httpproxy() != BLUETOOTH_ERROR_NONE) { + BT_ERR("Fail to prepare HTTP Proxy"); + return; + } + + if (_bt_hps_set_advertising_data() != BLUETOOTH_ERROR_NONE) { + BT_ERR("Fail to set advertising data"); + return; + } + + } else { + BT_ERR("Wrong Signal %s", signal_name); + } + } + + return; +} + +int _bt_hps_init_event_receiver() +{ + GError *error = NULL; + + BT_DBG(""); + + if (conn == NULL) { + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (error != NULL) { + BT_ERR("ERROR: Can't get on system bus [%s]", error->message); + g_clear_error(&error); + } + } + + property_sub_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_HPS_INTERFACE_NAME, + PROPERTIES_CHANGED, BT_HPS_OBJECT_PATH, NULL, 0, + _bt_hps_property_event_filter, + NULL, NULL); + + adapter_sub_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_HPS_INTERFACE_NAME, + BLE_ENABLED, BT_HPS_OBJECT_PATH, NULL, 0, + _bt_hps_adapter_event_filter, + NULL, NULL); + + return 0; +} + +void _bt_hps_deinit_event_receiver(void) +{ + BT_DBG(""); + g_dbus_connection_signal_unsubscribe(conn, property_sub_id); + g_dbus_connection_signal_unsubscribe(conn, adapter_sub_id); + conn = NULL; + return; +} + +int _bt_hps_set_advertising_data(void) +{ + int ret; + BT_DBG(""); + + // Temporary UUID is used. SIG have not yet defined the UUID yet + guint8 data[4] = {0x03, 0x02, 0x00, 0x19}; + bluetooth_advertising_data_t adv; + + BT_DBG("%x %x %x %x", data[0], data[1], data[2], data[3]); + memcpy(adv.data, data, sizeof(data)); + ret = bluetooth_set_advertising_data(0, &adv, sizeof(data)); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to set ADV data %d", ret); + return ret; + } + + ret = bluetooth_set_advertising(0, TRUE); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to set ADV %d", ret); + return ret; + } + + return 0; +} + +int _bt_hps_prepare_httpproxy(void) +{ + int ret = BLUETOOTH_ERROR_NONE; + char *char_uuid; + char *service_uuid; + char *desc_uuid; + bt_gatt_characteristic_property_t props; +#ifdef HPS_GATT_DB + char value[MAX_URI_LENGTH] = { 0 }; + struct hps_char_info *char_info = NULL; + char cp = 0x00; + char status[3] = { 0 }; +#endif + + BT_DBG(""); + + ret = bluetooth_gatt_init(); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to Init GATT %d", ret); + goto fail; + } + + service_uuid = g_strdup(HPS_UUID); + ret = bluetooth_gatt_add_service(service_uuid, &hps_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add service %d", ret); + goto fail; + } + + /* Characteristic URI */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE; + char_uuid = g_strdup(HTTP_URI_UUID); + ret = bluetooth_gatt_add_new_characteristic(hps_obj_path, char_uuid, props, &http_uri_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } + +#ifdef HPS_GATT_DB + ret = bluetooth_gatt_set_characteristic_value(http_uri_obj_path, value, MAX_URI_LENGTH); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } + + /* Store requets information */ + char_info = g_new0(struct hps_char_info, 1); + char_info->char_path = g_strdup(http_uri_obj_path); + _bt_hps_set_char_value(http_uri_obj_path, value, MAX_URI_LENGTH); + hps_char_list = g_slist_append(hps_char_list, char_info); +#endif + + /* Characteristic HTTP Headers */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE; + char_uuid = g_strdup(HTTP_HDR_UUID); + ret = bluetooth_gatt_add_new_characteristic(hps_obj_path, char_uuid, props, &http_hdr_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } +#ifdef HPS_GATT_DB + ret = bluetooth_gatt_set_characteristic_value(http_hdr_obj_path, value, MAX_HEADER_LENGTH); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } + + /* Store Characterisitc information */ + char_info = g_new0(struct hps_char_info, 1); + char_info->char_path = g_strdup(http_hdr_obj_path); + _bt_hps_set_char_value(http_hdr_obj_path, value, MAX_HEADER_LENGTH); + hps_char_list = g_slist_append(hps_char_list, char_info); +#endif + + /* Characteristic HTTP Entity Body */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE; + char_uuid = g_strdup(HTTP_ENTITY_UUID); + ret = bluetooth_gatt_add_new_characteristic(hps_obj_path, char_uuid, props, &http_entity_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } +#ifdef HPS_GATT_DB + ret = bluetooth_gatt_set_characteristic_value(http_entity_obj_path, value, MAX_ENTITY_LENGTH); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } + + /* Store Characterisitc information */ + char_info = g_new0(struct hps_char_info, 1); + char_info->char_path = g_strdup(http_entity_obj_path); + _bt_hps_set_char_value(http_entity_obj_path, value, MAX_ENTITY_LENGTH); + hps_char_list = g_slist_append(hps_char_list, char_info); +#endif + + /* Characteristic HTTP Control Point */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE; + char_uuid = g_strdup(HTTP_CP_UUID); + ret = bluetooth_gatt_add_new_characteristic(hps_obj_path, char_uuid, props, &http_cp_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } +#ifdef HPS_GATT_DB + ret = bluetooth_gatt_set_characteristic_value(http_cp_obj_path, &cp, 1); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } + + /* Store Characterisitc information */ + char_info = g_new0(struct hps_char_info, 1); + char_info->char_path = g_strdup(http_cp_obj_path); + _bt_hps_set_char_value(http_cp_obj_path, &cp, 1); + hps_char_list = g_slist_append(hps_char_list, char_info); +#endif + + /* Characteristic HTTP Status Code */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY; + char_uuid = g_strdup(HTTP_STATUS_UUID); + ret = bluetooth_gatt_add_new_characteristic(hps_obj_path, char_uuid, props, &http_status_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } +#ifdef HPS_GATT_DB + ret = bluetooth_gatt_set_characteristic_value(http_status_obj_path, status, 3); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } +#endif + desc_uuid = g_strdup(HTTP_STATUS_CCC_DESC_UUID); + ret = bluetooth_gatt_add_descriptor(http_status_obj_path, desc_uuid, &http_status_desc_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char descriptor %d", ret); + goto fail; + } +#ifdef HPS_GATT_DB + /* Store Characterisitc information */ + char_info = g_new0(struct hps_char_info, 1); + char_info->char_path = g_strdup(http_status_obj_path); + _bt_hps_set_char_value(http_status_obj_path, status, 3); + hps_char_list = g_slist_append(hps_char_list, char_info); +#endif + + /* Characteristic HTTPS Security */ + props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ | + BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE; + char_uuid = g_strdup(HTTP_SECURITY_UUID); + ret = bluetooth_gatt_add_new_characteristic(hps_obj_path, char_uuid, props, &http_security_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } +#ifdef HPS_GATT_DB + ret = bluetooth_gatt_set_characteristic_value(http_security_obj_path, &cp, 1); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to add new char %d", ret); + goto fail; + } + + /* Store Characterisitc information */ + char_info = g_new0(struct hps_char_info, 1); + char_info->char_path = g_strdup(http_security_obj_path); + _bt_hps_set_char_value(http_security_obj_path, &cp, 1); + hps_char_list = g_slist_append(hps_char_list, char_info); +#endif + + ret = bluetooth_gatt_register_service(hps_obj_path); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to register service %d", ret); + goto fail; + } + + return ret; + +fail: +#ifdef HPS_GATT_DB + delete_all_characterisitc(); + delete_all_notify_read_status(); +#endif + return ret; +} + + +static void _bt_hps_sig_handler(int sig) +{ + BT_DBG(""); + + switch(sig) { + case SIGTERM: + BT_DBG("caught signal - sigterm\n"); + break; + case SIGINT: + BT_DBG("caught signal - sigint\n"); + break; + case SIGKILL: + BT_DBG("caught signal - sigkill\n"); + break; + default: + BT_DBG("caught signal %d and ignored\n",sig); + break; + } +} + +void _bt_hps_exit(void) +{ + int ret; + BT_DBG(""); + + if(g_uri != NULL) { + g_free(g_uri); + g_uri = NULL; + } + + if(g_header != NULL) { + g_free(g_header); + g_header = NULL; + } + + if(g_entity != NULL) { + g_free(g_entity); + g_entity = NULL; + } + + soup_session_abort(hps_soup_session); + g_assert_cmpint(G_OBJECT (hps_soup_session)->ref_count, ==, 1); + g_object_unref(hps_soup_session); + +#ifdef HPS_GATT_DB + delete_all_characterisitc(); +#endif + + ret = bluetooth_gatt_deinit(); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to Deinit GATT %d", ret); + } + + ret = bluetooth_unregister_callback(); + if(ret != BLUETOOTH_ERROR_NONE) { + BT_ERR("Failed to Unregister callback %d", ret); + } + + _bt_hps_deinit_event_receiver(); + + _bt_hps_unregister_interface(); + + if (main_loop != NULL) { + g_main_loop_quit(main_loop); + } +} + +void bt_hps_event_callback(int event, bluetooth_event_param_t* param, + void *user_data) +{ + BT_DBG("HPS event %d", event); + return; +} + +/* HTTP Proxy Service Main loop */ +int main(void) +{ + struct sigaction sa; + + BT_ERR("Starting the bt-httpproxy daemon"); + + /* Values taken from http://www.browserscope.org/ following + * the rule "Do What Every Other Modern Browser Is Doing". They seem + * to significantly improve page loading time compared to soup's + * default values. + * Change MAX_CONNECTIONS_PER_HOST value 6 -> 12, and maxConnections is changed from 35 to 60. + * Enhanced network loading speed apply tunning value. */ + static const int maxConnections = 60; + static const int maxConnectionsPerHost = 12; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = _bt_hps_sig_handler; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGKILL, &sa, NULL); + + // g_type_init is deprecated glib 2.36 onwards, current version id 2.15 + g_type_init(); + +#ifndef HPS_GATT_DB + if(bluetooth_register_callback(bt_hps_event_callback, NULL) != BLUETOOTH_ERROR_NONE) { + BT_ERR("bluetooth_register_callback returned failiure"); + return -3; + } +#endif + + if (_bt_hps_register_interface() != BLUETOOTH_ERROR_NONE) { + BT_ERR("Fail to register http proxy service"); + return -4; + } + + if (_bt_hps_init_event_receiver() != BLUETOOTH_ERROR_NONE) { + BT_ERR("Fail to init event reciever"); + return -5; + } + + hps_soup_session = soup_session_async_new(); + if (hps_soup_session == NULL) { + BT_ERR("Failed to soup_session_async_new"); + return -6; + } + /* Set Soup Session Fetures */ + g_object_set(hps_soup_session, + SOUP_SESSION_MAX_CONNS, maxConnections, + SOUP_SESSION_MAX_CONNS_PER_HOST, maxConnectionsPerHost, + SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER, + SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_SNIFFER, + SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_DEFAULT, + SOUP_SESSION_USE_THREAD_CONTEXT, TRUE, + NULL); + + main_loop = g_main_loop_new(NULL, FALSE); + + g_main_loop_run(main_loop); + + BT_DBG("g_main_loop_quit called!"); + + if (main_loop != NULL) { + g_main_loop_unref(main_loop); + } + + return 0; +} + +#endif diff --git a/bt-httpproxy/bt-httpproxy.h b/bt-httpproxy/bt-httpproxy.h new file mode 100644 index 0000000..43d1b96 --- /dev/null +++ b/bt-httpproxy/bt-httpproxy.h @@ -0,0 +1,102 @@ +/* + * Bluetooth-httpproxy-service + * + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: C S Bhargava + * + * 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_HTTPPROXY_H__ +#define __BT_HTTPPROXY_H__ + +#ifdef HPS_FEATURE + +#define BT_HPS_LE_ADAPTER_INTERFACE "org.bluez.Adapter1" +#define BT_HPS_LE_ADAPTER_PATH "/org/projectx/bt/le/adapter" + +#define BT_HPS_SERVICE_NAME "org.projectx.httpproxy" +#define BT_HPS_OBJECT_PATH "/org/projectx/httpproxy" +#define BT_HPS_INTERFACE_NAME "org.projectx.httpproxy_service" + +#define BT_HPS_CHAR_INTERFACE "org.bluez.GattCharacteristic1" +#define BT_HPS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" + +#define BLE_ENABLED "LeEnabled" +#define BLE_DISABLED "LeDisabled" +#define PROPERTIES_CHANGED "PropertiesChanged" + +/* 512 is the max uri supported by http spec */ +#define MAX_URI_LENGTH 512 +/* 512 is the max Header length supported by http spec */ +#define MAX_HEADER_LENGTH 512 +/* 512 is the max entity body length supported by http spec */ +#define MAX_ENTITY_LENGTH 512 + + +/* HTTP Control Point Commands + OPTIONS, TRACE, CONNECT are not supported +*/ +enum { + HTTP_REQUEST_NONE = 0x00, + HTTP_GET_REQUEST = 0x01, + HTTP_HEAD_REQUEST = 0x02, + HTTP_POST_REQUEST = 0x03, + HTTP_PUT_REQUEST = 0x04, + HTTP_DELETE_REQUEST = 0x05, + HTTPS_GET_REQUEST = 0x06, + HTTPS_HEAD_REQUEST = 0x07, + HTTPS_POST_REQUEST = 0x08, + HTTPS_PUT_REQUEST = 0x09, + HTTPS_DELETE_REQUEST = 0x0A, + HTTP_REQUEST_CANCEL = 0x0B, + HTTP_REQUEST_MAX = HTTP_REQUEST_CANCEL +}; + +enum { + DS_NONE = 0x00, + DS_HEADER_RECEIVED = 0x01, + DS_HEADER_TRUNCATED = 0x02, + DS_BODY_RECEIVED = 0x03, + DS_BODY_TRUNCATED = 0x04, + DS_MAX = DS_BODY_TRUNCATED +}; + +typedef enum http_request_state_tag { + HTTP_REQ_STATE_IDLE = 0x00, + HTTP_REQ_STATE_EXECUTED = HTTP_REQ_STATE_IDLE, + HTTP_REQ_STATE_INPROGRESS = 0x01, +} http_request_state; + + +// Temporary UUIDs. SIG has to define the UUIDs yet. +#define HPS_UUID "00001900-0000-1000-8000-00805f9b34fb" +#define HTTP_URI_UUID "00001901-0000-1000-8000-00805f9b34fb" +#define HTTP_HDR_UUID "00001902-0000-1000-8000-00805f9b34fb" +#define HTTP_ENTITY_UUID "00001903-0000-1000-8000-00805f9b34fb" +#define HTTP_CP_UUID "00001904-0000-1000-8000-00805f9b34fb" +#define HTTP_STATUS_UUID "00001905-0000-1000-8000-00805f9b34fb" +/* CCC descriptor UUID is predefined by SIG */ +#define HTTP_STATUS_CCC_DESC_UUID "2902" +#define HTTP_SECURITY_UUID "00001906-0000-1000-8000-00805f9b34fb" + +void _bt_hps_exit(void); +int _bt_hps_prepare_httpproxy(void); +int _bt_hps_set_advertising_data(void); + + +#endif + +#endif diff --git a/bt-httpproxy/org.projectx.httpproxy.service b/bt-httpproxy/org.projectx.httpproxy.service new file mode 100644 index 0000000..7320fac --- /dev/null +++ b/bt-httpproxy/org.projectx.httpproxy.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.projectx.httpproxy +Exec=/usr/bin/bt-httpproxy +User=root \ No newline at end of file diff --git a/bt-service/CMakeLists.txt b/bt-service/CMakeLists.txt index 2a7b4f2..230f100 100644 --- a/bt-service/CMakeLists.txt +++ b/bt-service/CMakeLists.txt @@ -55,6 +55,7 @@ SET(PKG_MODULES vconf syspopup-caller dbus-glib-1 + dbus-1 gio-2.0 alarm-service capi-content-mime-type @@ -62,6 +63,7 @@ SET(PKG_MODULES pkgmgr cynara-client cynara-creds-gdbus + eventsystem ) IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_NETWORK_TETHERING_ENABLE") @@ -107,6 +109,7 @@ ADD_DEFINITIONS("-DAPPNAME=\"${APP_NAME}\"") ADD_DEFINITIONS("-DAPP_DIR=\"${APP_DIR}\"") ADD_DEFINITIONS("-DAPP_LOCALEDIR=\"${APP_LOCALEDIR}\"") ADD_DEFINITIONS("-DAPP_SYSCONFDIR=\"${APP_SYSCONFDIR}\"") +ADD_DEFINITIONS("-DHPS_FEATURE") IF(LIBNOTIFY_SUPPORT OR LIBNOTIFICATION_SUPPORT) ADD_DEFINITIONS("-DDATA_DIR_ICON=\"${SHARE_INSTALL_PREFIX}\"") @@ -116,6 +119,7 @@ ENDIF(LIBNOTIFY_SUPPORT OR LIBNOTIFICATION_SUPPORT) SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${service_pkgs_LDFLAGS}) # to permit usage of bluetooth_cancel_bonding in bt-popup.c. This build bluetooth-api first. IF(LIBNOTIFY_SUPPORT) diff --git a/bt-service/bt-request-handler.c b/bt-service/bt-request-handler.c index 01c0db5..c0de85c 100755 --- a/bt-service/bt-request-handler.c +++ b/bt-service/bt-request-handler.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -101,6 +102,7 @@ int __bt_obexd_request(int function_name, GVariant *in_param2, GVariant *in_param3, GVariant *in_param4, + GVariant *in_param5, GArray **out_param1); int __bt_agent_request(int function_name, int request_type, @@ -217,7 +219,7 @@ static void __bt_service_method(GDBusConnection *connection, request_type, request_id, invocation, param1, param2, param3, - param4, &out_param1); + param4, param5, &out_param1); break; case BT_AGENT_SERVICE: result = __bt_agent_request(service_function, @@ -700,18 +702,18 @@ int __bt_bluez_request(int function_name, } case BT_LE_CONN_UPDATE: { bluetooth_device_address_t local_address = { {0} }; - bluetooth_le_conn_update_t parameters = {0}; + bluetooth_le_connection_param_t parameters = {0}; __bt_service_get_parameters(in_param1, &local_address, sizeof(bluetooth_device_address_t)); __bt_service_get_parameters(in_param2, ¶meters, - sizeof(bluetooth_le_conn_update_t)); + sizeof(bluetooth_le_connection_param_t)); result = _bt_le_conn_update(local_address.addr, parameters.interval_min, parameters.interval_max, parameters.latency, - parameters.time_out); + parameters.timeout); break; } case BT_IS_ADVERTISING: { @@ -797,6 +799,24 @@ int __bt_bluez_request(int function_name, result = _bt_cancel_bonding(); break; } + case BT_PASSKEY_REPLY: { + const char *passkey = NULL; + gboolean authentication_reply = FALSE; + + passkey = g_variant_get_data(in_param1); + __bt_service_get_parameters(in_param2, + &authentication_reply, sizeof(gboolean)); + result = _bt_passkey_reply(passkey, authentication_reply); + break; + } + case BT_PASSKEY_CONFIRMATION_REPLY: { + gboolean confirmation_reply = FALSE; + + __bt_service_get_parameters(in_param1, + &confirmation_reply, sizeof(gboolean)); + result = _bt_passkey_confirmation_reply(confirmation_reply); + break; + } case BT_UNBOND_DEVICE: { bluetooth_device_address_t address = { {0} }; @@ -882,6 +902,48 @@ int __bt_bluez_request(int function_name, break; } + case BT_SET_PIN_CODE: { + bluetooth_device_address_t address = { {0} }; + bluetooth_device_pin_code_t pin_code = { {0} }; + + __bt_service_get_parameters(in_param1, + &address, sizeof(bluetooth_device_address_t)); + __bt_service_get_parameters(in_param2, + &pin_code, sizeof(bluetooth_device_pin_code_t)); + + result = _bt_set_pin_code(&address, &pin_code); + break; + } + case BT_UNSET_PIN_CODE: { + bluetooth_device_address_t address = { {0} }; + + __bt_service_get_parameters(in_param1, + &address, sizeof(bluetooth_device_address_t)); + + result = _bt_unset_pin_code(&address); + break; + } + case BT_UPDATE_LE_CONNECTION_MODE: { + bluetooth_device_address_t remote_address = { { 0 } }; + bluetooth_le_connection_param_t param = { 0 }; + bluetooth_le_connection_mode_t mode = BLUETOOTH_LE_CONNECTION_MODE_BALANCED; + + __bt_service_get_parameters(in_param1, &remote_address, + sizeof(bluetooth_device_address_t)); + __bt_service_get_parameters(in_param2, &mode, + sizeof(bluetooth_le_connection_mode_t)); + + result = _bt_get_le_connection_parameter(mode, ¶m); + if (result != BLUETOOTH_ERROR_NONE) + break; + + result = _bt_le_conn_update(remote_address.addr, + param.interval_min, + param.interval_max, + param.latency, + param.timeout); + break; + } case BT_HID_CONNECT: { bluetooth_device_address_t address = { {0} }; @@ -1330,7 +1392,7 @@ int __bt_bluez_request(int function_name, char *uuid; int socket_fd = -1; - sender = dbus_g_method_get_sender(context); + sender = (char *)g_dbus_method_invocation_get_sender(context); uuid = &g_array_index(in_param1, char, 0); result = _bt_rfcomm_create_socket(sender, uuid); @@ -1417,8 +1479,11 @@ int __bt_bluez_request(int function_name, __bt_service_get_parameters(in_param2, &auto_connect, sizeof(gboolean)); - result = _bt_connect_le_device(&address, auto_connect); - + result = _bt_connect_le_device(request_id, &address, auto_connect); + if (result != BLUETOOTH_ERROR_NONE) { + g_array_append_vals(*out_param1, &address, + sizeof(bluetooth_device_address_t)); + } break; } case BT_DISCONNECT_LE: { @@ -1427,8 +1492,11 @@ int __bt_bluez_request(int function_name, __bt_service_get_parameters(in_param1, &address, sizeof(bluetooth_device_address_t)); - result = _bt_disconnect_le_device(&address); - + result = _bt_disconnect_le_device(request_id, &address); + if (result != BLUETOOTH_ERROR_NONE) { + g_array_append_vals(*out_param1, &address, + sizeof(bluetooth_device_address_t)); + } break; } case BT_SET_LE_PRIVACY: { @@ -1452,6 +1520,49 @@ int __bt_bluez_request(int function_name, case BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR: /* Just call to check the privilege */ break; +#ifndef GATT_NO_RELAY + case BT_GATT_WATCH_CHARACTERISTIC: { + char *sender = NULL; + + sender = (char *)g_dbus_method_invocation_get_sender(context); + + result = _bt_insert_gatt_client_sender(sender); + + break; + } + case BT_GATT_UNWATCH_CHARACTERISTIC: { + char *sender = NULL; + + sender = (char *)g_dbus_method_invocation_get_sender(context); + + result = _bt_delete_gatt_client_sender(sender); + + break; + } +#endif + case BT_LE_IPSP_INIT: + result = _bt_initialize_ipsp(); + break; + case BT_LE_IPSP_DEINIT: + result = _bt_deinitialize_ipsp(); + break; + case BT_LE_IPSP_CONNECT: { + bluetooth_device_address_t address = { {0} }; + __bt_service_get_parameters(in_param1, &address, + sizeof(bluetooth_device_address_t)); + + result = _bt_connect_le_ipsp_device(&address); + break; + } + case BT_LE_IPSP_DISCONNECT: { + bluetooth_device_address_t address = { {0} }; + + __bt_service_get_parameters(in_param1, &address, + sizeof(bluetooth_device_address_t)); + + result = _bt_disconnect_le_ipsp_device(&address); + break; + } case BT_LE_READ_MAXIMUM_DATA_LENGTH: { bluetooth_le_read_maximum_data_length_t max_le_datalength = {0}; @@ -1515,6 +1626,7 @@ int __bt_obexd_request(int function_name, GVariant *in_param2, GVariant *in_param3, GVariant *in_param4, + GVariant *in_param5, GArray **out_param1) { BT_DBG("+"); @@ -1531,6 +1643,14 @@ int __bt_obexd_request(int function_name, bt_file_path_t path; char **file_path; int file_count; + GDBusProxy *process_proxy; + guint owner_pid = 0; + int opp_server_pid = 0; + gchar *owner_sender_name; + GDBusConnection *owner_connection = NULL; + GVariant *val_get = NULL; + GError *error_connection = NULL; + GError *errro_proxy = NULL; GArray *param2; __bt_service_get_parameters(in_param1, &address, @@ -1547,17 +1667,77 @@ int __bt_obexd_request(int function_name, path = g_array_index(param2, bt_file_path_t, i); file_path[i] = g_strdup(path.path); } - BT_DBG("_bt_opp_client_push_files"); - result = _bt_opp_client_push_files(request_id, context, - &address, file_path, - file_count); + + owner_connection = g_dbus_method_invocation_get_connection(context); + owner_sender_name = g_dbus_method_invocation_get_sender(context); + + BT_DBG("sender = %s", owner_sender_name); + + process_proxy = g_dbus_proxy_new_sync(owner_connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + NULL, &error_connection); + + if(process_proxy == NULL) + BT_DBG("Fail to get process_proxy"); + + if (error_connection) { + BT_DBG("Fail to get proxy : %s", error_connection->message); + g_error_free(error_connection); + error_connection = NULL; + } + + if (process_proxy) { + val_get = g_dbus_proxy_call_sync(process_proxy, + "GetConnectionUnixProcessID", + g_variant_new("(s)", owner_sender_name), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, + &errro_proxy); + + if (val_get == NULL) { + BT_DBG("Fail to get pid"); + } else { + g_variant_get(val_get, "(u)", &owner_pid); + BT_DBG("request is from pid %d\n", owner_pid); + } + + if (errro_proxy) { + g_error("Unable to get PID for %s: %s", + owner_sender_name, errro_proxy->message); + g_error_free(errro_proxy); + errro_proxy = NULL; + } + } else { + BT_DBG("fail to get proxy"); + } + + opp_server_pid = _bt_obex_get_native_pid(); + + BT_DBG("owner_pid, agent_info.native_server->app_pid = %d, %d", + owner_pid, opp_server_pid); + if (opp_server_pid == owner_pid) { + BT_DBG("The exception case : _bt_opp_client_push_files"); + result = _bt_opp_client_push_files(request_id, context, + &address, file_path, + file_count); + } else { + BT_DBG("normal case"); + result = _bt_opp_client_push_files(request_id, context, + &address, file_path, + file_count); + } for (i = 0; i < file_count; i++) { g_free(file_path[i]); } g_free(file_path); g_array_free(param2, TRUE); - + if (process_proxy) + g_object_unref(process_proxy); break; } case BT_OPP_CANCEL_PUSH: { @@ -1587,7 +1767,6 @@ int __bt_obexd_request(int function_name, sizeof(gboolean)); __bt_service_get_parameters(in_param3, &app_pid, sizeof(int)); - result = _bt_obex_server_allocate(sender, path, app_pid, is_native); @@ -1629,7 +1808,6 @@ int __bt_obexd_request(int function_name, char *file_name; file_name = (char *)g_variant_get_data(in_param1); - result = _bt_obex_server_accept_authorize(file_name, TRUE); break; @@ -1647,8 +1825,8 @@ int __bt_obexd_request(int function_name, __bt_service_get_parameters(in_param2, &is_native, sizeof(gboolean)); - result = _bt_obex_server_set_destination_path(destination_path, - is_native); + result = _bt_obex_server_set_destination_path( + destination_path, is_native); break; } diff --git a/bt-service/bt-service-adapter-le.c b/bt-service/bt-service-adapter-le.c index 09ae374..780483f 100755 --- a/bt-service/bt-service-adapter-le.c +++ b/bt-service/bt-service-adapter-le.c @@ -22,8 +22,7 @@ */ #include -//#include -//#include +#include #include #include #include @@ -87,6 +86,82 @@ static gboolean is_le_scanning = FALSE; static gboolean scan_filter_enabled = FALSE; static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN; +static GSList *gatt_client_senders = NULL; + + +gboolean _bt_is_set_scan_parameter(void) +{ + return is_le_set_scan_parameter; +} + +void _bt_init_gatt_client_senders(void) +{ + _bt_clear_request_list(); +} + +int _bt_insert_gatt_client_sender(char *sender) +{ + char *info; + + retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM); + + info = g_strdup(sender); + retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION); + + gatt_client_senders = g_slist_append(gatt_client_senders, info); + + BT_DBG("insert sender: %s", sender); + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_delete_gatt_client_sender(char *sender) +{ + GSList *l; + char *info; + + BT_DBG("remove sender: %s", sender); + + for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) { + info = l->data; + if (info == NULL) + continue; + + if (g_strcmp0(info, sender) == 0) { + BT_DBG("remove info"); + gatt_client_senders = g_slist_remove(gatt_client_senders, info); + g_free(info); + return BLUETOOTH_ERROR_NONE; + } + } + + return BLUETOOTH_ERROR_NOT_FOUND; +} + +void _bt_clear_gatt_client_senders(void) +{ + if (gatt_client_senders) { + g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL); + g_slist_free(gatt_client_senders); + gatt_client_senders = NULL; + } +} + +static void __bt_send_foreach_event(gpointer data, gpointer user_data) +{ + char *sender = data; + GVariant *param = user_data; + + _bt_send_event_to_dest(sender, BT_DEVICE_EVENT,BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, + param); +} + +void _bt_send_char_value_changed_event(void *param) +{ + g_slist_foreach(gatt_client_senders, __bt_send_foreach_event, + (gpointer)param); +} + void __bt_free_le_adv_slot(void) { int i; @@ -724,7 +799,7 @@ int __bt_get_available_scan_filter_slot_id(void) bt_adapter_le_scanner_t *scanner; GSList *fl; bluetooth_le_scan_filter_t *filter_data; - gboolean *slot_check_list; + gboolean *slot_check_list = NULL; int i; if (le_feature_info.max_filter == 0) { @@ -732,6 +807,10 @@ int __bt_get_available_scan_filter_slot_id(void) return -1; } slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter); + if (slot_check_list == NULL) { + BT_ERR("Fail to allocate memory"); + return -1; + } for (l = scanner_list; l != NULL; l = g_slist_next(l)) { scanner = l->data; @@ -760,12 +839,12 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil GDBusProxy *proxy; GError *error = NULL; GVariant *ret, *param; - GVariant *arr_uuid_param, *arr_uuid_mask_param; - GVariant *arr_data_param, *arr_data_mask_param; - GArray *arr_uuid; - GArray *arr_uuid_mask; - GArray *arr_data; - GArray *arr_data_mask; + GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL; + GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL; + GArray *arr_uuid = NULL; + GArray *arr_uuid_mask = NULL; + GArray *arr_data = NULL; + GArray *arr_data_mask = NULL; bt_adapter_le_scanner_t *scanner = NULL; bluetooth_le_scan_filter_t *filter_data = NULL; int feature_selection = 0; @@ -777,31 +856,26 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8)); - arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8)); - arr_data = g_array_new(TRUE, TRUE, sizeof(guint8)); - arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8)); - - arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->service_uuid.data_len * sizeof(guint8), TRUE, NULL, NULL); - arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid_mask, filter->service_uuid_mask.data_len * sizeof(guint8), TRUE, NULL, NULL); - arr_data_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_data, filter->service_data.data_len * sizeof(guint8), TRUE, NULL, NULL); - arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_data_mask, filter->service_data_mask.data_len * sizeof(guint8), TRUE, NULL, NULL); - if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) { char address[BT_ADDRESS_STRING_SIZE] = { 0 }; feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS; _bt_convert_addr_type_to_string(address, filter->device_address.addr); + arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_data_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + param = g_variant_new("(iiiiii@ay@aysu@ay@ay)", 0, // client_if 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02) BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type - slot_id, // filter_index + *slot_id, // filter_index 0, // company_id 0, // company_id_mask arr_uuid_param, // p_uuid @@ -826,11 +900,20 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) { feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME; + arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_data_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + param = g_variant_new("(iiiiii@ay@aysu@ay@ay)", 0, // client_if 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02) BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type - slot_id, // filter_index + *slot_id, // filter_index 0, // company_id 0, // company_id_mask arr_uuid_param, // p_uuid @@ -855,19 +938,26 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) { feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID; + arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8)); + arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8)); + g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8)); g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8)); arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->service_uuid.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL); arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->service_uuid_mask.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL); + arr_data_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); param = g_variant_new("(iiiiii@ay@aysu@ay@ay)", 0, // client_if 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02) BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type - slot_id, // filter_index + *slot_id, // filter_index 0, // company_id 0, // company_id_mask arr_uuid_param, // p_uuid @@ -887,24 +977,36 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil } if (ret) g_variant_unref(ret); + + g_array_free(arr_uuid, TRUE); + g_array_free(arr_uuid_mask, TRUE); + g_array_free(arr_data, TRUE); + g_array_free(arr_data_mask, TRUE); } if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) { feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID; + arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8)); + arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8)); + g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8)); g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8)); arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->service_solicitation_uuid.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL); arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL); + arr_data_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); param = g_variant_new("(iiiiii@ay@aysu@ay@ay)", 0, // client_if 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02) BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type - slot_id, // filter_index + *slot_id, // filter_index 0, // company_id 0, // company_id_mask arr_uuid_param, // p_uuid @@ -924,24 +1026,34 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil } if (ret) g_variant_unref(ret); + + g_array_free(arr_uuid, TRUE); + g_array_free(arr_uuid_mask, TRUE); } if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) { feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA; + arr_data = g_array_new(TRUE, TRUE, sizeof(guint8)); + arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8)); + g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8)); g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8)); + arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); arr_data_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->service_data.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_data->data, arr_data->len, TRUE, NULL, NULL); arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->service_data_mask.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL); param = g_variant_new("(iiiiii@ay@aysu@ay@ay)", 0, // client_if 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02) BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type - slot_id, // filter_index + *slot_id, // filter_index 0, // company_id 0, // company_id_mask arr_uuid_param, // p_uuid @@ -961,24 +1073,34 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil } if (ret) g_variant_unref(ret); + + g_array_free(arr_data, TRUE); + g_array_free(arr_data_mask, TRUE); } if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) { feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA; + arr_data = g_array_new(TRUE, TRUE, sizeof(guint8)); + arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8)); + g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8)); g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8)); + arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); + arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay", + NULL, 0, TRUE, NULL, NULL); arr_data_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->manufacturer_data.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_data->data, arr_data->len, TRUE, NULL, NULL); arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay", - arr_uuid, filter->manufacturer_data_mask.data_len * sizeof(guint8), TRUE, NULL, NULL); + arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL); param = g_variant_new("(iiiiii@ay@aysu@ay@ay)", 0, // client_if 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02) BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type - slot_id, // filter_index + *slot_id, // filter_index filter->manufacturer_id, // company_id 0xFFFF, // company_id_mask arr_uuid_param, // p_uuid @@ -998,19 +1120,17 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil } if (ret) g_variant_unref(ret); - } - g_array_free(arr_uuid, TRUE); - g_array_free(arr_uuid_mask, TRUE); - g_array_free(arr_data, TRUE); - g_array_free(arr_data_mask, TRUE); + g_array_free(arr_data, TRUE); + g_array_free(arr_data_mask, TRUE); + } BT_DBG("Filter selection %.2x", feature_selection); param = g_variant_new("(iiiiiiiiiiii)", 0, // client_if 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02) - slot_id, // filter_index + *slot_id, // filter_index feature_selection, // feat_seln 0, // list_logic_type (OR - 0x00, AND - 0x01) 1, // filt_logic_type (OR - 0x00, AND - 0x01) @@ -1032,15 +1152,20 @@ int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *fil scanner = __bt_find_scanner_from_list(sender); if (scanner == NULL) { scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t)); - scanner->sender = strdup(sender); - scanner_list = g_slist_append(scanner_list, scanner); + if (scanner) { + scanner->sender = strdup(sender); + scanner_list = g_slist_append(scanner_list, scanner); + } } filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t)); - memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t)); - filter_data->slot_id = *slot_id; + if (filter_data) { + memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t)); + filter_data->slot_id = *slot_id; - scanner->filter_list = g_slist_append(scanner->filter_list, filter_data); + if (scanner) + scanner->filter_list = g_slist_append(scanner->filter_list, filter_data); + } if (ret) g_variant_unref(ret); @@ -1144,6 +1269,8 @@ int _bt_start_le_scan(const char *sender) if (scanner == NULL) { scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t)); + retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL); + scanner->sender = strdup(sender); scanner_list = g_slist_append(scanner_list, scanner); } @@ -1152,6 +1279,7 @@ int _bt_start_le_scan(const char *sender) BT_ERR("BT is already in LE scanning"); return BLUETOOTH_ERROR_IN_PROGRESS; } + scanner->is_scanning = TRUE; proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1178,14 +1306,12 @@ int _bt_start_le_scan(const char *sender) } else { BT_INFO("LE Full Scan is already on progress"); } - - scanner->is_scanning = TRUE; return BLUETOOTH_ERROR_NONE; } else { if (is_le_set_scan_parameter == FALSE) { /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */ bluetooth_le_scan_params_t scan_params; - scan_params.type = 1; + scan_params.type = BT_LE_ACTIVE_SCAN; scan_params.interval = 5000; scan_params.window = 500; _bt_set_scan_parameters(&scan_params); @@ -1223,8 +1349,6 @@ int _bt_start_le_scan(const char *sender) if (ret) g_variant_unref(ret); - - scanner->is_scanning = TRUE; return BLUETOOTH_ERROR_NONE; } @@ -1814,15 +1938,78 @@ int _bt_clear_white_list(void) return BLUETOOTH_ERROR_NONE; } +int _bt_initialize_ipsp(void) +{ + BT_DBG("+"); + GDBusProxy *proxy; + GError *error = NULL; + GVariant *ret; + + if (_bt_adapter_get_status() != BT_ACTIVATED && + _bt_adapter_get_le_status() != BT_LE_ACTIVATED) { + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } + + proxy = _bt_get_adapter_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp", + NULL,G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (error) { + BT_ERR("Initialize IPSP Failed :[%s]", error->message); + g_clear_error(&error); + return BLUETOOTH_ERROR_INTERNAL; + } + if (ret) + g_variant_unref(ret); + + BT_INFO("IPSP initialization called successfully"); + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_deinitialize_ipsp(void) +{ + BT_DBG("+"); + GDBusProxy *proxy; + GError *error = NULL; + GVariant *ret; + bt_le_status_t le_status = _bt_adapter_get_le_status(); + + if (_bt_adapter_get_status() != BT_ACTIVATED && + _bt_adapter_get_le_status() != BT_LE_ACTIVATED) { + return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED; + } + + proxy = _bt_get_adapter_proxy(); + retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp", + NULL,G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (error) { + BT_ERR("De-Initialize IPSP Failed :[%s]", error->message); + g_clear_error(&error); + return BLUETOOTH_ERROR_INTERNAL; + } + if (ret) + g_variant_unref(ret); + + BT_INFO("IPSP De-initialization called successfully"); + + return BLUETOOTH_ERROR_NONE; +} + int _bt_le_read_maximum_data_length( bluetooth_le_read_maximum_data_length_t *max_le_datalength) { GError *error = NULL; GDBusProxy *proxy; GVariant *reply = NULL; + int ret = BLUETOOTH_ERROR_NONE; guint16 max_tx_octets, max_tx_time; guint16 max_rx_octets, max_rx_time; - int err; proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1842,21 +2029,16 @@ int _bt_le_read_maximum_data_length( return BLUETOOTH_ERROR_INTERNAL; } - g_variant_get(reply ,"(qqqqi)", &max_tx_octets, &max_tx_time, - &max_rx_octets, &max_rx_time, &err); - - g_variant_unref(reply); - - if (err) { - BT_DBG("error is : %d", err); - return BLUETOOTH_ERROR_INTERNAL; - } + g_variant_get(reply ,"(qqqq)", &max_tx_octets, &max_tx_time, + &max_rx_octets, &max_rx_time); max_le_datalength->max_tx_octets = max_tx_octets; max_le_datalength->max_tx_time = max_tx_time; max_le_datalength->max_rx_octets = max_rx_octets; max_le_datalength->max_rx_time = max_rx_time; + g_variant_unref(reply); + return BLUETOOTH_ERROR_NONE; } int _bt_le_write_host_suggested_default_data_length( @@ -1865,6 +2047,7 @@ int _bt_le_write_host_suggested_default_data_length( GError *error = NULL; GDBusProxy *proxy; GVariant *reply = NULL; + int ret = BLUETOOTH_ERROR_NONE; proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1900,8 +2083,8 @@ int _bt_le_read_host_suggested_default_data_length( GError *error = NULL; GDBusProxy *proxy; GVariant *reply = NULL; + int ret = BLUETOOTH_ERROR_NONE; guint16 def_tx_octets, def_tx_time; - int err; proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1919,18 +2102,13 @@ int _bt_le_read_host_suggested_default_data_length( return BLUETOOTH_ERROR_INTERNAL; } - g_variant_get(reply ,"(qqi)", &def_tx_octets, &def_tx_time, &err); - - g_variant_unref(reply); - - if (err) { - BT_DBG("error is : %d", err); - return BLUETOOTH_ERROR_INTERNAL; - } + g_variant_get(reply ,"(qq)", &def_tx_octets, &def_tx_time); def_data_length->def_tx_octets = def_tx_octets; def_data_length->def_tx_time = def_tx_time; + g_variant_unref(reply); + return BLUETOOTH_ERROR_NONE; } @@ -1938,6 +2116,9 @@ int _bt_le_set_data_length(bluetooth_device_address_t *device_address, const unsigned int max_tx_Octets, const unsigned int max_tx_Time) { GError *error = NULL; + GDBusProxy *proxy; + GVariant *reply = NULL; + int ret = BLUETOOTH_ERROR_NONE; guint16 txOctets = max_tx_Octets; guint16 txTime = max_tx_Time; char address[BT_ADDRESS_STRING_SIZE] = { 0 }; @@ -1947,9 +2128,7 @@ int _bt_le_set_data_length(bluetooth_device_address_t *device_address, _bt_convert_addr_type_to_string(address, device_address->addr); - device_path = _bt_get_device_object_path(address); - - BT_DBG("devic path is %s", device_path); + device_path = _bt_get_device_object_path(&address); if (device_path == NULL) { BT_DBG("Device path is null"); @@ -1960,7 +2139,7 @@ int _bt_le_set_data_length(bluetooth_device_address_t *device_address, if (conn == NULL) { BT_ERR("conn == NULL"); g_free(device_path); - return BLUETOOTH_ERROR_INTERNAL; + return NULL; } device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, @@ -1987,4 +2166,4 @@ int _bt_le_set_data_length(bluetooth_device_address_t *device_address, } return BLUETOOTH_ERROR_NONE; -} \ No newline at end of file +} diff --git a/bt-service/bt-service-adapter.c b/bt-service/bt-service-adapter.c index d7725ac..685d437 100644 --- a/bt-service/bt-service-adapter.c +++ b/bt-service/bt-service-adapter.c @@ -33,11 +33,8 @@ #include #include #include - #include -#if 0 #include -#endif #include #include "alarm.h" @@ -224,14 +221,14 @@ int __bt_set_visible_time(int timeout) visible_timer.timeout = timeout; - if (timeout <= 0) - return BLUETOOTH_ERROR_NONE; - #ifndef TIZEN_WEARABLE if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0) BT_ERR("Set vconf failed"); #endif + if (timeout <= 0) + return BLUETOOTH_ERROR_NONE; + if (!visible_timer.alarm_init) { /* Set Alarm timer to switch off BT */ result = alarmmgr_init("bt-service"); @@ -480,6 +477,12 @@ static void __bt_set_visible_mode(void) if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0) BT_ERR("Set vconf failed"); } + } else { + if (_bt_set_discoverable_mode( + BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, + timeout) != BLUETOOTH_ERROR_NONE) { + BT_ERR("Set connectable mode failed"); + } } } #endif @@ -560,11 +563,9 @@ void _bt_set_disabled(int result) ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode); /* Update the vconf BT status in normal Deactivation case only */ - -#if 0 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE && ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) { -#endif + BT_DBG("Update vconf for BT normal Deactivation"); if (result == BLUETOOTH_ERROR_TIMEOUT) @@ -574,12 +575,11 @@ void _bt_set_disabled(int result) /* Update Bluetooth Status to notify other modules */ if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0) BT_ERR("Set vconf failed"); -#if 0 + if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE, EVT_VAL_BT_OFF) != ES_R_OK) BT_ERR("Fail to set value"); -#endif -// + } if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0) BT_ERR("Set vconf failed\n"); @@ -607,11 +607,9 @@ static int __bt_set_le_enabled(void) if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0) BT_ERR("Set vconf failed\n"); -#if 0 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE, EVT_VAL_BT_LE_ON) != ES_R_OK) BT_ERR("Fail to set value"); -#endif /* Send enabled event to API */ /* @@ -647,21 +645,17 @@ void _bt_set_le_disabled(int result) /* Update Bluetooth Status to notify other modules */ BT_DBG("Update vconf for BT LE normal Deactivation"); - if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0) BT_ERR("Set vconf failed\n"); _bt_adapter_set_le_status(BT_LE_DEACTIVATED); -#if 0 + if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE, EVT_VAL_BT_LE_OFF) != ES_R_OK) BT_ERR("Fail to set value"); -#endif - if (_bt_adapter_get_status() != BT_DEACTIVATED) { - /* Send disabled event */ - _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED, - g_variant_new_int32(result)); - } + /* Send disabled event */ + _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED, + g_variant_new_int32(result)); } void *_bt_get_adapter_agent(void) @@ -824,10 +818,12 @@ void _bt_handle_adapter_added(void) if (ret < 0) BT_ERR("Unable to register key handler"); - if (le_status == BT_LE_ACTIVATING) { + if (le_status == BT_LE_ACTIVATING || + status == BT_ACTIVATING) { __bt_set_le_enabled(); _bt_adapter_set_le_status(BT_LE_ACTIVATED); } + if (status == BT_ACTIVATING) { __bt_set_enabled(); _bt_adapter_set_status(BT_ACTIVATED); @@ -837,13 +833,12 @@ void _bt_handle_adapter_added(void) #endif _bt_service_register_vconf_handler(); -#if 0 + /* eventsystem */ if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id, (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) { BT_ERR("Fail to register system event"); } -#endif } void _bt_handle_adapter_removed(void) @@ -872,11 +867,10 @@ void _bt_handle_adapter_removed(void) adapter_agent = NULL; _bt_reliable_terminate_service(NULL); -#if 0 + if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) { BT_ERR("Fail to unregister system event"); } -#endif } @@ -916,7 +910,6 @@ static gboolean __bt_enable_timeout_cb(gpointer user_data) } g_variant_unref(result); - _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT); _bt_terminate_service(NULL); @@ -959,7 +952,6 @@ static gboolean __bt_enable_le_timeout_cb(gpointer user_data) } g_variant_unref(result); - _bt_adapter_set_le_status(BT_LE_DEACTIVATED); _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT); @@ -996,17 +988,6 @@ void _bt_adapter_start_enable_timer(void) return; } -static gboolean __bt_adapter_enabled_cb(gpointer user_data) -{ - BT_DBG("+"); - - __bt_set_enabled(); - _bt_adapter_set_status(BT_ACTIVATED); - - return FALSE; -} - - int _bt_enable_adapter(void) { GDBusProxy *proxy; @@ -1092,7 +1073,6 @@ int _bt_enable_adapter(void) return BLUETOOTH_ERROR_INTERNAL; } g_variant_unref(result); - if (le_status == BT_LE_ACTIVATED) { __bt_set_enabled(); } else { @@ -1243,7 +1223,6 @@ int __bt_disable_cb(void) } g_variant_unref(result); - return BLUETOOTH_ERROR_NONE; } @@ -1543,7 +1522,6 @@ int _bt_disable_adapter_le(void) } g_variant_unref(result); - _bt_set_le_disabled(BLUETOOTH_ERROR_NONE); BT_DBG("le status : %d", _bt_adapter_get_le_status()); BT_DBG("-"); @@ -1749,7 +1727,7 @@ int _bt_is_service_used(char *service_uuid, gboolean *used) int ret = BLUETOOTH_ERROR_NONE; GVariant *result; GVariant *value; - GVariantIter *iter; + GVariantIter *iter = NULL; gchar *uuid; BT_DBG("+"); @@ -1779,8 +1757,7 @@ int _bt_is_service_used(char *service_uuid, gboolean *used) g_variant_get(result, "(v)", &value); g_variant_get(value, "as", &iter); - - if (iter == NULL) { + if(iter == NULL) { BT_ERR("Failed to get UUIDs(%s)",service_uuid); *used = FALSE; g_variant_unref(result); @@ -1832,7 +1809,7 @@ static gboolean __bt_get_discoverable_property(void) g_clear_error(&error); } else BT_ERR("Failed to get Discoverable property"); - return FALSE; + return BLUETOOTH_ERROR_INTERNAL; } g_variant_get(result, "(v)", &temp); @@ -2580,8 +2557,3 @@ int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data) return BLUETOOTH_ERROR_NONE; } - -int _bt_get_enable_timer_id(void) -{ - return timer_id; -} diff --git a/bt-service/bt-service-agent.c b/bt-service/bt-service-agent.c index 53d386f..8370a33 100644 --- a/bt-service/bt-service-agent.c +++ b/bt-service/bt-service-agent.c @@ -90,6 +90,8 @@ extern guint nap_connected_device_count; g_variant_unref(variant); \ variant = NULL +static gboolean syspopup_mode = TRUE; + static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address, const gchar *name); static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class); @@ -468,6 +470,8 @@ static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device) GVariant *reply = NULL; GVariant *reply_temp = NULL; GVariant *tmp_value; + GVariant *param; + int result = BLUETOOTH_ERROR_NONE; BT_DBG("+"); @@ -525,14 +529,31 @@ static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device) gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000", NULL); #else - _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, - name, str_passkey, NULL, - _gap_agent_get_path(agent)); + if (syspopup_mode) { + BT_DBG("LAUNCH SYSPOPUP"); + _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, + name, str_passkey, NULL, + _gap_agent_get_path(agent)); + } else { + BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY"); + param = g_variant_new("(isss)", result, address, name, str_passkey); + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param); + } #endif } else { BT_DBG("Show Pin entry"); - _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL, + + if (syspopup_mode) { + BT_DBG("LAUNCH SYSPOPUP"); + _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL, NULL, _gap_agent_get_path(agent)); + } else { + BT_DBG("Send BLUETOOTH_EVENT_PIN_REQUEST"); + param = g_variant_new("(iss)", result, address, name); + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_PIN_REQUEST, param); + } } done: @@ -581,8 +602,19 @@ static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device) gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000", NULL); #else - _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL, - _gap_agent_get_path(agent)); + if (syspopup_mode) { + BT_DBG("LAUNCH SYSPOPUP"); + _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL, + _gap_agent_get_path(agent)); + } else { + int result = BLUETOOTH_ERROR_NONE; + GVariant *param; + + BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_REQUEST"); + param = g_variant_new("(iss)", result, address, name); + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_PASSKEY_REQUEST, param); + } #endif done: @@ -635,9 +667,21 @@ static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device, gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, str_passkey, NULL); #else - _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name, - str_passkey, NULL, - _gap_agent_get_path(agent)); + if (syspopup_mode) { + BT_DBG("LAUNCH SYSPOPUP"); + _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name, + str_passkey, NULL, + _gap_agent_get_path(agent)); + } else { + int result = BLUETOOTH_ERROR_NONE; + GVariant *param; + + BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY"); + param = g_variant_new("(isss)", result, address, name, str_passkey); + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param); + } + #endif g_free(str_passkey); @@ -721,10 +765,20 @@ static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device, BT_DBG("Confirm reply"); gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL); #else - BT_DBG("LAUNCH SYSPOPUP"); - _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name, - str_passkey, NULL, - _gap_agent_get_path(agent)); + if (syspopup_mode) { + BT_DBG("LAUNCH SYSPOPUP"); + _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name, + str_passkey, NULL, + _gap_agent_get_path(agent)); + } else { + int result = BLUETOOTH_ERROR_NONE; + GVariant *param; + + BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST"); + param = g_variant_new("(isss)", result, address, name, str_passkey); + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param); + } #endif #endif @@ -740,6 +794,7 @@ done: static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address) { BT_DBG("On Going Pairing is cancelled by remote\n"); + #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT) syspopup_destroy_all(); #endif @@ -900,7 +955,7 @@ fail: NULL) == TRUE) { _bt_send_event(BT_OPP_SERVER_EVENT, BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE, - g_variant_new("iss", result, address, name)); + g_variant_new("(iss)", result, address, name)); goto done; } @@ -911,10 +966,12 @@ fail: osp_serv = _gap_agent_get_osp_server(agent, BT_RFCOMM_SERVER, (char *)uuid); - _bt_send_event(BT_RFCOMM_SERVER_EVENT, - BLUETOOTH_EVENT_RFCOMM_AUTHORIZE, - g_variant_new("issssn", result, address, uuid, - name, osp_serv->path, osp_serv->fd)); + if (osp_serv) { + _bt_send_event(BT_RFCOMM_SERVER_EVENT, + BLUETOOTH_EVENT_RFCOMM_AUTHORIZE, + g_variant_new("(issssn)", result, address, uuid, + name, osp_serv->path, osp_serv->fd)); + } goto done; } diff --git a/bt-service/bt-service-audio.c b/bt-service/bt-service-audio.c index 9bda3f2..ec9e9ab 100644 --- a/bt-service/bt-service-audio.c +++ b/bt-service/bt-service-audio.c @@ -735,6 +735,7 @@ int _bt_audio_disconnect(int request_id, int type, _bt_convert_addr_type_to_string(address, device_address->addr); func_data = g_malloc0(sizeof(bt_audio_function_data_t)); + retv_if(func_data == NULL, BLUETOOTH_ERROR_INTERNAL); func_data->address = g_strdup(address); func_data->req_id = request_id; diff --git a/bt-service/bt-service-avrcp.c b/bt-service/bt-service-avrcp.c index 0db7daf..49397e2 100644 --- a/bt-service/bt-service-avrcp.c +++ b/bt-service/bt-service-avrcp.c @@ -155,7 +155,7 @@ static void __bt_avrcp_agent_method(GDBusConnection *connection, gchar *interface = NULL; gchar *property = NULL; gchar *loop_status = NULL; - GVariant *value; + GVariant *value = NULL; if (g_strcmp0(method_name, "Set") == 0) { g_variant_get(parameters, "(&s&sv)", &interface, &property, @@ -167,6 +167,11 @@ static void __bt_avrcp_agent_method(GDBusConnection *connection, } } + if (value == NULL) { + BT_ERR("value is NULL"); + goto fail; + } + BT_DBG("Property: %s\n", property); if (g_strcmp0(property, "Shuffle") == 0) { @@ -215,7 +220,8 @@ static void __bt_avrcp_agent_method(GDBusConnection *connection, return; fail: - g_variant_unref(value); + if (value) + g_variant_unref(value); err = __bt_avrcp_set_error(ret); g_dbus_method_invocation_return_gerror(invocation, err); g_clear_error(&err); diff --git a/bt-service/bt-service-common.c b/bt-service/bt-service-common.c index c5ffe0f..f06b161 100644 --- a/bt-service/bt-service-common.c +++ b/bt-service/bt-service-common.c @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include #include @@ -39,9 +37,7 @@ #include #include #include -#if 0 #include -#endif #include "bluetooth-api.h" #include "bt-service-common.h" @@ -61,11 +57,7 @@ GDBusConnection *_bt_gdbus_init_system_gconn(void) { GError *error = NULL; - if (!g_thread_supported()) { - g_thread_init(NULL); - } - -// dbus_g_thread_init(); + dbus_threads_init_default(); g_type_init(); @@ -139,6 +131,9 @@ static GDBusProxy *__bt_init_adapter_proxy(void) retv_if(system_conn == NULL, NULL); } + manager_proxy = _bt_get_manager_proxy(); + retv_if(manager_proxy == NULL, NULL); + adapter_path = _bt_get_adapter_path(); retv_if(adapter_path == NULL, NULL); @@ -168,6 +163,9 @@ static GDBusProxy *__bt_init_adapter_properties_proxy(void) retv_if(system_conn == NULL, NULL); } + manager_proxy = _bt_get_manager_proxy(); + retv_if(manager_proxy == NULL, NULL); + adapter_path = _bt_get_adapter_path(); retv_if(adapter_path == NULL, NULL); @@ -299,13 +297,12 @@ static char *__bt_extract_adapter_path(GVariantIter *iter) if (object_path == NULL) continue; - while (g_variant_iter_loop(interface_iter, "{sa{sv}}", + while (g_variant_iter_loop(interface_iter, "{&sa{sv}}", &interface_str, &svc_iter)) { if (g_strcmp0(interface_str, "org.bluez.Adapter1") != 0) continue; BT_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); @@ -796,7 +793,7 @@ void _bt_logging_connection(gboolean connect, int addr_type) BT_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); } -#if 0 + int _bt_eventsystem_set_value(const char *event, const char *key, const char *value) { int ret; @@ -806,15 +803,15 @@ int _bt_eventsystem_set_value(const char *event, const char *key, const char *va bundle_add_str(b, key, value); - ret = eventsystem_request_sending_system_event(event, b); + ret = eventsystem_send_system_event(event, b); - BT_DBG("request_sending_system_event result: %d", ret); + BT_DBG("eventsystem_send_system_event result: %d", ret); bundle_free(b); return ret; } -#endif + void _bt_swap_byte_ordering(char *data, int data_len) { char temp; diff --git a/bt-service/bt-service-device.c b/bt-service/bt-service-device.c index 0a36214..ba1d46d 100644 --- a/bt-service/bt-service-device.c +++ b/bt-service/bt-service-device.c @@ -36,11 +36,13 @@ #include "bt-service-common.h" #include "bt-service-event.h" #include "bt-service-device.h" +#include "bt-service-adapter-le.h" #include "bt-service-rfcomm-client.h" #include "bt-service-util.h" #include "bt-service-agent.h" #include "bt-service-network.h" #include "bt-service-adapter.h" +#include "bt-service-gap-agent.h" #define BT_SYSPOPUP_IPC_RESPONSE_OBJECT "/org/projectx/bt_syspopup_res" #define BT_SYSPOPUP_INTERFACE "User.Bluetooth.syspopup" @@ -53,6 +55,21 @@ #define BT_LE_CONN_SLAVE_LATENCY_MAX 499 #define BT_LE_CONN_INTERVAL_SPLIT 1.25 /* msec */ #define BT_LE_CONN_TO_SPLIT 10 /* msec */ +#define BT_DEVICE_PIN_CODE_SLOT_MAX 10 + +#define BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT 20000 /* msec */ + +#define BT_LE_CONN_PARAM_BALANCED_MIN_INTERVAL 30 /* msec */ +#define BT_LE_CONN_PARAM_BALANCED_MAX_INTERVAL 50 /* msec */ +#define BT_LE_CONN_PARAM_BALANCED_SLAVE_LATENCY 0 /* event */ + +#define BT_LE_CONN_PARAM_LOW_LATENCY_MIN_INTERVAL 7.5 /* msec */ +#define BT_LE_CONN_PARAM_LOW_LATENCY_MAX_INTERVAL 10 /* msec */ +#define BT_LE_CONN_PARAM_LOW_LATENCY_SLAVE_LATENCY 0 /* event */ + +#define BT_LE_CONN_PARAM_LOW_POWER_MIN_INTERVAL 80 /* msec */ +#define BT_LE_CONN_PARAM_LOW_POWER_MAX_INTERVAL 100 /* msec */ +#define BT_LE_CONN_PARAM_LOW_POWER_SLAVE_LATENCY 2 /* event */ typedef struct { int req_id; @@ -65,9 +82,17 @@ typedef struct { unsigned short conn_type; } bt_funcion_data_t; +typedef struct { + char *address; + char *pin_code; +} bt_pin_code_info_t; + gboolean is_device_creating; bt_funcion_data_t *bonding_info; bt_funcion_data_t *searching_info; +bt_funcion_data_t *le_connection_info; + +static GSList *pin_info_list = NULL; /* This HID Mouse does not support pairing precedure. need to skip it. */ #define SMB_MOUSE_LAP_ADDR "00:12:A1" @@ -569,35 +594,20 @@ static int __bt_retry_bond(void) } -static int __bt_remove_and_bond(void) +static int __bt_remove_and_bond(char *device_path) { GDBusProxy *adapter_proxy; GVariant *result = NULL; GError *err = NULL; - char *data = NULL; - char *device_path = NULL; BT_CHECK_PARAMETER(bonding_info, return); BT_CHECK_PARAMETER(bonding_info->addr, return); + retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); + adapter_proxy = _bt_get_adapter_proxy(); retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - result = g_dbus_proxy_call_sync(adapter_proxy, "FindDevice", - g_variant_new("(s)", bonding_info->addr), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL); - if (result == NULL) - return BLUETOOTH_ERROR_INTERNAL; - - g_variant_get(result , "(&o)", &data); - device_path = g_strdup(data); - g_variant_unref(result); - - retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); - result = g_dbus_proxy_call_sync(adapter_proxy, "UnpairDevice", g_variant_new("(o)", device_path), G_DBUS_CALL_FLAGS_NONE, @@ -605,16 +615,11 @@ static int __bt_remove_and_bond(void) NULL, &err); - g_free(device_path); - - if (result == NULL) { - if (err != NULL) { - BT_ERR("UnpairDevice Fail: %s", err->message); - g_error_free(err); - return BLUETOOTH_ERROR_INTERNAL; - } + if (err != NULL) { + BT_ERR("UnpairDevice Fail: %s", err->message); + g_error_free(err); + return BLUETOOTH_ERROR_INTERNAL; } - g_variant_unref(result); return __bt_retry_bond(); } @@ -641,9 +646,10 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, GVariant *out_param1; request_info_t *req_info; bluetooth_device_info_t dev_info; - bt_remote_dev_info_t *remote_dev_info = NULL; + bt_remote_dev_info_t *remote_dev_info; GVariant *manufacture_data; GVariant *param; + const char *device_path; #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT) /* Terminate ALL system popup */ @@ -668,12 +674,19 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, goto done; } + device_path = g_dbus_proxy_get_object_path(proxy); + + BT_DBG("device path: %s", device_path); + if (err != NULL) { + g_dbus_error_strip_remote_error(err); BT_ERR("Error occured in CreateBonding [%s]", err->message); if (g_strrstr(err->message, "Already Exists")) { BT_INFO("Existing Bond, remove and retry"); - ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE); + ret_if(__bt_remove_and_bond(device_path) == BLUETOOTH_ERROR_NONE); + + BT_INFO("Fail to retry bonding"); result = BLUETOOTH_ERROR_PARING_FAILED; } else if (_bt_agent_is_canceled() || @@ -741,10 +754,8 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, goto dbus_return; remote_dev_info = _bt_get_remote_device_info(bonding_info->addr); - if (NULL == remote_dev_info) { - BT_ERR("Failed to get remote device info"); + if (remote_dev_info == NULL) goto dbus_return; - } GVariant *uuids = NULL; GVariantBuilder *builder = NULL; @@ -1109,7 +1120,7 @@ static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res, GVariant *out_param1; int result = BLUETOOTH_ERROR_NONE; bluetooth_device_info_t dev_info; - bt_remote_dev_info_t *remote_dev_info = NULL; + bt_remote_dev_info_t *remote_dev_info; request_info_t *req_info; GVariant *uuid_list, *manufacture_data; GVariant *param; @@ -1133,13 +1144,14 @@ static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res, } if (err != NULL) { + g_dbus_error_strip_remote_error(err); BT_ERR("Error occured in Proxy call [%s]\n", err->message); - if (!strcmp("Operation canceled", err->message)) { + if (g_strrstr("Operation canceled", err->message)) { result = BLUETOOTH_ERROR_CANCEL_BY_USER; - } else if (!strcmp("In Progress", err->message)) { + } else if (g_strrstr("In Progress", err->message)) { result = BLUETOOTH_ERROR_IN_PROGRESS; - } else if (!strcmp("Host is down", err->message)) { + } else if (g_strrstr("Host is down", err->message)) { result = BLUETOOTH_ERROR_HOST_DOWN; } else { result = BLUETOOTH_ERROR_CONNECTION_ERROR; @@ -1159,10 +1171,8 @@ static void __bt_discover_cb(GDBusProxy *proxy, GAsyncResult *res, } remote_dev_info = _bt_get_remote_device_info(searching_info->addr); - if (NULL == remote_dev_info) { - BT_ERR("Failed to get remote device info"); + if (remote_dev_info == NULL) goto dbus_return; - } event: builder = g_variant_builder_new(G_VARIANT_TYPE("as")); @@ -1189,7 +1199,6 @@ event: remote_dev_info->manufacturer_data_len, manufacture_data); - /* Send the event to application */ _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_SERVICE_SEARCHED, @@ -1290,9 +1299,6 @@ int _bt_search_device(int request_id, return BLUETOOTH_ERROR_NONE; fail: - if (device_proxy) - g_object_unref(device_proxy); - g_free(searching_info->addr); g_free(searching_info); searching_info = NULL; @@ -1469,18 +1475,18 @@ int _bt_is_gatt_connected(bluetooth_device_address_t *device_address, retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED); device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, - NULL, BT_BLUEZ_NAME, object_path, - BT_PROPERTIES_INTERFACE, NULL, NULL); + NULL, BT_BLUEZ_NAME, + object_path, BT_PROPERTIES_INTERFACE, NULL, NULL); g_free(object_path); retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); result = g_dbus_proxy_call_sync(device_proxy, "GetAll", - g_variant_new("(s)", BT_DEVICE_INTERFACE), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (result == NULL) { + g_variant_new("(s)", BT_DEVICE_INTERFACE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (error != NULL || result == NULL) { if (error != NULL) { BT_ERR("Error occured in Proxy call [%s]\n", error->message); g_error_free(error); @@ -1492,17 +1498,16 @@ int _bt_is_gatt_connected(bluetooth_device_address_t *device_address, g_variant_get(result , "(@a{sv})", &value); g_variant_unref(result); - tmp_value = g_variant_lookup_value(value, "GattConnected", G_VARIANT_TYPE_BOOLEAN); + tmp_value = g_variant_lookup_value (value, "GattConnected", G_VARIANT_TYPE_BOOLEAN); + if (tmp_value == NULL) { g_object_unref(device_proxy); - g_variant_unref(value); return BLUETOOTH_ERROR_INTERNAL; } - *is_connected = g_variant_get_boolean(tmp_value); + *is_connected = g_variant_get_boolean (tmp_value); BT_DBG("gatt is connected : %d", *is_connected); - g_variant_unref(tmp_value); g_variant_unref(value); g_object_unref(device_proxy); @@ -1551,7 +1556,7 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, g_free(object_path); if (device_proxy == NULL) { BT_DBG("Device don't have this service"); - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ERROR_NONE; } result = g_dbus_proxy_call_sync(device_proxy, "GetProperties", @@ -1568,20 +1573,21 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, g_error_free(error); } g_object_unref(device_proxy); - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ERROR_NONE; } g_variant_get(result , "(@a{sv})", &value); g_variant_unref(result); - - tmp_value = g_variant_lookup_value (value, "Connected", G_VARIANT_TYPE_BOOLEAN); - if (tmp_value != NULL) { - g_object_unref(device_proxy); - return BLUETOOTH_ERROR_INTERNAL; + if (value) { + tmp_value = g_variant_lookup_value(value, + "Connected", + G_VARIANT_TYPE_BOOLEAN); + if (tmp_value) { + *is_connected = g_variant_get_boolean(tmp_value); + g_variant_unref(tmp_value); + } + g_variant_unref(value); } - *is_connected = g_variant_get_boolean (tmp_value); - g_variant_unref(tmp_value); - g_variant_unref(value); } else if(connection_type == BLUETOOTH_NAP_SERVICE) { return _bt_is_network_connected(_bt_get_net_conn(), device_address->addr, is_connected); @@ -1589,7 +1595,7 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, uuid = _bt_get_profile_uuid128(connection_type); if (uuid == NULL) { BT_ERR("uuid is NULL"); - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ERROR_NONE; } BT_DBG("uuid: %s", uuid); @@ -1604,7 +1610,7 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, if (device_proxy == NULL) { BT_DBG("Device don't have this service"); g_free(uuid); - return BLUETOOTH_ERROR_INTERNAL; + return BLUETOOTH_ERROR_NONE; } result = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile", @@ -1620,12 +1626,11 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, BT_ERR("Error occured in Proxy call [%s]\n", error->message); g_error_free(error); } - g_object_unref(device_proxy); - return BLUETOOTH_ERROR_INTERNAL; + } else { + g_variant_get(result, "(b)", is_connected); + g_free(uuid); + g_variant_unref(result); } - g_variant_get(result, "(b)", is_connected); - g_free(uuid); - g_variant_unref(result); } g_object_unref(device_proxy); @@ -1697,11 +1702,88 @@ int _bt_get_connected_link(bluetooth_device_address_t *device_address, return ret; } -int _bt_connect_le_device(const bluetooth_device_address_t *bd_addr, gboolean auto_connect) +static void __bt_connect_le_device_cb(GDBusProxy *proxy, GAsyncResult *res, + gpointer user_data) +{ + GError *err = NULL; + GVariant *out_param1; + request_info_t *req_info; + bluetooth_device_address_t device_addr = { {0} }; + int result = BLUETOOTH_ERROR_NONE; + + BT_DBG("+"); + g_dbus_proxy_call_finish(proxy, res, &err); + + /* When cb datas of lescan are received, back to parameta values for Web TCT */ + if ( _bt_is_set_scan_parameter() == FALSE) { + bluetooth_le_scan_params_t scan_params; + BT_ERR("set parameter of lescan when receive cb data"); + scan_params.type = BT_LE_ACTIVE_SCAN; + scan_params.interval = 5000; + scan_params.window = 500; + _bt_set_scan_parameters(&scan_params); + } + + req_info = _bt_get_request_info(le_connection_info->req_id); + if (req_info == NULL) { + BT_ERR("req_info == NULL"); + g_object_unref(proxy); + le_connection_info->device_proxy = NULL; + goto done; + } + + if (err != NULL) { + BT_ERR("Error occured in ConnectLE [%s]", err->message); + + if (g_strrstr(err->message, "NotSupported")) { + BT_INFO("Connection Not Supported"); + result = BLUETOOTH_ERROR_CONNECTION_ERROR; + } else if (g_strrstr(err->message, "AlreadyConnected")) { + BT_INFO("Connection already exists"); + result = BLUETOOTH_ERROR_ALREADY_CONNECT; + } else if (g_strrstr(err->message, "Connection Timeout")) { + BT_INFO("Connection Timeout"); + result = BLUETOOTH_ERROR_TIMEOUT; + } else { + BT_DBG("Default case"); + result = BLUETOOTH_ERROR_CONNECTION_ERROR; + } + } + + g_object_unref(proxy); + le_connection_info->device_proxy = NULL; + + _bt_convert_addr_string_to_type(device_addr.addr, + le_connection_info->addr); + + if (req_info->context == NULL) + goto done; + + out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL); + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(iv)", result, out_param1)); + + g_variant_unref(out_param1); + + _bt_delete_request_list(req_info->req_id); +done: + if (err) + g_error_free(err); + + g_free(le_connection_info->addr); + g_free(le_connection_info); + le_connection_info = NULL; + + BT_DBG("-"); +} + +int _bt_connect_le_device(int request_id, + const bluetooth_device_address_t *bd_addr, + gboolean auto_connect) { char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; gchar *device_path = NULL; - GError *error = NULL; GDBusProxy *device_proxy = NULL; GDBusProxy *adapter_proxy; GDBusConnection *conn; @@ -1712,6 +1794,14 @@ int _bt_connect_le_device(const bluetooth_device_address_t *bd_addr, gboolean au _bt_convert_addr_type_to_string(device_address, (unsigned char *)bd_addr->addr); + if (le_connection_info) { + BT_ERR("LE Connection in progress"); + return BLUETOOTH_ERROR_DEVICE_BUSY; + } + +/* When auto_connect is true, Web TCT fail. It need to be checked */ + auto_connect = FALSE; + conn = _bt_get_system_gconn(); retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -1733,15 +1823,199 @@ int _bt_connect_le_device(const bluetooth_device_address_t *bd_addr, gboolean au g_free(device_path); retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - g_dbus_proxy_call_sync(device_proxy, "ConnectLE", + + le_connection_info = g_malloc0(sizeof(bt_funcion_data_t)); + le_connection_info->addr = g_strdup(device_address); + le_connection_info->req_id = request_id; + le_connection_info->device_proxy = device_proxy; + +/* The connection between Ble device and TM1 often fail. So It need to be set for Web TCT*/ + if ( _bt_is_set_scan_parameter() == FALSE) { + BT_ERR("set parameter of le scan when connect device"); + bluetooth_le_scan_params_t scan_params; + scan_params.type = BT_LE_ACTIVE_SCAN; + scan_params.interval = 60; + scan_params.window = 60; + _bt_set_scan_parameters(&scan_params); + } + + g_dbus_proxy_call(device_proxy, "ConnectLE", g_variant_new("(b)", auto_connect), G_DBUS_CALL_FLAGS_NONE, - -1, + BT_MAX_DBUS_TIMEOUT, NULL, - &error); + (GAsyncReadyCallback)__bt_connect_le_device_cb, + NULL); + + + return ret; +} + +static void __bt_disconnect_le_device_cb(GDBusProxy *proxy, GAsyncResult *res, + gpointer user_data) +{ + GError *err = NULL; + GVariant *out_param1; + request_info_t *req_info; + bt_funcion_data_t *le_disconnection_info = user_data; + bluetooth_device_address_t device_addr = { {0} }; + int result = BLUETOOTH_ERROR_NONE; + + BT_DBG("+"); + g_dbus_proxy_call_finish(proxy, res, &err); + + req_info = _bt_get_request_info(le_disconnection_info->req_id); + if (req_info == NULL) { + BT_ERR("req_info == NULL"); + g_object_unref(proxy); + le_disconnection_info->device_proxy = NULL; + goto done; + } + + if (err != NULL) { + BT_ERR("Error occured in DisconnectLE [%s]", err->message); + + if (g_strrstr(err->message, "NotSupported")) { + BT_INFO("Connection Not Supported"); + result = BLUETOOTH_ERROR_CONNECTION_ERROR; + } else if (g_strrstr(err->message, "NotConnected")) { + BT_INFO("Connection does not exists"); + result = BLUETOOTH_ERROR_NOT_CONNECTED; + } else if (g_strrstr(err->message, "Cancelled")) { + BT_INFO("User Cancelled"); + result = BLUETOOTH_ERROR_CANCEL_BY_USER; + } else { + BT_DBG("Default case"); + result = BLUETOOTH_ERROR_CONNECTION_ERROR; + } + } + + g_object_unref(proxy); + le_disconnection_info->device_proxy = NULL; + + _bt_convert_addr_string_to_type(device_addr.addr, + le_disconnection_info->addr); + + if (req_info->context == NULL) + goto done; + out_param1 = g_variant_new_from_data((const GVariantType *)"ay", + &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL); + + g_dbus_method_invocation_return_value(req_info->context, + g_variant_new("(iv)", result, out_param1)); + + g_variant_unref(out_param1); + + _bt_delete_request_list(req_info->req_id); +done: + if (err) + g_error_free(err); + + g_free(le_disconnection_info->addr); + g_free(le_disconnection_info); + le_disconnection_info = NULL; + + BT_DBG("-"); +} + +int _bt_disconnect_le_device(int request_id, + const bluetooth_device_address_t *bd_addr) +{ + char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + gchar *device_path = NULL; + GDBusProxy *device_proxy = NULL; + GDBusProxy *adapter_proxy; + GDBusConnection *conn; + int ret = BLUETOOTH_ERROR_NONE; + bt_funcion_data_t *le_disconnection_info = NULL; + + BT_CHECK_PARAMETER(bd_addr, return); + + _bt_convert_addr_type_to_string(device_address, + (unsigned char *)bd_addr->addr); + + conn = _bt_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + adapter_proxy = _bt_get_adapter_proxy(); + retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + device_path = _bt_get_device_object_path(device_address); + if (device_path == NULL) { + BT_DBG("device_path NULL"); + ret = BLUETOOTH_ERROR_INTERNAL; + return ret; + } + + retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); + + device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, + device_path, BT_DEVICE_INTERFACE, NULL, NULL); + g_free(device_path); + retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + le_disconnection_info = g_malloc0(sizeof(bt_funcion_data_t)); + le_disconnection_info->addr = g_strdup(device_address); + le_disconnection_info->req_id = request_id; + le_disconnection_info->device_proxy = device_proxy; + + g_dbus_proxy_call(device_proxy, "DisconnectLE", + NULL, + G_DBUS_CALL_FLAGS_NONE, + BT_MAX_DBUS_TIMEOUT, + NULL, + (GAsyncReadyCallback)__bt_disconnect_le_device_cb, + le_disconnection_info); + + return ret; +} + +int _bt_connect_le_ipsp_device(const bluetooth_device_address_t *bd_addr) +{ + char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; + gchar *device_path = NULL; + GError *error = NULL; + GDBusProxy *device_proxy = NULL; + GDBusProxy *adapter_proxy; + GDBusConnection *conn; + int ret = BLUETOOTH_ERROR_NONE; + + BT_CHECK_PARAMETER(bd_addr, return); + + _bt_convert_addr_type_to_string(device_address, + (unsigned char *)bd_addr->addr); + + conn = _bt_get_system_gconn(); + retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + adapter_proxy = _bt_get_adapter_proxy(); + retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + device_path = _bt_get_device_object_path(device_address); + if (device_path == NULL) { + BT_DBG("device_path NULL"); + ret = BLUETOOTH_ERROR_INTERNAL; + return ret; + } + + retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); + + device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, BT_BLUEZ_NAME, + device_path, BT_DEVICE_INTERFACE, NULL, NULL); + g_free(device_path); + retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); + + g_dbus_proxy_call_sync(device_proxy, "ConnectIpsp", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); if (error) { - BT_ERR("ConnectLE Call Error %s[%s]", error->message, device_address); + BT_ERR("ConnectIpsp Call Error %s[%s]", error->message, device_address); g_error_free(error); g_object_unref(device_proxy); return BLUETOOTH_ERROR_INTERNAL; @@ -1752,7 +2026,7 @@ int _bt_connect_le_device(const bluetooth_device_address_t *bd_addr, gboolean au return ret; } -int _bt_disconnect_le_device(const bluetooth_device_address_t *bd_addr) +int _bt_disconnect_le_ipsp_device(const bluetooth_device_address_t *bd_addr) { char device_address[BT_ADDRESS_STRING_SIZE] = { 0 }; gchar *device_path = NULL; @@ -1783,19 +2057,19 @@ int _bt_disconnect_le_device(const bluetooth_device_address_t *bd_addr) retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL); device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, - NULL, BT_BLUEZ_NAME, - device_path, BT_DEVICE_INTERFACE, NULL, NULL); + NULL, BT_BLUEZ_NAME, + device_path, BT_DEVICE_INTERFACE, NULL, NULL); g_free(device_path); retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL); - g_dbus_proxy_call_sync(device_proxy, "DisconnectLE", + g_dbus_proxy_call_sync(device_proxy, "DisconnectIpsp", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { - BT_ERR("DisconnectLE Call Error %s[%s]", error->message, device_address); + BT_ERR("DisconnectIpsp Call Error %s[%s]", error->message, device_address); g_error_free(error); g_object_unref(device_proxy); return BLUETOOTH_ERROR_INTERNAL; @@ -2061,3 +2335,160 @@ int _bt_le_conn_update(unsigned char *device_address, fail: return ret; } + +int _bt_set_pin_code(bluetooth_device_address_t *device_address, + bluetooth_device_pin_code_t *pin_code) +{ + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + GSList *l = NULL; + bt_pin_code_info_t *pin_info = NULL; + + BT_CHECK_PARAMETER(device_address, return); + BT_CHECK_PARAMETER(pin_code, return); + retv_if(g_slist_length(pin_info_list) >= BT_DEVICE_PIN_CODE_SLOT_MAX, + BLUETOOTH_ERROR_NO_RESOURCES); + + _bt_convert_addr_type_to_string(address, device_address->addr); + + for (l = pin_info_list; l != NULL; l = l->next) { + pin_info = l->data; + + if (g_strcmp0(pin_info->address, address) == 0) { + g_free(pin_info->pin_code); + pin_info->pin_code = g_strdup(pin_code->pin_code); + return BLUETOOTH_ERROR_NONE; + } + } + + pin_info = g_malloc0(sizeof(bt_pin_code_info_t)); + if (pin_info != NULL) { + pin_info->address = g_strdup(address); + pin_info->pin_code = g_strdup(pin_code->pin_code); + pin_info_list = g_slist_append(pin_info_list, pin_info); + return BLUETOOTH_ERROR_NONE; + } + + return BLUETOOTH_ERROR_INTERNAL; +} + +gint __bt_compare_address(gpointer *a, gpointer *b) +{ + bt_pin_code_info_t *pin_info = (bt_pin_code_info_t *)a; + char *address = (char *)b; + return g_strcmp0(pin_info->address, address); +} + +int _bt_unset_pin_code(bluetooth_device_address_t *device_address) +{ + char address[BT_ADDRESS_STRING_SIZE] = { 0 }; + GSList *l = NULL; + bt_pin_code_info_t *pin_info = NULL; + + BT_CHECK_PARAMETER(device_address, return); + + _bt_convert_addr_type_to_string(address, device_address->addr); + + l = g_slist_find_custom(pin_info_list, address, + (GCompareFunc)__bt_compare_address); + if (l) + pin_info = l->data; + if (pin_info) { + pin_info_list = g_slist_remove(pin_info_list, pin_info); + g_free(pin_info->address); + g_free(pin_info->pin_code); + g_free(pin_info); + } + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_get_device_pin_code(const char *address, char *pin_code) +{ + GSList *l = NULL; + + BT_CHECK_PARAMETER(address, return); + BT_CHECK_PARAMETER(pin_code, return); + + for (l = pin_info_list; l != NULL; l = l->next) { + bt_pin_code_info_t *pin_info = l->data; + + if (g_strcmp0(pin_info->address, address) == 0) { + g_strlcpy(pin_code, pin_info->pin_code, + BLUETOOTH_PIN_CODE_MAX_LENGTH + 1); + + return BLUETOOTH_ERROR_NONE; + } + } + + return BLUETOOTH_ERROR_NOT_FOUND; +} + +int _bt_get_le_connection_parameter(bluetooth_le_connection_mode_t mode, + bluetooth_le_connection_param_t *param) +{ + if (param == NULL) + return BLUETOOTH_ERROR_INVALID_PARAM; + + if (mode < BLUETOOTH_LE_CONNECTION_MODE_BALANCED || + mode > BLUETOOTH_LE_CONNECTION_MODE_LOW_POWER) + return BLUETOOTH_ERROR_INVALID_PARAM; + + memset(param, 0x00, sizeof(bluetooth_le_connection_param_t)); + + switch (mode) { + case BLUETOOTH_LE_CONNECTION_MODE_BALANCED: + param->interval_min = BT_LE_CONN_PARAM_BALANCED_MIN_INTERVAL; + param->interval_max = BT_LE_CONN_PARAM_BALANCED_MAX_INTERVAL; + param->latency = BT_LE_CONN_PARAM_BALANCED_SLAVE_LATENCY; + param->timeout = BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT; + break; + + case BLUETOOTH_LE_CONNECTION_MODE_LOW_LATENCY: + param->interval_min = BT_LE_CONN_PARAM_LOW_LATENCY_MIN_INTERVAL; + param->interval_max = BT_LE_CONN_PARAM_LOW_LATENCY_MAX_INTERVAL; + param->latency = BT_LE_CONN_PARAM_LOW_LATENCY_SLAVE_LATENCY; + param->timeout = BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT; + break; + + case BLUETOOTH_LE_CONNECTION_MODE_LOW_POWER: + param->interval_min = BT_LE_CONN_PARAM_LOW_POWER_MIN_INTERVAL; + param->interval_max = BT_LE_CONN_PARAM_LOW_POWER_MAX_INTERVAL; + param->latency = BT_LE_CONN_PARAM_LOW_POWER_SLAVE_LATENCY; + param->timeout = BT_LE_CONN_PARAM_DEFAULT_SUPERVISION_TIMEOUT; + break; + + default: + BT_ERR("Unhandled mode : %d", mode); + break; + } + + return BLUETOOTH_ERROR_NONE; +} + +int _bt_passkey_reply(const char *passkey, gboolean authentication_reply) +{ + GapAgentPrivate *agent = _bt_get_adapter_agent(); + retv_if(!agent, BLUETOOTH_ERROR_INTERNAL); + + if (authentication_reply) + gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, passkey, NULL); + else + gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, passkey, NULL); + + BT_DBG("BT_PASSKEY_REPLY"); + return BLUETOOTH_ERROR_NONE; +} + +int _bt_passkey_confirmation_reply(gboolean confirmation_reply) +{ + GapAgentPrivate *agent = _bt_get_adapter_agent(); + retv_if(!agent, BLUETOOTH_ERROR_INTERNAL); + + if (confirmation_reply) + gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL); + else + gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL); + + BT_DBG("BT_PASSKEY_CONFIRMATION_REPLY"); + return BLUETOOTH_ERROR_NONE; +} diff --git a/bt-service/bt-service-event-receiver.c b/bt-service/bt-service-event-receiver.c index 22da88d..46ace3b 100755 --- a/bt-service/bt-service-event-receiver.c +++ b/bt-service/bt-service-event-receiver.c @@ -205,8 +205,9 @@ static gboolean __bt_parse_device_properties(GVariant *item, if (len > 0) { char *manufacturer_data = (char *)g_variant_get_data(manufacturer_var); dev_info->manufacturer_data = g_malloc0(len); - memcpy(dev_info->manufacturer_data, manufacturer_data, - len); + if (dev_info->manufacturer_data) + memcpy(dev_info->manufacturer_data, manufacturer_data, + len); } g_variant_unref(manufacturer_var); } @@ -250,8 +251,8 @@ static gboolean __bt_parse_interface(GVariant *msg, g_variant_unref(inner_iter); g_variant_unref(child); } - if (optional_param) - g_variant_unref(optional_param); + + g_variant_unref(optional_param); return FALSE; } @@ -299,7 +300,6 @@ gboolean _bt_discovery_finished_cb(gpointer user_data) } _bt_set_cancel_by_user(FALSE); - _bt_disable_all_scanner_status(); _bt_set_discovery_status(FALSE); param = g_variant_new("(i)", result); _bt_send_event(BT_ADAPTER_EVENT, @@ -321,6 +321,7 @@ static gboolean __bt_le_discovery_finished_cb(gpointer user_data) } _bt_set_cancel_by_user(FALSE); + _bt_disable_all_scanner_status(); _bt_set_le_scan_status(FALSE); param = g_variant_new("(i)", result); _bt_send_event(BT_LE_ADAPTER_EVENT, @@ -755,17 +756,27 @@ static void __bt_adapter_property_changed_event(GVariant *msg, const char *path) char *value = NULL; GVariantIter *iter = NULL; g_variant_get(val, "as", &iter); - while (g_variant_iter_loop(iter, "s", &name)) { - BT_DBG("name = %s", name); - g_variant_iter_loop(iter, "s", &value); - BT_DBG("Value = %s", value); - if (FALSE == _bt_update_le_feature_support(name, value)) - BT_INFO("Fail to update LE feature info"); - } - if (iter) + if (iter) { + while (g_variant_iter_loop(iter, "s", &name)) { + BT_DBG("name = %s", name); + g_variant_iter_loop(iter, "s", &value); + BT_DBG("Value = %s", value); + if (FALSE == _bt_update_le_feature_support(name, value)) + BT_INFO("Fail to update LE feature info"); + } g_variant_iter_free(iter); - } else { - BT_DBG("property : [%s]", property); + } + } else if (strcasecmp(property, "IpspInitStateChanged") == 0) { + gboolean ipsp_initialized = FALSE; + + g_variant_get(val, "b", &ipsp_initialized); + BT_DBG("IPSP init state changed: %d", ipsp_initialized); + param = g_variant_new("(b)", ipsp_initialized); + + /* Send event to application */ + _bt_send_event(BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED, + param); } } } @@ -875,7 +886,7 @@ static void __bt_device_property_changed_event(GVariant *msg, const char *path) } BT_DBG("Address type %d", remote_dev_info->addr_type); - if (remote_dev_info && remote_dev_info->addr_type == 0) { + if (remote_dev_info->addr_type == 0) { BT_DBG("Name %s", remote_dev_info->name); GVariant *uuids = NULL; @@ -1062,6 +1073,28 @@ static void __bt_device_property_changed_event(GVariant *msg, const char *path) event, param); g_free(address); + } else if (strcasecmp(property, "IpspConnected") == 0) { + gboolean connected = FALSE; + + g_variant_get(val, "b", &connected); + + + event = connected ? BLUETOOTH_EVENT_IPSP_CONNECTED : + BLUETOOTH_EVENT_IPSP_DISCONNECTED; + + address = g_malloc0(BT_ADDRESS_STRING_SIZE); + + _bt_convert_device_path_to_address(path, address); + + BT_DBG("Ipspconnected: %d", connected); + BT_DBG("address: %s", address); + param = g_variant_new("(is)", result, address); + + /* Send event to application */ + _bt_send_event(BT_DEVICE_EVENT, + event, + param); + g_free(address); } } BT_DBG("-"); @@ -1399,9 +1432,9 @@ void __bt_gatt_char_property_changed_event(GVariant *msg, TRUE, NULL, NULL); param = g_variant_new("(is@ay)", result, char_handle, byte_array); - _bt_send_event(BT_DEVICE_EVENT, - BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, - param); + + /* Send event only registered client */ + _bt_send_char_value_changed_event(param); } g_byte_array_free(gp_byte_array, TRUE); } @@ -1409,7 +1442,44 @@ void __bt_gatt_char_property_changed_event(GVariant *msg, } g_free(char_handle); } -void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) + +void _bt_handle_gatt_event(GVariant *msg, const char *member, const char *path) +{ + ret_if(path == NULL); + + if (strcasecmp(member, "GattValueChanged") == 0) { + +#if 0 // Debug Only + /*** Debug only ***/ + GVariant *value = NULL; + int value_len = 0; + char *buffer = NULL; + + g_variant_get(msg, "(is@ay)", NULL, NULL, &value); + value_len = g_variant_get_size(value); + if (value_len > 0) { + char buf[8 * 5 + 1] = { 0 }; + int i; + int to; + buffer = (char *)g_variant_get_data(value); + to = value_len > (sizeof(buf) / 5) ? sizeof(buf) / 5 : value_len; + + for (i = 0; i < to; i++) + snprintf(&buf[i * 5], 6, "0x%02x ", buffer[i]); + buf[i * 5] = '\0'; + BT_DBG("GATT Val[%d] %s", value_len, buf); + } + g_variant_unref(value); + /******/ +#endif + + /* Send event only registered client */ + _bt_send_char_value_changed_event(msg); + } +} + + +void _bt_handle_device_event(GVariant *msg, const char *member, const char *path) { int event; int result = BLUETOOTH_ERROR_NONE; @@ -1429,6 +1499,8 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) gboolean connected = FALSE; char *address; address = g_malloc0(BT_ADDRESS_STRING_SIZE); + ret_if(address == NULL); + _bt_convert_device_path_to_address(path, address); g_variant_get(msg, "(b)", &connected); @@ -1460,6 +1532,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) } address = g_malloc0(BT_ADDRESS_STRING_SIZE); + ret_if(address == NULL); _bt_convert_device_path_to_address(path, address); @@ -1510,6 +1583,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) ret_if(_bt_is_device_creating() == TRUE); address = g_malloc0(BT_ADDRESS_STRING_SIZE); + ret_if(address == NULL); _bt_convert_device_path_to_address(path, address); @@ -1559,6 +1633,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) g_variant_get(msg, "(y)", &addr_type); address = g_malloc0(BT_ADDRESS_STRING_SIZE); + ret_if(address == NULL); _bt_convert_device_path_to_address(path, address); dev_name = _bt_get_bonded_device_name(address); @@ -1588,6 +1663,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) result = disc_reason; address = g_malloc0(BT_ADDRESS_STRING_SIZE); + ret_if(address == NULL); _bt_convert_device_path_to_address(path, address); dev_name = _bt_get_bonded_device_name(address); @@ -1627,6 +1703,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) g_variant_get(msg, "(si)", &profile_uuid, &state); address = g_malloc0(BT_ADDRESS_STRING_SIZE); + ret_if(address == NULL); _bt_convert_device_path_to_address(path, address); @@ -1798,6 +1875,8 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) ret_if(_bt_is_le_scanning() == FALSE); le_dev_info = g_malloc0(sizeof(bt_remote_le_dev_info_t)); + if (le_dev_info == NULL) + return; g_variant_get(msg, "(syyii@ay)", &le_dev_info->address, &le_dev_info->addr_type, @@ -1810,6 +1889,12 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) buffer = (char *)g_variant_get_data(value); le_dev_info->adv_data = g_memdup(buffer, buffer_len); + if (le_dev_info->adv_data == NULL && + le_dev_info->adv_type != BT_LE_ADV_SCAN_RSP) { + _bt_free_le_device_info(le_dev_info); + g_variant_unref(value); + return; + } if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) { _bt_send_scan_result_event(le_dev_info, NULL); @@ -1820,13 +1905,21 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) if (le_dev_info->adv_type != BT_LE_ADV_SCAN_RSP) { /* ADV_IND */ adv_info = g_malloc0(sizeof(bt_le_adv_info_t)); + if (adv_info == NULL) { + _bt_free_le_device_info(le_dev_info); + g_variant_unref(value); + return; + } + adv_info->addr = g_strdup(le_dev_info->address); adv_info->data_len = le_dev_info->adv_data_len; adv_info->data = g_malloc0(le_dev_info->adv_data_len); - memcpy(adv_info->data, le_dev_info->adv_data, - le_dev_info->adv_data_len); + if (adv_info->data) { + memcpy(adv_info->data, le_dev_info->adv_data, + le_dev_info->adv_data_len); - __bt_add_adv_ind_info(adv_info); + __bt_add_adv_ind_info(adv_info); + } } else { /* SCAN_RSP */ adv_info = __bt_get_adv_ind_info(le_dev_info->address); @@ -1852,8 +1945,7 @@ void _bt_handle_device_event(GVariant *msg, const char *member,const char *path) param = g_variant_new("(isqqqq)", result, address, tx_octets, tx_time, rx_octets, rx_time); /* Send event to application */ - _bt_send_event(BT_DEVICE_EVENT, - event, param); + _bt_send_event(BT_DEVICE_EVENT, event, param); g_free(address); } @@ -2266,7 +2358,7 @@ static void __bt_manager_event_filter(GDBusConnection *connection, if (strcasecmp(signal_name, "InterfacesAdded") == 0) { g_variant_get(parameters, "(&o@a{sa{sv}})", &obj_path, &value); - if (strcasecmp(obj_path, BT_BLUEZ_HCI_PATH) == 0){ + if (strcasecmp(obj_path, BT_BLUEZ_HCI_PATH) == 0) { #ifdef USB_BLUETOOTH BT_DBG("Enable Adapter"); _bt_enable_adapter(); @@ -2284,7 +2376,14 @@ static void __bt_manager_event_filter(GDBusConnection *connection, _bt_is_le_scanning() == FALSE); cache_info = g_malloc0(sizeof(bt_cache_info_t)); + ret_if(cache_info == NULL); + dev_info = g_malloc0(sizeof(bt_remote_dev_info_t)); + if (dev_info == NULL) { + __bt_free_cache_info(cache_info); + return; + } + cache_info->dev_info = dev_info; if (__bt_parse_interface(parameters, dev_info) == FALSE) { @@ -2351,7 +2450,6 @@ static void __bt_manager_event_filter(GDBusConnection *connection, BT_DBG("InterfacesRemoved"); _bt_handle_adapter_removed(); #endif - if (g_strcmp0(interface_name, BT_MEDIATRANSPORT_INTERFACE) == 0) { bt_event = BT_MEDIA_TRANSFER_EVENT; } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) { @@ -2378,20 +2476,19 @@ static void __bt_manager_event_filter(GDBusConnection *connection, } if (*current != '\0') { + g_free(current); if (name) g_free(name); if (previous) g_free(previous); - if (current) - g_free(current); return; } if (strcasecmp(name, BT_BLUEZ_NAME) == 0) { BT_DBG("Bluetoothd is terminated"); - if (_bt_adapter_get_status() != BT_DEACTIVATING) { + if (_bt_adapter_get_status() == BT_ACTIVATED) __bt_disable_cb(); - } + _bt_handle_adapter_removed(); __bt_devices_list_free(); } @@ -2439,6 +2536,8 @@ static void __bt_manager_event_filter(GDBusConnection *connection, _bt_handle_agent_event(parameters, signal_name); } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) { _bt_handle_device_event(parameters, signal_name, object_path); + } else if (g_strcmp0(interface_name, BT_GATT_CHAR_INTERFACE) == 0) { + _bt_handle_gatt_event(parameters, signal_name, object_path); } return; @@ -2655,6 +2754,7 @@ int _bt_register_manager_subscribe_signal(GDBusConnection *conn, static int subs_name_owner_id = -1; static int subs_property_id = -1; static int subs_adapter_id = -1; + static int subs_gatt_id = -1; if (subscribe) { if (subs_interface_added_id == -1) { @@ -2692,6 +2792,13 @@ int _bt_register_manager_subscribe_signal(GDBusConnection *conn, __bt_manager_event_filter, NULL, NULL); } + if (subs_gatt_id == -1) { + subs_gatt_id = g_dbus_connection_signal_subscribe(conn, + NULL, BT_GATT_CHAR_INTERFACE, + NULL, NULL, NULL, 0, + __bt_manager_event_filter, + NULL, NULL); + } } else { if (subs_interface_added_id != -1) { g_dbus_connection_signal_unsubscribe(conn, @@ -2713,10 +2820,14 @@ int _bt_register_manager_subscribe_signal(GDBusConnection *conn, subs_property_id); subs_property_id = -1; } - if (subs_adapter_id == -1) { + if (subs_adapter_id != -1) { g_dbus_connection_signal_unsubscribe(conn, subs_adapter_id); subs_adapter_id = -1; } + if (subs_gatt_id != -1) { + g_dbus_connection_signal_unsubscribe(conn, subs_gatt_id); + subs_gatt_id = -1; + } } return 0; } diff --git a/bt-service/bt-service-event-sender.c b/bt-service/bt-service-event-sender.c index 55ae7e5..eb1edf2 100755 --- a/bt-service/bt-service-event-sender.c +++ b/bt-service/bt-service-event-sender.c @@ -33,6 +33,35 @@ static GDBusConnection *event_conn; static GDBusConnection *hf_local_term_event_conn; +#ifdef HPS_FEATURE +int _bt_send_to_hps(void) +{ + gboolean ret = FALSE; + GError *error = NULL; + + BT_DBG(" "); + + retv_if(event_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + + ret = g_dbus_connection_emit_signal(event_conn, NULL, + "/org/projectx/httpproxy", + "org.projectx.httpproxy_service", + BT_LE_ENABLED, + NULL, &error); + if (!ret) { + if (error != NULL) { + BT_ERR("D-Bus API failure: errCode[%x], \ + message[%s]", + error->code, error->message); + g_clear_error(&error); + } + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} +#endif + int _bt_send_event(int event_type, int event, GVariant *param) { BT_DBG("+"); @@ -171,6 +200,18 @@ int _bt_send_event(int event_type, int event, GVariant *param) case BLUETOOTH_EVENT_RAW_RSSI: signal = BT_RAW_RSSI_EVENT; break; + case BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY: + signal = BT_KBD_PASSKEY_DISPLAY_REQ_RECEIVED; + break; + case BLUETOOTH_EVENT_PIN_REQUEST: + signal = BT_PIN_REQ_RECEIVED; + break; + case BLUETOOTH_EVENT_PASSKEY_REQUEST: + signal = BT_PASSKEY_REQ_RECEIVED; + break; + case BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST: + signal = BT_PASSKEY_CFM_REQ_RECEIVED; + break; case BLUETOOTH_EVENT_SERVICE_SEARCHED: signal = BT_SERVICE_SEARCHED; break; @@ -306,10 +347,10 @@ int _bt_send_event(int event_type, int event, GVariant *param) signal = BT_A2DP_SOURCE_CONNECTED; BT_INFO_C("Connected [A2DP Source]"); break; - case BLUETOOTH_EVENT_AV_SOURCE_DISCONNECTED: - signal = BT_A2DP_SOURCE_DISCONNECTED; - BT_INFO_C("Disconnected [A2DP Source]"); - break; + case BLUETOOTH_EVENT_AV_SOURCE_DISCONNECTED: + signal = BT_A2DP_SOURCE_DISCONNECTED; + BT_INFO_C("Disconnected [A2DP Source]"); + break; case BLUETOOTH_EVENT_AVRCP_CONNECTED: case BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED: signal = BT_AVRCP_CONNECTED; @@ -351,6 +392,15 @@ int _bt_send_event(int event_type, int event, GVariant *param) case BLUETOOTH_EVENT_GATT_DISCONNECTED: signal = BT_GATT_DISCONNECTED; break; + case BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED: + signal = BT_IPSP_INITIALIZED; + break; + case BLUETOOTH_EVENT_IPSP_CONNECTED: + signal = BT_IPSP_CONNECTED; + break; + case BLUETOOTH_EVENT_IPSP_DISCONNECTED: + signal = BT_IPSP_DISCONNECTED; + break; case BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED: signal = BT_GATT_CHAR_VAL_CHANGED; break; @@ -372,7 +422,12 @@ int _bt_send_event(int event_type, int event, GVariant *param) } g_object_unref(msg1); - BT_DBG("-"); + +#ifdef HPS_FEATURE + if (g_strcmp0(signal, BT_LE_ENABLED) == 0) + _bt_send_to_hps(); +#endif + return BLUETOOTH_ERROR_NONE; } @@ -386,6 +441,7 @@ int _bt_send_event_to_dest(const char* dest, int event_type, retv_if(event_conn == NULL, BLUETOOTH_ERROR_INTERNAL); + BT_DBG("dest : %s", dest); BT_DBG("event_type [%d], event [%d]", event_type, event); switch (event_type) { @@ -395,6 +451,9 @@ int _bt_send_event_to_dest(const char* dest, int event_type, case BT_LE_ADAPTER_EVENT: path = BT_LE_ADAPTER_PATH; break; + case BT_DEVICE_EVENT: + path = BT_DEVICE_PATH; + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; @@ -416,6 +475,9 @@ int _bt_send_event_to_dest(const char* dest, int event_type, case BLUETOOTH_EVENT_LE_DISCOVERY_FINISHED: signal = BT_LE_DISCOVERY_FINISHED; break; + case BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED: + signal = BT_GATT_CHAR_VAL_CHANGED; + break; default: BT_ERR("Unknown event"); return BLUETOOTH_ERROR_INTERNAL; diff --git a/bt-service/bt-service-gap-agent.c b/bt-service/bt-service-gap-agent.c index 0578822..98f2e9c 100644 --- a/bt-service/bt-service-gap-agent.c +++ b/bt-service/bt-service-gap-agent.c @@ -399,7 +399,11 @@ gboolean _gap_agent_register(GapAgentPrivate *agent) } reply = g_dbus_proxy_call_sync(agent_manager, "RegisterAgent", +#ifdef TIZEN_BT_IO_CAPA_NO_INPUT_OUTPUT + g_variant_new("(os)", priv->path, "NoInputNoOutput"), +#else g_variant_new("(os)", priv->path, "DisplayYesNo"), +#endif G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (reply == NULL) { @@ -491,54 +495,54 @@ static gboolean __gap_agent_unregister(GapAgentPrivate *agent) static const gchar gap_agent_bluez_introspection_xml[] = "" " " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " +" " +" " +" " " " " " +" " +" " +" " +" " " " " " -" " -" " -" " -" " +" " +" " +" " +" " +" " +" " +" " " " " " " " " " +" " +" " +" " +" " +" " " " " " " " +" " +" " +" " +" " " " " " " " +" " +" " +" " +" " " " " " " " -" " -" " -" " +" " +" " +" " +" " " " ""; diff --git a/bt-service/bt-service-main.c b/bt-service/bt-service-main.c index acdf110..51398f7 100644 --- a/bt-service/bt-service-main.c +++ b/bt-service/bt-service-main.c @@ -21,16 +21,13 @@ * */ -//#include #include #include #include #include #include -#if 0 #include -#endif #include "bt-internal-types.h" #include "bt-service-common.h" @@ -59,6 +56,9 @@ static void __bt_release_service(void) _bt_clear_request_list(); +#ifndef GATT_NO_RELAY + _bt_clear_gatt_client_senders(); +#endif _bt_service_cynara_deinit(); BT_DBG("Terminating the bt-service daemon"); @@ -89,11 +89,10 @@ gboolean _bt_terminate_service(gpointer user_data) if(vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0) BT_ERR("Set vconf failed\n"); -#if 0 + if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE, EVT_VAL_BT_OFF) != ES_R_OK) BT_ERR("Fail to set value"); -#endif } } @@ -104,11 +103,9 @@ gboolean _bt_terminate_service(gpointer user_data) if(vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0) BT_ERR("Set vconf failed\n"); -#if 0 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE, EVT_VAL_BT_LE_OFF) != ES_R_OK) BT_ERR("Fail to set value"); -#endif } } @@ -156,7 +153,7 @@ gboolean _bt_reliable_terminate_service(gpointer user_data) static gboolean __bt_check_bt_service(void *data) { int bt_status = VCONFKEY_BT_STATUS_OFF; - int bt_le_status = 0; + int bt_le_status = VCONFKEY_BT_LE_STATUS_OFF; bt_status_t status = BT_DEACTIVATED; bt_le_status_t le_status = BT_LE_DEACTIVATED; int flight_mode_deactivation = 0; @@ -164,6 +161,7 @@ static gboolean __bt_check_bt_service(void *data) #if 0 int ps_mode_deactivation = 0; #endif + status = _bt_adapter_get_status(); le_status = _bt_adapter_get_le_status(); BT_DBG("State: %d, LE State: %d", status, le_status); @@ -201,7 +199,7 @@ static gboolean __bt_check_bt_service(void *data) _bt_enable_core(); } - if ((bt_le_status == 1) && (le_status == BT_LE_DEACTIVATED)) { + if ((bt_le_status == VCONFKEY_BT_LE_STATUS_ON) && (le_status == BT_LE_DEACTIVATED)) { BT_DBG("Previous session was le enabled. Turn BT LE on automatically."); /* Enable the BT LE */ @@ -213,6 +211,7 @@ static gboolean __bt_check_bt_service(void *data) if ((status != BT_ACTIVATING && status != BT_ACTIVATED) && (le_status != BT_LE_ACTIVATING && le_status != BT_LE_ACTIVATED)){ + _bt_terminate_service(NULL); } } #endif @@ -269,6 +268,10 @@ int main(void) _bt_init_request_list(); +#ifndef GATT_NO_RELAY + _bt_init_gatt_client_senders(); +#endif + g_timeout_add(500, (GSourceFunc)__bt_check_bt_service, NULL); if (terminated == TRUE) { diff --git a/bt-service/bt-service-network.c b/bt-service/bt-service-network.c index 1829891..9d74d66 100644 --- a/bt-service/bt-service-network.c +++ b/bt-service/bt-service-network.c @@ -205,7 +205,7 @@ static void __bt_network_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res, bt_function_data_t *func_data; request_info_t *req_info; - g_dbus_proxy_call_finish(proxy, res, &g_error); + reply = g_dbus_proxy_call_finish(proxy, res, &g_error); g_object_unref(proxy); if (reply == NULL) { @@ -285,6 +285,7 @@ int _bt_network_activate(void) NULL, &err); if (err != NULL) { + g_dbus_error_strip_remote_error(err); BT_ERR("Network server register Error: %s\n", err->message); if (g_strcmp0(err->message, "Already Exists") == 0) { ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED; @@ -329,6 +330,7 @@ int _bt_network_deactivate(void) NULL, &err); if (err != NULL) { + g_dbus_error_strip_remote_error(err); BT_ERR("Network server unregister Error: %s\n", err->message); if (g_strcmp0(err->message, "Operation currently not available") == 0) { @@ -528,8 +530,5 @@ int _bt_network_server_disconnect(int request_id, (GAsyncReadyCallback)__bt_network_disconnect_cb, func_data); - g_free(func_data->address); - g_free(func_data); - return BLUETOOTH_ERROR_NONE; } diff --git a/bt-service/bt-service-obex-agent.c b/bt-service/bt-service-obex-agent.c index 174373e..f79550c 100644 --- a/bt-service/bt-service-obex-agent.c +++ b/bt-service/bt-service-obex-agent.c @@ -389,13 +389,11 @@ void _bt_obex_agent_new(char *path) } } info = (bt_obex_agent_info *)malloc (sizeof(bt_obex_agent_info)); - if (info == NULL) { - BT_ERR("Failed to allocate memory"); - return; + if (info) { + memset(info, 0, sizeof(bt_obex_agent_info)); + info->path = g_strdup(path); + obex_agent_list = g_slist_append(obex_agent_list, info); } - memset(info, 0, sizeof(bt_obex_agent_info)); - info->path = g_strdup(path); - obex_agent_list = g_slist_append(obex_agent_list, info); } void _bt_obex_agent_destroy(char *path) @@ -450,6 +448,8 @@ gboolean _bt_obex_setup(const char *path) } new_conn_node = g_dbus_node_info_new_for_xml(obex_service_agent_xml1, NULL); + if (new_conn_node == NULL) + return FALSE; info->openobex_id = g_dbus_connection_register_object(conn, info->path, new_conn_node->interfaces[0], @@ -485,8 +485,10 @@ void _bt_obex_set_authorize_cb(char *object_path, { bt_obex_agent_info *info = __find_obex_agent_info(object_path);; - info->authorize_cb = func; - info->authorize_data = data; + if (info) { + info->authorize_cb = func; + info->authorize_data = data; + } } void _bt_obex_set_release_cb(char *object_path, diff --git a/bt-service/bt-service-obex-server.c b/bt-service/bt-service-obex-server.c index 8b89771..775146b 100644 --- a/bt-service/bt-service-obex-server.c +++ b/bt-service/bt-service-obex-server.c @@ -90,6 +90,11 @@ typedef struct { static GSList *transfers; static bt_obex_agent_info_t agent_info; +int _bt_obex_get_native_pid(void) +{ + return agent_info.native_server->app_pid; +} + static GQuark __bt_obex_error_quark(void) { static GQuark quark = 0; @@ -230,7 +235,7 @@ static char *__bt_get_remote_device_name(const char *bdaddress) device_path = _bt_get_device_object_path((char *)bdaddress); retv_if(device_path == NULL, NULL); - conn = _bt_get_session_gconn(); + conn = _bt_get_system_gconn(); retv_if(conn == NULL, NULL); BT_INFO("Device_path %s", device_path); device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, diff --git a/bt-service/bt-service-oob.c b/bt-service/bt-service-oob.c index ded3a18..3fa096e 100644 --- a/bt-service/bt-service-oob.c +++ b/bt-service/bt-service-oob.c @@ -112,7 +112,6 @@ int _bt_oob_read_local_data(bt_oob_data_t *local_oob_data) memcpy(local_oob_data->randomizer, local_randomizer, local_oob_data->randomizer_len); - return BLUETOOTH_ERROR_NONE; } diff --git a/bt-service/bt-service-opp-client.c b/bt-service/bt-service-opp-client.c index 74b1829..97519e8 100644 --- a/bt-service/bt-service-opp-client.c +++ b/bt-service/bt-service-opp-client.c @@ -341,7 +341,9 @@ static void __bt_sending_release_cb(GDBusProxy *proxy, BT_DBG("Session Removed"); } - sending_info->result = result; + if (sending_info->result != BLUETOOTH_ERROR_CANCEL_BY_USER) + sending_info->result = result; + param = g_variant_new("(isi)", sending_info->result, sending_info->address, sending_info->request_id); @@ -472,7 +474,7 @@ static void __bt_send_file_cb(GDBusProxy *proxy, const char *transfer_name = NULL; const char *file_name = NULL; int size = 0; - GVariantIter *iter; + GVariantIter *iter = NULL; value = g_dbus_proxy_call_finish(proxy, res, &error); if (error) { BT_ERR("%s", error->message); diff --git a/bt-service/bt-service-pbap.c b/bt-service/bt-service-pbap.c index 29a8c89..a2b643d 100644 --- a/bt-service/bt-service-pbap.c +++ b/bt-service/bt-service-pbap.c @@ -46,40 +46,42 @@ #define PBAP_SESSION_SERVICE "org.bluez.obex" #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1" -#define PBAP_VCARDLIST_MAXLENGTH 256 - -typedef enum { -PBAP_FIELD_ALL, -PBAP_FIELD_VERSION, -PBAP_FIELD_FN, -PBAP_FIELD_N, -PBAP_FIELD_PHOTO, -PBAP_FIELD_BDAY, -PBAP_FIELD_ADR, -PBAP_FIELD_LABEL, -PBAP_FIELD_TEL, -PBAP_FIELD_EMAIL, -PBAP_FIELD_MAILER, -PBAP_FIELD_TZ, -PBAP_FIELD_GEO, -PBAP_FIELD_TITLE, -PBAP_FIELD_ROLE, -PBAP_FIELD_LOGO, -PBAP_FIELD_AGENT, -PBAP_FIELD_ORG, -PBAP_FIELD_NOTE, -PBAP_FIELD_REV, -PBAP_FIELD_SOUND, -PBAP_FIELD_URL, -PBAP_FIELD_UID, -PBAP_FIELD_KEY, -PBAP_FIELD_NICKNAME, -PBAP_FIELD_CATEGORIES, -PBAP_FIELD_PROID, -PBAP_FIELD_CLASS, -PBAP_FIELD_SORT_STRING, -PBAP_FIELD_X_IRMC_CALL_DATETIME, -} bt_pbap_field_e; +#define PBAP_VCARDLIST_MAXLENGTH 256 + +#define PBAP_NUM_OF_FIELDS_ENTRY 29 +#define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL) + +char *FIELDS[] = { + "VERSION", + "FN", + "N", + "PHOTO", + "BDAY", + "ADR", + "LABEL", + "TEL", + "EMAIL", + "MAILER", + "TZ", + "GEO", + "TITLE", + "ROLE", + "LOGO", + "AGENT", + "ORG", + "NOTE", + "REV", + "SOUND", + "URL", + "UID", + "KEY", + "NICKNAME", + "CATEGORIES", + "PROID", + "CLASS", + "SORT-STRING", + "X-IRMC-CALL-DATETIME", /* 29 */ +}; char *SOURCE[] = { "int", //Phone memory @@ -782,14 +784,18 @@ int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data) { BT_DBG("+"); + int i; char *format_str = NULL; + char *fields_str = NULL; char *order_str = NULL; char *target_file = "/opt/usr/media/Downloads/pb.vcf"; bt_pbap_pull_parameters_t *app_param = pbap_data->app_param; GVariantBuilder builder; + GVariantBuilder inner_builder; GVariant *filters; g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY); /* Add MaxlistCount*/ g_variant_builder_add(&builder, "{sv}", "MaxCount", @@ -815,6 +821,28 @@ int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data) g_variant_new("s", format_str)); } + /* Add Filter AttributeMask (64bit) */ + if (app_param->fields > 0) { + if (app_param->fields == PBAP_FIELD_ALL) { + BT_DBG("** CHECKED ALL **"); + fields_str = g_strdup("ALL"); + g_variant_builder_add(&inner_builder, "s", fields_str); + g_free(fields_str); + } else { + for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) { + if (app_param->fields & (1ULL << i)) { + BT_DBG("** CHECKED[%d]", i); + fields_str = g_strdup(FIELDS[i]); + g_variant_builder_add(&inner_builder, "s", fields_str); + g_free(fields_str); + } + } + } + + g_variant_builder_add(&builder, "{sv}", "Fields", + g_variant_new("as", &inner_builder)); + } + filters = g_variant_builder_end(&builder); //**************************** @@ -880,6 +908,9 @@ int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data) g_free(folder); g_free(order_str); g_hash_table_unref(filters); + /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null. + The path should be reset here */ + selected_path.type = -1; BT_DBG("-"); return BLUETOOTH_ERROR_NONE; @@ -889,15 +920,19 @@ int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data) { BT_DBG("+"); + int i; char *format_str = NULL; + char *fields_str = NULL; char *target_file = "/opt/usr/media/Downloads/pb.vcf"; char *vcard_handle = NULL; char vcard[10] = { 0, }; GVariantBuilder builder; + GVariantBuilder inner_builder; GVariant *filters; bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param; g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY); /* Add Format Filter only if other than vCard 2.1 (default)*/ // if (app_param->format > 0) { @@ -905,6 +940,29 @@ int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data) g_variant_builder_add(&builder, "{sv}", "Format", g_variant_new("s", format_str)); // } + + /* Add Filter AttributeMask (64bit) */ + if (app_param->fields > 0) { + if (app_param->fields == PBAP_FIELD_ALL) { + BT_DBG("** CHECKED ALL **"); + fields_str = g_strdup("ALL"); + g_variant_builder_add(&inner_builder, "s", fields_str); + g_free(fields_str); + } else { + for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) { + if (app_param->fields & (1ULL << i)) { + BT_DBG("** CHECKED[%d]", i); + fields_str = g_strdup(FIELDS[i]); + g_variant_builder_add(&inner_builder, "s", fields_str); + g_free(fields_str); + } + } + } + + g_variant_builder_add(&builder, "{sv}", "Fields", + g_variant_new("as", &inner_builder)); + } + filters = g_variant_builder_end(&builder); //**************************** diff --git a/bt-service/bt-service-rfcomm-client.c b/bt-service/bt-service-rfcomm-client.c index e1e6a99..a7eeed0 100644 --- a/bt-service/bt-service-rfcomm-client.c +++ b/bt-service/bt-service-rfcomm-client.c @@ -21,8 +21,7 @@ * */ -//#include -//#include +#include #include #include #include diff --git a/bt-service/bt-service-rfcomm-server.c b/bt-service/bt-service-rfcomm-server.c index 1710da6..0ec0d5d 100644 --- a/bt-service/bt-service-rfcomm-server.c +++ b/bt-service/bt-service-rfcomm-server.c @@ -21,8 +21,7 @@ * */ -//#include -//#include +#include #include #include #include diff --git a/bt-service/include/bt-service-adapter-le.h b/bt-service/include/bt-service-adapter-le.h index a1275a4..80099b2 100755 --- a/bt-service/include/bt-service-adapter-le.h +++ b/bt-service/include/bt-service-adapter-le.h @@ -127,6 +127,23 @@ int _bt_le_write_host_suggested_default_data_length(const unsigned int def_tx_Oc int _bt_le_read_host_suggested_default_data_length(bluetooth_le_read_host_suggested_data_length_t *def_data_length); int _bt_le_set_data_length(bluetooth_device_address_t *device_address, const unsigned int max_tx_Octets, const unsigned int max_tx_Time); + +int _bt_initialize_ipsp(void); + +int _bt_deinitialize_ipsp(void); + +void _bt_init_gatt_client_senders(void); + +int _bt_insert_gatt_client_sender(char *sender); + +int _bt_delete_gatt_client_sender(char *sender); + +void _bt_clear_gatt_client_senders(void); + +void _bt_send_char_value_changed_event(void *param); + +gboolean _bt_is_set_scan_parameter(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bt-service/include/bt-service-common.h b/bt-service/include/bt-service-common.h index a5fec2a..37db665 100644 --- a/bt-service/include/bt-service-common.h +++ b/bt-service/include/bt-service-common.h @@ -381,9 +381,9 @@ int _bt_set_socket_non_blocking(int socket_fd); int _bt_set_non_blocking_tty(int sk); void _bt_deinit_bluez_proxy(void); -#if 0 + int _bt_eventsystem_set_value(const char *event, const char *key, const char *value); -#endif + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bt-service/include/bt-service-device.h b/bt-service/include/bt-service-device.h index 738da3a..e019c8d 100644 --- a/bt-service/include/bt-service-device.h +++ b/bt-service/include/bt-service-device.h @@ -39,6 +39,10 @@ int _bt_bond_device(int request_id, int _bt_cancel_bonding(void); +int _bt_passkey_reply(const char *passkey, gboolean authentication_reply); + +int _bt_passkey_confirmation_reply(gboolean confirmation_reply); + int _bt_unbond_device(int request_id, bluetooth_device_address_t *device_address, GArray **out_param1); @@ -63,6 +67,13 @@ int _bt_is_device_connected(bluetooth_device_address_t *device_address, int _bt_get_connected_link(bluetooth_device_address_t *device_address, bluetooth_connected_link_t *connected); +int _bt_set_pin_code(bluetooth_device_address_t *device_address, + bluetooth_device_pin_code_t *pin_code); + +int _bt_unset_pin_code(bluetooth_device_address_t *device_address); + +int _bt_get_device_pin_code(const char *address, char *pin_code); + gboolean _bt_is_device_creating(void); void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair); @@ -73,19 +84,29 @@ char *_bt_get_bonded_device_name(char *address); gboolean _bt_is_bonding_device_address(const char *address); -int _bt_connect_le_device(const bluetooth_device_address_t *bd_addr, gboolean auto_connect); +int _bt_connect_le_device(int request_id, + const bluetooth_device_address_t *bd_addr, + gboolean auto_connect); -int _bt_disconnect_le_device(const bluetooth_device_address_t *bd_addr); +int _bt_disconnect_le_device(int request_id, + const bluetooth_device_address_t *bd_addr); int _bt_le_conn_update(unsigned char *device_address, guint16 interval_min, guint16 interval_max, guint16 latency, guint16 time_out); +int _bt_get_le_connection_parameter(bluetooth_le_connection_mode_t mode, + bluetooth_le_connection_param_t *param); + 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); +int _bt_connect_le_ipsp_device(const bluetooth_device_address_t *bd_addr); + +int _bt_disconnect_le_ipsp_device(const bluetooth_device_address_t *bd_addr); + #ifdef __cplusplus } diff --git a/bt-service/include/bt-service-obex-server.h b/bt-service/include/bt-service-obex-server.h index 571f1f2..a7f23e5 100644 --- a/bt-service/include/bt-service-obex-server.h +++ b/bt-service/include/bt-service-obex-server.h @@ -80,6 +80,8 @@ void _bt_obex_transfer_connected(void); void _bt_obex_transfer_disconnected(void); +int _bt_obex_get_native_pid(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bt-service/org.projectx.bt.service b/bt-service/org.projectx.bt.service index 079751c..7444ab5 100644 --- a/bt-service/org.projectx.bt.service +++ b/bt-service/org.projectx.bt.service @@ -1,4 +1,5 @@ [D-BUS Service] Name=org.projectx.bt Exec=/bin/false +User=root SystemdService=bluetooth-frwk.service diff --git a/include/bluetooth-api.h b/include/bluetooth-api.h index 90dda2a..7703e48 100755 --- a/include/bluetooth-api.h +++ b/include/bluetooth-api.h @@ -45,6 +45,7 @@ extern "C" { #define BLUETOOTH_VERSION_LENGTH_MAX 30 /**< This specifies bluetooth device version length */ #define BLUETOOTH_INTERFACE_NAME_LENGTH 16 #define BLUETOOTH_DEVICE_NAME_LENGTH_MAX 248 /**< This specifies maximum device name length */ +#define BLUETOOTH_DEVICE_PASSKEY_LENGTH_MAX 50 /**< This specifies maximum length of the passkey */ #define BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX 31 /**< This specifies maximum AD data length */ #define BLUETOOTH_SCAN_RESP_DATA_LENGTH_MAX 31 /**< This specifies maximum LE Scan response data length */ #define BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX 240 /**< This specifies maximum manufacturer data length */ @@ -55,7 +56,10 @@ extern "C" { #define BLUETOOTH_UUID_STRING_MAX 50 #define BLUETOOTH_PATH_STRING 50 -#define BLUETOOTH_OOB_DATA_LENGTH 16 +#define BLUETOOTH_OOB_DATA_LENGTH 16 + +#define BLUETOOTH_PIN_CODE_MAX_LENGTH 16 + /** * This is Bluetooth Connected event role */ @@ -212,6 +216,10 @@ typedef struct { char data[BLUETOOTH_MANUFACTURER_DATA_LENGTH_MAX]; } bluetooth_manufacturer_data_t; +typedef struct { + char pin_code[BLUETOOTH_PIN_CODE_MAX_LENGTH + 1]; +} bluetooth_device_pin_code_t; + /** * Adapter state */ @@ -345,6 +353,14 @@ typedef enum }bt_gatt_characteristic_property_t; /** +* Remote device request types for attributes +*/ +typedef enum { + BLUETOOTH_GATT_ATT_REQUEST_TYPE_READ = 0x00, /* Read Requested*/ + BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE = 0x01, /* Write Requested*/ +} bluetooth_gatt_att_request_tyep_t; + +/** * Advertising parameters */ typedef struct { @@ -370,8 +386,9 @@ typedef struct { guint16 interval_min; guint16 interval_max; guint16 latency; - guint16 time_out; -} bluetooth_le_conn_update_t; + guint16 timeout; +} bluetooth_le_connection_param_t; + /* LE Read Maximum Data Length */ @@ -427,6 +444,8 @@ typedef struct { /**< Base ID for PBAP Client events */ #define BLUETOOTH_EVENT_AVRCP_CONTROL_BASE ((int)(BLUETOOTH_EVENT_PBAP_CLIENT_BASE + 0x0020)) /**< Base ID for AVRCP events */ +#define BLUETOOTH_EVENT_IPSP_BASE ((int)(BLUETOOTH_EVENT_AVRCP_CONTROL_BASE + 0x0020)) + /**< Base ID for IPSP events */ /** * Bluetooth event type @@ -457,6 +476,10 @@ typedef enum { BLUETOOTH_EVENT_DEVICE_AUTHORIZED, /**< Bluetooth event authorize device */ BLUETOOTH_EVENT_DEVICE_UNAUTHORIZED, /**< Bluetooth event unauthorize device */ BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED, /**< Bluetooth event mode changed */ + BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, /**Bluetooth event for displaying keyboard passkey to user*/ + BLUETOOTH_EVENT_PIN_REQUEST, /**Bluetooth event for PIN input by user*/ + BLUETOOTH_EVENT_PASSKEY_REQUEST, /**Bluetooth event for entering Passkey by user*/ + BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, /**Bluetooth event for Passkey confirmation by user*/ BLUETOOTH_EVENT_CONNECTABLE_CHANGED, /**< Bluetooth event connectable changed */ BLUETOOTH_EVENT_RSSI_ENABLED, /**< Bluetooth event RSSI monitoring enabled */ @@ -523,6 +546,9 @@ typedef enum { BLUETOOTH_EVENT_GATT_DISCONNECTED, /** #include -#include -#include #include #include "bluetooth-api.h" diff --git a/include/bluetooth-ipsp-api.h b/include/bluetooth-ipsp-api.h new file mode 100644 index 0000000..7dee34a --- /dev/null +++ b/include/bluetooth-ipsp-api.h @@ -0,0 +1,138 @@ +/* + * Bluetooth-frwk + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Paras Kumar + * + * 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 __BLUETOOTH_LE_IPSP_API_H +#define __BLUETOOTH_LE_IPSP_API_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#define IPSP_ADDRESS_LENGTH 6 + +#define IPSP_ERROR_NONE ((int)0) + +#define IPSP_ERROR_BASE ((int)0) +#define IPSP_ERROR_ALREADY_INITIALIZED ((int)IPSP_ERROR_BASE - 0x01) +#define IPSP_ERROR_NOT_INITIALIZED ((int)IPSP_ERROR_BASE - 0x01) +#define IPSP_ERROR_NOT_PAIRED ((int)IPSP_ERROR_BASE - 0x02) +#define IPSP_ERROR_INTERNAL ((int)IPSP_ERROR_BASE - 0x03) +#define IPSP_ERROR_INVALID_PARAM ((int)IPSP_ERROR_BASE - 0x04) +#define IPSP_ERROR_NOT_ENABLED ((int)IPSP_ERROR_BASE - 0x05) +#define IPSP_ERROR_CONNECTION_FAILED ((int)IPSP_ERROR_BASE - 0x06) +#define IPSP_ERROR_PERMISSION_DEINED ((int)BLUETOOTH_ERROR_BASE - 0x07) + +typedef struct { + int event; + int result; + void *param_data; + void *user_data; +} ipsp_event_param_t; + +typedef void (*ipsp_cb_func_ptr)(int, ipsp_event_param_t *, void *); + +typedef struct { + unsigned char addr[IPSP_ADDRESS_LENGTH]; +} ipsp_device_address_t; + +/** + * @fn int bluetooth_le_ipsp_init(void) + * + * @brief Initializes IPSP service and register the service to Bluez + * + * This function is a synchronous call. + * The IPSP Initialize request is responded by BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED event. + * + * @return IPSP_ERROR_NONE - Success \n + * IPSP_ERROR_ALREADY_INITIALIZED - Aready Initialized \n + * IPSP_ERROR_INTERNAL - Internal Error \n + * IPSP_ERROR_NOT_ENABLED - Not enabled \n + * + * @exception None + * @param[in] None + * @remark None + * + */ +int bluetooth_le_ipsp_init(void); + +/** + * @fn int bluetooth_le_ipsp_deinit(void) + * + * @brief De-Initialize IPSP service and un-register the callback + * The IPSP De-Initialize request is responded by BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED event. + * + * This function is a synchronous call. + * + * @return IPSP_ERROR_NONE - Success \n + * IPSP_ERROR_NOTY_INITIALIZED - Aready Initialized \n + * IPSP_ERROR_INTERNAL - Internal Error \n + * IPSP_ERROR_NOT_ENABLED - Not enabled \n + * + * @remark None + * + */ +int bluetooth_le_ipsp_deinit(void); + +/** + * @fn int bluetooth_le_ipsp_connect(const ipsp_device_address_t *device_address); + * + * @brief Connects to IPSP Router device. It establishes connection for 6Lowpan over LE. + * + * This function is a asynchronous call. + * + * @return IPSP_ERROR_NONE - Success \n + * BLUETOOTH_ERROR_INVALID_PARAM -Invalid Parameters \n + * BLUETOOTH_ERROR_DEVICE_NOT_ENABLED - Bluetooth Not enabled \n + * + * @exception None + * @param[in] device_address - remote device address. + * + * @remark None + * @see bluetooth_le_ipsp_disconnect() + */ +int bluetooth_le_ipsp_connect(const ipsp_device_address_t *device_address); + +/** + * @fn int bluetooth_le_ipsp_disconnect(const ipsp_device_address_t *device_address); + * + * @brief Disconnects to IPSP Router device. It disconnects connection for 6Lowpan over LE. + * + * This function is a asynchronous call. + * + * @return IPSP_ERROR_NONE - Success \n + * BLUETOOTH_ERROR_INVALID_PARAM -Invalid Parameters \n + * BLUETOOTH_ERROR_DEVICE_NOT_ENABLED - Bluetooth Not enabled \n + * + * @exception None + * @param[in] device_address - remote device address. + * + * @remark None + * @see bluetooth_le_ipsp_disconnect() + */ +int bluetooth_le_ipsp_disconnect(const ipsp_device_address_t *device_address); + + +#ifdef __cplusplus +} +#endif +#endif /* __BLUETOOTH_LE_IPSP_API_H */ + diff --git a/include/bluetooth-telephony-api.h b/include/bluetooth-telephony-api.h index a41d8cf..845805d 100644 --- a/include/bluetooth-telephony-api.h +++ b/include/bluetooth-telephony-api.h @@ -26,8 +26,6 @@ #include #include -#include -#include #include #ifdef __cplusplus diff --git a/include/bt-internal-types.h b/include/bt-internal-types.h index af923e4..665aada 100755 --- a/include/bt-internal-types.h +++ b/include/bt-internal-types.h @@ -69,6 +69,9 @@ typedef enum { BT_AVRCP_CONTROL_EVENT, BT_A2DP_SOURCE_EVENT, BT_HID_DEVICE_EVENT, +#ifdef GATT_NO_RELAY + BT_GATT_BLUEZ_EVENT, /* GattValueChanged from bluez directly */ +#endif /* Will be added */ } bt_event_type_t; @@ -129,6 +132,7 @@ typedef enum { #define BT_FUNC_PBAP_BASE ((int)(BT_FUNC_RFCOMM_BASE + 0x0020)) #define BT_FUNC_HDP_BASE ((int)(BT_FUNC_PBAP_BASE + 0x0020)) #define BT_FUNC_GATT_BASE ((int)(BT_FUNC_HDP_BASE + 0x0020)) +#define BT_FUNC_IPSP_BASE ((int)(BT_FUNC_GATT_BASE + 0x0020)) typedef enum { BT_CHECK_ADAPTER = BT_FUNC_BASE, @@ -182,6 +186,8 @@ typedef enum { BT_BOND_DEVICE = BT_FUNC_DEVICE_BASE, BT_BOND_DEVICE_BY_TYPE, BT_CANCEL_BONDING, + BT_PASSKEY_REPLY, + BT_PASSKEY_CONFIRMATION_REPLY, BT_UNBOND_DEVICE, BT_SEARCH_SERVICE, BT_CANCEL_SEARCH_SERVICE, @@ -191,6 +197,9 @@ typedef enum { BT_UNSET_AUTHORIZATION, BT_IS_DEVICE_CONNECTED, BT_GET_CONNECTED_LINK_TYPE, + BT_SET_PIN_CODE, + BT_UNSET_PIN_CODE, + BT_UPDATE_LE_CONNECTION_MODE, BT_HID_CONNECT = BT_FUNC_HID_BASE, BT_HID_DISCONNECT, BT_HID_DEVICE_ACTIVATE, @@ -280,6 +289,14 @@ typedef enum { BT_GATT_SET_PROPERTY_REQUEST, BT_GATT_READ_CHARACTERISTIC, BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR, +#ifndef GATT_NO_RELAY + BT_GATT_WATCH_CHARACTERISTIC, + BT_GATT_UNWATCH_CHARACTERISTIC, +#endif + BT_LE_IPSP_INIT = BT_FUNC_IPSP_BASE, + BT_LE_IPSP_DEINIT, + BT_LE_IPSP_CONNECT, + BT_LE_IPSP_DISCONNECT, } bt_function_t; typedef struct { @@ -310,6 +327,9 @@ typedef struct { #define BT_HF_SERVICE_INTERFACE "org.tizen.HfApp" #define BT_CORE_EVENT_INTERFACE "org.projectx.bt_core_event" #define BT_HF_LOCAL_TERM_EVENT_INTERFACE "org.projectx.bt_hf_local_term" +#ifdef GATT_NO_RELAY +#define BT_GATT_CHARACTERISTIC_INTERFACE "org.bluez.GattCharacteristic1" +#endif #define BT_ADAPTER_PATH "/org/projectx/bt/adapter" #define BT_LE_ADAPTER_PATH "/org/projectx/bt/le/adapter" @@ -344,6 +364,7 @@ typedef struct { #define BT_LE_DISCOVERY_STARTED "LEDiscoveryStarted" #define BT_LE_DISCOVERY_FINISHED "LEDiscoveryFinished" #define BT_LE_DEVICE_FOUND "LEDeviceFound" +#define BT_READ_MAXIMUM_LE_DATA_LENGTH "ReadMaximumLEDataLength" #define BT_ADVERTISING_STARTED "AdvertisingStarted" #define BT_ADVERTISING_STOPPED "AdvertisingStopped" #define BT_ADVERTISING_MANUFACTURER_DATA_CHANGED "AdvertisingManufacturerDataChanged" @@ -354,6 +375,10 @@ typedef struct { #define BT_DEVICE_PROFILE_STATE_CHANGED "ProfileStateChanged" #define BT_BOND_CREATED "BondCreated" #define BT_BOND_DESTROYED "BondDestroyed" +#define BT_KBD_PASSKEY_DISPLAY_REQ_RECEIVED "KeyBoardPasskeyDisplayRequest" +#define BT_PIN_REQ_RECEIVED "PinRequest" +#define BT_PASSKEY_REQ_RECEIVED "PasskeyRequest" +#define BT_PASSKEY_CFM_REQ_RECEIVED "PasskeyConfirmRequest" #define BT_DEVICE_AUTHORIZED "DeviceAuthorized" #define BT_DEVICE_UNAUTHORIZED "DeviceUnauthorized" #define BT_RSSI_MONITORING_ENABLED "RssiMonitoringEnabled" @@ -413,11 +438,17 @@ typedef struct { #define BT_GATT_CONNECTED "GattConnected" #define BT_GATT_DISCONNECTED "GattDisconnected" #define BT_GATT_CHAR_VAL_CHANGED "GattCharValueChanged" +#ifdef GATT_NO_RELAY +#define BT_GATT_BLUEZ_CHAR_VAL_CHANGED "GattValueChanged" +#endif #define BT_HARDWARE_ERROR "HardwareError" #define BT_TX_TIMEOUT_ERROR "TxTimeoutError" #define BT_HF_LOCAL_TERM "HandsfreeLocalTermination" #define BT_HID_DEVICE_CONNECTED "HIDConnected" #define BT_HID_DEVICE_DISCONNECTED "HIDDisconnected" +#define BT_IPSP_INITIALIZED "IpspInitStateChanged" +#define BT_IPSP_CONNECTED "IpspConnected" +#define BT_IPSP_DISCONNECTED "IpspDisconnected" #define BT_LE_DATA_LENGTH_CHANGED "LEDataLengthChanged" #ifdef __cplusplus diff --git a/packaging/bluetooth-frwk.spec b/packaging/bluetooth-frwk.spec index b2fdcbb..a435491 100644 --- a/packaging/bluetooth-frwk.spec +++ b/packaging/bluetooth-frwk.spec @@ -47,7 +47,8 @@ BuildRequires: pkgconfig(capi-content-mime-type) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(pkgmgr) #BuildRequires: pkgconfig(journal) -#BuildRequires: pkgconfig(eventsystem) +BuildRequires: pkgconfig(eventsystem) +BuildRequires: pkgconfig(libsoup-2.4) %if "%{?profile}" == "mobile" BuildRequires: pkgconfig(capi-network-tethering) %endif @@ -83,6 +84,14 @@ Requires: %{name} = %{version}-%{release} %description service This package is Bluetooth Service daemon to manage BT services. +%package httpproxy +Summary: Bluetooth HTTP Proxy Service daemon +Group: TO_BE/FILLED +Requires: %{name} = %{version}-%{release} + +%description httpproxy +This package is Bluetooth HTTP Proxy Service daemon + %package core Summary: Bluetooth Core daemon Group: Network & Connectivity/Bluetooth @@ -173,6 +182,7 @@ rm -rf %{buildroot} install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk-service +install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk-httpproxy install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk-devel #mkdir -p %{buildroot}%{_libdir}/systemd/user @@ -237,6 +247,7 @@ sed -i 's/%TZ_SYS_DEFAULT_USER/app/' %{buildroot}%{_datadir}/dbus-1/system-servi %{_includedir}/bt-service/bluetooth-telephony-api.h %{_includedir}/bt-service/bluetooth-media-control.h %{_includedir}/bt-service/bluetooth-scmst-api.h +%{_includedir}/bt-service/bluetooth-ipsp-api.h %{_libdir}/pkgconfig/bluetooth-api.pc %{_libdir}/libbluetooth-api.so %{_datadir}/license/bluetooth-frwk-devel @@ -245,7 +256,6 @@ sed -i 's/%TZ_SYS_DEFAULT_USER/app/' %{buildroot}%{_datadir}/dbus-1/system-servi %manifest %{name}.manifest %defattr(-, root, root) %{_datadir}/dbus-1/system-services/org.projectx.bt.service - %{_bindir}/bt-service #%{_libdir}/systemd/user/bluetooth-frwk-tv.service %{_unitdir}/%{_servicedir}/bluetooth-frwk.service @@ -263,6 +273,13 @@ sed -i 's/%TZ_SYS_DEFAULT_USER/app/' %{buildroot}%{_datadir}/dbus-1/system-servi %{_datadir}/icons/default/bt-icon.png %endif +%files httpproxy +%manifest %{name}.manifest +%defattr(-, root, root) +%{_bindir}/bt-httpproxy +%{_datadir}/license/bluetooth-frwk-httpproxy +%{_datadir}/dbus-1/system-services/org.projectx.httpproxy.service + %files core %manifest %{name}.manifest %defattr(-, root, root) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4c628e3..37e1396 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,7 +9,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) INCLUDE(FindPkgConfig) -pkg_check_modules(package REQUIRED dlog dbus-glib-1 glib-2.0 gthread-2.0) +pkg_check_modules(package REQUIRED dlog dbus-1 glib-2.0 gthread-2.0 gobject-2.0) FOREACH(flag ${package_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/test/bluetooth-frwk-test.c b/test/bluetooth-frwk-test.c index 146086c..be1a291 100644 --- a/test/bluetooth-frwk-test.c +++ b/test/bluetooth-frwk-test.c @@ -536,7 +536,9 @@ int test_input_callback(void *data) //bluetooth_device_address_t device_address={{0x00,0x19,0x0E,0x01,0x61,0x17}}; /* DO-DH79-PYUN04 */ //bluetooth_device_address_t device_address={{0x00,0x16,0x38,0xC3,0x1F,0xD2}}; /* DO-DH79-PYUN03 */ //bluetooth_device_address_t device_address={{0x58,0x17,0x0C,0xEC,0x6A,0xF3}}; /* MW600 */ - bluetooth_device_address_t device_address={{0x00,0x0D,0xFD,0x24,0x5E,0xFF}}; /* Motorola S9 */ + //bluetooth_device_address_t device_address={{0x00,0x0D,0xFD,0x24,0x5E,0xFF}}; /* Motorola S9 */ + bluetooth_device_address_t device_address={{0xDC,0x2C,0x26,0xD0,0xF3,0xC1}}; /* BT Keyboard */ + //bluetooth_device_address_t device_address={{0x00,0x1F,0x20,0x36,0x41,0xAC}}; /* BT Mouse */ TC_PRT("dev [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]", \ device_address.addr[0], device_address.addr[1], device_address.addr[2], \ @@ -1230,12 +1232,7 @@ void startup() { TC_PRT("bluetooth framework TC startup"); - if(!g_thread_supported()) - { - g_thread_init(NULL); - } - - dbus_g_thread_init(); + dbus_threads_init_default(); g_type_init(); main_loop = g_main_loop_new(NULL, FALSE); @@ -1705,6 +1702,65 @@ void bt_event_callback(int event, bluetooth_event_param_t* param, void *user_dat break; } #endif + case BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY: + { + bluetooth_authentication_request_info_t *auth_info = param->param_data; + + TC_PRT("BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY"); + TC_PRT("Device Address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]", + auth_info->device_address.addr[0], auth_info->device_address.addr[1], + auth_info->device_address.addr[2], auth_info->device_address.addr[3], + auth_info->device_address.addr[4], auth_info->device_address.addr[5]); + TC_PRT("Device Name : [%s]", auth_info->device_name.name); + TC_PRT("Passkey: [%s]", auth_info->str_passkey); + break; + } + case BLUETOOTH_EVENT_PIN_REQUEST: + { + bluetooth_authentication_request_info_t *auth_info = param->param_data; + + TC_PRT("BLUETOOTH_EVENT_PIN_REQUEST"); + TC_PRT("Device Address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]", + auth_info->device_address.addr[0], auth_info->device_address.addr[1], + auth_info->device_address.addr[2], auth_info->device_address.addr[3], + auth_info->device_address.addr[4], auth_info->device_address.addr[5]); + TC_PRT("Device Name : [%s]", auth_info->device_name.name); + + TC_PRT("bluetooth_passkey_reply(\"0000\", TRUE)"); + bluetooth_passkey_reply("0000", TRUE); + break; + } + case BLUETOOTH_EVENT_PASSKEY_REQUEST: + { + bluetooth_authentication_request_info_t *auth_info = param->param_data; + + TC_PRT("BLUETOOTH_EVENT_PASSKEY_REQUEST"); + TC_PRT("Device Address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]", + auth_info->device_address.addr[0], auth_info->device_address.addr[1], + auth_info->device_address.addr[2], auth_info->device_address.addr[3], + auth_info->device_address.addr[4], auth_info->device_address.addr[5]); + TC_PRT("Device Name : [%s]", auth_info->device_name.name); + + TC_PRT("bluetooth_passkey_reply(\"0000\", TRUE)"); + bluetooth_passkey_reply("0000", TRUE); + break; + } + case BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST: + { + bluetooth_authentication_request_info_t *auth_info = param->param_data; + + TC_PRT("BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST"); + TC_PRT("Device Address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]", + auth_info->device_address.addr[0], auth_info->device_address.addr[1], + auth_info->device_address.addr[2], auth_info->device_address.addr[3], + auth_info->device_address.addr[4], auth_info->device_address.addr[5]); + TC_PRT("Device Name : [%s]", auth_info->device_name.name); + TC_PRT("Passkey: [%s]", auth_info->str_passkey); + + TC_PRT("bluetooth_passkey_confirmation_reply: TRUE"); + bluetooth_passkey_confirmation_reply(TRUE); + break; + } default: TC_PRT("received event [0x%04x]", event); break; diff --git a/test/gatt-test/CMakeLists.txt b/test/gatt-test/CMakeLists.txt index 12f135a..4b6eff6 100644 --- a/test/gatt-test/CMakeLists.txt +++ b/test/gatt-test/CMakeLists.txt @@ -9,7 +9,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../lib) INCLUDE(FindPkgConfig) -pkg_check_modules(package REQUIRED dlog dbus-glib-1 glib-2.0 gthread-2.0) +pkg_check_modules(package REQUIRED dlog dbus-1 glib-2.0 gthread-2.0 gobject-2.0) FOREACH(flag ${package_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/test/gatt-test/bluetooth-gatt-test.c b/test/gatt-test/bluetooth-gatt-test.c index 9aab4e8..d2ae5b1 100644 --- a/test/gatt-test/bluetooth-gatt-test.c +++ b/test/gatt-test/bluetooth-gatt-test.c @@ -231,10 +231,7 @@ void startup() { TC_PRT("bluetooth framework TC startup"); - if (!g_thread_supported()) - g_thread_init(NULL); - - dbus_g_thread_init(); + dbus_threads_init_default(); g_type_init(); main_loop = g_main_loop_new(NULL, FALSE); diff --git a/test/handsfree/CMakeLists.txt b/test/handsfree/CMakeLists.txt index 0f76c64..dcb80d6 100644 --- a/test/handsfree/CMakeLists.txt +++ b/test/handsfree/CMakeLists.txt @@ -8,7 +8,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/bt-api/) INCLUDE(FindPkgConfig) -pkg_check_modules(package REQUIRED dlog dbus-glib-1 glib-2.0 gthread-2.0) +pkg_check_modules(package REQUIRED dlog dbus-1 glib-2.0 gthread-2.0 gobject-2.0) FOREACH(flag ${package_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/test/handsfree/bluetooth-hf-test.c b/test/handsfree/bluetooth-hf-test.c index e57dd57..1b3e2ab 100644 --- a/test/handsfree/bluetooth-hf-test.c +++ b/test/handsfree/bluetooth-hf-test.c @@ -476,11 +476,7 @@ void startup() { TC_PRT("bluetooth framework TC startup"); - if (!g_thread_supported()) { - g_thread_init(NULL); - } - - dbus_g_thread_init(); + dbus_threads_init_default(); g_type_init(); main_loop = g_main_loop_new(NULL, FALSE); diff --git a/test/le-adv/CMakeLists.txt b/test/le-adv/CMakeLists.txt index eecfc22..d55ce1d 100644 --- a/test/le-adv/CMakeLists.txt +++ b/test/le-adv/CMakeLists.txt @@ -9,7 +9,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../lib) INCLUDE(FindPkgConfig) -pkg_check_modules(package REQUIRED dlog dbus-glib-1 glib-2.0 gthread-2.0) +pkg_check_modules(package REQUIRED dlog dbus-1 glib-2.0 gthread-2.0 gobject-2.0) FOREACH(flag ${package_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/test/le-adv/bluetooth-advertising-test.c b/test/le-adv/bluetooth-advertising-test.c index 459c7a0..c409f10 100644 --- a/test/le-adv/bluetooth-advertising-test.c +++ b/test/le-adv/bluetooth-advertising-test.c @@ -241,10 +241,7 @@ void startup() { TC_PRT("bluetooth framework TC startup"); - if (!g_thread_supported()) - g_thread_init(NULL); - - dbus_g_thread_init(); + dbus_threads_init_default(); g_type_init(); main_loop = g_main_loop_new(NULL, FALSE); diff --git a/test/media-control/CMakeLists.txt b/test/media-control/CMakeLists.txt index 657f5c2..08b9a1b 100644 --- a/test/media-control/CMakeLists.txt +++ b/test/media-control/CMakeLists.txt @@ -8,7 +8,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/bt-api) INCLUDE(FindPkgConfig) -pkg_check_modules(package REQUIRED dlog dbus-glib-1 glib-2.0 gthread-2.0) +pkg_check_modules(package REQUIRED dlog dbus-1 glib-2.0 gthread-2.0 gobject-2.0) FOREACH(flag ${package_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/test/telephony/bluetooth-telephony-test.c b/test/telephony/bluetooth-telephony-test.c index 45be199..9a99661 100644 --- a/test/telephony/bluetooth-telephony-test.c +++ b/test/telephony/bluetooth-telephony-test.c @@ -297,11 +297,7 @@ void startup() { TC_PRT("bluetooth framework TC startup"); - if (!g_thread_supported()) { - g_thread_init(NULL); - } - - dbus_g_thread_init(); + dbus_threads_init_default(); g_type_init(); main_loop = g_main_loop_new(NULL, FALSE); -- 2.7.4