2013-11-05 13:21:34

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCHv2 0/6] Query remote services support

V2:
- function fetch_remote__uids renamed to browse_remote_sdp
- result of browse_remote_sdp changed to uint8_t
- sdp_req_list name changed to browse_reqs
- browse_reqs contains requests, not addresses

Marcin Kraglak (6):
android: Initial implementation of get_remote_services
android: Fetch remote device uuids after pairing
android: Pass found uuids to remote_device_properties_cb
android: Add supported uuids when adapter is initialized
android: Implement class of device property callback
android: Add support for getting adapter uuids

android/adapter.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 305 insertions(+), 8 deletions(-)

--
1.8.4.1



2013-11-07 08:04:53

by Andrei Emeltchenko

[permalink] [raw]
Subject: Re: [PATCHv2 4/6] android: Add supported uuids when adapter is initialized

Hi All,

On Tue, Nov 05, 2013 at 02:21:38PM +0100, Marcin Kraglak wrote:
> It will set class of device with proper service hints.
> We set it statically because we want to keep code simple.
>
> ---
> android/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 59 insertions(+)
>
> diff --git a/android/adapter.c b/android/adapter.c
> index 0f24cac..70b9265 100644
> --- a/android/adapter.c
> +++ b/android/adapter.c
> @@ -52,6 +52,29 @@ static GIOChannel *notification_io = NULL;
> /* This list contains addresses which are asked for records */
> static GSList *browse_reqs;
>
> +/*
> + * This is an array of supported uuids and service hints. We add them via mgmt
> + * interface when adapter is initialized. Uuids are in reverse orded.
> + */
> +static const struct mgmt_cp_add_uuid supported_services[] = {
> + /* OBEX_OPP_UUID */
> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
> + 0x00, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00 },
> + .svc_hint = 0x10 },

I think PBAP is missing here. BTW can we define those strings separately
so that it might be used to compare.

Socket HAL identify service by UUID so I need to derive RFCOMM channel
from it. I am thinking simply comparing those strings.

Any opinion on this?

Best regards
Andrei Emeltchenko

2013-11-06 11:08:06

by Marcin Kraglak

[permalink] [raw]
Subject: Re: [PATCHv2 4/6] android: Add supported uuids when adapter is initialized

Hi Johan, Marcel

On 6 November 2013 09:41, Marcel Holtmann <[email protected]> wrote:
> Hi Johan,
>
>>> It will set class of device with proper service hints.
>>> We set it statically because we want to keep code simple.
>>>
>>> ---
>>> android/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 59 insertions(+)
>>
>> I've applied patches 1-3, but am a bit confused about this one.
>>
>>> diff --git a/android/adapter.c b/android/adapter.c
>>> index 0f24cac..70b9265 100644
>>> --- a/android/adapter.c
>>> +++ b/android/adapter.c
>>> @@ -52,6 +52,29 @@ static GIOChannel *notification_io = NULL;
>>> /* This list contains addresses which are asked for records */
>>> static GSList *browse_reqs;
>>>
>>> +/*
>>> + * This is an array of supported uuids and service hints. We add them via mgmt
>>> + * interface when adapter is initialized. Uuids are in reverse orded.
>>> + */
>>> +static const struct mgmt_cp_add_uuid supported_services[] = {
>>> + /* OBEX_OPP_UUID */
>>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>>> + 0x00, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00 },
>>> + .svc_hint = 0x10 },
>>> + /* HFP_AG_UUID */
>>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>>> + 0x00, 0x10, 0x00, 0x00, 0x1f, 0x11, 0x00, 0x00 },
>>> + .svc_hint = 0x40 },
>>> + /* ADVANCED_AUDIO_UUID */
>>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>>> + 0x00, 0x10, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00 },
>>> + .svc_hint = 0x08 },
>>> + /* PANU_UUID */
>>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>>> + 0x00, 0x10, 0x00, 0x00, 0x15, 0x11, 0x00, 0x00 },
>>> + .svc_hint = 0x02 }
>>> +};
>>
>> I seem to remember the discussion around this drifting back to doing the
>> registration dynamically. Do I remember wrong? Wasn't it so that at
>> least some UUIDs (such as PAN) with a bluedroid based system only appear
>> when you actually enable support for the profile in the UI?
>
> looking at a Nexus 4, the SDP database seems static. The PAN record is always present.
>
> I think dynamic is on the level do we compile in support for the PAN HAL module or not. So the record and UUID list should come from the PAN module. So it is kinda dynamic in that sense, but ultimately static.
>
> Regards
>
> Marcel
>

