* [PATCH 5/6] shared: Add support for local disconnect to HFP
From: Szymon Janc @ 2014-02-11 16:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1392137346-26272-1-git-send-email-szymon.janc@tieto.com>
This allows to locally trigger disconnection.
---
src/shared/hfp.c | 8 ++++++++
src/shared/hfp.h | 2 ++
2 files changed, 10 insertions(+)
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 3944e97..2c793f9 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -445,3 +445,11 @@ bool hfp_gw_set_disconnect_handler(struct hfp_gw *hfp,
return true;
}
+
+bool hfp_gw_disconnect(struct hfp_gw *hfp)
+{
+ if (!hfp)
+ return false;
+
+ return io_shutdown(hfp->io);
+}
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index 75ec484..5a86dfe 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -92,3 +92,5 @@ bool hfp_gw_set_disconnect_handler(struct hfp_gw *hfp,
hfp_disconnect_func_t callback,
void *user_data,
hfp_destroy_func_t destroy);
+
+bool hfp_gw_disconnect(struct hfp_gw *hfp);
--
1.8.5.3
^ permalink raw reply related
* [PATCH 6/6] android/handsfree: Use HFP code for connection handling
From: Szymon Janc @ 2014-02-11 16:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1392137346-26272-1-git-send-email-szymon.janc@tieto.com>
HFP code is now able to handle disconnection on its own so just use
this instead of using own watches.
---
android/handsfree.c | 50 +++++++++++++-------------------------------------
1 file changed, 13 insertions(+), 37 deletions(-)
diff --git a/android/handsfree.c b/android/handsfree.c
index 9482b2e..a973bd5 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -52,8 +52,6 @@
static struct {
bdaddr_t bdaddr;
uint8_t state;
- GIOChannel *io;
- guint watch;
struct hfp_gw *gw;
} device;
@@ -96,38 +94,23 @@ static void device_cleanup(void)
device.gw = NULL;
}
- if (device.watch) {
- g_source_remove(device.watch);
- device.watch = 0;
- }
-
- if (device.io) {
- g_io_channel_unref(device.io);
- device.io = NULL;
- }
-
device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTED);
memset(&device, 0, sizeof(device));
}
-static gboolean watch_cb(GIOChannel *chan, GIOCondition cond,
- gpointer user_data)
+static void at_command_handler(const char *command, void *user_data)
{
- DBG("");
-
- device.watch = 0;
-
- device_cleanup();
+ hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
- return FALSE;
+ hfp_gw_disconnect(device.gw);
}
-static void at_command_handler(const char *command, void *user_data)
+static void disconnect_watch(void *user_data)
{
- hfp_gw_send_result(device.gw, HFP_RESULT_ERROR);
+ DBG("");
- g_io_channel_shutdown(device.io, TRUE, NULL);
+ device_cleanup();
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
@@ -139,22 +122,15 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
goto failed;
}
- g_io_channel_set_close_on_unref(chan, TRUE);
-
device.gw = hfp_gw_new(g_io_channel_unix_get_fd(chan));
if (!device.gw)
goto failed;
+ g_io_channel_set_close_on_unref(chan, FALSE);
+
hfp_gw_set_close_on_unref(device.gw, true);
hfp_gw_set_command_handler(device.gw, at_command_handler, NULL, NULL);
-
- device.watch = g_io_add_watch(chan,
- G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- watch_cb, NULL);
- if (device.watch == 0)
- goto failed;
-
- device.io = g_io_channel_ref(chan);
+ hfp_gw_set_disconnect_handler(device.gw, disconnect_watch, NULL, NULL);
device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTED);
@@ -332,11 +308,11 @@ static void handle_disconnect(const void *buf, uint16_t len)
goto failed;
}
- if (device.io) {
- device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTING);
- g_io_channel_shutdown(device.io, TRUE, NULL);
- } else {
+ if (device.state == HAL_EV_HANDSFREE_CONNECTION_STATE_CONNECTING) {
device_cleanup();
+ } else {
+ device_set_state(HAL_EV_HANDSFREE_CONNECTION_STATE_DISCONNECTING);
+ hfp_gw_disconnect(device.gw);
}
status = HAL_STATUS_SUCCESS;
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH 1/6] shared: Add support for disonnect handler to GLib based IO handling
From: Marcel Holtmann @ 2014-02-11 16:57 UTC (permalink / raw)
To: Szymon Janc; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392137346-26272-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
> ---
> src/shared/io-glib.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 58 insertions(+), 1 deletion(-)
>
> diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
> index 77ba19e..a4f982d 100644
> --- a/src/shared/io-glib.c
> +++ b/src/shared/io-glib.c
> @@ -40,6 +40,10 @@ struct io {
> io_callback_func_t write_callback;
> io_destroy_func_t write_destroy;
> void *write_data;
> + guint disconnect_watch;
> + io_callback_func_t disconnect_callback;
> + io_destroy_func_t disconnect_destroy;
> + void *disconnect_data;
> };
>
> static struct io *io_ref(struct io *io)
> @@ -258,8 +262,61 @@ done:
> return true;
> }
>
> +static void disconnect_watch_destroy(gpointer user_data)
> +{
> + struct io *io = user_data;
> +
> + if (io->disconnect_destroy)
> + io->disconnect_destroy(io->disconnect_data);
> +
> + io->disconnect_watch = 0;
> + io->disconnect_callback = NULL;
> + io->disconnect_destroy = NULL;
> + io->disconnect_data = NULL;
> +
> + io_unref(io);
> +}
> +
> +static gboolean disconnect_callback(GIOChannel *channel, GIOCondition cond,
> + gpointer user_data)
> +{
> + struct io *io = user_data;
> + bool result;
> +
> + if (io->disconnect_callback)
> + result = io->disconnect_callback(io, io->disconnect_data);
> + else
> + result = false;
> +
> + return result ? TRUE : FALSE;
> +}
> +
> bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback,
> void *user_data, io_destroy_func_t destroy)
> {
> - return false;
> + if (!io)
> + return false;
> +
> + if (io->disconnect_watch > 0) {
> + g_source_remove(io->disconnect_watch);
> + io->disconnect_watch = 0;
> + }
> +
> + if (!callback)
> + goto done;
> +
> + io->disconnect_watch = g_io_add_watch_full(io->channel,
> + G_PRIORITY_DEFAULT,
> + G_IO_HUP | G_IO_ERR | G_IO_NVAL,
If we are using G_IO_HUP here, we should remove it from the other callback handling?
> + disconnect_callback, io_ref(io),
> + disconnect_watch_destroy);
> + if (io->disconnect_watch == 0)
> + return false;
> +
> + io->disconnect_destroy = destroy;
> + io->disconnect_data = user_data;
we normally have an extra empty line here. You might also fix the previous patch then.
> +done:
> + io->disconnect_callback = callback;
> +
> + return true;
> }
> --
> 1.8.5.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH 00/11] Socket HAL updates
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
Hi,
Current socket HAL implementation is missing major feature which is
ability to register RFCOMM server from application (so use some UUID
and assign channel number dynamically). This corresponds to
BluetoothAdapter::listenUsing(insecure)RfcommWithServiceRecord APIs
in Android.
This series of patches adds this feature with other required fixes
and also some does some minor refactoring.
Andrzej Kaczmarek (11):
android/bluetooth: Handle 128-bit UUIDs
android/socket: Refactor socket related symbol names
android/socket: Improve logging
android/socket: Simplify SDP records handling
android/socket: Make servers list as static array
android/tester: Update test data
android/socket: Add support for dynamic channel numbers
android/socket: Register SDP record for application service
android/socket: Include HF AG in built-in profiles
android/socket: Update channel numbers
android/socket: Fix sockets security
android/android-tester.c | 2 +-
android/bluetooth.c | 61 ++---
android/hal-msg.h | 3 +
android/socket.c | 658 +++++++++++++++++++++++------------------------
4 files changed, 349 insertions(+), 375 deletions(-)
--
1.8.5.3
^ permalink raw reply
* [PATCH 01/11] android/bluetooth: Handle 128-bit UUIDs
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
It's now possible to add record with 128-bit UUID Service Class which
are used for custom applications. To simplify implementation adapter
uuids list stores now full UUID in uuid_t structure instead of uint16_t
short UUID.
---
android/bluetooth.c | 61 ++++++++++++++++++-----------------------------------
1 file changed, 21 insertions(+), 40 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 9f8e7b4..c064fe8 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1459,17 +1459,6 @@ static void load_link_keys(GSList *keys, bt_bluetooth_ready cb)
}
}
-/* output uint128 is in host order */
-static void uuid16_to_uint128(uint16_t uuid, uint128_t *u128)
-{
- uuid_t uuid16, uuid128;
-
- sdp_uuid16_create(&uuid16, uuid);
- sdp_uuid16_to_uuid128(&uuid128, &uuid16);
-
- ntoh128(&uuid128.value.uuid128, u128);
-}
-
static uint8_t get_adapter_uuids(void)
{
struct hal_ev_adapter_props_changed *ev;
@@ -1478,7 +1467,6 @@ static uint8_t get_adapter_uuids(void)
int len = uuid_count * sizeof(uint128_t);
uint8_t buf[BASELEN_PROP_CHANGED + len];
uint8_t *p;
- int i;
memset(buf, 0, sizeof(buf));
ev = (void *) buf;
@@ -1491,14 +1479,9 @@ static uint8_t get_adapter_uuids(void)
p = ev->props->val;
for (; list; list = g_slist_next(list)) {
- uint16_t uuid = GPOINTER_TO_UINT(list->data);
- uint128_t uint128;
-
- uuid16_to_uint128(uuid, &uint128);
+ uuid_t *uuid = list->data;
- /* Android expects swapped bytes in uuid */
- for (i = 0; i < 16; i++)
- p[15 - i] = uint128.data[i];
+ memcpy(p, &uuid->value.uuid128, sizeof(uint128_t));
p += sizeof(uint128_t);
}
@@ -1523,12 +1506,12 @@ static void remove_uuid_complete(uint8_t status, uint16_t length,
get_adapter_uuids();
}
-static void remove_uuid(uint16_t uuid)
+static void remove_uuid(uuid_t *uuid)
{
uint128_t uint128;
struct mgmt_cp_remove_uuid cp;
- uuid16_to_uint128(uuid, &uint128);
+ ntoh128((uint128_t *) uuid->value.uuid128.data, &uint128);
htob128(&uint128, (uint128_t *) cp.uuid);
mgmt_send(mgmt_if, MGMT_OP_REMOVE_UUID, adapter.index, sizeof(cp), &cp,
@@ -1549,14 +1532,14 @@ static void add_uuid_complete(uint8_t status, uint16_t length,
get_adapter_uuids();
}
-static void add_uuid(uint8_t svc_hint, uint16_t uuid)
+static void add_uuid(uint8_t svc_hint, uuid_t *uuid)
{
uint128_t uint128;
struct mgmt_cp_add_uuid cp;
- uuid16_to_uint128(uuid, &uint128);
-
+ ntoh128((uint128_t *) uuid->value.uuid128.data, &uint128);
htob128(&uint128, (uint128_t *) cp.uuid);
+
cp.svc_hint = svc_hint;
mgmt_send(mgmt_if, MGMT_OP_ADD_UUID, adapter.index, sizeof(cp), &cp,
@@ -1565,22 +1548,19 @@ static void add_uuid(uint8_t svc_hint, uint16_t uuid)
int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint)
{
- uint16_t uuid;
+ uuid_t *uuid;
- /* TODO support all types? */
- if (rec->svclass.type != SDP_UUID16) {
- warn("Ignoring unsupported UUID type");
- return -EINVAL;
- }
+ uuid = sdp_uuid_to_uuid128(&rec->svclass);
- uuid = rec->svclass.value.uuid16;
+ if (g_slist_find_custom(adapter.uuids, uuid, sdp_uuid_cmp)) {
+ char uuid_str[32];
- if (g_slist_find(adapter.uuids, GUINT_TO_POINTER(uuid))) {
- DBG("UUID 0x%x already added", uuid);
+ sdp_uuid2strn(uuid, uuid_str, sizeof(uuid_str));
+ DBG("UUID %s already added", uuid_str);
return -EALREADY;
}
- adapter.uuids = g_slist_prepend(adapter.uuids, GUINT_TO_POINTER(uuid));
+ adapter.uuids = g_slist_prepend(adapter.uuids, uuid);
add_uuid(svc_hint, uuid);
@@ -1591,20 +1571,21 @@ void bt_adapter_remove_record(uint32_t handle)
{
sdp_record_t *rec;
GSList *uuid_found;
- uint16_t uuid;
rec = sdp_record_find(handle);
if (!rec)
return;
- uuid = rec->svclass.value.uuid16;
-
- uuid_found = g_slist_find(adapter.uuids, GUINT_TO_POINTER(uuid));
+ uuid_found = g_slist_find_custom(adapter.uuids, &rec->svclass,
+ sdp_uuid_cmp);
if (uuid_found) {
+ uuid_t *uuid = uuid_found->data;
+
remove_uuid(uuid);
- adapter.uuids = g_slist_remove(adapter.uuids,
- uuid_found->data);
+ adapter.uuids = g_slist_remove(adapter.uuids, uuid);
+
+ free(uuid);
}
remove_record_from_server(handle);
--
1.8.5.3
^ permalink raw reply related
* [PATCH 02/11] android/socket: Refactor socket related symbol names
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch changes names of symbols related to various sockets to be
consistent and easier to follow in code.
Symbols related to actual BT (RFCOMM) socket are prefixed with "bt_".
Symbols related to local socket for Java comm are prefixed with "jv_".
Remote socket for Java comm is called "hal_sock".
---
android/socket.c | 186 ++++++++++++++++++++++++++++---------------------------
1 file changed, 95 insertions(+), 91 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 1375625..107042e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -71,12 +71,15 @@ GList *servers = NULL;
GList *connections = NULL;
struct rfcomm_sock {
- int fd; /* descriptor for communication with Java framework */
- int real_sock; /* real RFCOMM socket */
int channel; /* RFCOMM channel */
- guint rfcomm_watch;
- guint stack_watch;
+ /* for socket to BT */
+ int bt_sock;
+ guint bt_watch;
+
+ /* for socket to HAL */
+ int jv_sock;
+ guint jv_watch;
bdaddr_t dst;
uint32_t service_handle;
@@ -92,13 +95,13 @@ static int rfsock_set_buffer(struct rfcomm_sock *rfsock)
socklen_t len = sizeof(int);
int rcv, snd, size, err;
- err = getsockopt(rfsock->real_sock, SOL_SOCKET, SO_RCVBUF, &rcv, &len);
+ err = getsockopt(rfsock->bt_sock, SOL_SOCKET, SO_RCVBUF, &rcv, &len);
if (err < 0) {
error("getsockopt(SO_RCVBUF): %s", strerror(errno));
return -errno;
}
- err = getsockopt(rfsock->real_sock, SOL_SOCKET, SO_SNDBUF, &snd, &len);
+ err = getsockopt(rfsock->bt_sock, SOL_SOCKET, SO_SNDBUF, &snd, &len);
if (err < 0) {
error("getsockopt(SO_SNDBUF): %s", strerror(errno));
return -errno;
@@ -118,25 +121,25 @@ static void cleanup_rfsock(gpointer data)
{
struct rfcomm_sock *rfsock = data;
- DBG("rfsock: %p fd %d real_sock %d chan %u",
- rfsock, rfsock->fd, rfsock->real_sock, rfsock->channel);
+ DBG("rfsock: %p jv_sock %d bt_sock %d chan %u",
+ rfsock, rfsock->jv_sock, rfsock->bt_sock, rfsock->channel);
- if (rfsock->fd >= 0)
- if (close(rfsock->fd) < 0)
- error("close() fd %d failed: %s", rfsock->fd,
+ if (rfsock->jv_sock >= 0)
+ if (close(rfsock->jv_sock) < 0)
+ error("close() fd %d failed: %s", rfsock->jv_sock,
strerror(errno));
- if (rfsock->real_sock >= 0)
- if (close(rfsock->real_sock) < 0)
- error("close() fd %d: failed: %s", rfsock->real_sock,
+ if (rfsock->bt_sock >= 0)
+ if (close(rfsock->bt_sock) < 0)
+ error("close() fd %d: failed: %s", rfsock->bt_sock,
strerror(errno));
- if (rfsock->rfcomm_watch > 0)
- if (!g_source_remove(rfsock->rfcomm_watch))
- error("rfcomm_watch source was not found");
+ if (rfsock->bt_watch > 0)
+ if (!g_source_remove(rfsock->bt_watch))
+ error("bt_watch source was not found");
- if (rfsock->stack_watch > 0)
- if (!g_source_remove(rfsock->stack_watch))
+ if (rfsock->jv_watch > 0)
+ if (!g_source_remove(rfsock->jv_watch))
error("stack_watch source was not found");
if (rfsock->service_handle)
@@ -148,23 +151,23 @@ static void cleanup_rfsock(gpointer data)
g_free(rfsock);
}
-static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
+static struct rfcomm_sock *create_rfsock(int bt_sock, int *hal_sock)
{
int fds[2] = {-1, -1};
struct rfcomm_sock *rfsock;
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
error("socketpair(): %s", strerror(errno));
- *hal_fd = -1;
+ *hal_sock = -1;
return NULL;
}
rfsock = g_new0(struct rfcomm_sock, 1);
- rfsock->fd = fds[0];
- *hal_fd = fds[1];
- rfsock->real_sock = sock;
+ rfsock->jv_sock = fds[0];
+ *hal_sock = fds[1];
+ rfsock->bt_sock = bt_sock;
- if (sock < 0)
+ if (bt_sock < 0)
return rfsock;
if (rfsock_set_buffer(rfsock) < 0) {
@@ -604,7 +607,7 @@ static int try_write_all(int fd, unsigned char *buf, int len)
return sent;
}
-static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
+static gboolean jv_sock_client_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
struct rfcomm_sock *rfsock = data;
@@ -621,14 +624,14 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
goto fail;
}
- len = read(rfsock->fd, rfsock->buf, rfsock->buf_size);
+ len = read(rfsock->jv_sock, rfsock->buf, rfsock->buf_size);
if (len <= 0) {
error("read(): %s", strerror(errno));
/* Read again */
return TRUE;
}
- sent = try_write_all(rfsock->real_sock, rfsock->buf, len);
+ sent = try_write_all(rfsock->bt_sock, rfsock->buf, len);
if (sent < 0) {
error("write(): %s", strerror(errno));
goto fail;
@@ -642,7 +645,7 @@ fail:
return FALSE;
}
-static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
+static gboolean bt_sock_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
struct rfcomm_sock *rfsock = data;
@@ -659,14 +662,14 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
goto fail;
}
- len = read(rfsock->real_sock, rfsock->buf, rfsock->buf_size);
+ len = read(rfsock->bt_sock, rfsock->buf, rfsock->buf_size);
if (len <= 0) {
error("read(): %s", strerror(errno));
/* Read again */
return TRUE;
}
- sent = try_write_all(rfsock->fd, rfsock->buf, len);
+ sent = try_write_all(rfsock->jv_sock, rfsock->buf, len);
if (sent < 0) {
error("write(): %s", strerror(errno));
goto fail;
@@ -693,7 +696,7 @@ static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
cmd.channel = rfsock->channel;
cmd.status = 0;
- len = bt_sock_send_fd(rfsock->fd, &cmd, sizeof(cmd), fd_accepted);
+ len = bt_sock_send_fd(rfsock->jv_sock, &cmd, sizeof(cmd), fd_accepted);
if (len != sizeof(cmd)) {
error("Error sending accept signal");
return false;
@@ -702,7 +705,7 @@ static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
return true;
}
-static gboolean sock_server_stack_event_cb(GIOChannel *io, GIOCondition cond,
+static gboolean jv_sock_server_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
struct rfcomm_sock *rfsock = data;
@@ -723,13 +726,13 @@ static gboolean sock_server_stack_event_cb(GIOChannel *io, GIOCondition cond,
static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_sock *rfsock = user_data;
- struct rfcomm_sock *rfsock_acc;
- GIOChannel *io_stack;
+ struct rfcomm_sock *new_rfsock;
+ GIOChannel *jv_io;
GError *gerr = NULL;
bdaddr_t dst;
char address[18];
- int sock_acc;
- int hal_fd;
+ int new_sock;
+ int hal_sock;
guint id;
GIOCondition cond;
@@ -751,51 +754,51 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
ba2str(&dst, address);
DBG("Incoming connection from %s rfsock %p", address, rfsock);
- sock_acc = g_io_channel_unix_get_fd(io);
- rfsock_acc = create_rfsock(sock_acc, &hal_fd);
- if (!rfsock_acc) {
+ new_sock = g_io_channel_unix_get_fd(io);
+ new_rfsock = create_rfsock(new_sock, &hal_sock);
+ if (!new_rfsock) {
g_io_channel_shutdown(io, TRUE, NULL);
return;
}
- DBG("rfsock: fd %d real_sock %d chan %u sock %d",
- rfsock->fd, rfsock->real_sock, rfsock->channel,
- sock_acc);
+ DBG("rfsock: jv_sock %d bt_sock %d chan %u new_sock %d",
+ rfsock->jv_sock, rfsock->bt_sock, rfsock->channel,
+ new_sock);
- if (!sock_send_accept(rfsock, &dst, hal_fd)) {
- cleanup_rfsock(rfsock_acc);
+ if (!sock_send_accept(rfsock, &dst, hal_sock)) {
+ cleanup_rfsock(new_rfsock);
return;
}
- connections = g_list_append(connections, rfsock_acc);
+ connections = g_list_append(connections, new_rfsock);
/* Handle events from Android */
cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
- io_stack = g_io_channel_unix_new(rfsock_acc->fd);
- id = g_io_add_watch(io_stack, cond, sock_stack_event_cb, rfsock_acc);
- g_io_channel_unref(io_stack);
+ jv_io = g_io_channel_unix_new(new_rfsock->jv_sock);
+ id = g_io_add_watch(jv_io, cond, jv_sock_client_event_cb, new_rfsock);
+ g_io_channel_unref(jv_io);
- rfsock_acc->stack_watch = id;
+ new_rfsock->jv_watch = id;
/* Handle rfcomm events */
cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
- id = g_io_add_watch(io, cond, sock_rfcomm_event_cb, rfsock_acc);
+ id = g_io_add_watch(io, cond, bt_sock_event_cb, new_rfsock);
g_io_channel_set_close_on_unref(io, FALSE);
- rfsock_acc->rfcomm_watch = id;
+ new_rfsock->bt_watch = id;
- DBG("rfsock %p rfsock_acc %p stack_watch %d rfcomm_watch %d",
- rfsock, rfsock_acc, rfsock_acc->stack_watch,
- rfsock_acc->rfcomm_watch);
+ DBG("rfsock %p rfsock_acc %p jv_watch %d bt_watch %d",
+ rfsock, new_rfsock, new_rfsock->jv_watch,
+ new_rfsock->bt_watch);
}
static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
- uint8_t flags, int *hal_fd)
+ uint8_t flags, int *hal_sock)
{
const struct profile_info *profile;
struct rfcomm_sock *rfsock = NULL;
BtIOSecLevel sec_level;
- GIOChannel *io, *io_stack;
+ GIOChannel *io, *jv_io;
GIOCondition cond;
GError *err = NULL;
guint id;
@@ -820,7 +823,7 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
DBG("rfcomm channel %d svc_name %s", chan, name);
- rfsock = create_rfsock(-1, hal_fd);
+ rfsock = create_rfsock(-1, hal_sock);
if (!rfsock)
return HAL_STATUS_FAILED;
@@ -835,25 +838,25 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
goto failed;
}
- rfsock->real_sock = g_io_channel_unix_get_fd(io);
+ rfsock->bt_sock = g_io_channel_unix_get_fd(io);
g_io_channel_set_close_on_unref(io, FALSE);
g_io_channel_unref(io);
/* Handle events from Android */
cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
- io_stack = g_io_channel_unix_new(rfsock->fd);
- id = g_io_add_watch_full(io_stack, G_PRIORITY_HIGH, cond,
- sock_server_stack_event_cb, rfsock,
+ jv_io = g_io_channel_unix_new(rfsock->jv_sock);
+ id = g_io_add_watch_full(jv_io, G_PRIORITY_HIGH, cond,
+ jv_sock_server_event_cb, rfsock,
NULL);
- g_io_channel_unref(io_stack);
+ g_io_channel_unref(jv_io);
- rfsock->stack_watch = id;
+ rfsock->jv_watch = id;
- DBG("real_sock %d fd %d hal_fd %d", rfsock->real_sock, rfsock->fd,
- *hal_fd);
+ DBG("bt_sock %d jv_sock %d hal_sock %d", rfsock->bt_sock,
+ rfsock->jv_sock, *hal_sock);
- if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+ if (write(rfsock->jv_sock, &chan, sizeof(chan)) != sizeof(chan)) {
error("Error sending RFCOMM channel");
goto failed;
}
@@ -867,7 +870,7 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
failed:
cleanup_rfsock(rfsock);
- close(*hal_fd);
+ close(*hal_sock);
return HAL_STATUS_FAILED;
}
@@ -875,12 +878,12 @@ static void handle_listen(const void *buf, uint16_t len)
{
const struct hal_cmd_sock_listen *cmd = buf;
uint8_t status;
- int hal_fd;
+ int hal_sock;
switch (cmd->type) {
case HAL_SOCK_RFCOMM:
status = rfcomm_listen(cmd->channel, cmd->name, cmd->uuid,
- cmd->flags, &hal_fd);
+ cmd->flags, &hal_sock);
break;
case HAL_SOCK_SCO:
case HAL_SOCK_L2CAP:
@@ -895,8 +898,8 @@ static void handle_listen(const void *buf, uint16_t len)
goto failed;
ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN, 0, NULL,
- hal_fd);
- close(hal_fd);
+ hal_sock);
+ close(hal_sock);
return ;
failed:
@@ -916,7 +919,7 @@ static bool sock_send_connect(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr)
cmd.channel = rfsock->channel;
cmd.status = 0;
- len = write(rfsock->fd, &cmd, sizeof(cmd));
+ len = write(rfsock->jv_sock, &cmd, sizeof(cmd));
if (len < 0) {
error("%s", strerror(errno));
return false;
@@ -934,7 +937,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_sock *rfsock = user_data;
bdaddr_t *dst = &rfsock->dst;
- GIOChannel *io_stack;
+ GIOChannel *jv_io;
char address[18];
guint id;
GIOCondition cond;
@@ -947,8 +950,8 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
ba2str(dst, address);
DBG("Connected to %s", address);
- DBG("rfsock: fd %d real_sock %d chan %u sock %d",
- rfsock->fd, rfsock->real_sock, rfsock->channel,
+ DBG("rfsock: jv_sock %d bt_sock %d chan %u sock %d",
+ rfsock->jv_sock, rfsock->bt_sock, rfsock->channel,
g_io_channel_unix_get_fd(io));
if (!sock_send_connect(rfsock, dst))
@@ -956,18 +959,18 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
/* Handle events from Android */
cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
- io_stack = g_io_channel_unix_new(rfsock->fd);
- id = g_io_add_watch(io_stack, cond, sock_stack_event_cb, rfsock);
- g_io_channel_unref(io_stack);
+ jv_io = g_io_channel_unix_new(rfsock->jv_sock);
+ id = g_io_add_watch(jv_io, cond, jv_sock_client_event_cb, rfsock);
+ g_io_channel_unref(jv_io);
- rfsock->stack_watch = id;
+ rfsock->jv_watch = id;
/* Handle rfcomm events */
cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
- id = g_io_add_watch(io, cond, sock_rfcomm_event_cb, rfsock);
+ id = g_io_add_watch(io, cond, bt_sock_event_cb, rfsock);
g_io_channel_set_close_on_unref(io, FALSE);
- rfsock->rfcomm_watch = id;
+ rfsock->bt_watch = id;
return;
fail:
@@ -999,12 +1002,12 @@ static bool do_rfcomm_connect(struct rfcomm_sock *rfsock, int chan)
g_io_channel_set_close_on_unref(io, FALSE);
g_io_channel_unref(io);
- if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+ if (write(rfsock->jv_sock, &chan, sizeof(chan)) != sizeof(chan)) {
error("Error sending RFCOMM channel");
return false;
}
- rfsock->real_sock = g_io_channel_unix_get_fd(io);
+ rfsock->bt_sock = g_io_channel_unix_get_fd(io);
rfsock_set_buffer(rfsock);
rfsock->channel = chan;
connections = g_list_append(connections, rfsock);
@@ -1063,7 +1066,8 @@ fail:
}
static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
- const uint8_t *uuid, uint8_t flags, int *hal_fd)
+ const uint8_t *uuid, uint8_t flags,
+ int *hal_sock)
{
struct rfcomm_sock *rfsock;
uuid_t uu;
@@ -1074,7 +1078,7 @@ static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
return HAL_STATUS_INVALID;
}
- rfsock = create_rfsock(-1, hal_fd);
+ rfsock = create_rfsock(-1, hal_sock);
if (!rfsock)
return HAL_STATUS_FAILED;
@@ -1101,7 +1105,7 @@ static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
failed:
cleanup_rfsock(rfsock);
- close(*hal_fd);
+ close(*hal_sock);
return HAL_STATUS_FAILED;
}
@@ -1110,7 +1114,7 @@ static void handle_connect(const void *buf, uint16_t len)
const struct hal_cmd_sock_connect *cmd = buf;
bdaddr_t bdaddr;
uint8_t status;
- int hal_fd;
+ int hal_sock;
DBG("");
@@ -1119,7 +1123,7 @@ static void handle_connect(const void *buf, uint16_t len)
switch (cmd->type) {
case HAL_SOCK_RFCOMM:
status = connect_rfcomm(&bdaddr, cmd->channel, cmd->uuid,
- cmd->flags, &hal_fd);
+ cmd->flags, &hal_sock);
break;
case HAL_SOCK_SCO:
case HAL_SOCK_L2CAP:
@@ -1134,8 +1138,8 @@ static void handle_connect(const void *buf, uint16_t len)
goto failed;
ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT, 0, NULL,
- hal_fd);
- close(hal_fd);
+ hal_sock);
+ close(hal_sock);
return;
failed:
--
1.8.5.3
^ permalink raw reply related
* [PATCH 03/11] android/socket: Improve logging
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch makes logging more consistent by including rfsock pointer in
most messages which identifies socket structure unambigously (instead
of using bunch of file descriptors for the same purpose) and puts other
parameters in order in some cases.
Additionally, some new logs are introduced to better track socket
structures and connections lifetime.
---
android/socket.c | 71 ++++++++++++++++++++++++++++++++++----------------------
1 file changed, 43 insertions(+), 28 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 107042e..5045911 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -121,8 +121,8 @@ static void cleanup_rfsock(gpointer data)
{
struct rfcomm_sock *rfsock = data;
- DBG("rfsock: %p jv_sock %d bt_sock %d chan %u",
- rfsock, rfsock->jv_sock, rfsock->bt_sock, rfsock->channel);
+ DBG("rfsock %p bt_sock %d jv_sock %d", rfsock, rfsock->bt_sock,
+ rfsock->jv_sock);
if (rfsock->jv_sock >= 0)
if (close(rfsock->jv_sock) < 0)
@@ -167,6 +167,8 @@ static struct rfcomm_sock *create_rfsock(int bt_sock, int *hal_sock)
*hal_sock = fds[1];
rfsock->bt_sock = bt_sock;
+ DBG("rfsock %p", rfsock);
+
if (bt_sock < 0)
return rfsock;
@@ -619,8 +621,7 @@ static gboolean jv_sock_client_event_cb(GIOChannel *io, GIOCondition cond,
}
if (cond & (G_IO_ERR | G_IO_NVAL)) {
- error("Socket error: sock %d cond %d",
- g_io_channel_unix_get_fd(io), cond);
+ error("Socket %d error", g_io_channel_unix_get_fd(io));
goto fail;
}
@@ -639,6 +640,8 @@ static gboolean jv_sock_client_event_cb(GIOChannel *io, GIOCondition cond,
return TRUE;
fail:
+ DBG("rfsock %p jv_sock %d cond %d", rfsock, rfsock->jv_sock, cond);
+
connections = g_list_remove(connections, rfsock);
cleanup_rfsock(rfsock);
@@ -657,8 +660,7 @@ static gboolean bt_sock_event_cb(GIOChannel *io, GIOCondition cond,
}
if (cond & (G_IO_ERR | G_IO_NVAL)) {
- error("Socket error: sock %d cond %d",
- g_io_channel_unix_get_fd(io), cond);
+ error("Socket %d error", g_io_channel_unix_get_fd(io));
goto fail;
}
@@ -677,6 +679,8 @@ static gboolean bt_sock_event_cb(GIOChannel *io, GIOCondition cond,
return TRUE;
fail:
+ DBG("rfsock %p bt_sock %d cond %d", rfsock, rfsock->bt_sock, cond);
+
connections = g_list_remove(connections, rfsock);
cleanup_rfsock(rfsock);
@@ -710,7 +714,7 @@ static gboolean jv_sock_server_event_cb(GIOChannel *io, GIOCondition cond,
{
struct rfcomm_sock *rfsock = data;
- DBG("sock %d cond %d", g_io_channel_unix_get_fd(io), cond);
+ DBG("rfsock %p jv_sock %d cond %d", rfsock, rfsock->jv_sock, cond);
if (cond & G_IO_NVAL)
return FALSE;
@@ -752,7 +756,8 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
}
ba2str(&dst, address);
- DBG("Incoming connection from %s rfsock %p", address, rfsock);
+ DBG("Incoming connection from %s on channel %d (rfsock %p)", address,
+ rfsock->channel, rfsock);
new_sock = g_io_channel_unix_get_fd(io);
new_rfsock = create_rfsock(new_sock, &hal_sock);
@@ -761,9 +766,8 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
return;
}
- DBG("rfsock: jv_sock %d bt_sock %d chan %u new_sock %d",
- rfsock->jv_sock, rfsock->bt_sock, rfsock->channel,
- new_sock);
+ DBG("new rfsock %p bt_sock %d jv_sock %d hal_sock %d", new_rfsock,
+ new_rfsock->bt_sock, new_rfsock->jv_sock, hal_sock);
if (!sock_send_accept(rfsock, &dst, hal_sock)) {
cleanup_rfsock(new_rfsock);
@@ -786,10 +790,6 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
g_io_channel_set_close_on_unref(io, FALSE);
new_rfsock->bt_watch = id;
-
- DBG("rfsock %p rfsock_acc %p jv_watch %d bt_watch %d",
- rfsock, new_rfsock, new_rfsock->jv_watch,
- new_rfsock->bt_watch);
}
static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
@@ -802,8 +802,14 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
GIOCondition cond;
GError *err = NULL;
guint id;
+ uuid_t uu;
+ char uuid_str[32];
- DBG("");
+ sdp_uuid128_create(&uu, uuid);
+ sdp_uuid2strn(&uu, uuid_str, sizeof(uuid_str));
+
+ DBG("chan %d flags 0x%02x uuid %s name %s", chan, flags, uuid_str,
+ name);
if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) {
error("Invalid rfcomm listen params");
@@ -821,7 +827,7 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
sec_level = profile->sec_level;
}
- DBG("rfcomm channel %d svc_name %s", chan, name);
+ DBG("chan %d sec_level %d", chan, sec_level);
rfsock = create_rfsock(-1, hal_sock);
if (!rfsock)
@@ -853,8 +859,10 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
rfsock->jv_watch = id;
- DBG("bt_sock %d jv_sock %d hal_sock %d", rfsock->bt_sock,
- rfsock->jv_sock, *hal_sock);
+ DBG("rfsock %p bt_sock %d jv_sock %d hal_sock %d", rfsock,
+ rfsock->bt_sock,
+ rfsock->jv_sock,
+ *hal_sock);
if (write(rfsock->jv_sock, &chan, sizeof(chan)) != sizeof(chan)) {
error("Error sending RFCOMM channel");
@@ -948,11 +956,8 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
}
ba2str(dst, address);
- DBG("Connected to %s", address);
-
- DBG("rfsock: jv_sock %d bt_sock %d chan %u sock %d",
- rfsock->jv_sock, rfsock->bt_sock, rfsock->channel,
- g_io_channel_unix_get_fd(io));
+ DBG("Connected to %s on channel %d (rfsock %p)", address,
+ rfsock->channel, rfsock);
if (!sock_send_connect(rfsock, dst))
goto fail;
@@ -987,6 +992,8 @@ static bool do_rfcomm_connect(struct rfcomm_sock *rfsock, int chan)
if (rfsock->profile)
sec_level = rfsock->profile->sec_level;
+ DBG("rfsock %p sec_level %d chan %d", rfsock, sec_level, chan);
+
io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
@@ -1070,7 +1077,16 @@ static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
int *hal_sock)
{
struct rfcomm_sock *rfsock;
+ char address[18];
uuid_t uu;
+ char uuid_str[32];
+
+ sdp_uuid128_create(&uu, uuid);
+ sdp_uuid2strn(&uu, uuid_str, sizeof(uuid_str));
+ ba2str(addr, address);
+
+ DBG("addr %s chan %d flags 0x%02x uuid %s", address, chan, flags,
+ uuid_str);
if ((!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) ||
!bacmp(addr, BDADDR_ANY)) {
@@ -1082,16 +1098,15 @@ static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
if (!rfsock)
return HAL_STATUS_FAILED;
+ DBG("rfsock %p jv_sock %d hal_sock %d", rfsock, rfsock->jv_sock,
+ *hal_sock);
+
bacpy(&rfsock->dst, addr);
if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid))) {
if (!do_rfcomm_connect(rfsock, chan))
goto failed;
} else {
- memset(&uu, 0, sizeof(uu));
- uu.type = SDP_UUID128;
- memcpy(&uu.value.uuid128, uuid, sizeof(uint128_t));
-
rfsock->profile = get_profile_by_uuid(uuid);
if (bt_search_service(&adapter_addr, &rfsock->dst, &uu,
--
1.8.5.3
^ permalink raw reply related
* [PATCH 04/11] android/socket: Simplify SDP records handling
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
Records are now created using helper function which creates SDP record
with common contents like service class, name and protocols. Other
attributes are then added by custom functions.
---
android/socket.c | 281 ++++++++++++++++---------------------------------------
1 file changed, 80 insertions(+), 201 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 5045911..32de91a 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -180,18 +180,14 @@ static struct rfcomm_sock *create_rfsock(int bt_sock, int *hal_sock)
return rfsock;
}
-static sdp_record_t *create_opp_record(uint8_t chan, const char *svc_name)
+static sdp_record_t *create_rfcomm_record(uint8_t chan, uuid_t *uuid,
+ const char *svc_name,
+ bool has_obex)
{
- const char *service_name = "OBEX Object Push";
- sdp_list_t *svclass_id, *pfseq, *apseq, *root;
- uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
- sdp_profile_desc_t profile[1];
- sdp_list_t *aproto, *proto[3];
- uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
- void *dtds[sizeof(formats)], *values[sizeof(formats)];
- unsigned int i;
- uint8_t dtd = SDP_UINT8;
- sdp_data_t *sflist;
+ sdp_list_t *svclass_id;
+ sdp_list_t *seq, *proto_seq, *pbg_seq;
+ sdp_list_t *proto[2];
+ uuid_t l2cap_uuid, rfcomm_uuid, obex_uuid, pbg_uuid;
sdp_data_t *channel;
sdp_record_t *record;
@@ -201,267 +197,150 @@ static sdp_record_t *create_opp_record(uint8_t chan, const char *svc_name)
record->handle = sdp_next_handle();
- sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
- root = sdp_list_append(NULL, &root_uuid);
- sdp_set_browse_groups(record, root);
-
- sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID);
- svclass_id = sdp_list_append(NULL, &opush_uuid);
+ svclass_id = sdp_list_append(NULL, uuid);
sdp_set_service_classes(record, svclass_id);
- sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID);
- profile[0].version = 0x0100;
- pfseq = sdp_list_append(NULL, profile);
- sdp_set_profile_descs(record, pfseq);
-
sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
proto[0] = sdp_list_append(NULL, &l2cap_uuid);
- apseq = sdp_list_append(NULL, proto[0]);
+ seq = sdp_list_append(NULL, proto[0]);
sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
proto[1] = sdp_list_append(NULL, &rfcomm_uuid);
channel = sdp_data_alloc(SDP_UINT8, &chan);
proto[1] = sdp_list_append(proto[1], channel);
- apseq = sdp_list_append(apseq, proto[1]);
+ seq = sdp_list_append(seq, proto[1]);
- sdp_uuid16_create(&obex_uuid, OBEX_UUID);
- proto[2] = sdp_list_append(NULL, &obex_uuid);
- apseq = sdp_list_append(apseq, proto[2]);
+ if (has_obex) {
+ sdp_uuid16_create(&obex_uuid, OBEX_UUID);
+ proto[2] = sdp_list_append(NULL, &obex_uuid);
+ seq = sdp_list_append(seq, proto[2]);
+ }
- aproto = sdp_list_append(NULL, apseq);
- sdp_set_access_protos(record, aproto);
+ proto_seq = sdp_list_append(NULL, seq);
+ sdp_set_access_protos(record, proto_seq);
- for (i = 0; i < sizeof(formats); i++) {
- dtds[i] = &dtd;
- values[i] = &formats[i];
- }
- sflist = sdp_seq_alloc(dtds, values, sizeof(formats));
- sdp_attr_add(record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist);
+ sdp_uuid16_create(&pbg_uuid, PUBLIC_BROWSE_GROUP);
+ pbg_seq = sdp_list_append(NULL, &pbg_uuid);
+ sdp_set_browse_groups(record, pbg_seq);
if (svc_name)
- service_name = svc_name;
-
- sdp_set_info_attr(record, service_name, NULL, NULL);
+ sdp_set_info_attr(record, svc_name, NULL, NULL);
sdp_data_free(channel);
sdp_list_free(proto[0], NULL);
sdp_list_free(proto[1], NULL);
- sdp_list_free(proto[2], NULL);
- sdp_list_free(apseq, NULL);
- sdp_list_free(pfseq, NULL);
- sdp_list_free(aproto, NULL);
- sdp_list_free(root, NULL);
+ if (has_obex)
+ sdp_list_free(proto[2], NULL);
+ sdp_list_free(seq, NULL);
+ sdp_list_free(proto_seq, NULL);
+ sdp_list_free(pbg_seq, NULL);
sdp_list_free(svclass_id, NULL);
return record;
}
-static sdp_record_t *create_pbap_record(uint8_t chan, const char *svc_name)
+static sdp_record_t *create_opp_record(uint8_t chan, const char *svc_name)
{
- const char *service_name = "OBEX Phonebook Access Server";
- sdp_list_t *svclass_id, *pfseq, *apseq, *root;
- uuid_t root_uuid, pbap_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
- sdp_profile_desc_t profile[1];
- sdp_list_t *aproto, *proto[3];
- sdp_data_t *channel;
- uint8_t formats[] = { 0x01 };
+ uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff };
uint8_t dtd = SDP_UINT8;
- sdp_data_t *sflist;
+ uuid_t uuid;
+ sdp_list_t *seq;
+ sdp_profile_desc_t profile[1];
+ void *dtds[sizeof(formats)], *values[sizeof(formats)];
+ sdp_data_t *formats_list;
sdp_record_t *record;
+ size_t i;
- record = sdp_record_alloc();
+ sdp_uuid16_create(&uuid, OBEX_OBJPUSH_SVCLASS_ID);
+
+ record = create_rfcomm_record(chan, &uuid, svc_name, true);
if (!record)
return NULL;
- record->handle = sdp_next_handle();
-
- sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
- root = sdp_list_append(NULL, &root_uuid);
- sdp_set_browse_groups(record, root);
-
- sdp_uuid16_create(&pbap_uuid, PBAP_PSE_SVCLASS_ID);
- svclass_id = sdp_list_append(NULL, &pbap_uuid);
- sdp_set_service_classes(record, svclass_id);
-
- sdp_uuid16_create(&profile[0].uuid, PBAP_PROFILE_ID);
+ sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID);
profile[0].version = 0x0100;
- pfseq = sdp_list_append(NULL, profile);
- sdp_set_profile_descs(record, pfseq);
+ seq = sdp_list_append(NULL, profile);
+ sdp_set_profile_descs(record, seq);
- sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
- proto[0] = sdp_list_append(NULL, &l2cap_uuid);
- apseq = sdp_list_append(NULL, proto[0]);
+ for (i = 0; i < sizeof(formats); i++) {
+ dtds[i] = &dtd;
+ values[i] = &formats[i];
+ }
+ formats_list = sdp_seq_alloc(dtds, values, sizeof(formats));
+ sdp_attr_add(record, SDP_ATTR_SUPPORTED_FORMATS_LIST, formats_list);
- sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
- proto[1] = sdp_list_append(NULL, &rfcomm_uuid);
- channel = sdp_data_alloc(SDP_UINT8, &chan);
- proto[1] = sdp_list_append(proto[1], channel);
- apseq = sdp_list_append(apseq, proto[1]);
+ sdp_list_free(seq, NULL);
- sdp_uuid16_create(&obex_uuid, OBEX_UUID);
- proto[2] = sdp_list_append(NULL, &obex_uuid);
- apseq = sdp_list_append(apseq, proto[2]);
+ return record;
+}
- aproto = sdp_list_append(NULL, apseq);
- sdp_set_access_protos(record, aproto);
+static sdp_record_t *create_pbap_record(uint8_t chan, const char *svc_name)
+{
+ sdp_list_t *seq;
+ sdp_profile_desc_t profile[1];
+ uint8_t formats = 0x01;
+ sdp_record_t *record;
+ uuid_t uuid;
- sflist = sdp_data_alloc(dtd, formats);
- sdp_attr_add(record, SDP_ATTR_SUPPORTED_REPOSITORIES, sflist);
+ sdp_uuid16_create(&uuid, PBAP_PSE_SVCLASS_ID);
- if (svc_name)
- service_name = svc_name;
+ record = create_rfcomm_record(chan, &uuid, svc_name, true);
+ if (!record)
+ return NULL;
- sdp_set_info_attr(record, service_name, NULL, NULL);
+ sdp_uuid16_create(&profile[0].uuid, PBAP_PROFILE_ID);
+ profile[0].version = 0x0100;
+ seq = sdp_list_append(NULL, profile);
+ sdp_set_profile_descs(record, seq);
- sdp_data_free(channel);
- sdp_list_free(proto[0], NULL);
- sdp_list_free(proto[1], NULL);
- sdp_list_free(proto[2], NULL);
- sdp_list_free(apseq, NULL);
- sdp_list_free(pfseq, NULL);
- sdp_list_free(aproto, NULL);
- sdp_list_free(root, NULL);
- sdp_list_free(svclass_id, NULL);
+ sdp_attr_add_new(record, SDP_ATTR_SUPPORTED_REPOSITORIES, SDP_UINT8,
+ &formats);
+
+ sdp_list_free(seq, NULL);
return record;
}
static sdp_record_t *create_mas_record(uint8_t chan, const char *svc_name)
{
- const char *service_name = "MAP MAS SMS";
- sdp_list_t *svclass_id, *pfseq, *apseq, *root;
- uuid_t root_uuid, mse_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid;
+ sdp_list_t *seq;
sdp_profile_desc_t profile[1];
- sdp_list_t *aproto, *proto[3];
- sdp_data_t *channel;
uint8_t minst = DEFAULT_MAS_INSTANCE;
uint8_t mtype = DEFAULT_MAS_MSG_TYPE;
sdp_record_t *record;
+ uuid_t uuid;
- record = sdp_record_alloc();
+ sdp_uuid16_create(&uuid, MAP_MSE_SVCLASS_ID);
+
+ record = create_rfcomm_record(chan, &uuid, svc_name, true);
if (!record)
return NULL;
- record->handle = sdp_next_handle();
-
- sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
- root = sdp_list_append(NULL, &root_uuid);
- sdp_set_browse_groups(record, root);
-
- sdp_uuid16_create(&mse_uuid, MAP_MSE_SVCLASS_ID);
- svclass_id = sdp_list_append(NULL, &mse_uuid);
- sdp_set_service_classes(record, svclass_id);
-
sdp_uuid16_create(&profile[0].uuid, MAP_PROFILE_ID);
profile[0].version = 0x0101;
- pfseq = sdp_list_append(NULL, profile);
- sdp_set_profile_descs(record, pfseq);
+ seq = sdp_list_append(NULL, profile);
+ sdp_set_profile_descs(record, seq);
sdp_attr_add_new(record, SDP_ATTR_MAS_INSTANCE_ID, SDP_UINT8, &minst);
sdp_attr_add_new(record, SDP_ATTR_SUPPORTED_MESSAGE_TYPES, SDP_UINT8,
&mtype);
- sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
- proto[0] = sdp_list_append(NULL, &l2cap_uuid);
- apseq = sdp_list_append(NULL, proto[0]);
-
- sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
- proto[1] = sdp_list_append(NULL, &rfcomm_uuid);
- channel = sdp_data_alloc(SDP_UINT8, &chan);
- proto[1] = sdp_list_append(proto[1], channel);
- apseq = sdp_list_append(apseq, proto[1]);
-
- sdp_uuid16_create(&obex_uuid, OBEX_UUID);
- proto[2] = sdp_list_append(NULL, &obex_uuid);
- apseq = sdp_list_append(apseq, proto[2]);
-
- aproto = sdp_list_append(NULL, apseq);
- sdp_set_access_protos(record, aproto);
-
- if (svc_name)
- service_name = svc_name;
-
- sdp_set_info_attr(record, service_name, NULL, NULL);
-
- sdp_data_free(channel);
- sdp_list_free(proto[0], NULL);
- sdp_list_free(proto[1], NULL);
- sdp_list_free(proto[2], NULL);
- sdp_list_free(apseq, NULL);
- sdp_list_free(pfseq, NULL);
- sdp_list_free(aproto, NULL);
- sdp_list_free(root, NULL);
- sdp_list_free(svclass_id, NULL);
+ sdp_list_free(seq, NULL);
return record;
}
static sdp_record_t *create_spp_record(uint8_t chan, const char *svc_name)
{
- const char *service_name = "Serial Port";
- sdp_list_t *svclass_id, *apseq, *profiles, *root;
- uuid_t root_uuid, sp_uuid, l2cap, rfcomm;
- sdp_profile_desc_t profile;
- sdp_list_t *aproto, *proto[2];
- sdp_data_t *channel;
sdp_record_t *record;
+ uuid_t uuid;
- record = sdp_record_alloc();
+ sdp_uuid16_create(&uuid, SERIAL_PORT_SVCLASS_ID);
+
+ record = create_rfcomm_record(chan, &uuid, svc_name, false);
if (!record)
return NULL;
- record->handle = sdp_next_handle();
-
- sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
- root = sdp_list_append(NULL, &root_uuid);
- sdp_set_browse_groups(record, root);
-
- sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID);
- svclass_id = sdp_list_append(NULL, &sp_uuid);
- sdp_set_service_classes(record, svclass_id);
-
- sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID);
- profile.version = 0x0100;
- profiles = sdp_list_append(NULL, &profile);
- sdp_set_profile_descs(record, profiles);
-
- sdp_uuid16_create(&l2cap, L2CAP_UUID);
- proto[0] = sdp_list_append(NULL, &l2cap);
- apseq = sdp_list_append(NULL, proto[0]);
-
- sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
- proto[1] = sdp_list_append(NULL, &rfcomm);
- channel = sdp_data_alloc(SDP_UINT8, &chan);
- proto[1] = sdp_list_append(proto[1], channel);
- apseq = sdp_list_append(apseq, proto[1]);
-
- aproto = sdp_list_append(NULL, apseq);
- sdp_set_access_protos(record, aproto);
-
- sdp_add_lang_attr(record);
-
- if (svc_name)
- service_name = svc_name;
-
- sdp_set_info_attr(record, service_name, "BlueZ", "COM Port");
-
- sdp_set_url_attr(record, "http://www.bluez.org/",
- "http://www.bluez.org/", "http://www.bluez.org/");
-
- sdp_set_service_id(record, sp_uuid);
- sdp_set_service_ttl(record, 0xffff);
- sdp_set_service_avail(record, 0xff);
- sdp_set_record_state(record, 0x00001234);
-
- sdp_data_free(channel);
- sdp_list_free(proto[0], NULL);
- sdp_list_free(proto[1], NULL);
- sdp_list_free(apseq, NULL);
- sdp_list_free(aproto, NULL);
- sdp_list_free(root, NULL);
- sdp_list_free(svclass_id, NULL);
- sdp_list_free(profiles, NULL);
-
return record;
}
--
1.8.5.3
^ permalink raw reply related
* [PATCH 05/11] android/socket: Make servers list as static array
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
Since there is only small, fixed number of channels to allocate for
RFCOMM servers we can store them in static array. This will make
lookup for free channel simpler once we add support to assign channel
numbers dynamically.
At startup, channels reserved for built-in services which have static
channel number are marked as reserved so they cannot be assigned for
other service.
---
android/socket.c | 44 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 7 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 32de91a..4e823dd 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -45,6 +45,8 @@
#include "utils.h"
#include "socket.h"
+#define RFCOMM_CHANNEL_MAX 30
+
#define SPP_DEFAULT_CHANNEL 3
#define OPP_DEFAULT_CHANNEL 9
#define PBAP_DEFAULT_CHANNEL 15
@@ -64,9 +66,6 @@ static bdaddr_t adapter_addr;
static const uint8_t zero_uuid[16] = { 0 };
-/* Simple list of RFCOMM server sockets */
-GList *servers = NULL;
-
/* Simple list of RFCOMM connected sockets */
GList *connections = NULL;
@@ -90,6 +89,13 @@ struct rfcomm_sock {
const struct profile_info *profile;
};
+struct rfcomm_channel {
+ bool reserved;
+ struct rfcomm_sock *rfsock;
+};
+
+static struct rfcomm_channel servers[RFCOMM_CHANNEL_MAX + 1];
+
static int rfsock_set_buffer(struct rfcomm_sock *rfsock)
{
socklen_t len = sizeof(int);
@@ -599,7 +605,7 @@ static gboolean jv_sock_server_event_cb(GIOChannel *io, GIOCondition cond,
return FALSE;
if (cond & (G_IO_ERR | G_IO_HUP )) {
- servers = g_list_remove(servers, rfsock);
+ servers[rfsock->channel].rfsock = NULL;
cleanup_rfsock(rfsock);
}
@@ -690,7 +696,8 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
DBG("chan %d flags 0x%02x uuid %s name %s", chan, flags, uuid_str,
name);
- if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) {
+ if ((!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) ||
+ (chan > RFCOMM_CHANNEL_MAX)) {
error("Invalid rfcomm listen params");
return HAL_STATUS_INVALID;
}
@@ -706,12 +713,19 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
sec_level = profile->sec_level;
}
+ if (servers[chan].rfsock != NULL) {
+ error("Channel already registered (%d)", chan);
+ return HAL_STATUS_BUSY;
+ }
+
DBG("chan %d sec_level %d", chan, sec_level);
rfsock = create_rfsock(-1, hal_sock);
if (!rfsock)
return HAL_STATUS_FAILED;
+ rfsock->channel = chan;
+
io = bt_io_listen(accept_cb, NULL, rfsock, NULL, &err,
BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
BT_IO_OPT_CHANNEL, chan,
@@ -750,7 +764,7 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
rfsock->service_handle = sdp_service_register(profile, name);
- servers = g_list_append(servers, rfsock);
+ servers[chan].rfsock = rfsock;
return HAL_STATUS_SUCCESS;
@@ -1050,8 +1064,17 @@ static const struct ipc_handler cmd_handlers[] = {
void bt_socket_register(const bdaddr_t *addr)
{
+ size_t i;
+
DBG("");
+ /* make sure channels assigned for profiles are reserved and not used
+ * for app services
+ */
+ for (i = 0; i < G_N_ELEMENTS(profiles); i++)
+ if (profiles[i].channel)
+ servers[profiles[i].channel].reserved = true;
+
bacpy(&adapter_addr, addr);
ipc_register(HAL_SERVICE_ID_SOCK, cmd_handlers,
G_N_ELEMENTS(cmd_handlers));
@@ -1059,10 +1082,17 @@ void bt_socket_register(const bdaddr_t *addr)
void bt_socket_unregister(void)
{
+ int ch;
+
DBG("");
g_list_free_full(connections, cleanup_rfsock);
- g_list_free_full(servers, cleanup_rfsock);
+
+ for (ch = 0; ch <= RFCOMM_CHANNEL_MAX; ch++)
+ if (servers[ch].rfsock)
+ cleanup_rfsock(&servers[ch]);
+
+ memset(servers, 0, sizeof(servers));
ipc_unregister(HAL_SERVICE_ID_SOCK);
}
--
1.8.5.3
^ permalink raw reply related
* [PATCH 06/11] android/tester: Update test data
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
Trying to listen on already assigned channel will now return busy
status instead of just fail.
---
android/android-tester.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/android-tester.c b/android/android-tester.c
index 870ad8d..9198514 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -2757,7 +2757,7 @@ static const struct socket_data btsock_inv_listen_listen = {
.service_uuid = NULL,
.service_name = "Test service",
.flags = 0,
- .expected_status = BT_STATUS_FAIL,
+ .expected_status = BT_STATUS_BUSY,
.test_channel = true,
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH 07/11] android/socket: Add support for dynamic channel numbers
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds support to register server with channel number assigned
dynamically, i.e. first free number is assigned. Channels which are
reserved for built-in services are not assigned for other services.
---
android/socket.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 4e823dd..e560609 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -677,6 +677,21 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
new_rfsock->bt_watch = id;
}
+static int find_free_channel(void)
+{
+ int ch;
+
+ /* channel 0 is reserver so we don't use it */
+ for (ch = 1; ch <= RFCOMM_CHANNEL_MAX; ch++) {
+ struct rfcomm_channel *srv = &servers[ch];
+
+ if (!srv->reserved && srv->rfsock == NULL)
+ return ch;
+ }
+
+ return 0;
+}
+
static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
uint8_t flags, int *hal_sock)
{
@@ -704,15 +719,20 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
profile = get_profile_by_uuid(uuid);
if (!profile) {
- if (chan <= 0)
- return HAL_STATUS_INVALID;
-
sec_level = BT_IO_SEC_MEDIUM;
} else {
chan = profile->channel;
sec_level = profile->sec_level;
}
+ if (chan <= 0)
+ chan = find_free_channel();
+
+ if (!chan) {
+ error("No free channels");
+ return HAL_STATUS_BUSY;
+ }
+
if (servers[chan].rfsock != NULL) {
error("Channel already registered (%d)", chan);
return HAL_STATUS_BUSY;
--
1.8.5.3
^ permalink raw reply related
* [PATCH 08/11] android/socket: Register SDP record for application service
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds SDP record for services registered from application
(other than built-in services).
---
android/socket.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index e560609..9175bf3 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -350,6 +350,22 @@ static sdp_record_t *create_spp_record(uint8_t chan, const char *svc_name)
return record;
}
+static sdp_record_t *create_app_record(uint8_t chan,
+ const uint8_t *app_uuid,
+ const char *svc_name)
+{
+ sdp_record_t *record;
+ uuid_t uuid;
+
+ sdp_uuid128_create(&uuid, app_uuid);
+
+ record = create_rfcomm_record(chan, &uuid, svc_name, false);
+ if (!record)
+ return NULL;
+
+ return record;
+}
+
static const struct profile_info {
uint8_t uuid[16];
uint8_t channel;
@@ -396,19 +412,24 @@ static const struct profile_info {
},
};
-static uint32_t sdp_service_register(const struct profile_info *profile,
- const void *svc_name)
+static uint32_t sdp_service_register(uint8_t channel, const uint8_t *uuid,
+ const struct profile_info *profile,
+ const void *svc_name)
{
- sdp_record_t *record;
-
- if (!profile || !profile->create_record)
- return 0;
+ sdp_record_t *record = NULL;
+ uint8_t svc_hint = 0;
+
+ if (profile && profile->create_record) {
+ record = profile->create_record(channel, svc_name);
+ svc_hint = profile->svc_hint;
+ } else if (uuid) {
+ record = create_app_record(channel, uuid, svc_name);
+ }
- record = profile->create_record(profile->channel, svc_name);
if (!record)
return 0;
- if (bt_adapter_add_record(record, profile->svc_hint) < 0) {
+ if (bt_adapter_add_record(record, svc_hint) < 0) {
error("Failed to register on SDP record");
sdp_record_free(record);
return 0;
@@ -782,7 +803,8 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
goto failed;
}
- rfsock->service_handle = sdp_service_register(profile, name);
+ rfsock->service_handle = sdp_service_register(chan, uuid, profile,
+ name);
servers[chan].rfsock = rfsock;
--
1.8.5.3
^ permalink raw reply related
* [PATCH 09/11] android/socket: Include HF AG in built-in profiles
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds entry for HF AG profile in built-in profiles list. This
it to reserve channel number so it's not assigned to other service
registered by application. Method for creating SDP record is not
provided so it's not possible for application to register HF AG service
by mistake (this can be only done by handsfree profile implementation).
---
android/socket.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 9175bf3..4dcb5fc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -49,6 +49,7 @@
#define SPP_DEFAULT_CHANNEL 3
#define OPP_DEFAULT_CHANNEL 9
+#define HFAG_DEFAULT_CHANNEL 13
#define PBAP_DEFAULT_CHANNEL 15
#define MAS_DEFAULT_CHANNEL 16
@@ -375,6 +376,15 @@ static const struct profile_info {
} profiles[] = {
{
.uuid = {
+ 0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+ },
+ .channel = HFAG_DEFAULT_CHANNEL,
+ .svc_hint = 0,
+ .sec_level = BT_IO_SEC_MEDIUM,
+ .create_record = NULL
+ }, {
+ .uuid = {
0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
},
@@ -742,6 +752,9 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
if (!profile) {
sec_level = BT_IO_SEC_MEDIUM;
} else {
+ if (!profile->create_record)
+ return HAL_STATUS_INVALID;
+
chan = profile->channel;
sec_level = profile->sec_level;
}
--
1.8.5.3
^ permalink raw reply related
* [PATCH 10/11] android/socket: Update channel numbers
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
OPP and PBAP channel numbers are set to same values as in Bluedroid.
Both MAP and SPP use channel numbers assigned dynamically.
---
android/socket.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index 4dcb5fc..c790c24 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -47,11 +47,9 @@
#define RFCOMM_CHANNEL_MAX 30
-#define SPP_DEFAULT_CHANNEL 3
-#define OPP_DEFAULT_CHANNEL 9
+#define OPP_DEFAULT_CHANNEL 12
#define HFAG_DEFAULT_CHANNEL 13
-#define PBAP_DEFAULT_CHANNEL 15
-#define MAS_DEFAULT_CHANNEL 16
+#define PBAP_DEFAULT_CHANNEL 19
#define SVC_HINT_OBEX 0x10
@@ -406,7 +404,7 @@ static const struct profile_info {
0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
},
- .channel = MAS_DEFAULT_CHANNEL,
+ .channel = 0,
.svc_hint = SVC_HINT_OBEX,
.sec_level = BT_IO_SEC_MEDIUM,
.create_record = create_mas_record
@@ -415,7 +413,7 @@ static const struct profile_info {
0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
},
- .channel = SPP_DEFAULT_CHANNEL,
+ .channel = 0,
.svc_hint = 0,
.sec_level = BT_IO_SEC_MEDIUM,
.create_record = create_spp_record
--
1.8.5.3
^ permalink raw reply related
* [PATCH 11/11] android/socket: Fix sockets security
From: Andrzej Kaczmarek @ 2014-02-11 16:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1392137901-3403-1-git-send-email-andrzej.kaczmarek@tieto.com>
Socket security shall be based on flags passed from HAL.
Android public API uses both encrypt and auth flags for "secure"
sockets which should be mapped to high security on our side, but since
this would also trigger requirement for 16-digits pin code (which is
not used in Android) we'll ignore auth flag and use either low or
medium security based on encrypt flag value only.
---
android/hal-msg.h | 3 +++
android/socket.c | 29 +++++++++++++++++++----------
2 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index aba98ed..6ef00f9 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -235,6 +235,9 @@ struct hal_cmd_le_test_mode {
#define HAL_SOCK_SCO 0x02
#define HAL_SOCK_L2CAP 0x03
+#define HAL_SOCK_FLAG_ENCRYPT 0x01
+#define HAL_SOCK_FLAG_AUTH 0x02
+
#define HAL_OP_SOCK_LISTEN 0x01
struct hal_cmd_sock_listen {
uint8_t type;
diff --git a/android/socket.c b/android/socket.c
index c790c24..4e9121d 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -70,6 +70,7 @@ GList *connections = NULL;
struct rfcomm_sock {
int channel; /* RFCOMM channel */
+ BtIOSecLevel sec_level;
/* for socket to BT */
int bt_sock;
@@ -84,8 +85,6 @@ struct rfcomm_sock {
uint8_t *buf;
int buf_size;
-
- const struct profile_info *profile;
};
struct rfcomm_channel {
@@ -721,6 +720,19 @@ static int find_free_channel(void)
return 0;
}
+static BtIOSecLevel get_sec_level(uint8_t flags)
+{
+ /* HAL_SOCK_FLAG_AUTH should require MITM but in our case setting
+ * security to BT_IO_SEC_HIGH would also require 16-digits PIN code
+ * for pre-2.1 devices which is not what Android expects. For this
+ * reason we ignore this flag to not break apps which use "secure"
+ * sockets (have both auth and encrypt flags set, there is no public
+ * API in Android which should provide proper high security socket).
+ */
+ return flags & HAL_SOCK_FLAG_ENCRYPT ? BT_IO_SEC_MEDIUM :
+ BT_IO_SEC_LOW;
+}
+
static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
uint8_t flags, int *hal_sock)
{
@@ -748,7 +760,7 @@ static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid,
profile = get_profile_by_uuid(uuid);
if (!profile) {
- sec_level = BT_IO_SEC_MEDIUM;
+ sec_level = get_sec_level(flags);
} else {
if (!profile->create_record)
return HAL_STATUS_INVALID;
@@ -931,20 +943,16 @@ fail:
static bool do_rfcomm_connect(struct rfcomm_sock *rfsock, int chan)
{
- BtIOSecLevel sec_level = BT_IO_SEC_MEDIUM;
GIOChannel *io;
GError *gerr = NULL;
- if (rfsock->profile)
- sec_level = rfsock->profile->sec_level;
-
- DBG("rfsock %p sec_level %d chan %d", rfsock, sec_level, chan);
+ DBG("rfsock %p sec_level %d chan %d", rfsock, rfsock->sec_level, chan);
io = bt_io_connect(connect_cb, rfsock, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
BT_IO_OPT_DEST_BDADDR, &rfsock->dst,
BT_IO_OPT_CHANNEL, chan,
- BT_IO_OPT_SEC_LEVEL, sec_level,
+ BT_IO_OPT_SEC_LEVEL, rfsock->sec_level,
BT_IO_OPT_INVALID);
if (!io) {
error("Failed connect: %s", gerr->message);
@@ -1047,13 +1055,14 @@ static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan,
DBG("rfsock %p jv_sock %d hal_sock %d", rfsock, rfsock->jv_sock,
*hal_sock);
+ rfsock->sec_level = get_sec_level(flags);
+
bacpy(&rfsock->dst, addr);
if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid))) {
if (!do_rfcomm_connect(rfsock, chan))
goto failed;
} else {
- rfsock->profile = get_profile_by_uuid(uuid);
if (bt_search_service(&adapter_addr, &rfsock->dst, &uu,
sdp_search_cb, rfsock, NULL, 0) < 0) {
--
1.8.5.3
^ permalink raw reply related
* Re: [RFC] android/ipc: Add AVRCP HAL message definitions
From: Szymon Janc @ 2014-02-11 16:59 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1390406788-17152-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Wednesday 22 of January 2014 18:06:28 Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> ---
> android/hal-msg.h | 71
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71
> insertions(+)
>
> diff --git a/android/hal-msg.h b/android/hal-msg.h
> index d46b428..3937f07 100644
> --- a/android/hal-msg.h
> +++ b/android/hal-msg.h
> @@ -338,6 +338,77 @@ struct hal_cmd_a2dp_disconnect {
> uint8_t bdaddr[6];
> } __attribute__((packed));
>
> +/* AVRCP HAL API */
> +
> +#define HAL_OP_AVRCP_GET_PLAY_STATUS_RSP 0x01
> +struct hal_cmd_avrcp_get_play_status_rsp {
> + uint8_t status;
defines for enums should be added as well (this goes for all enums)
> + uint32_t len;
> + uint32_t pos;
> +} __attribute__((packed));
> +
> +#define HAL_OP_AVRCP_LIST_PLAYER_APP_ATTR_RSP 0x02
> +struct hal_cmd_avrcp_list_player_app_attr_rsp {
> + uint16_t len;
> + uint8_t data[0];
> +} __attribute__((packed));
> +
> +#define HAL_OP_AVRCP_LIST_PLAYER_APP_VAL_RSP 0x03
> +struct hal_cmd_avrcp_list_player_app_val_rsp {
> + uint16_t len;
> + uint8_t data[0];
> +} __attribute__((packed));
> +
> +#define MAX_APP_SETTINGS 8
> +struct player_setting {
> + uint8_t num_attr;
> + uint8_t attr_ids[MAX_APP_SETTINGS];
> + uint8_t attr_vals[MAX_APP_SETTINGS];
> +} __attribute__((packed));
> +
> +#define HAL_OP_AVRCP_GET_PLAYER_APP_VAL_RSP 0x04
> +struct hal_cmd_avrcp_get_player_app_val_rsp {
> + struct player_setting settings;
> +} __attribute__((packed));
> +
> +#define MAX_ATTR_STR_LEN 255
> +struct player_text {
> + uint32_t id;
> + uint8_t text[MAX_ATTR_STR_LEN];
> +} __attribute__((packed));
> +
> +#define HAL_OP_AVRCP_GET_PLAYER_APP_ATTR_TEXT_RSP 0x05
> +#define HAL_OP_AVRCP_GET_PLAYER_APP_VAL_TEXT_RSP 0x06
> +#define HAL_OP_AVRCP_GET_ELEMENT_ATTR_RSP 0x07
> +struct hal_cmd_avrcp_get_text_rsp {
> + uint16_t len;
> + struct player_text data[0];
> +} __attribute__((packed));
> +
> +#define HAL_OP_AVRCP_SET_PLAYER_APP_VAL_RSP 0x08
> +struct hal_cmd_avrcp_set_player_app_val_rsp {
> + uint8_t status;
> +} __attribute__((packed));
> +
> +union notification {
> + uint8_t status;
> + uint8_t uid[8];
> + uint32_t pos;
> + struct player_setting player_settings;
> +} __attribute__((packed));
> +
> +#define HAL_OP_AVRCP_REGISTER_NOTIFICATION_RSP 0x09
> +struct hal_cmd_avrcp_register_notification_rsp {
> + uint8_t id;
> + uint8_t type;
> + union notification param;
> +} __attribute__((packed));
> +
> +#define HAL_OP_AVRCP_SET_VOLUME 0x0a
> +struct hal_cmd_avrcp_set_volume {
> + uint8_t volume;
> +} __attribute__((packed));
> +
> /* PAN HAL API */
>
> /* PAN Roles */
Please add structures for notifications. Also hal-ipc-api.txt needs to be
updated before this can go in.
--
BR
Szymon Janc
^ permalink raw reply
* Re: [PATCH 3/6] shared: Add support for disconnect handler in HFP
From: Marcel Holtmann @ 2014-02-11 17:00 UTC (permalink / raw)
To: Szymon Janc; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392137346-26272-3-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
> It is no longer possible to send any data after disconnection.
> Extra reference is taken for disconnect watch to allow users to drop
> own reference in disconnect callback.
I am not sure that is the best way to do it. I get the feeling that we might better have an internal bool that is tracking if we are connected/disconnected. Thoughts?
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 4/6] shared: Add support for shutdown to IO
From: Marcel Holtmann @ 2014-02-11 17:02 UTC (permalink / raw)
To: Szymon Janc; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392137346-26272-4-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
> This allows to locally shutdown IO.
> ---
> src/shared/io-glib.c | 9 +++++++++
> src/shared/io-mainloop.c | 9 +++++++++
> src/shared/io.h | 2 ++
> 3 files changed, 20 insertions(+)
>
> diff --git a/src/shared/io-glib.c b/src/shared/io-glib.c
> index a4f982d..8290745 100644
> --- a/src/shared/io-glib.c
> +++ b/src/shared/io-glib.c
> @@ -320,3 +320,12 @@ done:
>
> return true;
> }
> +
> +bool io_shutdown(struct io *io)
> +{
> + if (!io || !io->channel)
> + return false;
> +
> + return g_io_channel_shutdown(io->channel, TRUE, NULL)
> + == G_IO_STATUS_NORMAL;
> +}
> diff --git a/src/shared/io-mainloop.c b/src/shared/io-mainloop.c
> index 14ab128..f1e3b3b 100644
> --- a/src/shared/io-mainloop.c
> +++ b/src/shared/io-mainloop.c
> @@ -26,6 +26,7 @@
> #endif
>
> #include <unistd.h>
> +#include <sys/socket.h>
>
> #include "monitor/mainloop.h"
> #include "src/shared/util.h"
> @@ -294,3 +295,11 @@ bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback,
>
> return true;
> }
> +
> +bool io_shutdown(struct io *io)
> +{
> + if (!io || io->fd < 0)
> + return false;
> +
> + return shutdown(io->fd, SHUT_RDWR) == 0;
> +}
I have no problem doing this, but why is this actually needed? Is not closing the socket good enough? Or would be better also add a shutdown_on_unref option?
Regards
Marcel
^ permalink raw reply
* [PATCH BlueZ] unit: Fix memory leaks in gobex tests
From: Anderson Lizardo @ 2014-02-11 18:16 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
---
unit/test-gobex-apparam.c | 2 ++
unit/test-gobex-transfer.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/unit/test-gobex-apparam.c b/unit/test-gobex-apparam.c
index e6a42cc..976c541 100644
--- a/unit/test-gobex-apparam.c
+++ b/unit/test-gobex-apparam.c
@@ -250,6 +250,8 @@ static void test_apparam_get_multi(void)
g_assert(string != NULL);
g_assert_cmpstr(string, ==, "ABC");
+ g_free(string);
+
g_obex_apparam_free(apparam);
}
diff --git a/unit/test-gobex-transfer.c b/unit/test-gobex-transfer.c
index 128a467..7c9fd43 100644
--- a/unit/test-gobex-transfer.c
+++ b/unit/test-gobex-transfer.c
@@ -511,6 +511,7 @@ static void test_stream_put_req_abort(void)
g_obex_unref(obex);
g_assert_error(d.err, G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED);
+ g_error_free(d.err);
}
static void test_stream_put_rsp_abort(void)
@@ -556,6 +557,7 @@ static void test_stream_put_rsp_abort(void)
g_obex_unref(obex);
g_assert_error(d.err, G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED);
+ g_error_free(d.err);
}
static void handle_put_seq_wait(GObex *obex, GObexPacket *req,
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 1/7] android: Use 16-bit UUID for SDP search
From: Anderson Lizardo @ 2014-02-11 18:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
These UUIDs are assigned by BT-SIG and therefore there is no need to
use full 128-bit UUIDs. This also avoids unnecessary conversion from
string representation.
---
android/handsfree.c | 3 +--
android/hidhost.c | 7 +++----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/android/handsfree.c b/android/handsfree.c
index 9482b2e..a869d58 100644
--- a/android/handsfree.c
+++ b/android/handsfree.c
@@ -34,7 +34,6 @@
#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
-#include "lib/uuid.h"
#include "src/sdp-client.h"
#include "src/uuid-helper.h"
#include "src/shared/hfp.h"
@@ -294,7 +293,7 @@ static void handle_connect(const void *buf, uint16_t len)
device_init(&bdaddr);
- bt_string2uuid(&uuid, HFP_HS_UUID);
+ sdp_uuid16_create(&uuid, HANDSFREE_SVCLASS_ID);
if (bt_search_service(&adapter_addr, &device.bdaddr, &uuid,
sdp_search_cb, NULL, NULL, 0) < 0) {
error("handsfree: SDP search failed");
diff --git a/android/hidhost.c b/android/hidhost.c
index 8bd3455..45fe14f 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -37,7 +37,6 @@
#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
-#include "lib/uuid.h"
#include "src/shared/mgmt.h"
#include "src/sdp-client.h"
#include "src/uuid-helper.h"
@@ -751,7 +750,7 @@ static void hid_sdp_did_search_cb(sdp_list_t *recs, int err, gpointer data)
dev->version = data->val.uint16;
}
- bt_string2uuid(&uuid, HID_UUID);
+ sdp_uuid16_create(&uuid, HID_SVCLASS_ID);
if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
hid_sdp_search_cb, dev, NULL, 0) < 0) {
error("failed to search sdp details");
@@ -792,7 +791,7 @@ static void bt_hid_connect(const void *buf, uint16_t len)
ba2str(&dev->dst, addr);
DBG("connecting to %s", addr);
- bt_string2uuid(&uuid, PNP_UUID);
+ sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID);
if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
error("Failed to search DeviceID SDP details");
@@ -1293,7 +1292,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
dev->ctrl_io = g_io_channel_ref(chan);
dev->uhid_fd = -1;
- bt_string2uuid(&uuid, PNP_UUID);
+ sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID);
if (bt_search_service(&src, &dev->dst, &uuid,
hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
error("failed to search did sdp details");
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 2/7] android/tester: Update SDP PDU after UUID change
From: Anderson Lizardo @ 2014-02-11 18:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1392143552-11395-1-git-send-email-anderson.lizardo@openbossa.org>
Now it is expected to receive a 16-bit UUID for PNP_INFO.
---
android/android-tester.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/android/android-tester.c b/android/android-tester.c
index 870ad8d..d635732 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -3307,16 +3307,10 @@ static void hid_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
static const uint8_t did_req_pdu[] = { 0x06, /* PDU id */
0x00, 0x00, /* Transaction id */
- 0x00, 0x1d, /* Req length */
- 0x35, 0x11, /* Attributes length */
- 0x1c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb, 0xff,
- 0xff, 0x35, 0x05, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x00,
- 0x06, 0x00, 0x01, 0x00, 0x1d, 0x35, 0x11, 0x1c, 0x00,
- 0x00, 0x11, 0x24, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
- 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb, 0xff, 0xff, 0x35,
- 0x05, 0x0a, 0x00, 0x0, 0xff, 0xff,
- 0x00 }; /* no continuation */
+ 0x00, 0x0f, /* Req length */
+ 0x35, 0x03, /* Attributes length */
+ 0x19, 0x12, 0x00, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00,
+ 0x00, 0xff, 0xff, 0x00 }; /* no continuation */
static const uint8_t did_rsp_pdu[] = { 0x07, /* PDU id */
0x00, 0x00, /* Transaction id */
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 3/7] android/hidhost: Trivial coding style fix
From: Anderson Lizardo @ 2014-02-11 18:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1392143552-11395-1-git-send-email-anderson.lizardo@openbossa.org>
Fix two lines over 80 columns.
---
android/hidhost.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/hidhost.c b/android/hidhost.c
index 45fe14f..f54ca6d 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -793,7 +793,7 @@ static void bt_hid_connect(const void *buf, uint16_t len)
sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID);
if (bt_search_service(&adapter_addr, &dev->dst, &uuid,
- hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
+ hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
error("Failed to search DeviceID SDP details");
hid_device_remove(dev);
status = HAL_STATUS_FAILED;
@@ -1294,7 +1294,7 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID);
if (bt_search_service(&src, &dev->dst, &uuid,
- hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
+ hid_sdp_did_search_cb, dev, NULL, 0) < 0) {
error("failed to search did sdp details");
hid_device_remove(dev);
return;
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 4/7] android/client: Fix set_info command
From: Anderson Lizardo @ 2014-02-11 18:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1392143552-11395-1-git-send-email-anderson.lizardo@openbossa.org>
Although this command is not implemented by BlueZ, make sure it is
callable from haltest so at least the IPC can be tested.
Also memset() the hid_info parameter to not pass uninitialized data
around.
---
android/client/if-hh.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/android/client/if-hh.c b/android/client/if-hh.c
index 56eb698..0341d25 100644
--- a/android/client/if-hh.c
+++ b/android/client/if-hh.c
@@ -229,6 +229,9 @@ static void virtual_unplug_p(int argc, const char **argv)
/* set_info */
+/* Same completion as connect_c */
+#define set_info_c connect_c
+
static void set_info_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
@@ -236,8 +239,11 @@ static void set_info_p(int argc, const char **argv)
RETURN_IF_NULL(if_hh);
VERIFY_ADDR_ARG(2, &addr);
- /* TODO: set_info does not seem to be called anywhere */
+ memset(&hid_info, 0, sizeof(hid_info));
+
+ /* This command is intentionally not supported. See comment from
+ * bt_hid_info() in android/hidhost.c */
EXEC(if_hh->set_info, &addr, hid_info);
}
@@ -416,7 +422,7 @@ static struct method methods[] = {
STD_METHODCH(connect, "<addr>"),
STD_METHODCH(disconnect, "<addr>"),
STD_METHODCH(virtual_unplug, "<addr>"),
- STD_METHOD(set_info),
+ STD_METHODCH(set_info, "<addr>"),
STD_METHODCH(get_protocol, "<addr> <mode>"),
STD_METHODCH(set_protocol, "<addr> <mode>"),
STD_METHODCH(get_report, "<addr> <type> <report_id> <size>"),
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 5/7] android/test-ipc: Fix crash due to invalid ipc_register() parameter
From: Anderson Lizardo @ 2014-02-11 18:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1392143552-11395-1-git-send-email-anderson.lizardo@openbossa.org>
This test checks for proper handling of invalid Service ID on a IPC
message, but it was attempting to register handlers for this invalid ID,
which on current ipc_register() implementation was causing a buffer
overrun.
The fix was to use a valid ID during registration, but still attempt to
use an invalid one when sending the message.
---
android/test-ipc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/test-ipc.c b/android/test-ipc.c
index 3a0729e..7318251 100644
--- a/android/test-ipc.c
+++ b/android/test-ipc.c
@@ -526,7 +526,7 @@ static const struct hal_hdr test_cmd_service_offrange_hdr = {
static const struct test_data test_cmd_service_offrange = {
.cmd = &test_cmd_service_offrange_hdr,
.cmd_size = sizeof(struct hal_hdr),
- .service = HAL_SERVICE_ID_MAX + 1,
+ .service = 0,
.handlers = cmd_handlers,
.handlers_size = 1,
.expected_signal = SIGTERM
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 6/7] android: Add assertion for ID parameter in ipc_register/ipc_unregister
From: Anderson Lizardo @ 2014-02-11 18:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1392143552-11395-1-git-send-email-anderson.lizardo@openbossa.org>
It is a programming error to pass a invalid ID for these functions (i.e.
the ID is statically defined on the code). Given that this ID is used
for indexing an array, adding an assertion will ensure that improper API
usage will not cause random crashes due to memory corruption.
---
android/ipc.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/android/ipc.c b/android/ipc.c
index ab0f1a4..373345c 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -336,12 +336,16 @@ void ipc_send_notif(uint8_t service_id, uint8_t opcode, uint16_t len,
void ipc_register(uint8_t service, const struct ipc_handler *handlers,
uint8_t size)
{
+ g_assert(service <= HAL_SERVICE_ID_MAX);
+
services[service].handler = handlers;
services[service].size = size;
}
void ipc_unregister(uint8_t service)
{
+ g_assert(service <= HAL_SERVICE_ID_MAX);
+
services[service].handler = NULL;
services[service].size = 0;
}
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox