Merge BlueZ upstream master branch
Merged several post-5.28-release fixes from BlueZ upstream .
BUG=none
TEST=emerge bluez
diff --git a/android/Android.mk b/android/Android.mk
index c1a9eff..ff71089 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -539,6 +539,34 @@
include $(BUILD_EXECUTABLE)
#
+# hciconfig
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ bluez/tools/hciconfig.c \
+ bluez/tools/csr.c \
+ bluez/lib/bluetooth.c \
+ bluez/lib/hci.c \
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/bluez \
+
+LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
+
+LOCAL_STATIC_LIBRARIES := \
+ bluetooth-headers \
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := hciconfig
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac
+
+include $(BUILD_EXECUTABLE)
+
+#
# l2ping
#
diff --git a/android/README b/android/README
index 7b1f126..687beec 100644
--- a/android/README
+++ b/android/README
@@ -403,7 +403,9 @@
BlueZ.
For Android 5.0 Lollipop:
-<TBD>
+https://android-review.googlesource.com/99761
+https://android-review.googlesource.com/100297
+https://android-review.googlesource.com/102882
For Android 4.4 KitKat:
https://android-review.googlesource.com/82757
diff --git a/android/gatt.c b/android/gatt.c
index 466c1ea..5f3050f 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -1488,9 +1488,9 @@
struct connect_data data;
struct att_range range;
uint32_t status;
+ GError *err = NULL;
GAttrib *attrib;
uint16_t mtu;
- uint16_t cid;
if (dev->state != DEVICE_CONNECT_READY) {
error("gatt: Device not in a connecting state!?");
@@ -1510,9 +1510,13 @@
goto reply;
}
- if (!bt_io_get(io, &gerr, BT_IO_OPT_IMTU, &mtu, BT_IO_OPT_CID, &cid,
- BT_IO_OPT_INVALID) || cid == ATT_CID)
- mtu = ATT_DEFAULT_LE_MTU;
+ if (!bt_io_get(io, &err, BT_IO_OPT_IMTU, &mtu, BT_IO_OPT_INVALID)) {
+ error("gatt: Could not get imtu: %s", err->message);
+ device_set_state(dev, DEVICE_DISCONNECTED);
+ status = GATT_FAILURE;
+ g_error_free(err);
+ goto reply;
+ }
attrib = g_attrib_new(io, mtu);
if (!attrib) {
diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index f15c12e..515cf4e 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -456,7 +456,7 @@
Command parameters: Socket type (1 octet)
Service name (256 octets)
Service UUID (16 octets)
- Channel (2 octets)
+ Channel (4 octets)
Socket flags (1 octet)
Response parameters: File descriptor (inline)
@@ -474,7 +474,7 @@
Command parameters: Remote address (6 octets)
Socket type (1 octet)
Service UUID (16 octets)
- Channel (2 octets)
+ Channel (4 octets)
Socket flags (1 octet)
Response parameters: File descriptor (inline)
diff --git a/android/handsfree.c b/android/handsfree.c
index 98d40b3..76f5653 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -1536,10 +1536,10 @@
static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data)
{
struct hf_device *dev = data;
- sdp_list_t *protos, *classes;
+ sdp_list_t *protos;
GError *gerr = NULL;
GIOChannel *io;
- uuid_t uuid;
+ uuid_t class;
int channel;
DBG("");
@@ -1550,35 +1550,29 @@
goto fail;
}
- if (!recs || !recs->data) {
- info("handsfree: no HSP SDP records found");
- goto fail;
+ sdp_uuid16_create(&class, HEADSET_SVCLASS_ID);
+
+ /* Find record with proper service class */
+ for (; recs; recs = recs->next) {
+ sdp_record_t *rec = recs->data;
+
+ if (rec && !sdp_uuid_cmp(&rec->svclass, &class))
+ break;
}
- if (sdp_get_service_classes(recs->data, &classes) < 0 || !classes) {
- error("handsfree: unable to get service classes from record");
+ if (!recs || !recs->data) {
+ info("handsfree: no valid HSP SDP records found");
goto fail;
}
if (sdp_get_access_protos(recs->data, &protos) < 0) {
error("handsfree: unable to get access protocols from record");
- sdp_list_free(classes, free);
goto fail;
}
/* TODO read remote version? */
/* TODO read volume control support */
- memcpy(&uuid, classes->data, sizeof(uuid));
- sdp_list_free(classes, free);
-
- if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 ||
- uuid.value.uuid16 != HEADSET_SVCLASS_ID) {
- sdp_list_free(protos, NULL);
- error("handsfree: invalid service record or not HSP");
- goto fail;
- }
-
channel = sdp_get_proto_port(protos, RFCOMM_UUID);
sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
sdp_list_free(protos, NULL);
@@ -1621,10 +1615,10 @@
static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data)
{
struct hf_device *dev = data;
- sdp_list_t *protos, *classes;
+ sdp_list_t *protos;
GError *gerr = NULL;
GIOChannel *io;
- uuid_t uuid;
+ uuid_t class;
int channel;
DBG("");
@@ -1635,6 +1629,16 @@
goto fail;
}
+ sdp_uuid16_create(&class, HANDSFREE_SVCLASS_ID);
+
+ /* Find record with proper service class */
+ for (; recs; recs = recs->next) {
+ sdp_record_t *rec = recs->data;
+
+ if (rec && !sdp_uuid_cmp(&rec->svclass, &class))
+ break;
+ }
+
if (!recs || !recs->data) {
info("handsfree: no HFP SDP records found, trying HSP");
@@ -1646,26 +1650,8 @@
return;
}
- if (sdp_get_service_classes(recs->data, &classes) < 0 || !classes) {
- error("handsfree: unable to get service classes from record");
- goto fail;
- }
-
if (sdp_get_access_protos(recs->data, &protos) < 0) {
error("handsfree: unable to get access protocols from record");
- sdp_list_free(classes, free);
- goto fail;
- }
-
- /* TODO read remote version? */
-
- memcpy(&uuid, classes->data, sizeof(uuid));
- sdp_list_free(classes, free);
-
- if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 ||
- uuid.value.uuid16 != HANDSFREE_SVCLASS_ID) {
- sdp_list_free(protos, NULL);
- error("handsfree: invalid service record or not HFP");
goto fail;
}
@@ -1677,6 +1663,8 @@
goto fail;
}
+ /* TODO read remote version? */
+
io = bt_io_connect(connect_cb, dev, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
diff --git a/android/log.c b/android/log.c
index 09d226a..8013eba 100644
--- a/android/log.c
+++ b/android/log.c
@@ -25,7 +25,10 @@
#endif
#include <fcntl.h>
+#include <stdarg.h>
#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <time.h>
diff --git a/android/pics-iopt.txt b/android/pics-iopt.txt
index 1276224..a0c9b95 100644
--- a/android/pics-iopt.txt
+++ b/android/pics-iopt.txt
@@ -78,7 +78,7 @@
TSPC_support_ False Support for: Extended
ExtendedServiceDiscoveryProfile_L2CAP SDP. Version: L2CAP
-TSPC_support_FAXProfile_DE False Support for: FAX Profile
+TSPC_support_FAXProfile_DT False Support for: FAX Profile
Role: Data Terminal
TSPC_support_FAXProfile_GW False Support for: FAX Profile
@@ -96,7 +96,7 @@
TSPC_support_HealthDeviceProfile_Source False Support for: HDP
Role: Source
-TSPC_support_NewHandsFreeProfile_AG True Support for: HFP
+TSPC_support_NewHandsFreeProfile_AG True (*) Support for: HFP
Role: Audio gateway
TSPC_support_NewHandsFreeProfile_HF False Support for: HFP
diff --git a/android/pics-pbap.txt b/android/pics-pbap.txt
index cb4126c..afd100b 100644
--- a/android/pics-pbap.txt
+++ b/android/pics-pbap.txt
@@ -1,6 +1,6 @@
PBAP PICS for the PTS tool.
-PTS version: 5.3
+PTS version: 6.0
* - different than PTS defaults
# - not yet implemented/supported
@@ -8,17 +8,6 @@
M - mandatory
O - optional
- Major Profile Version (X.Y)
--------------------------------------------------------------------------------
-Parameter Name Selected Description
--------------------------------------------------------------------------------
-TSPC_PBAP_0_1 False Role: PBAP 1.0 (C.1)
-TSPC_PBAP_0_2 True (*) Role: PBAP 1.1 (C.1)
-TSPC_PBAP_0_3 False Role: PBAP 1.2 (C.1)
--------------------------------------------------------------------------------
-C.1: Mandatory to support one and only one major profile version.
--------------------------------------------------------------------------------
-
Roles
-------------------------------------------------------------------------------
@@ -31,6 +20,28 @@
-------------------------------------------------------------------------------
+ Client Major Profile Version (X.Y)
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_PBAP_2a_1 False PBAP 1.0 (C.1)
+TSPC_PBAP_2a_2 False PBAP 1.1 (C.1)
+TSPC_PBAP_2a_3 False PBAP 1.2 (C.1)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support one and only one major profile version.
+-------------------------------------------------------------------------------
+
+
+ Client Minor Profile Version (X.Y)
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_PBAP_2b_1 False PBAP 1.1.1 (C.1)
+-------------------------------------------------------------------------------
+C.1: Optional if 2a/2 (PBAP 1.1) is supported, otherwise Excluded.
+-------------------------------------------------------------------------------
+
+
Supported features (PCE)
-------------------------------------------------------------------------------
Parameter Name Selected Description
@@ -169,7 +180,29 @@
-------------------------------------------------------------------------------
- Supported features ( PSE )
+ Server Major Profile Version (X.Y)
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_PBAP_9a_1 False PBAP 1.0 (C.1)
+TSPC_PBAP_9a_2 True (*) PBAP 1.1 (C.1)
+TSPC_PBAP_9a_3 False PBAP 1.2 (C.1)
+-------------------------------------------------------------------------------
+C.1: Mandatory to support one and only one major profile version.
+-------------------------------------------------------------------------------
+
+
+ Server Minor Profile Version (X.Y.Z)
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_PBAP_9b_1 False PBAP 1.1.1 (C.1)
+-------------------------------------------------------------------------------
+C.1: Optional if 9a/2 (PBAP 1.1) is supported, otherwise Excluded.
+-------------------------------------------------------------------------------
+
+
+ Supported features (PSE)
-------------------------------------------------------------------------------
Parameter Name Selected Description
-------------------------------------------------------------------------------
@@ -430,7 +463,7 @@
-------------------------------------------------------------------------------
Parameter Name Selected Description
-------------------------------------------------------------------------------
-TSPC_PBAP_26_1 False (*) PSE: GOEP v2.0 or later (M)
+TSPC_PBAP_26_1 False PSE: GOEP v2.0 or later (M)
TSPC_PBAP_26_2 False (*) PSE: GOEP v2 Backwards Compatibility (M)
TSPC_PBAP_26_3 False PSE: OBEX over L2CAP (M)
TSPC_PBAP_26_4 False PSE: OBEX SRM (M)
diff --git a/android/pixit-iopt.txt b/android/pixit-iopt.txt
index 53837de..4cc6fd4 100644
--- a/android/pixit-iopt.txt
+++ b/android/pixit-iopt.txt
@@ -1,6 +1,6 @@
IOPT PIXIT for the PTS tool.
-PTS version: 5.3
+PTS version: 6.0
* - different than PTS defaults
& - should be set to IUT Bluetooth address
diff --git a/android/pixit-pbap.txt b/android/pixit-pbap.txt
index f7a93c6..034456a 100644
--- a/android/pixit-pbap.txt
+++ b/android/pixit-pbap.txt
@@ -1,6 +1,6 @@
PBAP PIXIT for the PTS tool.
-PTS version: 5.3
+PTS version: 6.0
* - different than PTS defaults
& - should be set to IUT Bluetooth address
diff --git a/android/pts-iopt.txt b/android/pts-iopt.txt
index f746b1c..7b776a9 100644
--- a/android/pts-iopt.txt
+++ b/android/pts-iopt.txt
@@ -1,7 +1,7 @@
PTS test results for IOPT
-PTS version: 5.3
-Tested: 18-November-2014
+PTS version: 6.0
+Tested: 03-February-2015
Android version: 5.0
Results:
@@ -14,12 +14,13 @@
Test Name Result Notes
-------------------------------------------------------------------------------
TC_COD_BV_01_I PASS IUT must be discoverable
-TC_COD_BV_02_I N/A Under PTS 5.1 test shall be disabled as there is
- matching test case in HFP test suit (test No. 15)
- PICS settings for HFP shall be disabled for IOPT
-TC_SDSS_BV_02_I PASS
-TC_SDAS_BV_03_I PASS
-TC_SDR_BV_04_I PASS for every PTS bt profile:
- haltest: bluetooth get_remote_service_record <addr>
- <requred 128 sdp uuid>
+TC_COD_BV_02_I N/A
+TC_SDSS_BV_02_I PASS Note: HDP sink record should be registered before test
+ run, e.g. register health app via HDPSample.apk
+TC_SDAS_BV_03_I PASS Note: HDP sink record should be registered before test
+ run, e.g. register health app via HDPSample.apk
+TC_SDR_BV_04_I PASS For every asked to check PTS bt profile:
+ haltest: bluetooth get_remote_service_record <PTS addr>
+ <profile uuid>
+ Note: 0000xxxx - acceptable 16bit uuid format
-------------------------------------------------------------------------------
diff --git a/android/pts-pbap.txt b/android/pts-pbap.txt
index 8194bd7..8931690 100644
--- a/android/pts-pbap.txt
+++ b/android/pts-pbap.txt
@@ -1,7 +1,7 @@
PTS test results for PBAP
-PTS version: 5.3
-Tested: 17-November-2014
+PTS version: 6.0
+Tested: 30-January-2015
Android version: 5.0
Results:
diff --git a/android/tester-gatt.c b/android/tester-gatt.c
index 23c6609..15a54fa 100644
--- a/android/tester-gatt.c
+++ b/android/tester-gatt.c
@@ -1084,7 +1084,7 @@
static struct iovec att_read_req_op_v = raw_pdu(L2CAP_ATT_READ_REQ);
static struct iovec att_write_req_op_v = raw_pdu(L2CAP_ATT_WRITE_REQ);
-static struct iovec svc_change_ccc_handle_v = raw_pdu(0x1a, 0x00);
+static struct iovec svc_change_ccc_handle_v = raw_pdu(0x1c, 0x00);
static struct iovec svc_change_ccc_value_v = raw_pdu(0x00, 0x01);
static void gatt_client_register_action(void)
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 5f353df..f2674aa 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -856,7 +856,7 @@
a = l->data;
- if (a->len <= offset)
+ if (a->len < offset)
return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle,
ATT_ECODE_INVALID_OFFSET, pdu, len);
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 5edb991..d0fc054 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -88,6 +88,7 @@
* the remote peripheral.
*/
unsigned int svc_chngd_ind_id;
+ bool svc_chngd_registered;
struct queue *svc_chngd_queue; /* Queued service changed events */
bool in_svc_chngd;
@@ -234,12 +235,6 @@
&properties, NULL))
return NULL;
- /* Find the CCC characteristic */
- ccc = NULL;
- gatt_db_service_foreach_desc(attr, find_ccc, &ccc);
- if (!ccc)
- return NULL;
-
chrc = new0(struct notify_chrc, 1);
if (!chrc)
return NULL;
@@ -250,8 +245,17 @@
return NULL;
}
+ /*
+ * Find the CCC characteristic. Some characteristics that allow
+ * notifications may not have a CCC descriptor. We treat these as
+ * automatically successful.
+ */
+ ccc = NULL;
+ gatt_db_service_foreach_desc(attr, find_ccc, &ccc);
+ if (ccc)
+ chrc->ccc_handle = gatt_db_attribute_get_handle(ccc);
+
chrc->value_handle = value_handle;
- chrc->ccc_handle = gatt_db_attribute_get_handle(ccc);
chrc->properties = properties;
queue_push_tail(client->notify_chrcs, chrc);
@@ -1020,6 +1024,7 @@
util_debug(client->debug_callback, client->debug_data,
"Re-registered handler for \"Service Changed\" after "
"change in GATT service");
+ client->svc_chngd_registered = true;
return;
}
@@ -1089,6 +1094,7 @@
/* The GATT service was modified. Re-register the handler for
* indications from the "Service Changed" characteristic.
*/
+ client->svc_chngd_registered = false;
client->svc_chngd_ind_id = bt_gatt_client_register_notify(client,
gatt_db_attribute_get_handle(attr),
service_changed_reregister_cb,
@@ -1197,6 +1203,7 @@
goto done;
}
+ client->svc_chngd_registered = true;
client->ready = true;
success = true;
util_debug(client->debug_callback, client->debug_data,
@@ -1239,13 +1246,16 @@
service_changed_register_cb,
service_changed_cb,
client, NULL);
- client->ready = false;
+
+ if (!client->svc_chngd_registered)
+ client->ready = false;
if (client->svc_chngd_ind_id)
return;
util_debug(client->debug_callback, client->debug_data,
"Failed to register handler for \"Service Changed\"");
+ success = false;
fail:
util_debug(client->debug_callback, client->debug_data,
@@ -1423,18 +1433,17 @@
*/
if (notify_data->att_id) {
bt_att_cancel(notify_data->client->att, notify_data->att_id);
- notify_data_unref(notify_data);
- return;
+ goto done;
}
- if (__sync_sub_and_fetch(¬ify_data->chrc->notify_count, 1)) {
- notify_data_unref(notify_data);
- return;
- }
+ if (__sync_sub_and_fetch(¬ify_data->chrc->notify_count, 1) ||
+ !notify_data->chrc->ccc_handle)
+ goto done;
if (notify_data_write_ccc(notify_data, false, disable_ccc_callback))
return;
+done:
notify_data_unref(notify_data);
}
@@ -2571,9 +2580,7 @@
/* Add the handler to the bt_gatt_client's general list */
queue_push_tail(client->notify_list, notify_data);
- /* Assign an ID to the handler and notify the caller that it was
- * successfully registered.
- */
+ /* Assign an ID to the handler. */
if (client->next_reg_id < 1)
client->next_reg_id = 1;
@@ -2591,7 +2598,7 @@
/*
* If the ref count is not zero, then notifications are already enabled.
*/
- if (chrc->notify_count > 0) {
+ if (chrc->notify_count > 0 || !chrc->ccc_handle) {
complete_notify_request(notify_data);
return notify_data->id;
}
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index 780d640..f72d58e 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -1170,10 +1170,9 @@
uint16_t handle = PTR_TO_UINT(user_data);
uint16_t start, end;
- start = service->attributes[0]->handle;
- end = start + service->num_handles;
+ gatt_db_service_get_handles(service, &start, &end);
- return (start <= handle) && (handle < end);
+ return (start <= handle) && (handle <= end);
}
struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db,
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 05a8563..0ce3121 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -610,10 +610,9 @@
return NULL;
}
- if (!io_set_read_handler(hfp->io, can_read_data,
- hfp, read_watch_destroy)) {
- queue_destroy(hfp->cmd_handlers,
- destroy_cmd_handler);
+ if (!io_set_read_handler(hfp->io, can_read_data, hfp,
+ read_watch_destroy)) {
+ queue_destroy(hfp->cmd_handlers, destroy_cmd_handler);
io_destroy(hfp->io);
ringbuf_free(hfp->write_buf);
ringbuf_free(hfp->read_buf);
diff --git a/test/pbap-client b/test/pbap-client
index 51e26eb..16a786b 100755
--- a/test/pbap-client
+++ b/test/pbap-client
@@ -170,6 +170,6 @@
pbap_client.flush_transfers(lambda: test_paths(paths[1:]))
- test_paths(["PB", "ICH", "OCH", "MCH", "CCH"])
+ test_paths(["PB", "ICH", "OCH", "MCH", "CCH", "SPD", "FAV"])
mainloop.run()
diff --git a/tools/btgatt-server.c b/tools/btgatt-server.c
index f6ad8c3..d27cf10 100644
--- a/tools/btgatt-server.c
+++ b/tools/btgatt-server.c
@@ -631,7 +631,7 @@
"\t-s, --security-level <sec>\tSet security level (low|"
"medium|high)\n"
"\t-v, --verbose\t\t\tEnable extra logging\n"
- "\t-r, --heart-rate\t\tEnable Heart Rate service"
+ "\t-r, --heart-rate\t\tEnable Heart Rate service\n"
"\t-h, --help\t\t\tDisplay help\n");
}