diff options
author | Jaekyu Park <jk7744.park@samsung.com> | 2016-05-27 16:51:54 +0900 |
---|---|---|
committer | Jaekyu Park <jk7744.park@samsung.com> | 2016-05-27 16:51:54 +0900 |
commit | 1928f1338ddc67a3bc7953685de29bf41f241fd5 (patch) | |
tree | 7937326ff5491e75e74d34fff0cc94de0648c1c9 | |
parent | d1e34c62c3def30900d06c57fdd8d4645e2206e9 (diff) | |
download | bluez-tizen_2.4.tar.gz bluez-tizen_2.4.tar.bz2 bluez-tizen_2.4.zip |
Tizen 2.4 SDK Rev6 Releasesubmit/tizen_2.4/20160530.023224accepted/tizen/2.4/mobile/20160530.220500tizen_2.4accepted/tizen_2.4_mobile
-rw-r--r-- | bluez.rule | 5 | ||||
-rw-r--r-- | gdbus/gdbus.h | 6 | ||||
-rw-r--r-- | gdbus/object.c | 59 | ||||
-rw-r--r-- | obexd/plugins/messages-tizen.c | 19 | ||||
-rw-r--r-- | obexd/plugins/phonebook-tizen.c | 27 | ||||
-rw-r--r--[-rwxr-xr-x] | packaging/bluez.spec | 1 | ||||
-rwxr-xr-x | src/device.c | 6 | ||||
-rw-r--r-- | src/gatt-client.c | 77 | ||||
-rw-r--r-- | src/gatt-database.c | 243 | ||||
-rw-r--r-- | src/shared/gatt-db.c | 16 | ||||
-rw-r--r-- | src/shared/gatt-db.h | 5 |
11 files changed, 390 insertions, 74 deletions
@@ -4,8 +4,3 @@ bluez security-server::api-permissions -w---- bluez dfms-kernel rwx--- dbus bluez rwx--- bluez _ rwx--- -dbus _ rwx--- -dbus tizen::vconf::setting::admin rw---l -dbus tizen::vconf::public::r::platform::rw rw---l -dbus tizen::vconf::platform::rw rw---l -dbus tizen::vconf::platform::r rw---l diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h index 9814838..ffb12cb 100644 --- a/gdbus/gdbus.h +++ b/gdbus/gdbus.h @@ -271,6 +271,12 @@ gboolean g_dbus_emit_signal_valist(DBusConnection *connection, const char *path, const char *interface, const char *name, int type, va_list args); +#ifdef GATT_NO_RELAY +gboolean g_dbus_emit_signal_to_dest(DBusConnection *connection, + const char *dest, const char *path, + const char *interface, const char *name, int type, ...); +#endif + guint g_dbus_add_service_watch(DBusConnection *connection, const char *name, GDBusWatchFunction connect, GDBusWatchFunction disconnect, diff --git a/gdbus/object.c b/gdbus/object.c index d5456d2..94f074a 100644 --- a/gdbus/object.c +++ b/gdbus/object.c @@ -1673,6 +1673,65 @@ gboolean g_dbus_emit_signal(DBusConnection *connection, return result; } +#ifdef GATT_NO_RELAY +static gboolean g_dbus_emit_signal_valist_to_dest(DBusConnection *connection, + const char *dest, const char *path, const char *interface, + const char *name, int type, va_list args) +{ + DBusMessage *signal; + dbus_bool_t ret; + const GDBusArgInfo *args_info; + + if (!check_signal(connection, path, interface, name, &args_info)) + return FALSE; + + signal = dbus_message_new_signal(path, interface, name); + if (signal == NULL) { + error("Unable to allocate new %s.%s signal", interface, name); + return FALSE; + } + + ret = dbus_message_append_args_valist(signal, type, args); + if (!ret) + goto fail; + + if (g_dbus_args_have_signature(args_info, signal) == FALSE) { + error("%s.%s: got unexpected signature '%s'", interface, name, + dbus_message_get_signature(signal)); + ret = FALSE; + goto fail; + } + + ret = dbus_message_set_destination(signal, dest); + if (!ret) + error("Fail to set destination"); + + return g_dbus_send_message(connection, signal); + +fail: + dbus_message_unref(signal); + + return ret; +} + +gboolean g_dbus_emit_signal_to_dest(DBusConnection *connection, + const char *dest, const char *path, + const char *interface, const char *name, int type, ...) +{ + va_list args; + gboolean result; + + va_start(args, type); + + result = g_dbus_emit_signal_valist_to_dest(connection, dest, path, + interface, name, type, args); + + va_end(args); + + return result; +} +#endif + gboolean g_dbus_emit_signal_valist(DBusConnection *connection, const char *path, const char *interface, const char *name, int type, va_list args) diff --git a/obexd/plugins/messages-tizen.c b/obexd/plugins/messages-tizen.c index 1681f54..690237a 100644 --- a/obexd/plugins/messages-tizen.c +++ b/obexd/plugins/messages-tizen.c @@ -1,22 +1,23 @@ /* * - * OBEX Server + * OBEX Server + * + * Copyright (c) 2000-2016 Samsung Electronics Co., Ltd. All rights reserved. * - * Copyright (C) 2012 Samsung Electronics Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ diff --git a/obexd/plugins/phonebook-tizen.c b/obexd/plugins/phonebook-tizen.c index f0048a6..a09bcf1 100644 --- a/obexd/plugins/phonebook-tizen.c +++ b/obexd/plugins/phonebook-tizen.c @@ -1,27 +1,26 @@ /* + * * OBEX Server * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2000-2016 Samsung Electronics Co., Ltd. All rights reserved. * - * Contact: Hocheol Seo <hocheol.seo@samsung.com> - * Girishashok Joshi <girish.joshi@samsung.com> - * Chanyeol Park <chanyeol.park@samsung.com> * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * 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. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ - #ifdef HAVE_CONFIG_H #include <config.h> #endif diff --git a/packaging/bluez.spec b/packaging/bluez.spec index a19a3de..4f6e252 100755..100644 --- a/packaging/bluez.spec +++ b/packaging/bluez.spec @@ -92,6 +92,7 @@ export CFLAGS="${CFLAGS} -D__BROADCOM_PATCH__" %endif %endif +export CFLAGS="${CFLAGS} -DGATT_NO_RELAY" export LDFLAGS=" -lncurses -Wl,--as-needed " export CFLAGS+=" -DPBAP_SIM_ENABLE -DSUPPORT_AVRCP_TARGET" %reconfigure --disable-static \ diff --git a/src/device.c b/src/device.c index 93e0305..d13ad62 100755 --- a/src/device.c +++ b/src/device.c @@ -2850,10 +2850,8 @@ void device_set_gatt_connected(struct btd_device *device, gboolean connected) return; } - if (device->gatt_connected == connected) - return; - - device->gatt_connected = connected; + if (device->gatt_connected != connected) + device->gatt_connected = connected; DBG("GattConnected %d", connected); diff --git a/src/gatt-client.c b/src/gatt-client.c index 0887dc1..4e63917 100644 --- a/src/gatt-client.c +++ b/src/gatt-client.c @@ -846,9 +846,6 @@ static void notify_characteristic_cb(struct gatt_db_attribute *attr, int err, if (err) return; - - g_dbus_emit_property_changed(btd_get_dbus_connection(), chrc->path, - GATT_CHARACTERISTIC_IFACE, "ChangedValue"); } #endif @@ -1223,6 +1220,65 @@ static bool match_notify_sender(const void *a, const void *b) return strcmp(client->owner, sender) == 0; } +#ifdef GATT_NO_RELAY +struct char_value { + uint8_t *data; + uint8_t len; + char *chrc_path; +}; + +static void emit_value_changed_signal_to_dest(gpointer data, gpointer user_data) +{ + dbus_int32_t result = 0; + struct notify_client *notify_client = data; + struct char_value *value = user_data; + + g_dbus_emit_signal_to_dest(btd_get_dbus_connection(), + notify_client->owner, value->chrc_path, + GATT_CHARACTERISTIC_IFACE, "GattValueChanged", + DBUS_TYPE_INT32, &result, + DBUS_TYPE_STRING, &value->chrc_path, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &value->data, value->len, + DBUS_TYPE_INVALID); +} +#endif + +#ifdef __TIZEN_PATCH__ +void gatt_characteristic_value_changed(void *data, uint8_t data_len, void *user_data) +{ + struct characteristic *chrc = user_data; + char *chrc_path = strdup(chrc->path); +#ifdef GATT_NO_RELAY + struct char_value *value; + + value = new0(struct char_value, 1); + value->len = data_len; + value->data = data; + value->chrc_path = chrc_path; + + queue_foreach(chrc->notify_clients, + emit_value_changed_signal_to_dest, value); + + + if (value) + g_free(value); +#else + dbus_int32_t result = 0; + + g_dbus_emit_signal(btd_get_dbus_connection(), chrc->path, + GATT_CHARACTERISTIC_IFACE, "GattValueChanged", + DBUS_TYPE_INT32, &result, + DBUS_TYPE_STRING, &chrc_path, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len, + DBUS_TYPE_INVALID); +#endif + + if (chrc_path) + free(chrc_path); + +} +#endif + static void notify_cb(uint16_t value_handle, const uint8_t *value, uint16_t length, void *user_data) { @@ -1239,6 +1295,8 @@ static void notify_cb(uint16_t value_handle, const uint8_t *value, #ifdef __TIZEN_PATCH__ gatt_db_attribute_write(chrc->attr, 0, value, length, 0, NULL, notify_characteristic_cb, chrc); + + gatt_characteristic_value_changed(value, length, chrc); #else gatt_db_attribute_write(chrc->attr, 0, value, length, 0, NULL, write_characteristic_cb, chrc); @@ -1481,6 +1539,15 @@ static const GDBusMethodTable characteristic_methods[] = { #endif }; +#ifdef __TIZEN_PATCH__ +static const GDBusSignalTable characteristic_signals[] = { + { GDBUS_SIGNAL("GattValueChanged", + GDBUS_ARGS({ "Result", "i"}, + { "Characteristic Path","s"}, + { "GattData", "ay"})) }, +}; +#endif + static void characteristic_free(void *data) { struct characteristic *chrc = data; @@ -1549,7 +1616,11 @@ static struct characteristic *characteristic_create( if (!g_dbus_register_interface(btd_get_dbus_connection(), chrc->path, GATT_CHARACTERISTIC_IFACE, +#ifdef __TIZEN_PATCH__ + characteristic_methods, characteristic_signals, +#else characteristic_methods, NULL, +#endif characteristic_properties, chrc, characteristic_free)) { error("Unable to register GATT characteristic with handle " diff --git a/src/gatt-database.c b/src/gatt-database.c index 0fa0f58..8beb8c3 100644 --- a/src/gatt-database.c +++ b/src/gatt-database.c @@ -225,7 +225,7 @@ static bool dev_addr_match(const void *a, const void *b) } static struct device_state * -find_device_state_from_address(struct btd_gatt_database *database, bdaddr_t *bdaddr) +find_device_state_from_address(struct btd_gatt_database *database, const bdaddr_t *bdaddr) { struct device_info dev_info; @@ -965,11 +965,178 @@ struct notify { bool indicate; }; +#ifdef __TIZEN_PATCH__ +struct notify_indicate { + struct btd_gatt_database *database; + GDBusProxy *proxy; + uint16_t handle, ccc_handle; + const uint8_t *value; + uint16_t len; + bool indicate; +}; + +struct notify_indicate_cb { + GDBusProxy *proxy; + struct btd_device *device; +}; + +static void indicate_confirm_free(void *data) +{ + struct notify_indicate_cb *indicate = data; + + if (indicate) + free(indicate); +} + +static void indicate_confirm_setup_cb(DBusMessageIter *iter, void *user_data) +{ + struct btd_device *device = user_data; + char dstaddr[18] = { 0 }; + char *addr_value = NULL; + gboolean complete = FALSE; + + ba2str(device_get_address(device), dstaddr); + addr_value = g_strdup(dstaddr); + + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, + &addr_value); + + complete = TRUE; + dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, + &complete); +} + +static void indicate_confirm_reply_cb(DBusMessage *message, void *user_data) +{ + DBusError error; + + dbus_error_init(&error); + + if (dbus_set_error_from_message(&error, message) == TRUE) { + DBG("Failed to send indication/notification"); + dbus_error_free(&error); + return; + } +} +#endif + static void conf_cb(void *user_data) { DBG("GATT server received confirmation"); +#ifdef __TIZEN_PATCH__ + struct notify_indicate_cb *confirm = user_data; + + if (confirm) { + /* Send confirmation to application */ + if (g_dbus_proxy_method_call(confirm->proxy, "IndicateConfirm", + indicate_confirm_setup_cb, + indicate_confirm_reply_cb, confirm->device, + NULL) == TRUE) + return; + } +#endif } +#ifdef __TIZEN_PATCH__ +static void send_notification_indication_to_device(void *data, void *user_data) +{ + struct device_state *device_state = data; + struct notify_indicate *notify_indicate = user_data; + struct ccc_state *ccc; + struct btd_device *device; + struct notify_indicate_cb *confirm; + + ccc = find_ccc_state(device_state, notify_indicate->ccc_handle); + if (!ccc) + return; + + if (!ccc->value[0] || (notify_indicate->indicate && !(ccc->value[0] & 0x02))) + return; + + device = btd_adapter_get_device(notify_indicate->database->adapter, + &device_state->bdaddr, + device_state->bdaddr_type); + if (!device) + return; + + confirm = new0(struct notify_indicate_cb, 1); + confirm->proxy = notify_indicate->proxy; + confirm->device = device; + /* + * TODO: If the device is not connected but bonded, send the + * notification/indication when it becomes connected. + */ + if (!notify_indicate->indicate) { + DBG("GATT server sending notification"); + bt_gatt_server_send_notification( + btd_device_get_gatt_server(device), + notify_indicate->handle, notify_indicate->value, + notify_indicate->len); + /* In case of Notification, send response to application + * as remote device do not respond for notification */ + conf_cb(confirm); + return; + } + + DBG("GATT server sending indication"); + + bt_gatt_server_send_indication(btd_device_get_gatt_server(device), + notify_indicate->handle, + notify_indicate->value, + notify_indicate->len, conf_cb, + confirm, indicate_confirm_free); +} + +static void send_notification_indication_to_devices(GDBusProxy *proxy, + struct btd_gatt_database *database, + uint16_t handle, const uint8_t *value, + uint16_t len, uint16_t ccc_handle, + bool indicate) +{ + struct notify_indicate notify_indicate; + DBG(""); + memset(¬ify_indicate, 0, sizeof(notify_indicate)); + + notify_indicate.database = database; + notify_indicate.proxy = proxy; + notify_indicate.handle = handle; + notify_indicate.ccc_handle = ccc_handle; + notify_indicate.value = value; + notify_indicate.len = len; + notify_indicate.indicate = indicate; + + queue_foreach(database->device_states, send_notification_indication_to_device, + ¬ify_indicate); +} + +static void send_unicast_notification_indication_to_device(GDBusProxy *proxy, + struct btd_gatt_database *database, + uint16_t handle, const uint8_t *value, + uint16_t len, uint16_t ccc_handle, + bool indicate, const bdaddr_t *unicast_addr) +{ + struct device_state *dev_state; + struct notify_indicate notify_indicate; + DBG(""); + + memset(¬ify_indicate, 0, sizeof(notify_indicate)); + + notify_indicate.database = database; + notify_indicate.proxy = proxy; + notify_indicate.handle = handle; + notify_indicate.ccc_handle = ccc_handle; + notify_indicate.value = value; + notify_indicate.len = len; + notify_indicate.indicate = indicate; + + /* Find and return a device state. */ + dev_state = find_device_state_from_address(database, unicast_addr); + + if (dev_state) + send_notification_indication_to_device(dev_state, ¬ify_indicate); +} +#endif + static void send_notification_to_device(void *data, void *user_data) { struct device_state *device_state = data; @@ -1031,32 +1198,6 @@ static void send_notification_to_devices(struct btd_gatt_database *database, ¬ify); } -#ifdef __TIZEN_PATCH__ -static void send_unicast_notification_to_device(struct btd_gatt_database *database, - uint16_t handle, const uint8_t *value, - uint16_t len, uint16_t ccc_handle, - bool indicate, bdaddr_t *unicast_addr) -{ - struct notify notify; - struct device_state *dev_state; - - memset(¬ify, 0, sizeof(notify)); - - notify.database = database; - notify.handle = handle; - notify.ccc_handle = ccc_handle; - notify.value = value; - notify.len = len; - notify.indicate = indicate; - - /* Find and return a device state. */ - dev_state = find_device_state_from_address(database, unicast_addr); - - if (dev_state) - send_notification_to_device(dev_state, ¬ify); -} -#endif - static void send_service_changed(struct btd_gatt_database *database, struct gatt_db_attribute *attrib) { @@ -1947,6 +2088,7 @@ static void property_changed_cb(GDBusProxy *proxy, const char *name, uint8_t *value = NULL; int len = 0; #ifdef __TIZEN_PATCH__ + bool enable = FALSE; const bdaddr_t *unicast_addr = NULL; #endif @@ -1968,6 +2110,20 @@ static void property_changed_cb(GDBusProxy *proxy, const char *name, /* Truncate the value if it's too large */ len = MIN(BT_ATT_MAX_VALUE_LEN, len); value = len ? value : NULL; + } else if (strcmp(name, "Notifying") == 0) { + gboolean notify_indicate = FALSE; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN) { + DBG("Malformed \"Notifying\" property received"); + return; + } + + dbus_message_iter_get_basic(iter, ¬ify_indicate); + + DBG("Set Notification %d", notify_indicate); + /* Set notification/indication */ + set_ccc_notify_indicate(chrc->ccc, notify_indicate); + return; } else if (strcmp(name, "Unicast") == 0) { const char *address = NULL; if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) { @@ -1985,23 +2141,32 @@ static void property_changed_cb(GDBusProxy *proxy, const char *name, } else return; - unicast_addr = get_ccc_unicast_address(chrc->ccc); + enable = get_ccc_notify_indicate(chrc->ccc); - if (unicast_addr && bacmp(unicast_addr, BDADDR_ANY)) { - send_unicast_notification_to_device(chrc->service->database, - gatt_db_attribute_get_handle(chrc->attrib), - value, len, - gatt_db_attribute_get_handle(chrc->ccc), - chrc->props & BT_GATT_CHRC_PROP_INDICATE, - unicast_addr); - /* reset the unicast address */ - set_ccc_unicast_address(chrc->ccc, NULL); - } else - send_notification_to_devices(chrc->service->database, + if (enable) { + + unicast_addr = get_ccc_unicast_address(chrc->ccc); + + if (unicast_addr && bacmp(unicast_addr, BDADDR_ANY)) { + send_unicast_notification_indication_to_device(proxy, + chrc->service->database, + gatt_db_attribute_get_handle(chrc->attrib), + value, len, + gatt_db_attribute_get_handle(chrc->ccc), + chrc->props & BT_GATT_CHRC_PROP_INDICATE, + unicast_addr); + /* reset the unicast address */ + set_ccc_unicast_address(chrc->ccc, NULL); + } else + send_notification_indication_to_devices(proxy, + chrc->service->database, gatt_db_attribute_get_handle(chrc->attrib), value, len, gatt_db_attribute_get_handle(chrc->ccc), chrc->props & BT_GATT_CHRC_PROP_INDICATE); + + set_ccc_notify_indicate(chrc->ccc, FALSE); + } #else if (strcmp(name, "Value")) return; diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c index 3625fda..fd5c95e 100644 --- a/src/shared/gatt-db.c +++ b/src/shared/gatt-db.c @@ -90,6 +90,7 @@ struct gatt_db_attribute { uint16_t value_len; uint8_t *value; #ifdef __TIZEN_PATCH__ + bool notify_indicate; bdaddr_t unicast_addr; #endif @@ -1726,6 +1727,21 @@ bool gatt_db_attribute_reset(struct gatt_db_attribute *attrib) } #ifdef __TIZEN_PATCH__ +void set_ccc_notify_indicate(struct gatt_db_attribute *ccc, + bool enable) +{ + if (ccc) + ccc->notify_indicate = enable; +} + +bool get_ccc_notify_indicate(const struct gatt_db_attribute *ccc) +{ + if (ccc) + return ccc->notify_indicate; + + return false; +} + void set_ccc_unicast_address(const struct gatt_db_attribute *ccc, const char *address) { diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h index 026b024..581b7d5 100644 --- a/src/shared/gatt-db.h +++ b/src/shared/gatt-db.h @@ -236,6 +236,11 @@ bool gatt_db_attribute_write_result(struct gatt_db_attribute *attrib, bool gatt_db_attribute_reset(struct gatt_db_attribute *attrib); #ifdef __TIZEN_PATCH__ +void set_ccc_notify_indicate(struct gatt_db_attribute *ccc, + bool enable); + +bool get_ccc_notify_indicate(const struct gatt_db_attribute *ccc); + void set_ccc_unicast_address(const struct gatt_db_attribute *ccc, const char *address); |