diff options
author | DoHyun Pyun <dh79.pyun@samsung.com> | 2017-08-03 14:07:53 +0900 |
---|---|---|
committer | DoHyun Pyun <dh79.pyun@samsung.com> | 2017-08-08 10:48:18 +0900 |
commit | 6779a7b2f6b6befb25d4cd091f1bf57ae0e100ba (patch) | |
tree | ed882971e7a0f03031f4d7b36e4a603319a9da72 | |
parent | bfb7684c534013fe78500e86c7788e1d3b12e821 (diff) | |
download | bluez-6779a7b2f6b6befb25d4cd091f1bf57ae0e100ba.tar.gz bluez-6779a7b2f6b6befb25d4cd091f1bf57ae0e100ba.tar.bz2 bluez-6779a7b2f6b6befb25d4cd091f1bf57ae0e100ba.zip |
Apply tizen 3.0 based product patchsetssubmit/tizen/20170808.020532accepted/tizen/unified/20170808.171411
-------------------------------------------------
commit 8b87ae42ba818a0a469f51a45a5a9838e9894a4d
Author: Anurag Biradar <biradar.a@samsung.com>
Date: Mon Apr 10 19:51:01 2017 +0530
-------------------------------------------------
Change-Id: I067d5801f179cfdec856c90757b1a680f7d47150
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
-rw-r--r--[-rwxr-xr-x] | doc/device-api.txt | 21 | ||||
-rw-r--r--[-rwxr-xr-x] | lib/mgmt.h | 6 | ||||
-rw-r--r--[-rwxr-xr-x] | obexd/plugins/messages-tizen.c | 185 | ||||
-rw-r--r-- | packaging/.bluez.spec.swp | bin | 0 -> 16384 bytes | |||
-rwxr-xr-x | packaging/bluez.spec | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | profiles/audio/avctp.c | 4 | ||||
-rw-r--r--[-rwxr-xr-x] | profiles/audio/avdtp.c | 11 | ||||
-rw-r--r--[-rwxr-xr-x] | profiles/audio/avrcp.c | 5 | ||||
-rw-r--r--[-rwxr-xr-x] | profiles/input/device.c | 10 | ||||
-rw-r--r--[-rwxr-xr-x] | profiles/network/connection.c | 8 | ||||
-rw-r--r--[-rwxr-xr-x] | src/adapter.c | 84 | ||||
-rw-r--r--[-rwxr-xr-x] | src/adapter.h | 8 | ||||
-rw-r--r--[-rwxr-xr-x] | src/device.c | 64 | ||||
-rw-r--r-- | src/gatt-client.c | 72 | ||||
-rw-r--r--[-rwxr-xr-x] | src/gatt-database.c | 9 | ||||
-rw-r--r--[-rwxr-xr-x] | src/profile.c | 25 | ||||
-rw-r--r--[-rwxr-xr-x] | src/profile.h | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | src/shared/gatt-client.c | 260 | ||||
-rw-r--r--[-rwxr-xr-x] | src/shared/gatt-db.c | 116 | ||||
-rw-r--r--[-rwxr-xr-x] | src/shared/gatt-db.h | 30 | ||||
-rw-r--r--[-rwxr-xr-x] | tools/btsnoop.c | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | tools/hcidump.c | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | tools/parser/hci.c | 19 |
23 files changed, 582 insertions, 359 deletions
diff --git a/doc/device-api.txt b/doc/device-api.txt index d03906c4..0bcec4dd 100755..100644 --- a/doc/device-api.txt +++ b/doc/device-api.txt @@ -82,6 +82,27 @@ Methods void Connect() org.bluez.Error.NotSupported #ifdef TIZEN_FEATURE_BLUEZ_MODIFY + void DisconnectExtProfile(object profile) + + This method disconnects a specific profile of + this device. The profile needs to be added by + RegisterProfile method call. + + This method could be used when multiple profiles with + same UUID are registered and it needs to disconnect one + of them. + + There is no connection tracking for a profile, so + as long as the profile is registered this will always + succeed. + + Possible errors: org.bluez.Error.Failed + org.bluez.Error.InProgress + org.bluez.Error.InvalidArguments + org.bluez.Error.NotSupported +#endif + +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY void Pair(uint8 conn_type) #else void Pair() diff --git a/lib/mgmt.h b/lib/mgmt.h index 2a7b787a..f12e4026 100755..100644 --- a/lib/mgmt.h +++ b/lib/mgmt.h @@ -1086,6 +1086,12 @@ struct mgmt_cp_set_dev_rpa_res_support { uint8_t res_support; } __packed; +#define MGMT_OP_SET_STREAMING_MODE (TIZEN_OP_CODE_BASE + 0x1b) +struct mgmt_cp_set_streaming_mode { + uint8_t streaming_mode; + bdaddr_t bdaddr; +} __packed; + /* BEGIN TIZEN_Bluetooth :: name update changes */ #define MGMT_EV_DEVICE_NAME_UPDATE (TIZEN_EV_BASE + 0x01) struct mgmt_ev_device_name_update { diff --git a/obexd/plugins/messages-tizen.c b/obexd/plugins/messages-tizen.c index 5006607e..cb4116aa 100755..100644 --- a/obexd/plugins/messages-tizen.c +++ b/obexd/plugins/messages-tizen.c @@ -362,15 +362,21 @@ static void message_get_folder_list(DBusMessage *reply, void *user_data) DBusMessageIter entry; DBusError derr; const char *name = NULL; - struct message_folder *parent = {0,}, *child = {0,}; + struct message_folder *parent = folder_tree, *child = NULL; GSList *l; - DBG("+\n"); + DBG("+"); - for (l = folder_tree->subfolders; l != NULL; l = parent->subfolders) + for (l = folder_tree->subfolders; l != NULL; l = parent->subfolders) { parent = l->data; + if (parent == NULL) { + error("folder list is corrupted"); + dbus_message_unref(reply); + return; + } + } - DBG("Last child folder = %s \n", parent->name); + DBG("Last child folder = %s", parent->name); dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -385,7 +391,7 @@ static void message_get_folder_list(DBusMessage *reply, void *user_data) dbus_message_iter_recurse(&iter_struct, &entry); dbus_message_iter_get_basic(&entry, &name); - DBG("Folder name = %s \n", name); + DBG("Folder name = %s", name); child = create_folder(name); parent->subfolders = g_slist_append(parent->subfolders, child); @@ -393,7 +399,7 @@ static void message_get_folder_list(DBusMessage *reply, void *user_data) } } dbus_message_unref(reply); - DBG("-\n"); + DBG("-"); } static void message_get_msg_list(DBusPendingCall *call, void *user_data) @@ -430,7 +436,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) struct session *session = user_data; struct messages_message *data = g_new0(struct messages_message, 1); - DBG("+\n"); + DBG("+"); DBG("parameter_mask = %x; type = %d; period_begin = %s;" "period_end = %s; read_status = %d; recipient = %s;" "originator = %s; priority = %d", @@ -481,14 +487,14 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) continue; } - DBG("Msg handle = %s \n", msg_handle); + DBG("Msg handle = %s", msg_handle); data->handle = g_strdup(msg_handle); dbus_message_iter_next(&entry); dbus_message_iter_get_basic(&entry, &subject); if (mask & PMASK_SUBJECT) { - DBG("subject = %s\n", subject); + DBG("subject = %s", subject); data->subject = g_strndup(subject, BT_MAP_LIST_ITEM_MAX_LEN); data->mask |= PMASK_SUBJECT; @@ -498,7 +504,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &datetime); if ((mask & PMASK_DATETIME) && (NULL != datetime)) { - DBG("datetime = %s\n", datetime); + DBG("datetime = %s", datetime); char *begin = g_strdup(session->filter->period_begin); char *end = g_strdup(session->filter->period_end); char *time = g_strdup(datetime); @@ -525,7 +531,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) if ((mask & PMASK_SENDER_NAME) && (NULL != session->filter->originator)) { - DBG("sender_name = %s \n", sender_name); + DBG("sender_name = %s", sender_name); if (g_strstr_len(sender_name, -1, session->filter->originator)) { @@ -544,7 +550,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) if ((mask & PMASK_SENDER_ADDRESSING) && (NULL != sender_addressing)) { - DBG("sender_addressing = %s \n", sender_addressing); + DBG("sender_addressing = %s", sender_addressing); data->sender_addressing = g_strndup(sender_addressing, BT_MAP_LIST_ITEM_MAX_LEN); @@ -556,7 +562,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) if ((mask & PMASK_RECIPIENT_NAME) && (NULL != session->filter->recipient)) { - DBG("recipient_name = %s \n", recipient_name); + DBG("recipient_name = %s", recipient_name); if (g_strstr_len(recipient_name, -1, session->filter->recipient)) { @@ -576,7 +582,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) if ((mask & PMASK_RECIPIENT_ADDRESSING) && (NULL != recipient_addressing)) { - DBG("recipient_addressing=%s\n", recipient_addressing); + DBG("recipient_addressing=%s", recipient_addressing); data->recipient_addressing = g_strndup(recipient_addressing, @@ -588,7 +594,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &type); if ((mask & PMASK_TYPE) && (NULL != type)) { - DBG("type = %s \n", type); + DBG("type = %s", type); type_val = get_type_val(type); if (!(session->filter->type & type_val)) { @@ -601,7 +607,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &size); if ((mask & PMASK_SIZE) && (NULL != size)) { - DBG("size = %s \n", size); + DBG("size = %s", size); data->size = g_strdup(size); data->mask |= PMASK_SIZE; @@ -611,7 +617,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &reception_status); if (mask & PMASK_RECEPTION_STATUS) { - DBG("reception_status = %s \n", reception_status); + DBG("reception_status = %s", reception_status); data->reception_status = g_strdup(reception_status); data->mask |= PMASK_RECEPTION_STATUS; @@ -621,7 +627,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &text); if (mask & PMASK_TEXT) { - DBG("text = %d \n", text); + DBG("text = %d", text); data->text = text; data->mask |= PMASK_TEXT; } @@ -630,7 +636,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &attachment_size); if (mask & PMASK_ATTACHMENT_SIZE) { - DBG("attachment_size = %s\n", attachment_size); + DBG("attachment_size = %s", attachment_size); data->attachment_size = g_strdup(attachment_size); data->mask |= PMASK_ATTACHMENT_SIZE; @@ -640,7 +646,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &priority); if (mask & PMASK_PRIORITY) { - DBG("priority = %d \n", priority); + DBG("priority = %d", priority); priority_val = get_priority_val(priority); if ((session->filter->priority == 0) || @@ -658,7 +664,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &read); if (mask & PMASK_READ) { - DBG("read = %d \n", read); + DBG("read = %d", read); read_val = get_read_status_val(read); @@ -677,7 +683,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &sent); if (mask & PMASK_SENT) { - DBG("sent = %d \n", sent); + DBG("sent = %d", sent); data->sent = sent; data->mask |= PMASK_SENT; } @@ -686,7 +692,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&entry, &protect); if (mask & PMASK_PROTECTED) { - DBG("protect = %d \n", protect); + DBG("protect = %d", protect); data->protect = protect; data->mask |= PMASK_PROTECTED; } @@ -697,7 +703,7 @@ static void message_get_msg_list(DBusPendingCall *call, void *user_data) if ((mask & PMASK_REPLYTO_ADDRESSING) && (0x04 == get_type_val(type))) { - DBG("replyto_addressing = %s \n", replyto_addressing); + DBG("replyto_addressing = %s", replyto_addressing); if (replyto_addressing) data->replyto_addressing = g_strdup(replyto_addressing); @@ -722,7 +728,7 @@ done: g_free(session->name); session_filter_free(session->filter); dbus_message_unref(reply); - DBG("-\n"); + DBG("-"); } static void message_get_msg(DBusPendingCall *call, void *user_data) @@ -734,7 +740,7 @@ static void message_get_msg(DBusPendingCall *call, void *user_data) char *msg_body; gboolean fraction_deliver; - DBG("+\n"); + DBG("+"); dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -745,7 +751,7 @@ static void message_get_msg(DBusPendingCall *call, void *user_data) dbus_message_iter_get_basic(&iter, &fraction_deliver); dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &msg_body); - DBG("msg_body %s\n", msg_body); + DBG("msg_body %s", msg_body); session->get_msg_cb(session, -EAGAIN, fraction_deliver, msg_body, session->user_data); @@ -753,7 +759,7 @@ static void message_get_msg(DBusPendingCall *call, void *user_data) NULL, session->user_data); } dbus_message_unref(reply); - DBG("-\n"); + DBG("-"); } int messages_connect(void **s) @@ -761,7 +767,7 @@ int messages_connect(void **s) DBusMessage *message; DBusMessage *reply; DBusError err; - DBG("+\n"); + DBG("+"); struct session *session = g_new0(struct session, 1); @@ -778,6 +784,9 @@ int messages_connect(void **s) QUERY_GET_FOLDER_TREE); if (!message) { error("Can't allocate new message"); + g_free(session->cwd); + g_free(session); + *s = NULL; return -1; } @@ -793,13 +802,17 @@ int messages_connect(void **s) } dbus_message_unref(message); + + g_free(session->cwd); + g_free(session); + *s = NULL; return -1; } message_get_folder_list(reply, session); dbus_message_unref(message); - DBG("-\n"); + DBG("-"); return 0; } @@ -807,7 +820,7 @@ void messages_disconnect(void *s) { DBusMessage *message; struct session *session = s; - DBG("+\n"); + DBG("+"); destroy_folder_tree(folder_tree); folder_tree = NULL; @@ -829,12 +842,12 @@ void messages_disconnect(void *s) dbus_message_unref(message); - DBG("-\n"); + DBG("-"); } static gboolean notification_registration(gpointer user_data) { - DBG("+\n"); + DBG("+"); DBusMessage *message = NULL; gboolean reg; struct mns_reg_data *data = (struct mns_reg_data *)user_data; @@ -848,7 +861,7 @@ static gboolean notification_registration(gpointer user_data) goto done; } - DBG("data->notification_status = %d\n", data->notification_status); + DBG("data->notification_status = %d", data->notification_status); if (data->notification_status == 1) reg = TRUE; @@ -868,7 +881,7 @@ done: g_free(data->remote_addr); g_free(data); - DBG("-\n"); + DBG("-"); return FALSE; } @@ -876,15 +889,15 @@ int messages_set_notification_registration(void *session, char *address, uint8_t status, void *user_data) { - DBG("+\n"); + DBG("+"); struct mns_reg_data *data = g_new0(struct mns_reg_data, 1); data->notification_status = status; data->remote_addr = g_strdup(address); - DBG("status = %d\n", status); + DBG("status = %d", status); g_idle_add(notification_registration, data); - DBG("-\n"); + DBG("-"); return 1; } @@ -1002,7 +1015,7 @@ int messages_get_folder_listing(void *s, const char *name, messages_folder_listing_cb callback, void *user_data) { - DBG("+\n"); + DBG("+"); struct session *session = s; session->name = g_strdup(name); session->max = max; @@ -1013,7 +1026,7 @@ int messages_get_folder_listing(void *s, const char *name, g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, async_get_folder_listing, session, NULL); - DBG("-\n"); + DBG("-"); return 0; } @@ -1097,30 +1110,30 @@ int messages_get_messages_listing(void *session, const char *name, DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - if (filter->parameter_mask) + if (s->filter->parameter_mask) dict_append_entry(&dict, "ParameterMask", DBUS_TYPE_UINT32, - &filter->parameter_mask); - if (filter->type) + &s->filter->parameter_mask); + if (s->filter->type) dict_append_entry(&dict, "FilterMessageType", DBUS_TYPE_BYTE, - &filter->type); - if (filter->period_begin) + &s->filter->type); + if (s->filter->period_begin) dict_append_entry(&dict, "FilterPeriodBegin", DBUS_TYPE_STRING, - &filter->period_begin); - if (filter->period_end) + &s->filter->period_begin); + if (s->filter->period_end) dict_append_entry(&dict, "FilterPeriodEnd", DBUS_TYPE_STRING, - &filter->period_end); - if (filter->read_status) + &s->filter->period_end); + if (s->filter->read_status) dict_append_entry(&dict, "FilterReadStatus", DBUS_TYPE_BYTE, - &filter->read_status); - if (filter->recipient) + &s->filter->read_status); + if (s->filter->recipient) dict_append_entry(&dict, "FilterRecipient", DBUS_TYPE_STRING, - &filter->recipient); - if (filter->originator) + &s->filter->recipient); + if (s->filter->originator) dict_append_entry(&dict, "FilterOriginator", DBUS_TYPE_STRING, - &filter->originator); - if (filter->priority) + &s->filter->originator); + if (s->filter->priority) dict_append_entry(&dict, "FilterPriority", DBUS_TYPE_BYTE, - &filter->priority); + &s->filter->priority); dbus_message_iter_close_container(&iter, &dict); @@ -1134,7 +1147,7 @@ int messages_get_messages_listing(void *session, const char *name, } dbus_pending_call_set_notify(call, message_get_msg_list, s, NULL); dbus_message_unref(message); - DBG("-\n"); + DBG("-"); return 1; } @@ -1155,9 +1168,9 @@ int messages_push_message(void *session, const char *folder, gchar *folder_path = NULL; guint64 handle = 0; - DBG("+\n"); + DBG("+"); - DBG("session->cwd %s +\n", s->cwd); + DBG("session->cwd %s +", s->cwd); if (g_ascii_strncasecmp(s->cwd, "/telecom/msg", strlen("/telecom/msg")) != 0) { @@ -1183,17 +1196,17 @@ int messages_push_message(void *session, const char *folder, if (!(retry & 0x1)) { retry_send = FALSE; - DBG("Retry send %d\n", retry_send); + DBG("Retry send %d", retry_send); } if (charset & 0x1) { native = TRUE; - DBG("native send %d\n", native); + DBG("native send %d", native); } - DBG("save_copy %d\n", save_copy); - DBG("retry_send %d\n", retry_send); - DBG("native %d\n", native); + DBG("save_copy %d", save_copy); + DBG("retry_send %d", retry_send); + DBG("native %d", native); message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME, BT_MAP_SERVICE_OBJECT_PATH, @@ -1231,7 +1244,7 @@ int messages_push_message(void *session, const char *folder, if (!dbus_message_get_args(reply, &err, DBUS_TYPE_UINT64, &handle, DBUS_TYPE_INVALID)) { if (dbus_error_is_set(&err)) { - error("err %s\n", err.message); + error("err %s", err.message); dbus_error_free(&err); } g_free(folder_path); @@ -1240,14 +1253,14 @@ int messages_push_message(void *session, const char *folder, return -1; } - DBG("uint64 handle %"G_GUINT64_FORMAT"\n", handle); + DBG("uint64 handle %"G_GUINT64_FORMAT"", handle); s->push_msg_cb(s, 0, handle, s->user_data); g_free(folder_path); dbus_message_unref(message); dbus_message_unref(reply); - DBG("-\n"); + DBG("-"); return 1; } @@ -1255,7 +1268,7 @@ int messages_push_message_data(void *session, const char *bmsg, void *user_data) { DBusMessage *message; - DBG("+\n"); + DBG("+"); message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME, BT_MAP_SERVICE_OBJECT_PATH, @@ -1276,7 +1289,7 @@ int messages_push_message_data(void *session, const char *bmsg, void *user_data) } dbus_message_unref(message); - DBG("-\n"); + DBG("-"); return 1; } @@ -1295,11 +1308,11 @@ int messages_get_message(void *session, gboolean transcode = FALSE; gboolean first_request = TRUE; - DBG("+\n"); + DBG("+"); if (NULL != handle) { message_name = g_strdup(handle); - DBG("Message handle = %s\n", handle); + DBG("Message handle = %s", handle); } else { return -1; } @@ -1341,7 +1354,7 @@ int messages_get_message(void *session, dbus_pending_call_set_notify(call, message_get_msg, s, NULL); dbus_message_unref(message); g_free(message_name); - DBG("-\n"); + DBG("-"); return 1; } @@ -1352,7 +1365,7 @@ static void message_update_msg(DBusPendingCall *call, void *user_data) DBusError derr; struct session *session = user_data; int err; - DBG("+\n"); + DBG("+"); dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -1363,13 +1376,13 @@ static void message_update_msg(DBusPendingCall *call, void *user_data) if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) { dbus_message_iter_get_basic(&iter, &err); - DBG("Error : %d\n", err); + DBG("Error : %d", err); session->msg_update_cb(session, err, session->user_data); } } dbus_message_unref(reply); - DBG("-\n"); + DBG("-"); } int messages_update_inbox(void *session, @@ -1388,7 +1401,7 @@ int messages_update_inbox(void *session, DBusMessage *message; struct session *s = session; - DBG("+\n"); + DBG("+"); s->msg_update_cb = callback; s->user_data = user_data; @@ -1410,7 +1423,7 @@ int messages_update_inbox(void *session, } dbus_pending_call_set_notify(call, message_update_msg, s, NULL); dbus_message_unref(message); - DBG("-\n"); + DBG("-"); return 1; } @@ -1422,7 +1435,7 @@ static void message_status_msg(DBusPendingCall *call, void *user_data) struct session *session = user_data; int err; - DBG("+\n"); + DBG("+"); dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -1433,13 +1446,13 @@ static void message_status_msg(DBusPendingCall *call, void *user_data) if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_INT32) { dbus_message_iter_get_basic(&iter, &err); - DBG("Error : %d\n", err); + DBG("Error : %d", err); session->msg_status_cb(session, err, session->user_data); } } dbus_message_unref(reply); - DBG("-\n"); + DBG("-"); } int messages_set_read(void *session, const char *handle, uint8_t value, @@ -1451,12 +1464,12 @@ int messages_set_read(void *session, const char *handle, uint8_t value, char *message_name; gboolean read; - DBG("+\n"); + DBG("+"); if (NULL == handle) return -1; - DBG("Message handle = %s\n", handle); + DBG("Message handle = %s", handle); message_name = g_strdup(handle); s->msg_status_cb = callback; @@ -1489,7 +1502,7 @@ int messages_set_read(void *session, const char *handle, uint8_t value, dbus_pending_call_set_notify(call, message_status_msg, s, NULL); dbus_message_unref(message); g_free(message_name); - DBG("-\n"); + DBG("-"); return 1; } @@ -1504,12 +1517,12 @@ int messages_set_delete(void *session, const char *handle, char *message_name; gboolean del; - DBG("+\n"); + DBG("+"); if (NULL == handle) return -1; - DBG("Message handle = %s\n", handle); + DBG("Message handle = %s", handle); message_name = g_strdup(handle); s->msg_status_cb = callback; @@ -1542,7 +1555,7 @@ int messages_set_delete(void *session, const char *handle, dbus_pending_call_set_notify(call, message_status_msg, s, NULL); dbus_message_unref(message); g_free(message_name); - DBG("-\n"); + DBG("-"); return 1; } diff --git a/packaging/.bluez.spec.swp b/packaging/.bluez.spec.swp Binary files differnew file mode 100644 index 00000000..6fa13a30 --- /dev/null +++ b/packaging/.bluez.spec.swp diff --git a/packaging/bluez.spec b/packaging/bluez.spec index a5abb5f1..508931a3 100755 --- a/packaging/bluez.spec +++ b/packaging/bluez.spec @@ -168,7 +168,6 @@ export CFLAGS="$CFLAGS_DEFAULT" --libexecdir=%{_libexecdir} \ --enable-debug \ --enable-pie \ - --enable-serial \ --enable-usb=no \ --enable-tools \ --disable-bccmd \ diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c index ac90b127..e286c025 100755..100644 --- a/profiles/audio/avctp.c +++ b/profiles/audio/avctp.c @@ -1540,6 +1540,9 @@ int avctp_register(struct btd_adapter *adapter, gboolean master) g_free(server); return -1; } + +/* Tizen doesn't support AVRCP BROWSING CHANNEL */ +#ifndef TIZEN_FEATURE_BLUEZ_MODIFY server->browsing_io = avctp_server_socket(src, master, L2CAP_MODE_ERTM, AVCTP_BROWSING_PSM); if (!server->browsing_io) { @@ -1551,6 +1554,7 @@ int avctp_register(struct btd_adapter *adapter, gboolean master) g_free(server); return -1; } +#endif server->adapter = btd_adapter_ref(adapter); diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c index 7dbd3ac3..5cb7c176 100755..100644 --- a/profiles/audio/avdtp.c +++ b/profiles/audio/avdtp.c @@ -1130,11 +1130,10 @@ static void avdtp_sep_set_state(struct avdtp *session, { struct avdtp_stream *stream = sep->stream; #ifdef TIZEN_FEATURE_BLUEZ_MODIFY + struct btd_adapter *adapter = device_get_adapter(session->device); const bdaddr_t *dst; - if (TIZEN_FEATURE_BLUEZ_SPRD_QOS) - dst = device_get_address(session->device); - else if (TIZEN_FEATURE_BLUEZ_BRCM_QOS || TIZEN_FEATURE_BLUEZ_ROLE_CHANGE) - dst = device_get_address(session->device); + + dst = device_get_address(session->device); #endif avdtp_state_t old_state; struct avdtp_error err, *err_ptr = NULL; @@ -1176,6 +1175,8 @@ static void avdtp_sep_set_state(struct avdtp *session, if (TIZEN_FEATURE_BLUEZ_ROLE_CHANGE) fix_role_to_master(dst, FALSE); + + btd_adapter_set_streaming_mode(adapter, dst, FALSE); #endif /* TIZEN_FEATURE_BLUEZ_MODIFY */ break; case AVDTP_STATE_STREAMING: @@ -1193,6 +1194,8 @@ static void avdtp_sep_set_state(struct avdtp *session, } if (TIZEN_FEATURE_BLUEZ_ROLE_CHANGE) fix_role_to_master(dst, TRUE); + + btd_adapter_set_streaming_mode(adapter, dst, TRUE); #endif /* TIZEN_FEATURE_BLUEZ_MODIFY */ stream->open_acp = FALSE; break; diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index 2f2ccc3c..3d85ded2 100755..100644 --- a/profiles/audio/avrcp.c +++ b/profiles/audio/avrcp.c @@ -4702,6 +4702,11 @@ static int avrcp_connect(struct btd_service *service) DBG("Don't initiate avrcp connection with this headset"); return -ENOTSUP; } + + /* Device unpairing failed if AVRCP connection is triggered + during unpairing*/ + if (device_is_temporary(dev)) + return -EPERM; #endif return control_connect(service); } diff --git a/profiles/input/device.c b/profiles/input/device.c index ff553cb3..bac6cb24 100755..100644 --- a/profiles/input/device.c +++ b/profiles/input/device.c @@ -1531,8 +1531,12 @@ static struct input_device *find_device_role(const bdaddr_t *src, return NULL; service = btd_device_get_service(device, HID_DEVICE_UUID); - if (service == NULL) - return NULL; + if (service == NULL) { + DBG("Service not found, Probe Hid device profile for device"); + /* This will make sure we have hid device service for device */ + device_probe_profiles(device, NULL); + service = btd_device_get_service(device, HID_DEVICE_UUID); + } return btd_service_get_user_data(service); } @@ -1679,7 +1683,7 @@ int input_device_role_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int int input_device_role_close_channels(const bdaddr_t *src, const bdaddr_t *dst) { - struct input_device *idev = find_device(src, dst); + struct input_device *idev = find_device_role(src, dst); if (!idev) return -ENOENT; diff --git a/profiles/network/connection.c b/profiles/network/connection.c index 53d35fe6..b2aeeb48 100755..100644 --- a/profiles/network/connection.c +++ b/profiles/network/connection.c @@ -188,6 +188,14 @@ static void cancel_connection(struct network_conn *nc, int err) if (nc->state == CONNECTED) bnep_disconnect(nc->session); +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + else { + /* In error case we need to free session */ + DBG("Cancel Connection state %d", nc->state); + bnep_free(nc->session); + nc->session = NULL; + } +#endif #ifndef TIZEN_FEATURE_BLUEZ_MODIFY bnep_free(nc->session); diff --git a/src/adapter.c b/src/adapter.c index 092ea7af..7b936507 100755..100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -4128,8 +4128,6 @@ static DBusMessage *adapter_set_advertising(DBusConnection *conn, dbus_bool_t enable = FALSE; dbus_int32_t slot_id; - DBG("adapter_set_advertising"); - if (!(adapter->current_settings & MGMT_SETTING_POWERED)) return btd_error_not_ready(msg); @@ -4138,6 +4136,8 @@ static DBusMessage *adapter_set_advertising(DBusConnection *conn, DBUS_TYPE_INVALID)) return btd_error_invalid_args(msg); + DBG("%s advertising slot_id %d", enable ? "Enable" : "Disable", slot_id); + if (adapter_le_is_supported_multi_advertising() && slot_id > 0) err = adapter_le_enable_multi_adv(adapter, enable, slot_id); else @@ -5210,31 +5210,29 @@ static void le_read_maximum_data_length_return_param_complete( { struct btd_adapter *adapter = user_data; const struct mgmt_rp_le_read_maximum_data_length *rp = param; - uint16_t max_tx_octects, max_tx_time; - uint16_t max_rx_octects, max_rx_time; + uint16_t max_tx_octects = 0; + uint16_t max_tx_time = 0; + uint16_t max_rx_octects = 0; + uint16_t max_rx_time = 0; + int err = 0; if (!rp) { error("Error ocurred in Reading maximum data length, rp is NULL"); - g_free(adapter->read_handler); - return; + err = -EIO; + goto done; } if (status != MGMT_STATUS_SUCCESS) { error("le read maximum data length failed: %s (0x%02x)", mgmt_errstr(status), status); - max_tx_octects = 0; - max_tx_time =0; - max_rx_octects = 0; - max_rx_time = 0; - - g_free(adapter->read_handler); - return; + err = -EIO; + goto done; } if (length < sizeof(*rp)) { error("Too small le read maximum data length response"); - g_free(adapter->read_handler); - return; + err = -EIO; + goto done; } else { max_tx_octects = rp->max_tx_octets; max_tx_time =rp->max_tx_time; @@ -5242,13 +5240,14 @@ static void le_read_maximum_data_length_return_param_complete( max_rx_time = rp->max_rx_time; } +done: if (!adapter->read_handler || !adapter->read_handler->read_callback) { g_free(adapter->read_handler); return; } - adapter->read_handler->read_callback(adapter, + adapter->read_handler->read_callback(adapter, err, max_tx_octects, max_tx_time, max_rx_octects, max_rx_time, adapter->read_handler->user_data); @@ -5293,6 +5292,7 @@ static struct le_data_length_read_request *find_read_le_data_length_request( static void le_read_data_length_complete( struct btd_adapter *adapter, + int err, uint16_t max_tx_octects, uint16_t max_tx_time, uint16_t max_rx_octects, uint16_t max_rx_time, void *user_data) @@ -5301,20 +5301,26 @@ static void le_read_data_length_complete( struct le_data_length_read_request *read_request; read_request = find_read_le_data_length_request(adapter); + if (!read_request) return; - reply = g_dbus_create_reply(read_request->msg, - DBUS_TYPE_UINT16, &max_tx_octects, - DBUS_TYPE_UINT16, &max_tx_time, - DBUS_TYPE_UINT16, &max_rx_octects, - DBUS_TYPE_UINT16, &max_rx_time, - DBUS_TYPE_INVALID); - - if (!reply) { - btd_error_failed(read_request->msg, - "Failed to read max data length."); - return; + if (err) { + DBG("Failed to read max data length. errno[%d]", err); + reply = btd_error_failed(read_request->msg, + "Failed to read max data length"); + } else { + reply = g_dbus_create_reply(read_request->msg, + DBUS_TYPE_UINT16, &max_tx_octects, + DBUS_TYPE_UINT16, &max_tx_time, + DBUS_TYPE_UINT16, &max_rx_octects, + DBUS_TYPE_UINT16, &max_rx_time, + DBUS_TYPE_INVALID); + + if (!reply) { + reply = btd_error_failed(read_request->msg, + "Failed to create reply."); + } } read_requests = g_slist_remove(read_requests, read_request); @@ -13932,3 +13938,27 @@ bool btd_le_connect_before_pairing(void) return false; } + +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +int btd_adapter_set_streaming_mode(struct btd_adapter *adapter, + const bdaddr_t *bdaddr, gboolean enable) +{ + struct mgmt_cp_set_streaming_mode cp; + char addr[18]; + + ba2str(bdaddr, addr); + DBG("hci%u device %s", adapter->dev_id, addr); + + memset(&cp, 0, sizeof(cp)); + + cp.streaming_mode = enable ? 1 : 0; + bacpy(&cp.bdaddr, bdaddr); + + if (mgmt_send(adapter->mgmt, MGMT_OP_SET_STREAMING_MODE, + adapter->dev_id, sizeof(cp), &cp, + NULL, NULL, NULL) > 0) + return 0; + + return -EIO; +} +#endif diff --git a/src/adapter.h b/src/adapter.h index 985e28ed..91460417 100755..100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -321,9 +321,9 @@ uint8_t btd_adapter_get_rpa_res_support_value( int btd_adapter_set_dev_rpa_res_support(struct btd_adapter *adapter, struct btd_device *device); -#endif typedef void (*read_max_data_length_cb_t) (struct btd_adapter *adapter, + int result, const uint16_t max_txOctects, const uint16_t max_txTime, const uint16_t max_rxOctects, @@ -347,8 +347,12 @@ struct le_data_length_read_default_data_length_handler { int btd_adapter_le_set_data_length(struct btd_adapter *adapter, bdaddr_t *bdaddr, uint16_t max_tx_octets, uint16_t max_tx_time); -#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + void adapter_check_version(struct btd_adapter *adapter, uint8_t hci_ver); + +int btd_adapter_set_streaming_mode(struct btd_adapter *adapter, + const bdaddr_t *bdaddr, gboolean enable); + #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH charging_state_e get_charging_state(struct btd_adapter *adapter); #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */ diff --git a/src/device.c b/src/device.c index f0de2827..6b5fbe0d 100755..100644 --- a/src/device.c +++ b/src/device.c @@ -2526,6 +2526,55 @@ static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg, return btd_error_failed(msg, strerror(-err)); } +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +static DBusMessage *disconnect_ext_profile(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + struct btd_device *dev = user_data; + struct btd_profile *profile; + struct btd_service *service; + const char *sender, *path; + GSList *l; + int err; + + sender = dbus_message_get_sender(msg); + + DBG("sender %s", sender); + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + return btd_error_invalid_args(msg); + + profile = btd_profile_find_ext(sender, path); + if (!profile) + return btd_error_invalid_args(msg); + + l = find_service_with_profile(dev->services, profile); + if (!l) + return btd_error_invalid_args(msg); + + service = l->data; + + if (dev->disconnect) + return btd_error_in_progress(msg); + + dev->disconnect = dbus_message_ref(msg); + + err = btd_service_disconnect(service); + if (err == 0) + return NULL; + + if (dev->disconnect) + dbus_message_unref(dev->disconnect); + dev->disconnect = NULL; + + if (err == -ENOTSUP) + return btd_error_not_supported(msg); + + return btd_error_failed(msg, strerror(-err)); +} +#endif + static void store_services(struct btd_device *device) { struct btd_adapter *adapter = device->adapter; @@ -3635,7 +3684,6 @@ int btd_adapter_connect_otc(struct btd_device *device) if (!conn_info->io) { error("OTC Connect failed : %s", gerr->message); g_error_free(gerr); - g_io_channel_unref(conn_info->io); g_free(conn_info); return -EIO; } @@ -3727,6 +3775,7 @@ int btd_adapter_listen_otc(struct btd_device *device) if (!conn_info->io) { error("OTC Listen failed : %s", gerr->message); g_error_free(gerr); + g_free(conn_info); return -EIO; } @@ -4124,6 +4173,9 @@ static const GDBusMethodTable device_methods[] = { { GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }), NULL, disconnect_profile) }, #ifdef TIZEN_FEATURE_BLUEZ_MODIFY + { GDBUS_ASYNC_METHOD("DisconnectExtProfile", + GDBUS_ARGS({ "profile", "o" }), NULL, + disconnect_ext_profile) }, { GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL, pair_device) }, #else @@ -4580,10 +4632,12 @@ static void load_info(struct btd_device *device, const char *local, str = g_key_file_get_string(key_file, "General", "ManufacturerData", NULL); if (str) { - load_manufacturer_data_2digit(str, - device->manufacturer_data_len, buf); - device->manufacturer_data = g_memdup(buf, - device->manufacturer_data_len); + if (device->manufacturer_data_len < DEV_MAX_MANUFACTURER_DATA_LEN ) { + load_manufacturer_data_2digit(str, + device->manufacturer_data_len, buf); + device->manufacturer_data = g_memdup(buf, + device->manufacturer_data_len); + } g_free(str); } } diff --git a/src/gatt-client.c b/src/gatt-client.c index 85e23678..35fdde97 100644 --- a/src/gatt-client.c +++ b/src/gatt-client.c @@ -79,7 +79,6 @@ struct service { bool chrcs_ready; struct queue *pending_ext_props; guint idle_id; - guint idle_id2; #endif }; @@ -1743,9 +1742,6 @@ static void unregister_service(void *data) #ifdef TIZEN_FEATURE_BLUEZ_MODIFY if (service->idle_id) g_source_remove(service->idle_id); - - if (service->idle_id2) - g_source_remove(service->idle_id2); #endif queue_remove_all(service->chrcs, NULL, NULL, unregister_characteristic); @@ -1755,6 +1751,37 @@ static void unregister_service(void *data) } #ifdef TIZEN_FEATURE_BLUEZ_MODIFY +static void notify_service_added(struct service *service) +{ + char *svc_path; + + if (service == NULL) { + error("service is NULL"); + return; + } + + if (service->path == NULL) { + error("service->path is NULL"); + return; + } + if (!service->chrcs_ready) { + error("service is not ready"); + return; + } + + svc_path = g_strdup(service->path); + + g_dbus_emit_signal(btd_get_dbus_connection(), service->path, + GATT_SERVICE_IFACE, "GattServiceAdded", + DBUS_TYPE_STRING, &svc_path, + DBUS_TYPE_INVALID); + + g_free(svc_path); + + return; +} +#endif + static void notify_chrcs(struct service *service) { @@ -1767,8 +1794,13 @@ static void notify_chrcs(struct service *service) g_dbus_emit_property_changed(btd_get_dbus_connection(), service->path, GATT_SERVICE_IFACE, "Characteristics"); -} +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + if (service->primary == true) { + DBG("Notify Service Added"); + notify_service_added(service); + } #endif +} struct export_data { void *root; @@ -1847,10 +1879,12 @@ static bool create_characteristics(struct gatt_db_attribute *attr, gatt_db_service_foreach_char(attr, export_char, &data); - return !data.failed; + if (data.failed) + return false; + + return true; } -#ifdef TIZEN_FEATURE_BLUEZ_MODIFY static gboolean set_chrcs_ready(gpointer user_data) { struct service *service = user_data; @@ -1861,27 +1895,6 @@ static gboolean set_chrcs_ready(gpointer user_data) return FALSE; } -static gboolean notify_service_added_complete(gpointer user_data) -{ - struct service *service = user_data; - char *svc_path; - - if (service == NULL || service->path == NULL) - return FALSE; - - svc_path = g_strdup(service->path); - - g_dbus_emit_signal(btd_get_dbus_connection(), service->path, - GATT_SERVICE_IFACE, "GattServiceAdded", - DBUS_TYPE_STRING, &svc_path, - DBUS_TYPE_INVALID); - - g_free(svc_path); - - return FALSE; -} -#endif - static void export_service(struct gatt_db_attribute *attr, void *user_data) { struct btd_gatt_client *client = user_data; @@ -1910,9 +1923,6 @@ static void export_service(struct gatt_db_attribute *attr, void *user_data) */ if (!service->chrcs_ready && queue_isempty(service->pending_ext_props)) service->idle_id = g_idle_add(set_chrcs_ready, service); - - if (service->primary == true) - service->idle_id2 = g_idle_add(notify_service_added_complete, service); #endif } diff --git a/src/gatt-database.c b/src/gatt-database.c index 7dd22300..c198d176 100755..100644 --- a/src/gatt-database.c +++ b/src/gatt-database.c @@ -1104,11 +1104,12 @@ static void conf_cb(void *user_data) if (confirm) { /* Send confirmation to application */ - if (g_dbus_proxy_method_call(confirm->proxy, "IndicateConfirm", + g_dbus_proxy_method_call(confirm->proxy, "IndicateConfirm", indicate_confirm_setup_cb, indicate_confirm_reply_cb, confirm->device, - NULL) == TRUE) - return; + NULL); + g_dbus_proxy_unref(confirm->proxy); + confirm->proxy = NULL; } #endif } @@ -1136,7 +1137,7 @@ static void send_notification_indication_to_device(void *data, void *user_data) return; confirm = new0(struct notify_indicate_cb, 1); - confirm->proxy = notify_indicate->proxy; + confirm->proxy = g_dbus_proxy_ref(notify_indicate->proxy); confirm->device = device; /* * TODO: If the device is not connected but bonded, send the diff --git a/src/profile.c b/src/profile.c index bb833bd8..0ee3ce76 100755..100644 --- a/src/profile.c +++ b/src/profile.c @@ -811,8 +811,8 @@ <attribute id=\"0x0009\"> \ <sequence> \ <sequence> \ - <uuid value=\"0x0011\" /> \ - <uint16 value=\"0x0100\" /> \ + <uuid value=\"0x1124\" /> \ + <uint16 value=\"0x%04x\" /> \ </sequence> \ </sequence> \ </attribute> \ @@ -872,6 +872,9 @@ <attribute id=\"0x020b\"> \ <uint16 value=\"0x0100\" /> \ </attribute> \ + <attribute id=\"0x020d\"> \ + <boolean value=\"true\" /> \ + </attribute> \ <attribute id=\"0x020e\"> \ <boolean value=\"true\" /> \ </attribute> \ @@ -1023,6 +1026,22 @@ static struct ext_profile *find_ext_profile(const char *owner, return NULL; } +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +struct btd_profile *btd_profile_find_ext(const char *owner, const char *path) +{ + struct ext_profile *ext; + + if (!owner || !path) + return NULL; + + ext = find_ext_profile(owner, path); + if (!ext) + return NULL; + + return &ext->p; +} +#endif + static void ext_io_destroy(gpointer p) { struct ext_io *ext_io = p; @@ -2213,7 +2232,7 @@ static char *get_sync_record(struct ext_profile *ext, struct ext_io *l2cap, static char *get_hid_device_record(struct ext_profile *ext, struct ext_io *l2cap, struct ext_io *rfcomm) { - return g_strdup(HID_DEVICE_RECORD); + return g_strdup_printf(HID_DEVICE_RECORD, ext->version); } #endif diff --git a/src/profile.h b/src/profile.h index d6e20f38..bbdf05d9 100755..100644 --- a/src/profile.h +++ b/src/profile.h @@ -75,6 +75,7 @@ bool btd_profile_remove_custom_prop(const char *uuid, const char *name); #ifdef TIZEN_FEATURE_BLUEZ_MODIFY gboolean ext_profile_is_registered_as_client_role(struct btd_profile *p); +struct btd_profile *btd_profile_find_ext(const char *owner, const char *path); #endif void btd_profile_init(void); diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c index 025a5334..424dd74e 100755..100644 --- a/src/shared/gatt-client.c +++ b/src/shared/gatt-client.c @@ -344,13 +344,14 @@ struct discovery_op { struct bt_gatt_client *client; struct queue *pending_svcs; struct queue *pending_chrcs; - struct queue *svcs; struct queue *ext_prop_desc; struct gatt_db_attribute *cur_svc; bool success; uint16_t start; uint16_t end; uint16_t last; + uint16_t svc_first; + uint16_t svc_last; int ref_count; discovery_op_complete_func_t complete_func; discovery_op_fail_func_t failure_func; @@ -360,7 +361,6 @@ static void discovery_op_free(struct discovery_op *op) { queue_destroy(op->pending_svcs, NULL); queue_destroy(op->pending_chrcs, free); - queue_destroy(op->svcs, NULL); queue_destroy(op->ext_prop_desc, NULL); free(op); } @@ -410,7 +410,6 @@ static struct discovery_op *discovery_op_create(struct bt_gatt_client *client, op = new0(struct discovery_op, 1); op->pending_svcs = queue_new(); op->pending_chrcs = queue_new(); - op->svcs = queue_new(); op->ext_prop_desc = queue_new(); op->client = client; op->complete_func = complete_func; @@ -463,7 +462,7 @@ static void discover_incl_cb(bool success, uint8_t att_ecode, struct discovery_op *op = user_data; struct bt_gatt_client *client = op->client; struct bt_gatt_iter iter; - struct gatt_db_attribute *attr, *tmp; + struct gatt_db_attribute *attr; uint16_t handle, start, end; uint128_t u128; bt_uuid_t uuid; @@ -479,11 +478,6 @@ static void discover_incl_cb(bool success, uint8_t att_ecode, goto failed; } - /* Get the currently processed service */ - attr = op->cur_svc; - if (!attr) - goto failed; - if (!result || !bt_gatt_iter_init(&iter, result)) goto failed; @@ -508,12 +502,12 @@ static void discover_incl_cb(bool success, uint8_t att_ecode, "handle: 0x%04x, start: 0x%04x, end: 0x%04x," "uuid: %s", handle, start, end, uuid_str); - tmp = gatt_db_get_attribute(client->db, start); - if (!tmp) + attr = gatt_db_get_attribute(client->db, start); + if (!attr) goto failed; - tmp = gatt_db_service_add_included(attr, tmp); - if (!tmp) + attr = gatt_db_insert_included(client->db, handle, attr); + if (!attr) goto failed; /* @@ -522,62 +516,23 @@ static void discover_incl_cb(bool success, uint8_t att_ecode, * these entries, the correct handle must be assigned to the new * attribute. */ - if (gatt_db_attribute_get_handle(tmp) != handle) + if (gatt_db_attribute_get_handle(attr) != handle) goto failed; } next: - /* Move on to the next service */ - attr = queue_pop_head(op->pending_svcs); - if (!attr) { - /* - * We have processed all include definitions. Move on to - * characteristics. - */ - attr = queue_pop_head(op->svcs); - if (!attr) - goto failed; - - if (!gatt_db_attribute_get_service_handles(attr, &start, &end)) - goto failed; - - op->cur_svc = attr; - - client->discovery_req = bt_gatt_discover_characteristics( - client->att, - start, end, + client->discovery_req = bt_gatt_discover_characteristics(client->att, + op->svc_first, + op->svc_last, discover_chrcs_cb, discovery_op_ref(op), discovery_op_unref); - if (client->discovery_req) - return; - - util_debug(client->debug_callback, client->debug_data, - "Failed to start characteristic discovery"); - discovery_op_unref(op); - goto failed; - } - - queue_push_tail(op->svcs, attr); - op->cur_svc = attr; - if (!gatt_db_attribute_get_service_handles(attr, &start, &end)) - goto failed; - - if (start == end) - goto next; - - client->discovery_req = bt_gatt_discover_included_services(client->att, - start, end, - discover_incl_cb, - discovery_op_ref(op), - discovery_op_unref); if (client->discovery_req) return; util_debug(client->debug_callback, client->debug_data, - "Failed to start included discovery"); + "Failed to start characteristic discovery"); discovery_op_unref(op); - failed: discovery_op_complete(op, false, att_ecode); } @@ -604,7 +559,10 @@ static bool discover_descs(struct discovery_op *op, bool *discovering) *discovering = false; while ((chrc_data = queue_pop_head(op->pending_chrcs))) { - attr = gatt_db_service_insert_characteristic(op->cur_svc, + struct gatt_db_attribute *svc; + uint16_t start, end; + + attr = gatt_db_insert_characteristic(client->db, chrc_data->value_handle, &chrc_data->uuid, 0, chrc_data->properties, @@ -621,6 +579,25 @@ static bool discover_descs(struct discovery_op *op, bool *discovering) chrc_data->value_handle) goto failed; + /* Adjust current service */ + svc = gatt_db_get_service(client->db, chrc_data->value_handle); + if (op->cur_svc != svc) { + queue_remove(op->pending_svcs, svc); + + /* Done with the current service */ + gatt_db_service_set_active(op->cur_svc, true); + op->cur_svc = svc; + } + + gatt_db_attribute_get_service_handles(svc, &start, &end); + + /* + * Ajust end_handle in case the next chrc is not within the + * same service. + */ + if (chrc_data->end_handle > end) + chrc_data->end_handle = end; + /* * check for descriptors presence, before initializing the * desc_handle and avoid integer overflow during desc_handle @@ -630,6 +607,7 @@ static bool discover_descs(struct discovery_op *op, bool *discovering) free(chrc_data); continue; } + desc_start = chrc_data->value_handle + 1; client->discovery_req = bt_gatt_discover_descriptors( @@ -700,8 +678,6 @@ static void ext_prop_read_cb(bool success, uint8_t att_ecode, struct bt_gatt_client *client = op->client; bool discovering; struct gatt_db_attribute *desc_attr = NULL; - struct gatt_db_attribute *next_srv; - uint16_t start, end; util_debug(client->debug_callback, client->debug_data, "Ext. prop value: 0x%04x", (uint16_t)value[0]); @@ -718,42 +694,15 @@ static void ext_prop_read_cb(bool success, uint8_t att_ecode, if (read_ext_prop_desc(op)) return; - /* Continue with discovery */ - do { - if (!discover_descs(op, &discovering)) - goto failed; - - if (discovering) - return; - - /* Done with the current service */ - gatt_db_service_set_active(op->cur_svc, true); - - next_srv = queue_pop_head(op->svcs); - if (!next_srv) - goto done; - - if (!gatt_db_attribute_get_service_handles(next_srv, &start, - &end)) - goto failed; - - } while (start == end); - - /* Move on to the next service */ - op->cur_svc = next_srv; + if (!discover_descs(op, &discovering)) + goto failed; - client->discovery_req = bt_gatt_discover_characteristics(client->att, - start, end, - discover_chrcs_cb, - discovery_op_ref(op), - discovery_op_unref); - if (client->discovery_req) + if (discovering) return; - util_debug(client->debug_callback, client->debug_data, - "Failed to start characteristic discovery"); - - discovery_op_unref(op); + /* Done with the current service */ + gatt_db_service_set_active(op->cur_svc, true); + goto done; failed: success = false; @@ -770,7 +719,7 @@ static void discover_descs_cb(bool success, uint8_t att_ecode, struct bt_gatt_client *client = op->client; struct bt_gatt_iter iter; struct gatt_db_attribute *attr; - uint16_t handle, start, end; + uint16_t handle; uint128_t u128; bt_uuid_t uuid; char uuid_str[MAX_LEN_UUID_STR]; @@ -810,11 +759,15 @@ static void discover_descs_cb(bool success, uint8_t att_ecode, "handle: 0x%04x, uuid: %s", handle, uuid_str); - attr = gatt_db_service_insert_descriptor(op->cur_svc, handle, + attr = gatt_db_insert_descriptor(client->db, handle, &uuid, 0, NULL, NULL, NULL); - if (!attr) + if (!attr) { + util_debug(client->debug_callback, client->debug_data, + "Failed to insert descriptor at 0x%04x", + handle); goto failed; + } if (gatt_db_attribute_get_handle(attr) != handle) goto failed; @@ -837,30 +790,7 @@ next: /* Done with the current service */ gatt_db_service_set_active(op->cur_svc, true); - attr = queue_pop_head(op->svcs); - if (!attr) - goto done; - - if (!gatt_db_attribute_get_service_handles(attr, &start, &end)) - goto failed; - - if (start == end) - goto next; - - /* Move on to the next service */ - op->cur_svc = attr; - - client->discovery_req = bt_gatt_discover_characteristics(client->att, - start, end, - discover_chrcs_cb, - discovery_op_ref(op), - discovery_op_unref); - if (client->discovery_req) - return; - - util_debug(client->debug_callback, client->debug_data, - "Failed to start characteristic discovery"); - discovery_op_unref(op); + goto done; failed: success = false; @@ -926,7 +856,6 @@ static void discover_chrcs_cb(bool success, uint8_t att_ecode, struct discovery_op *op = user_data; struct bt_gatt_client *client = op->client; struct bt_gatt_iter iter; - struct gatt_db_attribute *attr; struct chrc *chrc_data; uint16_t start, end, value; uint8_t properties; @@ -947,7 +876,7 @@ static void discover_chrcs_cb(bool success, uint8_t att_ecode, goto done; } - if (!op->cur_svc || !result || !bt_gatt_iter_init(&iter, result)) + if (!result || !bt_gatt_iter_init(&iter, result)) goto failed; chrc_count = bt_gatt_result_characteristic_count(result); @@ -1003,30 +932,7 @@ next: /* Done with the current service */ gatt_db_service_set_active(op->cur_svc, true); - attr = queue_pop_head(op->svcs); - if (!attr) - goto done; - - if (!gatt_db_attribute_get_service_handles(attr, &start, &end)) - goto failed; - - if (start == end) - goto next; - - /* Move on to the next service */ - op->cur_svc = attr; - - client->discovery_req = bt_gatt_discover_characteristics(client->att, - start, end, - discover_chrcs_cb, - discovery_op_ref(op), - discovery_op_unref); - if (client->discovery_req) - return; - - util_debug(client->debug_callback, client->debug_data, - "Failed to start characteristic discovery"); - discovery_op_unref(op); + goto done; failed: success = false; @@ -1035,6 +941,26 @@ done: discovery_op_complete(op, success, att_ecode); } +static void discovery_found_service(struct discovery_op *op, + struct gatt_db_attribute *attr, + uint16_t start, uint16_t end) +{ + /* Skip if service already active */ + if (!gatt_db_service_get_active(attr)) { + queue_push_tail(op->pending_svcs, attr); + + /* Update discovery range */ + if (!op->svc_first || op->svc_first > start) + op->svc_first = start; + if (op->svc_last < end) + op->svc_last = end; + } + + /* Update last handle */ + if (end > op->last) + op->last = end; +} + static void discover_secondary_cb(bool success, uint8_t att_ecode, struct bt_gatt_result *result, void *user_data) @@ -1104,39 +1030,14 @@ static void discover_secondary_cb(bool success, uint8_t att_ecode, } } - /* Skip if service already active */ - if (!gatt_db_service_get_active(attr)) - queue_push_tail(op->pending_svcs, attr); - - /* Update last handle */ - if (end > op->last) - op->last = end; + /* Update pending list */ + discovery_found_service(op, attr, start, end); } next: - /* Sequentially discover included services */ - attr = queue_pop_head(op->pending_svcs); - - /* Complete with success if queue is empty */ - if (!attr) { - success = true; - goto done; - } - - /* - * Store the service in the svcs queue to be reused during - * characteristics discovery later. - */ - queue_push_tail(op->svcs, attr); - op->cur_svc = attr; - - if (!gatt_db_attribute_get_service_handles(attr, &start, &end)) { - success = false; - goto done; - } - client->discovery_req = bt_gatt_discover_included_services(client->att, - start, end, + op->svc_first, + op->svc_last, discover_incl_cb, discovery_op_ref(op), discovery_op_unref); @@ -1222,13 +1123,8 @@ static void discover_primary_cb(bool success, uint8_t att_ecode, } } - /* Skip if service already active */ - if (!gatt_db_service_get_active(attr)) - queue_push_tail(op->pending_svcs, attr); - - /* Update last handle */ - if (end > op->last) - op->last = end; + /* Update pending list */ + discovery_found_service(op, attr, start, end); } secondary: diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c index 69554a9c..5cc3b573 100755..100644 --- a/src/shared/gatt-db.c +++ b/src/shared/gatt-db.c @@ -736,6 +736,28 @@ service_insert_characteristic(struct gatt_db_service *service, } struct gatt_db_attribute * +gatt_db_insert_characteristic(struct gatt_db *db, + uint16_t handle, + const bt_uuid_t *uuid, + uint32_t permissions, + uint8_t properties, + gatt_db_read_t read_func, + gatt_db_write_t write_func, + void *user_data) +{ + struct gatt_db_attribute *attrib; + + attrib = gatt_db_get_service(db, handle); + if (!attrib) + return NULL; + + return service_insert_characteristic(attrib->service, handle, uuid, + permissions, properties, + read_func, write_func, + user_data); +} + +struct gatt_db_attribute * gatt_db_service_insert_characteristic(struct gatt_db_attribute *attrib, uint16_t handle, const bt_uuid_t *uuid, @@ -805,6 +827,26 @@ service_insert_descriptor(struct gatt_db_service *service, } struct gatt_db_attribute * +gatt_db_insert_descriptor(struct gatt_db *db, + uint16_t handle, + const bt_uuid_t *uuid, + uint32_t permissions, + gatt_db_read_t read_func, + gatt_db_write_t write_func, + void *user_data) +{ + struct gatt_db_attribute *attrib; + + attrib = gatt_db_get_service(db, handle); + if (!attrib) + return NULL; + + return service_insert_descriptor(attrib->service, handle, uuid, + permissions, read_func, write_func, + user_data); +} + +struct gatt_db_attribute * gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib, uint16_t handle, const bt_uuid_t *uuid, @@ -837,19 +879,15 @@ gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib, user_data); } -struct gatt_db_attribute * -gatt_db_service_add_included(struct gatt_db_attribute *attrib, +static struct gatt_db_attribute * +service_insert_included(struct gatt_db_service *service, uint16_t handle, struct gatt_db_attribute *include) { - struct gatt_db_service *service, *included; + struct gatt_db_service *included; uint8_t value[MAX_INCLUDED_VALUE_LEN]; uint16_t included_handle, len = 0; int index; - if (!attrib || !include) - return NULL; - - service = attrib->service; included = include->service; /* Adjust include to point to the first attribute */ @@ -876,7 +914,14 @@ gatt_db_service_add_included(struct gatt_db_attribute *attrib, if (!index) return NULL; - service->attributes[index] = new_attribute(service, 0, + /* Check if handle is in within service range */ + if (handle && handle <= service->attributes[0]->handle) + return NULL; + + if (!handle) + handle = get_handle_at_index(service, index - 1) + 1; + + service->attributes[index] = new_attribute(service, handle, &included_service_uuid, value, len); if (!service->attributes[index]) @@ -892,6 +937,40 @@ gatt_db_service_add_included(struct gatt_db_attribute *attrib, return attribute_update(service, index); } +struct gatt_db_attribute * +gatt_db_service_add_included(struct gatt_db_attribute *attrib, + struct gatt_db_attribute *include) +{ + if (!attrib || !include) + return NULL; + + return service_insert_included(attrib->service, 0, include); +} + +struct gatt_db_attribute * +gatt_db_service_insert_included(struct gatt_db_attribute *attrib, + uint16_t handle, + struct gatt_db_attribute *include) +{ + if (!attrib || !handle || !include) + return NULL; + + return service_insert_included(attrib->service, handle, include); +} + +struct gatt_db_attribute * +gatt_db_insert_included(struct gatt_db *db, uint16_t handle, + struct gatt_db_attribute *include) +{ + struct gatt_db_attribute *attrib; + + attrib = gatt_db_get_service(db, handle); + if (!attrib) + return NULL; + + return service_insert_included(attrib->service, handle, include); +} + bool gatt_db_service_set_active(struct gatt_db_attribute *attrib, bool active) { struct gatt_db_service *service; @@ -1319,20 +1398,35 @@ static bool find_service_for_handle(const void *data, const void *user_data) return (start <= handle) && (handle <= end); } -struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db, +struct gatt_db_attribute *gatt_db_get_service(struct gatt_db *db, uint16_t handle) { struct gatt_db_service *service; - int i; if (!db || !handle) return NULL; service = queue_find(db->services, find_service_for_handle, - UINT_TO_PTR(handle)); + UINT_TO_PTR(handle)); if (!service) return NULL; + return service->attributes[0]; +} + +struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db, + uint16_t handle) +{ + struct gatt_db_attribute *attrib; + struct gatt_db_service *service; + int i; + + attrib = gatt_db_get_service(db, handle); + if (!attrib) + return NULL; + + service = attrib->service; + for (i = 0; i < service->num_handles; i++) { if (!service->attributes[i]) continue; diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h index 8ac0c32e..1c3785a2 100755..100644 --- a/src/shared/gatt-db.h +++ b/src/shared/gatt-db.h @@ -78,6 +78,25 @@ gatt_db_service_insert_characteristic(struct gatt_db_attribute *attrib, void *user_data); struct gatt_db_attribute * +gatt_db_insert_characteristic(struct gatt_db *db, + uint16_t handle, + const bt_uuid_t *uuid, + uint32_t permissions, + uint8_t properties, + gatt_db_read_t read_func, + gatt_db_write_t write_func, + void *user_data); + +struct gatt_db_attribute * +gatt_db_insert_descriptor(struct gatt_db *db, + uint16_t handle, + const bt_uuid_t *uuid, + uint32_t permissions, + gatt_db_read_t read_func, + gatt_db_write_t write_func, + void *user_data); + +struct gatt_db_attribute * gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib, const bt_uuid_t *uuid, uint32_t permissions, @@ -94,8 +113,16 @@ gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib, void *user_data); struct gatt_db_attribute * +gatt_db_insert_included(struct gatt_db *db, uint16_t handle, + struct gatt_db_attribute *include); + +struct gatt_db_attribute * gatt_db_service_add_included(struct gatt_db_attribute *attrib, struct gatt_db_attribute *include); +struct gatt_db_attribute * +gatt_db_service_insert_included(struct gatt_db_attribute *attrib, + uint16_t handle, + struct gatt_db_attribute *include); bool gatt_db_service_set_active(struct gatt_db_attribute *attrib, bool active); bool gatt_db_service_get_active(struct gatt_db_attribute *attrib); @@ -170,6 +197,9 @@ unsigned int gatt_db_register(struct gatt_db *db, gatt_db_destroy_func_t destroy); bool gatt_db_unregister(struct gatt_db *db, unsigned int id); +struct gatt_db_attribute *gatt_db_get_service(struct gatt_db *db, + uint16_t handle); + struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db, uint16_t handle); diff --git a/tools/btsnoop.c b/tools/btsnoop.c index c2a194b1..2dd2499e 100755..100644 --- a/tools/btsnoop.c +++ b/tools/btsnoop.c @@ -688,6 +688,7 @@ int main(int argc, char *argv[]) case 's': command = SPLIT; input_path = optarg; + break; #endif case 't': type = optarg; diff --git a/tools/hcidump.c b/tools/hcidump.c index b460daa3..c98d60b9 100755..100644 --- a/tools/hcidump.c +++ b/tools/hcidump.c @@ -298,6 +298,7 @@ static int process_frames(int dev, int sock, int fd, unsigned long flags) len = write_n(fd, buf, frm.data_len + hdr_size); if (len < 0) { perror("Write error"); + close(fd); return -1; } written += len; diff --git a/tools/parser/hci.c b/tools/parser/hci.c index 8c7bd258..fc4099c2 100755..100644 --- a/tools/parser/hci.c +++ b/tools/parser/hci.c @@ -127,7 +127,11 @@ static char *event_str[EVENT_NUM + 1] = { "AMP Status Change", }; +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY +#define LE_EV_NUM 11 +#else #define LE_EV_NUM 5 +#endif static char *ev_le_meta_str[LE_EV_NUM + 1] = { "Unknown", "LE Connection Complete", @@ -135,6 +139,14 @@ static char *ev_le_meta_str[LE_EV_NUM + 1] = { "LE Connection Update Complete", "LE Read Remote Used Features Complete", "LE Long Term Key Request", +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + "LE Remote Connection Parameter Request", + "LE Data Length Change", + "LE Read Local P-256 Public Key Complete", + "LE Generate DHKey Complete", + "LE Enhanced Connection Complete", + "LE Direct Advertising Report", +#endif }; #define CMD_LINKCTL_NUM 60 @@ -3667,7 +3679,14 @@ static inline void le_meta_ev_dump(int level, struct frame *frm) frm->len -= EVT_LE_META_EVENT_SIZE; p_indent(level, frm); +#ifdef TIZEN_FEATURE_BLUEZ_MODIFY + if (subevent <= LE_EV_NUM) + printf("%s\n", ev_le_meta_str[subevent]); + else + printf("%s\n", ev_le_meta_str[0]); +#else printf("%s\n", ev_le_meta_str[subevent]); +#endif switch (mevt->subevent) { case EVT_LE_CONN_COMPLETE: |