Could it look like this:
we will hold that static array off uuids and svc hints and additional
profile_id.
Each profile will call generic method like
adapter_register_profile(profile_id) (just example), and it will add
sdp record to sdp server & uuid to mgmt interface. Profiles
implemented out of stack (I mean opp, pbab etc) will have static sdp
record and uuid which will be added once adapter is initialized. What
is your opinion?

Regards
Marcin

2013-11-06 08:41:52

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCHv2 4/6] android: Add supported uuids when adapter is initialized

Hi Johan,

>> It will set class of device with proper service hints.
>> We set it statically because we want to keep code simple.
>>
>> ---
>> android/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 59 insertions(+)
>
> I've applied patches 1-3, but am a bit confused about this one.
>
>> diff --git a/android/adapter.c b/android/adapter.c
>> index 0f24cac..70b9265 100644
>> --- a/android/adapter.c
>> +++ b/android/adapter.c
>> @@ -52,6 +52,29 @@ static GIOChannel *notification_io = NULL;
>> /* This list contains addresses which are asked for records */
>> static GSList *browse_reqs;
>>
>> +/*
>> + * This is an array of supported uuids and service hints. We add them via mgmt
>> + * interface when adapter is initialized. Uuids are in reverse orded.
>> + */
>> +static const struct mgmt_cp_add_uuid supported_services[] = {
>> + /* OBEX_OPP_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x10 },
>> + /* HFP_AG_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x1f, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x40 },
>> + /* ADVANCED_AUDIO_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x08 },
>> + /* PANU_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x15, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x02 }
>> +};
>
> I seem to remember the discussion around this drifting back to doing the
> registration dynamically. Do I remember wrong? Wasn't it so that at
> least some UUIDs (such as PAN) with a bluedroid based system only appear
> when you actually enable support for the profile in the UI?

looking at a Nexus 4, the SDP database seems static. The PAN record is always present.

I think dynamic is on the level do we compile in support for the PAN HAL module or not. So the record and UUID list should come from the PAN module. So it is kinda dynamic in that sense, but ultimately static.

Regards

Marcel


2013-11-06 08:27:11

by Marcin Kraglak

[permalink] [raw]
Subject: Re: [PATCHv2 4/6] android: Add supported uuids when adapter is initialized

As I remember we agreed to have dynamic sdp records and static list of
uuids (to have correct service hint in class of device). Bluedroid
sets service hint once, and send new adapter uuids when specific
services starts (for example when you init hidhost,
adapter_property_callback will return with new uuid). But it doesn't
matter if you add them at start of bluetooth interface or specific
profile init - it happens at the same time. I've also checked if uuids
are removed when profiles are cleaned - and bluedroid doesn't remove
uuids which were added at start.

On 6 November 2013 09:02, Johan Hedberg <[email protected]> wrote:
> Hi Marcin,
>
> On Tue, Nov 05, 2013, Marcin Kraglak wrote:
>> It will set class of device with proper service hints.
>> We set it statically because we want to keep code simple.
>>
>> ---
>> android/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 59 insertions(+)
>
> I've applied patches 1-3, but am a bit confused about this one.
>
>> diff --git a/android/adapter.c b/android/adapter.c
>> index 0f24cac..70b9265 100644
>> --- a/android/adapter.c
>> +++ b/android/adapter.c
>> @@ -52,6 +52,29 @@ static GIOChannel *notification_io = NULL;
>> /* This list contains addresses which are asked for records */
>> static GSList *browse_reqs;
>>
>> +/*
>> + * This is an array of supported uuids and service hints. We add them via mgmt
>> + * interface when adapter is initialized. Uuids are in reverse orded.
>> + */
>> +static const struct mgmt_cp_add_uuid supported_services[] = {
>> + /* OBEX_OPP_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x10 },
>> + /* HFP_AG_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x1f, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x40 },
>> + /* ADVANCED_AUDIO_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x08 },
>> + /* PANU_UUID */
>> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
>> + 0x00, 0x10, 0x00, 0x00, 0x15, 0x11, 0x00, 0x00 },
>> + .svc_hint = 0x02 }
>> +};
>
> I seem to remember the discussion around this drifting back to doing the
> registration dynamically. Do I remember wrong? Wasn't it so that at
> least some UUIDs (such as PAN) with a bluedroid based system only appear
> when you actually enable support for the profile in the UI?
>
> Johan

