* pull request: bluetooth 2013-11-11
From: Gustavo Padovan @ 2013-11-11 18:27 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, linux-bluetooth, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1537 bytes --]
Hi John,
A few fixes for 3.13. There is 3 fixes to the RFCOMM protocol. One crash fix to
L2CAP. A simple fix to a bad behaviour in the SMP protocol, and last, an
revert, that I sent in the last pull request but doesn't seem to be in your
tree.
Please pull or let me know of any issues. Thanks!
Gustavo
---
The following changes since commit 8ce9beac4661f576ea0d518b9f086bb52a171a37:
drivers: net: wireless: b43: Fix possible NULL ptr dereference (2013-10-18 13:41:11 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth master
for you to fetch changes up to 3244d4a55c95708b0fa6fd820a9009534ed08a5f:
Bluetooth: Fix rejecting SMP security request in slave role (2013-11-11 15:48:36 -0200)
----------------------------------------------------------------
Hans de Goede (1):
Bluetooth: revert: "Bluetooth: Add missing reset_resume dev_pm_ops"
Johan Hedberg (1):
Bluetooth: Fix rejecting SMP security request in slave role
Marcel Holtmann (1):
Bluetooth: Fix issue with RFCOMM getsockopt operation
Seung-Woo Kim (3):
Bluetooth: Fix RFCOMM bind fail for L2CAP sock
Bluetooth: Fix to set proper bdaddr_type for RFCOMM connect
Bluetooth: Fix crash in l2cap_chan_send after l2cap_chan_del
drivers/bluetooth/btusb.c | 1 -
net/bluetooth/l2cap_core.c | 3 +++
net/bluetooth/rfcomm/core.c | 3 +++
net/bluetooth/rfcomm/sock.c | 6 +++++-
net/bluetooth/smp.c | 3 +++
5 files changed, 14 insertions(+), 2 deletions(-)
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH BlueZ v2] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Johan Hedberg @ 2013-11-11 16:50 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1384186675-14940-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Mon, Nov 11, 2013, Luiz Augusto von Dentz wrote:
> This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
> so the server socket is only registered when there is an endpoint
> available and the record is properly registered.
> ---
> v2: Fix return of avdtp_server_init
>
> profiles/audio/a2dp.c | 11 -----
> profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
> profiles/audio/avdtp.h | 3 --
> 3 files changed, 60 insertions(+), 72 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ v2] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Luiz Augusto von Dentz @ 2013-11-11 16:17 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
so the server socket is only registered when there is an endpoint
available and the record is properly registered.
---
v2: Fix return of avdtp_server_init
profiles/audio/a2dp.c | 11 -----
profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
profiles/audio/avdtp.h | 3 --
3 files changed, 60 insertions(+), 72 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 8477b5d..6b3d6b2 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1187,17 +1187,8 @@ static struct a2dp_server *find_server(GSList *list, struct btd_adapter *a)
static struct a2dp_server *a2dp_server_register(struct btd_adapter *adapter)
{
struct a2dp_server *server;
- int av_err;
server = g_new0(struct a2dp_server, 1);
-
- av_err = avdtp_init(adapter);
- if (av_err < 0) {
- DBG("AVDTP not registered");
- g_free(server);
- return NULL;
- }
-
server->adapter = btd_adapter_ref(adapter);
servers = g_slist_append(servers, server);
@@ -1217,8 +1208,6 @@ static void a2dp_unregister_sep(struct a2dp_sep *sep)
static void a2dp_server_unregister(struct a2dp_server *server)
{
- avdtp_exit(server->adapter);
-
servers = g_slist_remove(servers, server);
btd_adapter_unref(server->adapter);
g_free(server);
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index dab8f1c..9378350 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -3683,6 +3683,45 @@ int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
&req, sizeof(req));
}
+static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
+{
+ GError *err = NULL;
+ GIOChannel *io;
+
+ io = bt_io_listen(NULL, avdtp_confirm_cb,
+ NULL, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_PSM, AVDTP_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_MASTER, master,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ }
+
+ return io;
+}
+
+static struct avdtp_server *avdtp_server_init(struct btd_adapter *adapter)
+{
+ struct avdtp_server *server;
+
+ server = g_new0(struct avdtp_server, 1);
+
+ server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
+ if (!server->io) {
+ g_free(server);
+ return NULL;
+ }
+
+ server->adapter = btd_adapter_ref(adapter);
+
+ servers = g_slist_append(servers, server);
+
+ return server;
+}
+
struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
uint8_t type,
uint8_t media_type,
@@ -3696,8 +3735,11 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
struct avdtp_local_sep *sep;
server = find_server(servers, adapter);
- if (!server)
- return NULL;
+ if (!server) {
+ server = avdtp_server_init(adapter);
+ if (!server)
+ return NULL;
+ }
if (g_slist_length(server->seps) > MAX_SEID)
return NULL;
@@ -3722,6 +3764,18 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
return sep;
}
+static void avdtp_server_destroy(struct avdtp_server *server)
+{
+ g_slist_free_full(server->sessions, avdtp_free);
+
+ servers = g_slist_remove(servers, server);
+
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ g_io_channel_unref(server->io);
+ btd_adapter_unref(server->adapter);
+ g_free(server);
+}
+
int avdtp_unregister_sep(struct avdtp_local_sep *sep)
{
struct avdtp_server *server;
@@ -3740,27 +3794,12 @@ int avdtp_unregister_sep(struct avdtp_local_sep *sep)
g_free(sep);
- return 0;
-}
-
-static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
-{
- GError *err = NULL;
- GIOChannel *io;
+ if (server->seps)
+ return 0;
- io = bt_io_listen(NULL, avdtp_confirm_cb,
- NULL, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, src,
- BT_IO_OPT_PSM, AVDTP_PSM,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
- BT_IO_OPT_MASTER, master,
- BT_IO_OPT_INVALID);
- if (!io) {
- error("%s", err->message);
- g_error_free(err);
- }
+ avdtp_server_destroy(server);
- return io;
+ return 0;
}
const char *avdtp_strerror(struct avdtp_error *err)
@@ -3823,43 +3862,6 @@ struct btd_device *avdtp_get_device(struct avdtp *session)
return session->device;
}
-int avdtp_init(struct btd_adapter *adapter)
-{
- struct avdtp_server *server;
-
- server = g_new0(struct avdtp_server, 1);
-
- server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
- if (!server->io) {
- g_free(server);
- return -1;
- }
-
- server->adapter = btd_adapter_ref(adapter);
-
- servers = g_slist_append(servers, server);
-
- return 0;
-}
-
-void avdtp_exit(struct btd_adapter *adapter)
-{
- struct avdtp_server *server;
-
- server = find_server(servers, adapter);
- if (!server)
- return;
-
- g_slist_free_full(server->sessions, avdtp_free);
-
- servers = g_slist_remove(servers, server);
-
- g_io_channel_shutdown(server->io, TRUE, NULL);
- g_io_channel_unref(server->io);
- btd_adapter_unref(server->adapter);
- g_free(server);
-}
-
gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
{
return g_slist_find(session->streams, stream) ? TRUE : FALSE;
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 3bf7503..5606506 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -308,6 +308,3 @@ struct btd_adapter *avdtp_get_adapter(struct avdtp *session);
struct btd_device *avdtp_get_device(struct avdtp *session);
void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc);
-
-int avdtp_init(struct btd_adapter *adapter);
-void avdtp_exit(struct btd_adapter *adapter);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH BlueZ] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Luiz Augusto von Dentz @ 2013-11-11 15:34 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1384179100-11209-1-git-send-email-luiz.dentz@gmail.com>
Hi,
On Mon, Nov 11, 2013 at 4:11 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
> so the server socket is only registered when there is an endpoint
> available and the record is properly registered.
> ---
> profiles/audio/a2dp.c | 11 -----
> profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
> profiles/audio/avdtp.h | 3 --
> 3 files changed, 60 insertions(+), 72 deletions(-)
>
> diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
> index 8477b5d..6b3d6b2 100644
> --- a/profiles/audio/a2dp.c
> +++ b/profiles/audio/a2dp.c
> @@ -1187,17 +1187,8 @@ static struct a2dp_server *find_server(GSList *list, struct btd_adapter *a)
> static struct a2dp_server *a2dp_server_register(struct btd_adapter *adapter)
> {
> struct a2dp_server *server;
> - int av_err;
>
> server = g_new0(struct a2dp_server, 1);
> -
> - av_err = avdtp_init(adapter);
> - if (av_err < 0) {
> - DBG("AVDTP not registered");
> - g_free(server);
> - return NULL;
> - }
> -
> server->adapter = btd_adapter_ref(adapter);
> servers = g_slist_append(servers, server);
>
> @@ -1217,8 +1208,6 @@ static void a2dp_unregister_sep(struct a2dp_sep *sep)
>
> static void a2dp_server_unregister(struct a2dp_server *server)
> {
> - avdtp_exit(server->adapter);
> -
> servers = g_slist_remove(servers, server);
> btd_adapter_unref(server->adapter);
> g_free(server);
> diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
> index dab8f1c..9a470f1 100644
> --- a/profiles/audio/avdtp.c
> +++ b/profiles/audio/avdtp.c
> @@ -3683,6 +3683,45 @@ int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
> &req, sizeof(req));
> }
>
> +static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
> +{
> + GError *err = NULL;
> + GIOChannel *io;
> +
> + io = bt_io_listen(NULL, avdtp_confirm_cb,
> + NULL, NULL, &err,
> + BT_IO_OPT_SOURCE_BDADDR, src,
> + BT_IO_OPT_PSM, AVDTP_PSM,
> + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
> + BT_IO_OPT_MASTER, master,
> + BT_IO_OPT_INVALID);
> + if (!io) {
> + error("%s", err->message);
> + g_error_free(err);
> + }
> +
> + return io;
> +}
> +
> +static struct avdtp_server *avdtp_server_init(struct btd_adapter *adapter)
> +{
> + struct avdtp_server *server;
> +
> + server = g_new0(struct avdtp_server, 1);
> +
> + server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
> + if (!server->io) {
> + g_free(server);
> + return NULL;
> + }
> +
> + server->adapter = btd_adapter_ref(adapter);
> +
> + servers = g_slist_append(servers, server);
> +
> + return 0;
> +}
> +
> struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
> uint8_t type,
> uint8_t media_type,
> @@ -3696,8 +3735,11 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
> struct avdtp_local_sep *sep;
>
> server = find_server(servers, adapter);
> - if (!server)
> - return NULL;
> + if (!server) {
> + server = avdtp_server_init(adapter);
> + if (!server)
> + return NULL;
> + }
>
> if (g_slist_length(server->seps) > MAX_SEID)
> return NULL;
> @@ -3722,6 +3764,18 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
> return sep;
> }
>
> +static void avdtp_server_destroy(struct avdtp_server *server)
> +{
> + g_slist_free_full(server->sessions, avdtp_free);
> +
> + servers = g_slist_remove(servers, server);
> +
> + g_io_channel_shutdown(server->io, TRUE, NULL);
> + g_io_channel_unref(server->io);
> + btd_adapter_unref(server->adapter);
> + g_free(server);
> +}
> +
> int avdtp_unregister_sep(struct avdtp_local_sep *sep)
> {
> struct avdtp_server *server;
> @@ -3740,27 +3794,12 @@ int avdtp_unregister_sep(struct avdtp_local_sep *sep)
>
> g_free(sep);
>
> - return 0;
> -}
> -
> -static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
> -{
> - GError *err = NULL;
> - GIOChannel *io;
> + if (server->seps)
> + return 0;
>
> - io = bt_io_listen(NULL, avdtp_confirm_cb,
> - NULL, NULL, &err,
> - BT_IO_OPT_SOURCE_BDADDR, src,
> - BT_IO_OPT_PSM, AVDTP_PSM,
> - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
> - BT_IO_OPT_MASTER, master,
> - BT_IO_OPT_INVALID);
> - if (!io) {
> - error("%s", err->message);
> - g_error_free(err);
> - }
> + avdtp_server_destroy(server);
>
> - return io;
> + return 0;
> }
>
> const char *avdtp_strerror(struct avdtp_error *err)
> @@ -3823,43 +3862,6 @@ struct btd_device *avdtp_get_device(struct avdtp *session)
> return session->device;
> }
>
> -int avdtp_init(struct btd_adapter *adapter)
> -{
> - struct avdtp_server *server;
> -
> - server = g_new0(struct avdtp_server, 1);
> -
> - server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
> - if (!server->io) {
> - g_free(server);
> - return -1;
> - }
> -
> - server->adapter = btd_adapter_ref(adapter);
> -
> - servers = g_slist_append(servers, server);
> -
> - return 0;
> -}
> -
> -void avdtp_exit(struct btd_adapter *adapter)
> -{
> - struct avdtp_server *server;
> -
> - server = find_server(servers, adapter);
> - if (!server)
> - return;
> -
> - g_slist_free_full(server->sessions, avdtp_free);
> -
> - servers = g_slist_remove(servers, server);
> -
> - g_io_channel_shutdown(server->io, TRUE, NULL);
> - g_io_channel_unref(server->io);
> - btd_adapter_unref(server->adapter);
> - g_free(server);
> -}
> -
> gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
> {
> return g_slist_find(session->streams, stream) ? TRUE : FALSE;
> diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
> index 3bf7503..5606506 100644
> --- a/profiles/audio/avdtp.h
> +++ b/profiles/audio/avdtp.h
> @@ -308,6 +308,3 @@ struct btd_adapter *avdtp_get_adapter(struct avdtp *session);
> struct btd_device *avdtp_get_device(struct avdtp *session);
>
> void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc);
> -
> -int avdtp_init(struct btd_adapter *adapter);
> -void avdtp_exit(struct btd_adapter *adapter);
> --
> 1.8.3.1
There is apparently a bug in this one, well send a v2 shortly.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH 4/4] android/pan: Handle connection and control state notifications
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/hal-pan.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/android/hal-pan.c b/android/hal-pan.c
index 76f5159..4173925 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -31,10 +31,41 @@ static bool interface_ready(void)
return cbs != NULL;
}
+static void handle_conn_state(void *buf)
+{
+ struct hal_ev_pan_conn_state *ev = buf;
+
+ if (cbs->connection_state_cb)
+ cbs->connection_state_cb(ev->state, ev->status,
+ (bt_bdaddr_t *) ev->bdaddr,
+ ev->local_role, ev->remote_role);
+}
+
+static void handle_ctrl_state(void *buf)
+{
+ struct hal_ev_pan_ctrl_state *ev = buf;
+
+ if (cbs->control_state_cb)
+ cbs->control_state_cb(ev->state, ev->status,
+ ev->local_role, (char *)ev->name);
+}
+
void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len)
{
if (!interface_ready())
return;
+
+ switch (opcode) {
+ case HAL_EV_PAN_CONN_STATE:
+ handle_conn_state(buf);
+ break;
+ case HAL_EV_PAN_CTRL_STATE:
+ handle_ctrl_state(buf);
+ break;
+ default:
+ DBG("Unhandled callback opcode=0x%x", opcode);
+ break;
+ }
}
static bt_status_t pan_enable(int local_role)
--
1.8.3.2
^ permalink raw reply related
* [PATCH 3/4] android/pan: Add notify method to PAN notifications
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/hal-pan.c | 6 ++++++
android/hal.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/android/hal-pan.c b/android/hal-pan.c
index a560055..76f5159 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -31,6 +31,12 @@ static bool interface_ready(void)
return cbs != NULL;
}
+void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len)
+{
+ if (!interface_ready())
+ return;
+}
+
static bt_status_t pan_enable(int local_role)
{
struct hal_cmd_pan_enable cmd;
diff --git a/android/hal.h b/android/hal.h
index 2ce7932..be5d491 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -31,3 +31,4 @@ void bt_thread_associate(void);
void bt_thread_disassociate(void);
void bt_notify_hidhost(uint16_t opcode, void *buf, uint16_t len);
void bt_notify_a2dp(uint16_t opcode, void *buf, uint16_t len);
+void bt_notify_pan(uint16_t opcode, void *buf, uint16_t len);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/4] android/pan: Add PAN cleanup interface implementation
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/hal-pan.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/android/hal-pan.c b/android/hal-pan.c
index cacc6c0..a560055 100644
--- a/android/hal-pan.c
+++ b/android/hal-pan.c
@@ -114,16 +114,18 @@ static bt_status_t pan_init(const btpan_callbacks_t *callbacks)
static void pan_cleanup()
{
+ struct hal_cmd_register_module cmd;
+
DBG("");
if (!interface_ready())
return;
- /* TODO: disable service */
-
- /* TODO: stop PAN thread */
-
cbs = NULL;
+ cmd.service_id = HAL_SERVICE_ID_PAN;
+
+ hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_UNREGISTER_MODULE,
+ sizeof(cmd), &cmd, 0, NULL, NULL);
}
static btpan_interface_t pan_if = {
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/4] android/pan: Add PAN related defines and event struct to hsl-msg header
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1384181621-8070-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
android/hal-msg.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 569c8ea..00d6e39 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -317,6 +317,33 @@ struct hal_cmd_a2dp_disconnect {
/* PAN HAL API */
+/* PAN Roles */
+#define HAL_PAN_ROLE_NONE 0x00
+#define HAL_PAN_ROLE_NAP 0x01
+#define HAL_PAN_ROLE_PANU 0x02
+
+/* PAN Control states */
+#define HAL_PAN_CTRL_ENABLED 0x00
+#define HAL_PAN_CTRL_DISABLED 0x01
+
+/* PAN Connection states */
+#define HAL_PAN_STATE_CONNECTED 0x00
+#define HAL_PAN_STATE_CONNECTING 0x01
+#define HAL_PAN_STATE_DISCONNECTED 0x02
+#define HAL_PAN_STATE_DISCONNECTING 0x03
+
+/* PAN status values */
+#define HAL_PAN_STATUS_FAIL 0x01
+#define HAL_PAN_STATUS_NOT_READY 0x02
+#define HAL_PAN_STATUS_NO_MEMORY 0x03
+#define HAL_PAN_STATUS_BUSY 0x04
+#define HAL_PAN_STATUS_DONE 0x05
+#define HAL_PAN_STATUS_UNSUPORTED 0x06
+#define HAL_PAN_STATUS_INVAL 0x07
+#define HAL_PAN_STATUS_UNHANDLED 0x08
+#define HAL_PAN_STATUS_AUTH_FAILED 0x09
+#define HAL_PAN_STATUS_DEVICE_DOWN 0x0A
+
#define HAL_OP_PAN_ENABLE 0x01
struct hal_cmd_pan_enable {
uint8_t local_role;
@@ -486,6 +513,23 @@ struct hal_ev_hidhost_virtual_unplug {
uint8_t status;
} __attribute__((packed));
+#define HAL_EV_PAN_CONN_STATE 0x81
+struct hal_ev_pan_conn_state {
+ uint8_t state;
+ uint8_t status;
+ uint8_t bdaddr[6];
+ uint8_t local_role;
+ uint8_t remote_role;
+} __attribute__((packed));
+
+#define HAL_EV_PAN_CTRL_STATE 0x82
+struct hal_ev_pan_ctrl_state {
+ uint8_t state;
+ uint8_t status;
+ uint8_t local_role;
+ uint8_t name[17];
+} __attribute__((packed));
+
#define HAL_EV_A2DP_CONNECTION_STATE 0x81
struct hal_ev_a2dp_connection_state {
uint8_t state;
--
1.8.3.2
^ permalink raw reply related
* [PATCH 0/4] Implement missing PAN interface and notifications
From: Ravi kumar Veeramally @ 2013-11-11 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Patch set implements missing cleanup interface and adds event structs
to hal-msg.h and implements connection and control state notifications.
Ravi kumar Veeramally (4):
android/pan: Add PAN related defines and event struct to hsl-msg
header
android/pan: Add PAN cleanup interface implementation
android/pan: Add notify method to PAN notifications
android/pan: Handle connection and control state notifications
android/hal-msg.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
android/hal-pan.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
android/hal.h | 1 +
3 files changed, 88 insertions(+), 4 deletions(-)
--
1.8.3.2
^ permalink raw reply
* [PATCH BlueZ] audio/AVDTP: Remove avdtp_init and avdtp_exit
From: Luiz Augusto von Dentz @ 2013-11-11 14:11 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This is now done on demand by avdtp_register_sep and avdtp_unregister_sep
so the server socket is only registered when there is an endpoint
available and the record is properly registered.
---
profiles/audio/a2dp.c | 11 -----
profiles/audio/avdtp.c | 118 +++++++++++++++++++++++++------------------------
profiles/audio/avdtp.h | 3 --
3 files changed, 60 insertions(+), 72 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 8477b5d..6b3d6b2 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1187,17 +1187,8 @@ static struct a2dp_server *find_server(GSList *list, struct btd_adapter *a)
static struct a2dp_server *a2dp_server_register(struct btd_adapter *adapter)
{
struct a2dp_server *server;
- int av_err;
server = g_new0(struct a2dp_server, 1);
-
- av_err = avdtp_init(adapter);
- if (av_err < 0) {
- DBG("AVDTP not registered");
- g_free(server);
- return NULL;
- }
-
server->adapter = btd_adapter_ref(adapter);
servers = g_slist_append(servers, server);
@@ -1217,8 +1208,6 @@ static void a2dp_unregister_sep(struct a2dp_sep *sep)
static void a2dp_server_unregister(struct a2dp_server *server)
{
- avdtp_exit(server->adapter);
-
servers = g_slist_remove(servers, server);
btd_adapter_unref(server->adapter);
g_free(server);
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index dab8f1c..9a470f1 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -3683,6 +3683,45 @@ int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
&req, sizeof(req));
}
+static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
+{
+ GError *err = NULL;
+ GIOChannel *io;
+
+ io = bt_io_listen(NULL, avdtp_confirm_cb,
+ NULL, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_PSM, AVDTP_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_MASTER, master,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("%s", err->message);
+ g_error_free(err);
+ }
+
+ return io;
+}
+
+static struct avdtp_server *avdtp_server_init(struct btd_adapter *adapter)
+{
+ struct avdtp_server *server;
+
+ server = g_new0(struct avdtp_server, 1);
+
+ server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
+ if (!server->io) {
+ g_free(server);
+ return NULL;
+ }
+
+ server->adapter = btd_adapter_ref(adapter);
+
+ servers = g_slist_append(servers, server);
+
+ return 0;
+}
+
struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
uint8_t type,
uint8_t media_type,
@@ -3696,8 +3735,11 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
struct avdtp_local_sep *sep;
server = find_server(servers, adapter);
- if (!server)
- return NULL;
+ if (!server) {
+ server = avdtp_server_init(adapter);
+ if (!server)
+ return NULL;
+ }
if (g_slist_length(server->seps) > MAX_SEID)
return NULL;
@@ -3722,6 +3764,18 @@ struct avdtp_local_sep *avdtp_register_sep(struct btd_adapter *adapter,
return sep;
}
+static void avdtp_server_destroy(struct avdtp_server *server)
+{
+ g_slist_free_full(server->sessions, avdtp_free);
+
+ servers = g_slist_remove(servers, server);
+
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ g_io_channel_unref(server->io);
+ btd_adapter_unref(server->adapter);
+ g_free(server);
+}
+
int avdtp_unregister_sep(struct avdtp_local_sep *sep)
{
struct avdtp_server *server;
@@ -3740,27 +3794,12 @@ int avdtp_unregister_sep(struct avdtp_local_sep *sep)
g_free(sep);
- return 0;
-}
-
-static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)
-{
- GError *err = NULL;
- GIOChannel *io;
+ if (server->seps)
+ return 0;
- io = bt_io_listen(NULL, avdtp_confirm_cb,
- NULL, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR, src,
- BT_IO_OPT_PSM, AVDTP_PSM,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
- BT_IO_OPT_MASTER, master,
- BT_IO_OPT_INVALID);
- if (!io) {
- error("%s", err->message);
- g_error_free(err);
- }
+ avdtp_server_destroy(server);
- return io;
+ return 0;
}
const char *avdtp_strerror(struct avdtp_error *err)
@@ -3823,43 +3862,6 @@ struct btd_device *avdtp_get_device(struct avdtp *session)
return session->device;
}
-int avdtp_init(struct btd_adapter *adapter)
-{
- struct avdtp_server *server;
-
- server = g_new0(struct avdtp_server, 1);
-
- server->io = avdtp_server_socket(adapter_get_address(adapter), TRUE);
- if (!server->io) {
- g_free(server);
- return -1;
- }
-
- server->adapter = btd_adapter_ref(adapter);
-
- servers = g_slist_append(servers, server);
-
- return 0;
-}
-
-void avdtp_exit(struct btd_adapter *adapter)
-{
- struct avdtp_server *server;
-
- server = find_server(servers, adapter);
- if (!server)
- return;
-
- g_slist_free_full(server->sessions, avdtp_free);
-
- servers = g_slist_remove(servers, server);
-
- g_io_channel_shutdown(server->io, TRUE, NULL);
- g_io_channel_unref(server->io);
- btd_adapter_unref(server->adapter);
- g_free(server);
-}
-
gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
{
return g_slist_find(session->streams, stream) ? TRUE : FALSE;
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 3bf7503..5606506 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -308,6 +308,3 @@ struct btd_adapter *avdtp_get_adapter(struct avdtp *session);
struct btd_device *avdtp_get_device(struct avdtp *session);
void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc);
-
-int avdtp_init(struct btd_adapter *adapter);
-void avdtp_exit(struct btd_adapter *adapter);
--
1.8.3.1
^ permalink raw reply related
* [RFCv1 9/9] android/hal-sock: Write channel to Android fd
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/socket.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 20f4e38..0188646 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,6 +27,7 @@
#include <glib.h>
#include <stdbool.h>
+#include <unistd.h>
#include <errno.h>
#include "lib/bluetooth.h"
@@ -292,6 +293,10 @@ static int handle_listen(void *buf)
rfslot->real_sock = g_io_channel_unix_get_fd(io);
rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
+ /* TODO: Check this */
+ if (write(rfslot->fd, &ch, sizeof(ch)) < 0)
+ return -1;
+
DBG("real_sock %d fd %d hal_fd %d",
rfslot->real_sock, rfslot->fd, rfslot->hal_fd);
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 8/9] android/hal-sock: Implement accept signal over Android fd
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Android expects to get accept signal over file descriptor which was
set during listen HAL call.
---
android/socket.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index a962cdc..20f4e38 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -36,6 +36,7 @@
#include "hal-ipc.h"
#include "ipc.h"
#include "adapter.h"
+#include "utils.h"
#include "socket.h"
/* Simple list of RFCOMM server sockets */
@@ -68,6 +69,45 @@ static struct rfcomm_slot *create_rfslot(int sock)
return rfslot;
}
+static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
+{
+ ssize_t ret;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iv;
+ char msgbuf[CMSG_SPACE(1)];
+
+ DBG("len %d sock_fd %d send_fd %d", len, sock_fd, send_fd);
+
+ if (sock_fd == -1 || send_fd == -1)
+ return -1;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_control = msgbuf;
+ msg.msg_controllen = sizeof(msgbuf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
+ memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
+
+ iv.iov_base = (unsigned char *) buf;
+ iv.iov_len = len;
+
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+
+ ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+ if (ret < 0) {
+ error("sendmsg(): sock_fd %d send_fd %d: %s",
+ sock_fd, send_fd, strerror(errno));
+ return ret;
+ }
+
+ return ret;
+}
+
static const uint8_t UUID_PBAP[] = {
0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
@@ -161,6 +201,21 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
return TRUE;
}
+static void socket_send_accept(struct rfcomm_slot *rfslot, bdaddr_t *bdaddr,
+ int fd_accepted)
+{
+ struct hal_sock_connect_signal cmd;
+
+ DBG("");
+
+ cmd.size = sizeof(cmd);
+ bdaddr2android(bdaddr, cmd.bdaddr);
+ cmd.channel = rfslot->channel;
+ cmd.status = 0;
+
+ bt_sock_send_fd(rfslot->fd, &cmd, sizeof(cmd), fd_accepted);
+}
+
static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_slot *rfslot = user_data;
@@ -190,6 +245,8 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
rfslot_acc = create_rfslot(sock_acc);
rfcomm_accepted_list = g_list_append(rfcomm_accepted_list, rfslot_acc);
+ socket_send_accept(rfslot, &dst, rfslot_acc->hal_fd);
+
/* Handle events from Android */
io_stack = g_io_channel_unix_new(rfslot_acc->fd);
g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 7/9] android/hal-sock: Implement RFCOMM events
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Copy data from RFCOMM socket to Android framework.
---
android/socket.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index dfad9da..a962cdc 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -129,6 +129,35 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
+ struct rfcomm_slot *rfslot = data;
+ unsigned char buf[1024] = { 0 };
+ int len;
+
+ DBG("rfslot: fd %d hal_fd %d real_sock %d chan %u sock %d",
+ rfslot->fd, rfslot->hal_fd, rfslot->real_sock, rfslot->channel,
+ g_io_channel_unix_get_fd(io));
+
+ if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+ error("Socket error: sock %d cond %d",
+ g_io_channel_unix_get_fd(io), cond);
+ g_io_channel_shutdown(io, TRUE, NULL);
+ return FALSE;
+ }
+
+ /* FIXME check real_sock vs sock(io) */
+ len = recv(rfslot->real_sock, buf, sizeof(buf), 0);
+ if (len <= 0) {
+ error("recv(): %s sock %d", strerror(errno), rfslot->real_sock);
+ return FALSE;
+ }
+
+ DBG("read %d bytes, write to fd %d", len, rfslot->fd);
+
+ if (send(rfslot->fd, buf, len, MSG_DONTWAIT) < 0) {
+ error("send(): %s sock %d", strerror(errno), rfslot->fd);
+ return FALSE;
+ }
+
return TRUE;
}
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 6/9] android/hal-sock: Implement Android RFCOMM stack events
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Handle events from Android framework. Write everything to real RFCOMM
socket.
---
android/socket.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 0ee53ba..dfad9da 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -94,6 +94,35 @@ static int get_rfcomm_chan(const uint8_t *uuid)
static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
+ struct rfcomm_slot *rfslot = data;
+ unsigned char buf[1024] = { 0 };
+ int len;
+
+ DBG("rfslot: fd %d hal_fd %d real_sock %d chan %u sock %d",
+ rfslot->fd, rfslot->hal_fd, rfslot->real_sock, rfslot->channel,
+ g_io_channel_unix_get_fd(io));
+
+ if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+ error("Socket error: sock %d cond %d",
+ g_io_channel_unix_get_fd(io), cond);
+ g_io_channel_shutdown(io, TRUE, NULL);
+ return FALSE;
+ }
+
+ /* FIXME check fd vs sock(io) */
+ len = recv(rfslot->fd, buf, sizeof(buf), 0);
+ if (len <= 0) {
+ error("recv(): %s", strerror(errno));
+ return FALSE;
+ }
+
+ DBG("read %d bytes write to %d", len, rfslot->real_sock);
+
+ if (send(rfslot->real_sock, buf, len, 0) < 0) {
+ error("send(): %s", strerror(errno));
+ return FALSE;
+ }
+
return TRUE;
}
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 5/9] android/hal-sock: Implement socket accepted event
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
When we get accepted event we create rfcomm slot and start listening
for events from Android framework and from RFCOMM real socket.
---
android/socket.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 80cb39e..0ee53ba 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -91,8 +91,58 @@ static int get_rfcomm_chan(const uint8_t *uuid)
return -1;
}
+static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
+ gpointer data)
+{
+ return TRUE;
+}
+
+static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
+ gpointer data)
+{
+ return TRUE;
+}
+
static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
+ struct rfcomm_slot *rfslot = user_data;
+ struct rfcomm_slot *rfslot_acc;
+ GIOChannel *io_stack;
+ bdaddr_t dst;
+ char address[18];
+ int sock_acc;
+
+ bt_io_get(io, &err,
+ BT_IO_OPT_DEST_BDADDR, &dst,
+ BT_IO_OPT_INVALID);
+ if (err) {
+ error("%s", err->message);
+ g_io_channel_shutdown(io, TRUE, NULL);
+ return;
+ }
+
+ ba2str(&dst, address);
+ DBG("Incoming connection from %s rfslot %p", address, rfslot);
+
+ DBG("rfslot: fd %d hal_fd %d real_sock %d chan %u sock %d",
+ rfslot->fd, rfslot->hal_fd, rfslot->real_sock, rfslot->channel,
+ g_io_channel_unix_get_fd(io));
+
+ sock_acc = g_io_channel_unix_get_fd(io);
+ rfslot_acc = create_rfslot(sock_acc);
+ rfcomm_accepted_list = g_list_append(rfcomm_accepted_list, rfslot_acc);
+
+ /* Handle events from Android */
+ io_stack = g_io_channel_unix_new(rfslot_acc->fd);
+ g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ sock_stack_event_cb, rfslot_acc);
+ g_io_channel_unref(io_stack);
+
+ /* Handle rfcomm events */
+ g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ sock_rfcomm_event_cb, rfslot_acc);
+
+ DBG("rfslot %p rfslot_acc %p", rfslot, rfslot_acc);
}
static int handle_listen(void *buf)
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 4/9] android/hal-sock: Initial listen handle
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Handle HAL socket listen call. Create RFCOMM socket and wait for events.
---
android/socket.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 92 insertions(+), 2 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index c283c5f..80cb39e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,22 +27,112 @@
#include <glib.h>
#include <stdbool.h>
+#include <errno.h>
#include "lib/bluetooth.h"
+#include "btio/btio.h"
#include "log.h"
#include "hal-msg.h"
#include "hal-ipc.h"
#include "ipc.h"
+#include "adapter.h"
#include "socket.h"
+/* Simple list of RFCOMM server sockets */
+GList *rfcomm_srv_list = NULL;
+/* Simple list of RFCOMM accepted sockets */
+GList *rfcomm_accepted_list = NULL;
-static int handle_listen(void *buf)
+struct rfcomm_slot {
+ int fd;
+ int hal_fd;
+ int real_sock;
+ uint32_t channel;
+};
+
+static struct rfcomm_slot *create_rfslot(int sock)
{
- DBG("Not implemented");
+ int fds[2] = {-1, -1};
+ struct rfcomm_slot *rfslot;
+
+ if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
+ error("socketpair(): %s", strerror(errno));
+ return NULL;
+ }
+
+ rfslot = g_malloc0(sizeof(*rfslot));
+ rfslot->fd = fds[0];
+ rfslot->hal_fd = fds[1];
+ rfslot->real_sock = sock;
+
+ return rfslot;
+}
+
+static const uint8_t UUID_PBAP[] = {
+ 0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+};
+#define RFCOMM_CHAN_PBAP 19
+
+static const uint8_t UUID_OPP[] = {
+ 0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+};
+#define RFCOMM_CHAN_OPP 12
+
+static int get_rfcomm_chan(const uint8_t *uuid)
+{
+ if (!memcmp(UUID_PBAP, uuid, sizeof(UUID_PBAP)))
+ return RFCOMM_CHAN_PBAP;
+
+ if (!memcmp(UUID_OPP, uuid, sizeof(UUID_OPP)))
+ return RFCOMM_CHAN_OPP;
return -1;
}
+static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+{
+}
+
+static int handle_listen(void *buf)
+{
+ struct hal_cmd_sock_listen *cmd = buf;
+ const bdaddr_t *src = bt_adapter_get_address();
+ struct rfcomm_slot *rfslot;
+ GIOChannel *io;
+ GError *err = NULL;
+ int ch;
+
+ DBG("");
+
+ ch = get_rfcomm_chan(cmd->uuid);
+ if (ch < 0)
+ return -1;
+
+ DBG("rfcomm channel %u", ch);
+
+ rfslot = create_rfslot(-1);
+
+ io = bt_io_listen(connect_cb, NULL, rfslot, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_CHANNEL, ch,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("Failed listen: %s", err->message);
+ g_error_free(err);
+ return -1;
+ }
+
+ rfslot->real_sock = g_io_channel_unix_get_fd(io);
+ rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
+
+ DBG("real_sock %d fd %d hal_fd %d",
+ rfslot->real_sock, rfslot->fd, rfslot->hal_fd);
+
+ return rfslot->hal_fd;
+}
+
static int handle_connect(void *buf)
{
DBG("Not implemented");
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 3/9] android/ahl-sock: Add connect signal to socket
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Connect signal is used to pass information to framework that socket
is accepted.
---
android/hal-msg.h | 2 ++
android/socket.h | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 569c8ea..68cc8ed 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -232,6 +232,8 @@ struct hal_cmd_sock_connect {
uint8_t flags;
} __attribute__((packed));
+/* Bluetooth Hidhost HAL api */
+
#define HAL_OP_HIDHOST_CONNECT 0x01
struct hal_cmd_hidhost_connect {
uint8_t bdaddr[6];
diff --git a/android/socket.h b/android/socket.h
index 7aa5574..ba56c9b 100644
--- a/android/socket.h
+++ b/android/socket.h
@@ -21,6 +21,13 @@
*
*/
+struct hal_sock_connect_signal {
+ short size;
+ uint8_t bdaddr[6];
+ int channel;
+ int status;
+} __attribute__((packed));
+
void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len);
bool bt_socket_register(int sk, const bdaddr_t *addr);
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 2/9] android: Avoid unneeded includes
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Declare struct mgmt in adapter.h. This avoids including mgmt.h in
every file using adapter functions like socket and hid.
---
android/adapter.h | 2 ++
android/hidhost.c | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/android/adapter.h b/android/adapter.h
index c62b859..3bda9d9 100644
--- a/android/adapter.h
+++ b/android/adapter.h
@@ -23,6 +23,8 @@
typedef void (*bt_adapter_ready)(int err);
+struct mgmt;
+
void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
bt_adapter_ready cb);
diff --git a/android/hidhost.c b/android/hidhost.c
index 683938f..8c3e9f6 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -38,7 +38,6 @@
#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/glib-helper.h"
#include "profiles/input/uhid_copy.h"
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 1/9] android/hal-sock: Add debug flag printing
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384178627-25991-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/hal-sock.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/android/hal-sock.c b/android/hal-sock.c
index b7bc88e..eafa451 100644
--- a/android/hal-sock.c
+++ b/android/hal-sock.c
@@ -55,8 +55,8 @@ static bt_status_t sock_listen(btsock_type_t type, const char *service_name,
return BT_STATUS_PARM_INVALID;
}
- DBG("uuid %s chan %d sock %p type %d service_name %s",
- btuuid2str(uuid), chan, sock, type, service_name);
+ DBG("uuid %s chan %d sock %p type %d service_name %s flags 0x%02x",
+ btuuid2str(uuid), chan, sock, type, service_name, flags);
switch (type) {
case BTSOCK_RFCOMM:
@@ -82,8 +82,8 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
return BT_STATUS_PARM_INVALID;
}
- DBG("uuid %s chan %d sock %p type %d", btuuid2str(uuid), chan, sock,
- type);
+ DBG("uuid %s chan %d sock %p type %d flags 0x%02x",
+ btuuid2str(uuid), chan, sock, type, flags);
if (type != BTSOCK_RFCOMM) {
error("Socket type %u not supported", type);
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 0/9] Socket HAL
From: Andrei Emeltchenko @ 2013-11-11 14:03 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This is initial code implementing socket HAL. Receiving files
through OPP currently working somehow.
For tracking rfcomm sockets I use structure rfslot which has following
fields:
- real_sock - real RFCOMM socket
- fd - fd to communicate with Android framework
- hal_fd - fd passed to Android framework with CMSG
Andrei Emeltchenko (9):
android/hal-sock: Add debug flag printing
android: Avoid unneeded includes
android/ahl-sock: Add connect signal to socket
android/hal-sock: Initial listen handle
android/hal-sock: Implement socket accepted event
android/hal-sock: Implement Android RFCOMM stack events
android/hal-sock: Implement RFCOMM events
android/hal-sock: Implement accept signal over Android fd
android/hal-sock: Write channel to Android fd
android/adapter.h | 2 +
android/hal-msg.h | 2 +
android/hal-sock.c | 8 +-
android/hidhost.c | 1 -
android/socket.c | 264 +++++++++++++++++++++++++++++++++++++++++++++++++++-
android/socket.h | 7 ++
6 files changed, 277 insertions(+), 7 deletions(-)
--
1.7.10.4
^ permalink raw reply
* Re: [RFCv1 2/9] android: Avoid unneeded includes
From: Szymon Janc @ 2013-11-11 13:31 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Andrei Emeltchenko, linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZJMGQHVog9cPDqqLfe7ocdBy4UTrW+T9a6SjWWE=qd6=w@mail.gmail.com>
Hi Luiz,
On Monday 11 November 2013 15:20:21 Luiz Augusto von Dentz wrote:
> Hi Andrei,
>
> On Mon, Nov 11, 2013 at 2:37 PM, Andrei Emeltchenko
>
> <Andrei.Emeltchenko.news@gmail.com> wrote:
> > From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> >
> > Declare struct mgmt in adapter.h. This avoids including mgmt.h in
> > every file using adapter functions like socket and hid.
> > ---
> >
> > android/adapter.h | 2 ++
> > android/hidhost.c | 1 -
> > 2 files changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/android/adapter.h b/android/adapter.h
> > index c62b859..3bda9d9 100644
> > --- a/android/adapter.h
> > +++ b/android/adapter.h
> > @@ -23,6 +23,8 @@
> >
> > typedef void (*bt_adapter_ready)(int err);
> >
> > +struct mgmt;
> > +
> >
> > void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
> >
> > bt_adapter_ready
> > cb);
> >
> > diff --git a/android/hidhost.c b/android/hidhost.c
> > index 683938f..8c3e9f6 100644
> > --- a/android/hidhost.c
> > +++ b/android/hidhost.c
> > @@ -38,7 +38,6 @@
> >
> > #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/glib-helper.h"
> > #include "profiles/input/uhid_copy.h"
> >
> > --
> > 1.7.10.4
>
> Well it looks like we need to find a proper place for the mgmt
> interaction, or then perhaps pass the fd and use mgmt_new on adapter
> but that seems to require some work as it does create a different mgmt
> objects with different queues which I don't think is safe to use.
I've some patches that try to address this issue. Should be able to send them
soon.
--
Szymon K. Janc
szymon.janc@gmail.com
^ permalink raw reply
* Re: [RFCv1 2/9] android: Avoid unneeded includes
From: Luiz Augusto von Dentz @ 2013-11-11 13:20 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1384173438-21708-3-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Mon, Nov 11, 2013 at 2:37 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Declare struct mgmt in adapter.h. This avoids including mgmt.h in
> every file using adapter functions like socket and hid.
> ---
> android/adapter.h | 2 ++
> android/hidhost.c | 1 -
> 2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/android/adapter.h b/android/adapter.h
> index c62b859..3bda9d9 100644
> --- a/android/adapter.h
> +++ b/android/adapter.h
> @@ -23,6 +23,8 @@
>
> typedef void (*bt_adapter_ready)(int err);
>
> +struct mgmt;
> +
> void bt_adapter_init(uint16_t index, struct mgmt *mgmt_if,
> bt_adapter_ready cb);
>
> diff --git a/android/hidhost.c b/android/hidhost.c
> index 683938f..8c3e9f6 100644
> --- a/android/hidhost.c
> +++ b/android/hidhost.c
> @@ -38,7 +38,6 @@
> #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/glib-helper.h"
> #include "profiles/input/uhid_copy.h"
> --
> 1.7.10.4
Well it looks like we need to find a proper place for the mgmt
interaction, or then perhaps pass the fd and use mgmt_new on adapter
but that seems to require some work as it does create a different mgmt
objects with different queues which I don't think is safe to use.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 3/3] obex: Use XDG_RUNTIME_DIR as a default root
From: Luiz Augusto von Dentz @ 2013-11-11 13:01 UTC (permalink / raw)
To: Bastien Nocera; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1384173342.1898.8.camel@nuvo>
Hi Bastien,
On Mon, Nov 11, 2013 at 2:35 PM, Bastien Nocera <hadess@hadess.net> wrote:
> On Mon, 2013-11-11 at 11:00 +0200, Luiz Augusto von Dentz wrote:
>> Hi Bastien,
>>
>> On Sun, Nov 10, 2013 at 3:46 PM, Bastien Nocera <hadess@hadess.net> wrote:
>> > On Sat, 2013-11-09 at 18:03 +0100, Bastien Nocera wrote:
>> >> It's per-user, so we won't try to overwrite somebody else's
>> >> files in /tmp when that happens.
>> >
>> > There might be another useful directory instead. We could use
>> > g_get_user_cache_dir() instead of the run-time dir. This would save
>> > cross-partition moves by default, making the move to the Downloads dir
>> > atomic (a single rename, which can fail, iterate until we find a "free"
>> > filename).
>> >
>> > Is that better for you?
>>
>> Yep, it sounds better. Regarding renaming that is up the agent, if you
>> really want to do that its probably fine but Im still not convinced
>> this is absolutely necessary if obexd is running with the same user as
>> the agent can just create the file while authorizing so you wouldn't
>> need to move after completed, but again this is completely up to the
>> agent to decide where the files should go.
>
> You seem to think that all the application/services running under one
> user would have the same rights. That's currently the case, but won't be
> in the future.
Interesting that would cause some problems for sure...
>> Btw, what about fd passing? In theory we can create a different
>> version of the agent interface to enable passing fd directly, and in
>> fact we were thinking about this already as for some services you
>> wanted them to be dynamic so we were thinking on having this set by
>> the agent when it registers.
>
> I'm fine with a file descriptor as well, but obex push server is
> currently broken in GNOME 3.10. I'm happy doing the changes in GNOME
> 3.12 (due in 6 months).
>
> Can we get the cache dir change in, and make the API change later on?
Yep, lets use the cache dir and then think about the API change.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [RFCv1 9/9] android/hal-sock: Write channel to Android fd
From: Andrei Emeltchenko @ 2013-11-11 12:37 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384173438-21708-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/socket.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 20f4e38..0188646 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,6 +27,7 @@
#include <glib.h>
#include <stdbool.h>
+#include <unistd.h>
#include <errno.h>
#include "lib/bluetooth.h"
@@ -292,6 +293,10 @@ static int handle_listen(void *buf)
rfslot->real_sock = g_io_channel_unix_get_fd(io);
rfcomm_srv_list = g_list_append(rfcomm_srv_list, rfslot);
+ /* TODO: Check this */
+ if (write(rfslot->fd, &ch, sizeof(ch)) < 0)
+ return -1;
+
DBG("real_sock %d fd %d hal_fd %d",
rfslot->real_sock, rfslot->fd, rfslot->hal_fd);
--
1.7.10.4
^ permalink raw reply related
* [RFCv1 8/9] android/hal-sock: Implement accept signal over Android fd
From: Andrei Emeltchenko @ 2013-11-11 12:37 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384173438-21708-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Android expects to get accept signal over file descriptor which was
set during listen HAL call.
---
android/socket.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index a962cdc..20f4e38 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -36,6 +36,7 @@
#include "hal-ipc.h"
#include "ipc.h"
#include "adapter.h"
+#include "utils.h"
#include "socket.h"
/* Simple list of RFCOMM server sockets */
@@ -68,6 +69,45 @@ static struct rfcomm_slot *create_rfslot(int sock)
return rfslot;
}
+static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd)
+{
+ ssize_t ret;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iv;
+ char msgbuf[CMSG_SPACE(1)];
+
+ DBG("len %d sock_fd %d send_fd %d", len, sock_fd, send_fd);
+
+ if (sock_fd == -1 || send_fd == -1)
+ return -1;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_control = msgbuf;
+ msg.msg_controllen = sizeof(msgbuf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
+ memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
+
+ iv.iov_base = (unsigned char *) buf;
+ iv.iov_len = len;
+
+ msg.msg_iov = &iv;
+ msg.msg_iovlen = 1;
+
+ ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+ if (ret < 0) {
+ error("sendmsg(): sock_fd %d send_fd %d: %s",
+ sock_fd, send_fd, strerror(errno));
+ return ret;
+ }
+
+ return ret;
+}
+
static const uint8_t UUID_PBAP[] = {
0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
@@ -161,6 +201,21 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
return TRUE;
}
+static void socket_send_accept(struct rfcomm_slot *rfslot, bdaddr_t *bdaddr,
+ int fd_accepted)
+{
+ struct hal_sock_connect_signal cmd;
+
+ DBG("");
+
+ cmd.size = sizeof(cmd);
+ bdaddr2android(bdaddr, cmd.bdaddr);
+ cmd.channel = rfslot->channel;
+ cmd.status = 0;
+
+ bt_sock_send_fd(rfslot->fd, &cmd, sizeof(cmd), fd_accepted);
+}
+
static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_slot *rfslot = user_data;
@@ -190,6 +245,8 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
rfslot_acc = create_rfslot(sock_acc);
rfcomm_accepted_list = g_list_append(rfcomm_accepted_list, rfslot_acc);
+ socket_send_accept(rfslot, &dst, rfslot_acc->hal_fd);
+
/* Handle events from Android */
io_stack = g_io_channel_unix_new(rfslot_acc->fd);
g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
--
1.7.10.4
^ 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