2013-11-06 08:02:54

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCHv2 4/6] android: Add supported uuids when adapter is initialized

Hi Marcin,

On Tue, Nov 05, 2013, Marcin Kraglak wrote:
> It will set class of device with proper service hints.
> We set it statically because we want to keep code simple.
>
> ---
> android/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 59 insertions(+)

I've applied patches 1-3, but am a bit confused about this one.

> diff --git a/android/adapter.c b/android/adapter.c
> index 0f24cac..70b9265 100644
> --- a/android/adapter.c
> +++ b/android/adapter.c
> @@ -52,6 +52,29 @@ static GIOChannel *notification_io = NULL;
> /* This list contains addresses which are asked for records */
> static GSList *browse_reqs;
>
> +/*
> + * This is an array of supported uuids and service hints. We add them via mgmt
> + * interface when adapter is initialized. Uuids are in reverse orded.
> + */
> +static const struct mgmt_cp_add_uuid supported_services[] = {
> + /* OBEX_OPP_UUID */
> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
> + 0x00, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00 },
> + .svc_hint = 0x10 },
> + /* HFP_AG_UUID */
> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
> + 0x00, 0x10, 0x00, 0x00, 0x1f, 0x11, 0x00, 0x00 },
> + .svc_hint = 0x40 },
> + /* ADVANCED_AUDIO_UUID */
> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
> + 0x00, 0x10, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00 },
> + .svc_hint = 0x08 },
> + /* PANU_UUID */
> + { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
> + 0x00, 0x10, 0x00, 0x00, 0x15, 0x11, 0x00, 0x00 },
> + .svc_hint = 0x02 }
> +};

I seem to remember the discussion around this drifting back to doing the
registration dynamically. Do I remember wrong? Wasn't it so that at
least some UUIDs (such as PAN) with a bluedroid based system only appear
when you actually enable support for the profile in the UI?

Johan

2013-11-05 13:21:35

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCHv2 1/6] android: Initial implementation of get_remote_services

This patch implements method to retrieve remote device sdp records.
Caching struct is implemented for adding fetched uuids to list.
sdp_req_list will contain list of devices which are asked for records.
Function get_remote_services will check if device is on list, and will
start sdp procedure.

---
android/adapter.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 99 insertions(+), 1 deletion(-)

diff --git a/android/adapter.c b/android/adapter.c
index 074fc68..40fb89d 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -35,6 +35,10 @@
#include "src/shared/mgmt.h"
#include "src/glib-helper.h"
#include "src/eir.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "lib/uuid.h"
+#include "src/sdp-client.h"
#include "log.h"
#include "hal-msg.h"
#include "ipc.h"
@@ -45,6 +49,8 @@
#define DEFAULT_IO_CAPABILITY 0x01

static GIOChannel *notification_io = NULL;
+/* This list contains addresses which are asked for records */
+static GSList *browse_reqs;

struct bt_adapter {
uint16_t index;
@@ -63,6 +69,20 @@ struct bt_adapter {
bool discovering;
};

+struct browse_req {
+ bdaddr_t bdaddr;
+ GSList *uuids;
+ int search_uuid;
+ int reconnect_attempt;
+};
+
+static const uint16_t uuid_list[] = {
+ L2CAP_UUID,
+ PNP_INFO_SVCLASS_ID,
+ PUBLIC_BROWSE_GROUP,
+ 0
+};
+
static struct bt_adapter *adapter;
static GSList *found_devices = NULL;

@@ -262,6 +282,79 @@ static void send_bond_state_change(const bdaddr_t *addr, uint8_t status,
HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev, -1);
}

+static void browse_req_free(struct browse_req *req)
+{
+ g_slist_free_full(req->uuids, g_free);
+ g_free(req);
+}
+
+static void update_records(struct browse_req *req, sdp_list_t *recs)
+{
+ /* TODO cache found uuids */
+}
+
+static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
+{
+ struct browse_req *req = user_data;
+ uuid_t uuid;
+
+ /* If we have a valid response and req->search_uuid == 2, then L2CAP
+ * UUID & PNP searching was successful -- we are done */
+ if (err < 0 || req->search_uuid == 2) {
+ if (err == -ECONNRESET && req->reconnect_attempt < 1) {
+ req->search_uuid--;
+ req->reconnect_attempt++;
+ } else {
+ goto done;
+ }
+ }
+
+ update_records(req, recs);
+
+ /* Search for mandatory uuids */
+ if (uuid_list[req->search_uuid]) {
+ sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+ bt_search_service(&adapter->bdaddr, &req->bdaddr, &uuid,
+ browse_cb, user_data, NULL);
+ return;
+ }
+
+done:
+ browse_reqs = g_slist_remove(browse_reqs, req);
+ browse_req_free(req);
+}
+
+static int req_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct browse_req *req = a;
+ const bdaddr_t *bdaddr = b;
+
+ return bacmp(&req->bdaddr, bdaddr);
+}
+
+static uint8_t browse_remote_sdp(const bdaddr_t *addr)
+{
+ struct browse_req *req;
+ uuid_t uuid;
+
+ if (g_slist_find_custom(browse_reqs, addr, req_cmp))
+ return HAL_STATUS_DONE;
+
+ req = g_new0(struct browse_req, 1);
+ bacpy(&req->bdaddr, addr);
+ sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
+
+ if (bt_search_service(&adapter->bdaddr,
+ &req->bdaddr, &uuid, browse_cb, req, NULL) < 0) {
+ browse_req_free(req);
+ return false;
+ }
+
+ browse_reqs = g_slist_append(browse_reqs, req);
+
+ return HAL_STATUS_SUCCESS;
+}
+
static void new_link_key_callback(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
@@ -1482,7 +1575,12 @@ static uint8_t ssp_reply(void *buf, uint16_t len)

static uint8_t get_remote_services(void *buf, uint16_t len)
{
- return HAL_STATUS_UNSUPPORTED;
+ struct hal_cmd_get_remote_services *cmd = buf;
+ bdaddr_t addr;
+
+ android2bdaddr(&cmd->bdaddr, &addr);
+
+ return browse_remote_sdp(&addr);
}

void bt_adapter_handle_cmd(GIOChannel *io, uint8_t opcode, void *buf,
--
1.8.4.1


2013-11-05 13:21:37

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCHv2 3/6] android: Pass found uuids to remote_device_properties_cb

Send remote device's uuids in remote_device_properties_cb.
This patch will pack found uuids to buffer containing property
with list of uuids and send it to notification socket.
---
android/adapter.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/android/adapter.c b/android/adapter.c
index cf22e5f..0f24cac 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -288,9 +288,87 @@ static void browse_req_free(struct browse_req *req)
g_free(req);
}

+static void fill_uuids(GSList *list, void *buf)
+{
+ for (; list; list = g_slist_next(list)) {
+ memcpy(buf, list->data, sizeof(uint128_t));
+ buf += sizeof(uint128_t);
+ }
+}
+
+static void remote_uuids_callback(struct browse_req *req)
+{
+ struct hal_ev_remote_device_props *ev;
+ int len;
+
+ len = sizeof(*ev) + sizeof(struct hal_property) + (sizeof(uint128_t) *
+ g_slist_length(req->uuids));
+ ev = g_malloc(len);
+
+ ev->status = HAL_STATUS_SUCCESS;
+ bdaddr2android(&req->bdaddr, &ev->bdaddr);
+ ev->num_props = 1;
+ ev->props[0].type = HAL_PROP_DEVICE_UUIDS;
+ ev->props[0].len = sizeof(uint128_t) * g_slist_length(req->uuids);
+ fill_uuids(req->uuids, ev->props[0].val);
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_REMOTE_DEVICE_PROPS, len, ev, -1);
+
+ g_free(ev);
+}
+
+static int uuid_128_cmp(gconstpointer a, gconstpointer b)
+{
+ return memcmp(a, b, sizeof(uint128_t));
+}
+
static void update_records(struct browse_req *req, sdp_list_t *recs)
{
- /* TODO cache found uuids */
+ for (; recs; recs = recs->next) {
+ sdp_record_t *rec = (sdp_record_t *) recs->data;
+ sdp_list_t *svcclass = NULL;
+ uuid_t uuid128;
+ uuid_t *tmp;
+ uint8_t *new_uuid;
+
+ if (!rec)
+ break;
+
+ if (sdp_get_service_classes(rec, &svcclass) < 0)
+ continue;
+
+ if (!svcclass)
+ continue;
+
+ tmp = svcclass->data;
+
+ switch (tmp->type) {
+ case SDP_UUID16:
+ sdp_uuid16_to_uuid128(&uuid128, tmp);
+ break;
+ case SDP_UUID32:
+ sdp_uuid32_to_uuid128(&uuid128, tmp);
+ break;
+ case SDP_UUID128:
+ memcpy(&uuid128, tmp, sizeof(uuid_t));
+ break;
+ default:
+ continue;
+ }
+
+ new_uuid = g_malloc(16);/* size of 128 bit uuid */
+ memcpy(new_uuid, &uuid128.value.uuid128,
+ sizeof(uuid128.value.uuid128));
+
+ /* Check if uuid is already added */
+ if (g_slist_find_custom(req->uuids, new_uuid, uuid_128_cmp))
+ g_free(new_uuid);
+ else
+ req->uuids = g_slist_append(req->uuids, new_uuid);
+
+ sdp_list_free(svcclass, free);
+ }
}

static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
@@ -320,6 +398,8 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
}

done:
+ remote_uuids_callback(req);
+
browse_reqs = g_slist_remove(browse_reqs, req);
browse_req_free(req);
}
--
1.8.4.1


2013-11-05 13:21:38

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCHv2 4/6] android: Add supported uuids when adapter is initialized

It will set class of device with proper service hints.
We set it statically because we want to keep code simple.

---
android/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 0f24cac..70b9265 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -52,6 +52,29 @@ static GIOChannel *notification_io = NULL;
/* This list contains addresses which are asked for records */
static GSList *browse_reqs;

+/*
+ * This is an array of supported uuids and service hints. We add them via mgmt
+ * interface when adapter is initialized. Uuids are in reverse orded.
+ */
+static const struct mgmt_cp_add_uuid supported_services[] = {
+ /* OBEX_OPP_UUID */
+ { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00 },
+ .svc_hint = 0x10 },
+ /* HFP_AG_UUID */
+ { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x1f, 0x11, 0x00, 0x00 },
+ .svc_hint = 0x40 },
+ /* ADVANCED_AUDIO_UUID */
+ { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00 },
+ .svc_hint = 0x08 },
+ /* PANU_UUID */
+ { .uuid = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x10, 0x00, 0x00, 0x15, 0x11, 0x00, 0x00 },
+ .svc_hint = 0x02 }
+};
+
struct bt_adapter {
uint16_t index;
struct mgmt *mgmt;
@@ -980,6 +1003,39 @@ static void load_link_keys(GSList *keys)
}
}

+static void add_uuid_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ if (status != MGMT_STATUS_SUCCESS) {
+ error("Failed to add UUID: %s (0x%02x)",
+ mgmt_errstr(status), status);
+ return;
+ }
+
+ mgmt_dev_class_changed_event(adapter->index, length, param, NULL);
+}
+
+static void add_uuids(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < NELEM(supported_services); i++)
+ mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID, adapter->index,
+ sizeof(supported_services[i]),
+ &supported_services[i], add_uuid_complete,
+ NULL, NULL);
+}
+
+static void clear_uuids(void)
+{
+ struct mgmt_cp_remove_uuid cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+ mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID, adapter->index,
+ sizeof(cp), &cp, NULL, NULL, NULL);
+}
+
static void set_mode_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -995,6 +1051,9 @@ static void set_mode_complete(uint8_t status, uint16_t length,
* event handling functions here.
*/
new_settings_callback(adapter->index, length, param, NULL);
+
+ clear_uuids();
+ add_uuids();
}

static bool set_mode(uint16_t opcode, uint8_t mode)
--
1.8.4.1


2013-11-05 13:21:39

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCHv2 5/6] android: Implement class of device property callback

This will send adapter property with class of device
to notification socket.

---
android/adapter.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 70b9265..89db078 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -212,6 +212,30 @@ static void scan_mode_changed(void)
g_free(ev);
}

+static void send_adapter_class(void)
+{
+ struct hal_ev_adapter_props_changed *ev;
+ int len;
+
+ len = sizeof(*ev) + sizeof(struct hal_property) + sizeof(uint32_t);
+
+ ev = g_malloc(len);
+
+ ev->num_props = 1;
+ ev->status = HAL_STATUS_SUCCESS;
+
+ ev->props[0].type = HAL_PROP_ADAPTER_CLASS;
+ ev->props[0].len = sizeof(uint32_t);
+ memcpy(ev->props->val, &adapter->dev_class, sizeof(uint32_t));
+
+ DBG("Adapter class %u", adapter->dev_class);
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_ADAPTER_PROPS_CHANGED, len, ev, -1);
+
+ g_free(ev);
+}
+
static void settings_changed(uint32_t settings)
{
uint32_t changed_mask;
@@ -280,7 +304,7 @@ static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length,

adapter->dev_class = dev_class;

- /* TODO: Inform prop change: Class */
+ send_adapter_class();

/* TODO: Gatt attrib set*/
}
@@ -1278,11 +1302,11 @@ static bool get_uuids(void)

static bool get_class(void)
{
- DBG("Not implemented");
+ DBG("");

- /* TODO: Add implementation */
+ send_adapter_class();

- return false;
+ return true;
}

static bool get_type(void)
--
1.8.4.1


2013-11-05 13:21:40

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCHv2 6/6] android: Add support for getting adapter uuids

Implement get adapter uuids command. It will pack supported
uuids to structure and send it via notification socket

---
android/adapter.c | 40 +++++++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/android/adapter.c b/android/adapter.c
index 89db078..6ce2211 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -1291,13 +1291,47 @@ static bool get_name(void)
return true;
}

+static void swap_uuid(const uint8_t *src, uint8_t *dst)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ dst[15 - i] = src[i];
+}
+
static bool get_uuids(void)
{
- DBG("Not implemented");
+ struct hal_ev_adapter_props_changed *ev;
+ unsigned int i;
+ int len;
+ uint8_t *p;

- /* TODO: Add implementation */
+ len = sizeof(*ev) + sizeof(struct hal_property) +
+ NELEM(supported_services) * sizeof(uint128_t);

- return false;
+ ev = g_malloc(len);
+
+ ev->num_props = 1;
+ ev->status = HAL_STATUS_SUCCESS;
+
+ ev->props[0].type = HAL_PROP_ADAPTER_UUIDS;
+ ev->props[0].len = sizeof(uint128_t) * NELEM(supported_services);
+ p = ev->props->val;
+
+ for (i = 0; i < NELEM(supported_services); i++) {
+ /* we have to swap supported uuids
+ * because hal expects them in reversed order
+ * than mgmt intrface */
+ swap_uuid(supported_services[i].uuid, p);
+ p += sizeof(uint128_t);
+ }
+
+ ipc_send(notification_io, HAL_SERVICE_ID_BLUETOOTH,
+ HAL_EV_ADAPTER_PROPS_CHANGED, len, ev, -1);
+
+ g_free(ev);
+
+ return true;
}

static bool get_class(void)
--
1.8.4.1


2013-11-05 13:21:36

by Marcin Kraglak

[permalink] [raw]
Subject: [PATCHv2 2/6] android: Fetch remote device uuids after pairing

Android framework expects list of bonded device's uuids.
Start sdp query after setting bond state to BOND_STATE_BONBED.

---
android/adapter.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/android/adapter.c b/android/adapter.c
index 40fb89d..cf22e5f 100644
--- a/android/adapter.c
+++ b/android/adapter.c
@@ -387,6 +387,8 @@ static void new_link_key_callback(uint16_t index, uint16_t length,

send_bond_state_change(&addr->bdaddr, HAL_STATUS_SUCCESS,
HAL_BOND_STATE_BONDED);
+
+ browse_remote_sdp(&addr->bdaddr);
}

static void pin_code_request_callback(uint16_t index, uint16_t length,
--
1.8.4.1