* [PATCH] android: Improve IPC helper to not send invalid status response
From: Szymon Janc @ 2013-11-18 10:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This fix issue with sending invalid success response from several
places where ipc_send_rsp was used for reporting success. Instead of
using using ipc_send for success response, make helper handle that.
---
android/a2dp.c | 2 +-
android/bluetooth.c | 2 +-
android/hidhost.c | 2 +-
android/ipc.c | 7 ++++++-
android/ipc.h | 2 +-
android/main.c | 12 ++++++++----
android/pan.c | 2 +-
android/socket.c | 2 +-
8 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/android/a2dp.c b/android/a2dp.c
index 936c28e..bb55e41 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -226,7 +226,7 @@ void bt_a2dp_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_A2DP, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_A2DP, opcode, status);
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 5c5c61e..7dc2ec3 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2268,7 +2268,7 @@ void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
error:
error("Error handling command 0x%02x status %u", opcode, status);
- ipc_send_rsp(sk, HAL_SERVICE_ID_BLUETOOTH, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_BLUETOOTH, opcode, status);
}
bool bt_bluetooth_register(int sk)
diff --git a/android/hidhost.c b/android/hidhost.c
index f5a607c..842b8ad 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -1109,7 +1109,7 @@ void bt_hid_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_HIDHOST, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_HIDHOST, opcode, status);
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
diff --git a/android/ipc.c b/android/ipc.c
index 729f157..34441d0 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -80,10 +80,15 @@ void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
}
}
-void ipc_send_rsp(int sk, uint8_t service_id, uint8_t status)
+void ipc_send_rsp(int sk, uint8_t service_id, uint8_t opcode, uint8_t status)
{
struct hal_status s;
+ if (status == HAL_STATUS_SUCCESS) {
+ ipc_send(sk, HAL_SERVICE_ID_BLUETOOTH, opcode, 0, NULL, -1);
+ return;
+ }
+
s.code = status;
ipc_send(sk, service_id, HAL_OP_STATUS, sizeof(s), &s, -1);
diff --git a/android/ipc.h b/android/ipc.h
index cf0f3d6..ad4a2d2 100644
--- a/android/ipc.h
+++ b/android/ipc.h
@@ -23,4 +23,4 @@
void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
void *param, int fd);
-void ipc_send_rsp(int sk, uint8_t service_id, uint8_t status);
+void ipc_send_rsp(int sk, uint8_t service_id, uint8_t opcode, uint8_t status);
diff --git a/android/main.c b/android/main.c
index a4f5e84..c9733f3 100644
--- a/android/main.c
+++ b/android/main.c
@@ -122,7 +122,8 @@ static void service_register(void *buf, uint16_t len)
return;
failed:
ipc_send_rsp(g_io_channel_unix_get_fd(hal_cmd_io),
- HAL_SERVICE_ID_CORE, HAL_STATUS_FAILED);
+ HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
+ HAL_STATUS_FAILED);
}
static void service_unregister(void *buf, uint16_t len)
@@ -164,7 +165,8 @@ static void service_unregister(void *buf, uint16_t len)
return;
failed:
ipc_send_rsp(g_io_channel_unix_get_fd(hal_cmd_io),
- HAL_SERVICE_ID_CORE, HAL_STATUS_FAILED);
+ HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
+ HAL_STATUS_FAILED);
}
static void handle_service_core(uint8_t opcode, void *buf, uint16_t len)
@@ -178,7 +180,8 @@ static void handle_service_core(uint8_t opcode, void *buf, uint16_t len)
break;
default:
ipc_send_rsp(g_io_channel_unix_get_fd(hal_cmd_io),
- HAL_SERVICE_ID_CORE, HAL_STATUS_FAILED);
+ HAL_SERVICE_ID_CORE, opcode,
+ HAL_STATUS_FAILED);
break;
}
}
@@ -274,7 +277,8 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
bt_pan_handle_cmd(fd, msg->opcode, msg->payload, msg->len);
break;
default:
- ipc_send_rsp(fd, msg->service_id, HAL_STATUS_FAILED);
+ ipc_send_rsp(fd, msg->service_id, msg->opcode,
+ HAL_STATUS_FAILED);
break;
}
diff --git a/android/pan.c b/android/pan.c
index 46b3700..2a11f46 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -87,7 +87,7 @@ void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_PAN, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_PAN, opcode, status);
}
bool bt_pan_register(int sk, const bdaddr_t *addr)
diff --git a/android/socket.c b/android/socket.c
index e580036..04bb7d1 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -75,7 +75,7 @@ void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_SOCK, HAL_STATUS_FAILED);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_SOCK, opcode, HAL_STATUS_FAILED);
}
bool bt_socket_register(int sk, const bdaddr_t *addr)
--
1.8.4.2
^ permalink raw reply related
* [PATCH] android/a2dp: Use NULL for zero pointer
From: Andrei Emeltchenko @ 2013-11-18 10:49 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/a2dp.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/android/a2dp.c b/android/a2dp.c
index 936c28e..4725e9e 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -280,31 +280,31 @@ static sdp_record_t *a2dp_record(void)
return NULL;
sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
- root = sdp_list_append(0, &root_uuid);
+ root = sdp_list_append(NULL, &root_uuid);
sdp_set_browse_groups(record, root);
sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
- svclass_id = sdp_list_append(0, &a2dp_uuid);
+ svclass_id = sdp_list_append(NULL, &a2dp_uuid);
sdp_set_service_classes(record, svclass_id);
sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
profile[0].version = a2dp_ver;
- pfseq = sdp_list_append(0, &profile[0]);
+ pfseq = sdp_list_append(NULL, &profile[0]);
sdp_set_profile_descs(record, pfseq);
sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
- proto[0] = sdp_list_append(0, &l2cap_uuid);
+ proto[0] = sdp_list_append(NULL, &l2cap_uuid);
psm = sdp_data_alloc(SDP_UINT16, &lp);
proto[0] = sdp_list_append(proto[0], psm);
- apseq = sdp_list_append(0, proto[0]);
+ apseq = sdp_list_append(NULL, proto[0]);
sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
- proto[1] = sdp_list_append(0, &avdtp_uuid);
+ proto[1] = sdp_list_append(NULL, &avdtp_uuid);
version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
proto[1] = sdp_list_append(proto[1], version);
apseq = sdp_list_append(apseq, proto[1]);
- aproto = sdp_list_append(0, apseq);
+ aproto = sdp_list_append(NULL, apseq);
sdp_set_access_protos(record, aproto);
features = sdp_data_alloc(SDP_UINT16, &feat);
@@ -314,13 +314,13 @@ static sdp_record_t *a2dp_record(void)
free(psm);
free(version);
- sdp_list_free(proto[0], 0);
- sdp_list_free(proto[1], 0);
- sdp_list_free(apseq, 0);
- sdp_list_free(pfseq, 0);
- sdp_list_free(aproto, 0);
- sdp_list_free(root, 0);
- sdp_list_free(svclass_id, 0);
+ sdp_list_free(proto[0], NULL);
+ sdp_list_free(proto[1], 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);
return record;
}
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH] android/a2dp: Use NULL for zero pointer
From: Johan Hedberg @ 2013-11-18 11:05 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1384771775-18659-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Mon, Nov 18, 2013, Andrei Emeltchenko wrote:
> ---
> android/a2dp.c | 28 ++++++++++++++--------------
> 1 file changed, 14 insertions(+), 14 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ 1/5] audio/AVDTP: Remove unused code
From: Luiz Augusto von Dentz @ 2013-11-18 11:50 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
profiles/audio/avdtp.c | 20 --------------------
profiles/audio/avdtp.h | 8 --------
2 files changed, 28 deletions(-)
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 9378350..25b7525 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -3283,31 +3283,11 @@ struct avdtp_remote_sep *avdtp_get_remote_sep(struct avdtp *session,
return NULL;
}
-uint8_t avdtp_get_seid(struct avdtp_remote_sep *sep)
-{
- return sep->seid;
-}
-
-uint8_t avdtp_get_type(struct avdtp_remote_sep *sep)
-{
- return sep->type;
-}
-
struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep)
{
return sep->codec;
}
-gboolean avdtp_get_delay_reporting(struct avdtp_remote_sep *sep)
-{
- return sep->delay_reporting;
-}
-
-struct avdtp_stream *avdtp_get_stream(struct avdtp_remote_sep *sep)
-{
- return sep->stream;
-}
-
struct avdtp_service_capability *avdtp_service_cap_new(uint8_t category,
void *data, int length)
{
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 5606506..30ade86 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -224,16 +224,8 @@ struct avdtp_service_capability *avdtp_service_cap_new(uint8_t category,
struct avdtp_remote_sep *avdtp_get_remote_sep(struct avdtp *session,
uint8_t seid);
-uint8_t avdtp_get_seid(struct avdtp_remote_sep *sep);
-
-uint8_t avdtp_get_type(struct avdtp_remote_sep *sep);
-
struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep);
-gboolean avdtp_get_delay_reporting(struct avdtp_remote_sep *sep);
-
-struct avdtp_stream *avdtp_get_stream(struct avdtp_remote_sep *sep);
-
int avdtp_discover(struct avdtp *session, avdtp_discover_cb_t cb,
void *user_data);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 2/5] audio/AVDTP: Remove public function that are only used locally
From: Luiz Augusto von Dentz @ 2013-11-18 11:50 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384775415-10159-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
profiles/audio/avdtp.c | 30 ++++++++++++------------------
profiles/audio/avdtp.h | 5 -----
2 files changed, 12 insertions(+), 23 deletions(-)
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 25b7525..de31e12 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -3183,8 +3183,8 @@ struct avdtp_service_capability *avdtp_stream_get_codec(
return NULL;
}
-gboolean avdtp_stream_has_capability(struct avdtp_stream *stream,
- struct avdtp_service_capability *cap)
+static gboolean avdtp_stream_has_capability(struct avdtp_stream *stream,
+ struct avdtp_service_capability *cap)
{
GSList *l;
struct avdtp_service_capability *stream_cap;
@@ -3219,7 +3219,16 @@ gboolean avdtp_stream_has_capabilities(struct avdtp_stream *stream,
struct avdtp_remote_sep *avdtp_stream_get_remote_sep(
struct avdtp_stream *stream)
{
- return avdtp_get_remote_sep(stream->session, stream->rseid);
+ GSList *l;
+
+ for (l = stream->session->seps; l; l = l->next) {
+ struct avdtp_remote_sep *sep = l->data;
+
+ if (sep->seid == stream->rseid)
+ return sep;
+ }
+
+ return NULL;
}
gboolean avdtp_stream_get_transport(struct avdtp_stream *stream, int *sock,
@@ -3268,21 +3277,6 @@ static int process_queue(struct avdtp *session)
return send_req(session, FALSE, req);
}
-struct avdtp_remote_sep *avdtp_get_remote_sep(struct avdtp *session,
- uint8_t seid)
-{
- GSList *l;
-
- for (l = session->seps; l; l = l->next) {
- struct avdtp_remote_sep *sep = l->data;
-
- if (sep->seid == seid)
- return sep;
- }
-
- return NULL;
-}
-
struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep)
{
return sep->codec;
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 30ade86..3c30d78 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -221,9 +221,6 @@ struct avdtp *avdtp_ref(struct avdtp *session);
struct avdtp_service_capability *avdtp_service_cap_new(uint8_t category,
void *data, int size);
-struct avdtp_remote_sep *avdtp_get_remote_sep(struct avdtp *session,
- uint8_t seid);
-
struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep);
int avdtp_discover(struct avdtp *session, avdtp_discover_cb_t cb,
@@ -243,8 +240,6 @@ gboolean avdtp_stream_get_transport(struct avdtp_stream *stream, int *sock,
GSList **caps);
struct avdtp_service_capability *avdtp_stream_get_codec(
struct avdtp_stream *stream);
-gboolean avdtp_stream_has_capability(struct avdtp_stream *stream,
- struct avdtp_service_capability *cap);
gboolean avdtp_stream_has_capabilities(struct avdtp_stream *stream,
GSList *caps);
struct avdtp_remote_sep *avdtp_stream_get_remote_sep(
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 3/5] audio/source: Remove shutdown parameter from source_disconnect
From: Luiz Augusto von Dentz @ 2013-11-18 11:50 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384775415-10159-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This parameter is always false so it never do anything.
---
profiles/audio/a2dp.c | 2 +-
profiles/audio/source.c | 5 +----
profiles/audio/source.h | 2 +-
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 864cb18..95ffa12 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1887,7 +1887,7 @@ static int a2dp_source_disconnect(struct btd_service *service)
DBG("path %s", path);
- return source_disconnect(service, FALSE);
+ return source_disconnect(service);
}
static int a2dp_sink_connect(struct btd_service *service)
diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 24a4353..7b129b7 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -380,16 +380,13 @@ gboolean source_new_stream(struct btd_service *service, struct avdtp *session,
return TRUE;
}
-int source_disconnect(struct btd_service *service, gboolean shutdown)
+int source_disconnect(struct btd_service *service)
{
struct source *source = btd_service_get_user_data(service);
if (!source->session)
return -ENOTCONN;
- if (shutdown)
- avdtp_set_device_disconnect(source->session, TRUE);
-
/* cancel pending connect */
if (source->connect_id > 0) {
a2dp_cancel(source->connect_id);
diff --git a/profiles/audio/source.h b/profiles/audio/source.h
index c16fb4b..a014c68 100644
--- a/profiles/audio/source.h
+++ b/profiles/audio/source.h
@@ -48,4 +48,4 @@ gboolean source_new_stream(struct btd_service *service, struct avdtp *session,
struct avdtp_stream *stream);
gboolean source_setup_stream(struct btd_service *service,
struct avdtp *session);
-int source_disconnect(struct btd_service *service, gboolean shutdown);
+int source_disconnect(struct btd_service *service);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 4/5] audio/sink: Remove shutdown parameter from sink_disconnect
From: Luiz Augusto von Dentz @ 2013-11-18 11:50 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384775415-10159-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This parameter is always false so it never do anything.
---
profiles/audio/a2dp.c | 2 +-
profiles/audio/sink.c | 5 +----
profiles/audio/sink.h | 2 +-
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 95ffa12..29a1593 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1919,7 +1919,7 @@ static int a2dp_sink_disconnect(struct btd_service *service)
DBG("path %s", path);
- return sink_disconnect(service, FALSE);
+ return sink_disconnect(service);
}
static int a2dp_source_server_probe(struct btd_profile *p,
diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index 400af06..4f39622 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -388,16 +388,13 @@ gboolean sink_new_stream(struct btd_service *service, struct avdtp *session,
return TRUE;
}
-int sink_disconnect(struct btd_service *service, gboolean shutdown)
+int sink_disconnect(struct btd_service *service)
{
struct sink *sink = btd_service_get_user_data(service);
if (!sink->session)
return -ENOTCONN;
- if (shutdown)
- avdtp_set_device_disconnect(sink->session, TRUE);
-
/* cancel pending connect */
if (sink->connect_id > 0) {
a2dp_cancel(sink->connect_id);
diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
index 904a33d..93c62a2 100644
--- a/profiles/audio/sink.h
+++ b/profiles/audio/sink.h
@@ -47,4 +47,4 @@ int sink_connect(struct btd_service *service);
gboolean sink_new_stream(struct btd_service *service, struct avdtp *session,
struct avdtp_stream *stream);
gboolean sink_setup_stream(struct btd_service *service, struct avdtp *session);
-int sink_disconnect(struct btd_service *service, gboolean shutdown);
+int sink_disconnect(struct btd_service *service);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 5/5] audio/AVDTP: Remove unused avdtp_set_device_disconnect
From: Luiz Augusto von Dentz @ 2013-11-18 11:50 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384775415-10159-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
profiles/audio/avdtp.c | 13 -------------
profiles/audio/avdtp.h | 2 --
2 files changed, 15 deletions(-)
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index de31e12..b7a7d9c 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -394,9 +394,6 @@ struct avdtp {
avdtp_session_state_t state;
- /* True if the entire device is being disconnected */
- gboolean device_disconnect;
-
guint auth_id;
GIOChannel *io;
@@ -1200,11 +1197,6 @@ static void set_disconnect_timer(struct avdtp *session)
if (session->dc_timer)
remove_disconnect_timer(session);
- if (session->device_disconnect) {
- session->dc_timer = g_idle_add(disconnect_timeout, session);
- return;
- }
-
session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
disconnect_timeout,
session);
@@ -3841,11 +3833,6 @@ gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
return g_slist_find(session->streams, stream) ? TRUE : FALSE;
}
-void avdtp_set_device_disconnect(struct avdtp *session, gboolean dev_dc)
-{
- session->device_disconnect = dev_dc;
-}
-
unsigned int avdtp_add_state_cb(struct btd_device *dev,
avdtp_session_state_cb cb, void *user_data)
{
diff --git a/profiles/audio/avdtp.h b/profiles/audio/avdtp.h
index 3c30d78..390c154 100644
--- a/profiles/audio/avdtp.h
+++ b/profiles/audio/avdtp.h
@@ -293,5 +293,3 @@ int avdtp_error_posix_errno(struct avdtp_error *err);
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);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH BlueZ 1/5] audio/AVDTP: Remove unused code
From: Johan Hedberg @ 2013-11-18 12:11 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1384775415-10159-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Mon, Nov 18, 2013, Luiz Augusto von Dentz wrote:
> ---
> profiles/audio/avdtp.c | 20 --------------------
> profiles/audio/avdtp.h | 8 --------
> 2 files changed, 28 deletions(-)
All five patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: BUG: unable to handle kernel paging request at 00000015832a8e23 RIP [<ffffffff81a57c30>] rfcomm_sock_getsockopt+0x140/0x240
From: Sander Eikelenboom @ 2013-11-18 12:32 UTC (permalink / raw)
To: Marcel Holtmann
Cc: Gustavo F. Padovan, linux-bluetooth@vger.kernel.org development
In-Reply-To: <344AB0A2-9E39-4294-A119-887D2FAA2036@holtmann.org>
=0D=0ASunday, November 17, 2013, 11:57:40 PM, you wrote:
> Hi Sander,
>> This 3.13 merge window seems to have introduced the following bluetooth =
regression for me:
>>=20
>> [ 62.040810] BUG: unable to handle kernel paging request at 0000001583=
2a8e23
>> [ 62.049196] IP: [<ffffffff81a57c30>] rfcomm_sock_getsockopt+0x140/0x2=
40
>> [ 62.057800] PGD 0=20
>> [ 62.064574] Oops: 0000 [#1] PREEMPT SMP=20
>> [ 62.070653] Modules linked in:
>> [ 62.076596] CPU: 4 PID: 5575 Comm: bluetoothd Not tainted 3.12.0-mw-2=
0131117+ #1
>> [ 62.082708] Hardware name: MSI MS-7640/890FXA-GD70 (MS-7640) , BIOS =
V1.8B1 09/13/2010
>> [ 62.088827] task: ffff88005863a180 ti: ffff880057688000 task.ti: ffff=
880057688000
>> [ 62.095020] RIP: e030:[<ffffffff81a57c30>] [<ffffffff81a57c30>] rfco=
mm_sock_getsockopt+0x140/0x240
>> [ 62.101372] RSP: e02b:ffff880057689ec8 EFLAGS: 00010246
>> [ 62.107668] RAX: 00000015832a8e23 RBX: 0000000000000003 RCX: 00007fff=
610ca0e8
>> [ 62.113957] RDX: 0000000000000003 RSI: 0000000000000012 RDI: ffff8800=
572a9e00
>> [ 62.120174] RBP: ffff880057689f18 R08: 00007fff610ca0ec R09: 00007fff=
610ca360
>> [ 62.126481] R10: 00007fff610ca0e8 R11: 0000000000000202 R12: ffff8800=
569c3000
>> [ 62.132872] R13: 00007fff610ca0e8 R14: 0000000000000000 R15: 00007fff=
610ca0ec
>> [ 62.139187] FS: 00007f0d0b348720(0000) GS:ffff88005f700000(0000) knl=
GS:0000000000000000
>> [ 62.145551] CS: e033 DS: 0000 ES: 0000 CR0: 000000008005003b
>> [ 62.151919] CR2: 00000015832a8e23 CR3: 0000000056f53000 CR4: 00000000=
00000660
>> [ 62.158338] Stack:
>> [ 62.164798] ffff880057689f18 ffffffff81a5799f 0015832a8e23001f ffff8=
80057689f40
>> [ 62.171410] ffff880057689f44 ffff8800572a9e00 0000000000000012 00000=
00000000003
>> [ 62.178096] 0000000000000000 00007fff610ca0e8 ffff880057689f78 fffff=
fff81905bc2
>> [ 62.184781] Call Trace:
>> [ 62.191344] [<ffffffff81a5799f>] ? rfcomm_sock_setsockopt+0x5f/0x1b0
>> [ 62.197978] [<ffffffff81905bc2>] SyS_getsockopt+0x62/0xb0
>> [ 62.204645] [<ffffffff81a8aa79>] system_call_fastpath+0x16/0x1b
>> [ 62.211366] Code: 84 24 40 04 00 00 4c 89 e9 83 e0 01 e8 ea 0a 9d ff =
85 c0 75 b5 45 31 f6 e9 42 ff ff ff 66 0f 1f 44 00 00 49 8b 84 24 50 04 00 =
00 <48> 8b 00 48 89 45 b8 e8 04 e7 6f ff 4c 89 f8 e8 2c fa 9c ff 85=20
>> [ 62.225815] RIP [<ffffffff81a57c30>] rfcomm_sock_getsockopt+0x140/0x=
240
>> [ 62.232986] RSP <ffff880057689ec8>
>> [ 62.240128] CR2: 00000015832a8e23
>> [ 62.247221] ---[ end trace 88f75f0c791ac25b ]---
>>=20
>> My bluetooth device is USB stick:
>> Bus 004 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth =
Dongle (HCI mode)
> I assume this is the same one we already fixed. Patch is on its way into =
Linus=92 tree. You can check bluetooth.git tree since that has this patch i=
ncluded.
Yes you are right !
Thx and sorry for the noise ..
--
Sander
> Regards
> Marcel
^ permalink raw reply
* [PATCH v2 1/2] android: Improve IPC helper to not send invalid status response
From: Szymon Janc @ 2013-11-18 12:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This fix issue with sending invalid success response from several
places where ipc_send_rsp was used for reporting success. Instead of
using using ipc_send for success response, make helper handle that.
---
V2: fixed hardcoded service id in ipc_send_rsp
android/a2dp.c | 2 +-
android/bluetooth.c | 2 +-
android/hidhost.c | 2 +-
android/ipc.c | 7 ++++++-
android/ipc.h | 2 +-
android/main.c | 12 ++++++++----
android/pan.c | 2 +-
android/socket.c | 2 +-
8 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/android/a2dp.c b/android/a2dp.c
index 936c28e..bb55e41 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -226,7 +226,7 @@ void bt_a2dp_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_A2DP, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_A2DP, opcode, status);
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 5c5c61e..7dc2ec3 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -2268,7 +2268,7 @@ void bt_bluetooth_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
error:
error("Error handling command 0x%02x status %u", opcode, status);
- ipc_send_rsp(sk, HAL_SERVICE_ID_BLUETOOTH, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_BLUETOOTH, opcode, status);
}
bool bt_bluetooth_register(int sk)
diff --git a/android/hidhost.c b/android/hidhost.c
index f5a607c..842b8ad 100644
--- a/android/hidhost.c
+++ b/android/hidhost.c
@@ -1109,7 +1109,7 @@ void bt_hid_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_HIDHOST, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_HIDHOST, opcode, status);
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
diff --git a/android/ipc.c b/android/ipc.c
index 729f157..8467b28 100644
--- a/android/ipc.c
+++ b/android/ipc.c
@@ -80,10 +80,15 @@ void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
}
}
-void ipc_send_rsp(int sk, uint8_t service_id, uint8_t status)
+void ipc_send_rsp(int sk, uint8_t service_id, uint8_t opcode, uint8_t status)
{
struct hal_status s;
+ if (status == HAL_STATUS_SUCCESS) {
+ ipc_send(sk, service_id, opcode, 0, NULL, -1);
+ return;
+ }
+
s.code = status;
ipc_send(sk, service_id, HAL_OP_STATUS, sizeof(s), &s, -1);
diff --git a/android/ipc.h b/android/ipc.h
index cf0f3d6..ad4a2d2 100644
--- a/android/ipc.h
+++ b/android/ipc.h
@@ -23,4 +23,4 @@
void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len,
void *param, int fd);
-void ipc_send_rsp(int sk, uint8_t service_id, uint8_t status);
+void ipc_send_rsp(int sk, uint8_t service_id, uint8_t opcode, uint8_t status);
diff --git a/android/main.c b/android/main.c
index a4f5e84..c9733f3 100644
--- a/android/main.c
+++ b/android/main.c
@@ -122,7 +122,8 @@ static void service_register(void *buf, uint16_t len)
return;
failed:
ipc_send_rsp(g_io_channel_unix_get_fd(hal_cmd_io),
- HAL_SERVICE_ID_CORE, HAL_STATUS_FAILED);
+ HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
+ HAL_STATUS_FAILED);
}
static void service_unregister(void *buf, uint16_t len)
@@ -164,7 +165,8 @@ static void service_unregister(void *buf, uint16_t len)
return;
failed:
ipc_send_rsp(g_io_channel_unix_get_fd(hal_cmd_io),
- HAL_SERVICE_ID_CORE, HAL_STATUS_FAILED);
+ HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
+ HAL_STATUS_FAILED);
}
static void handle_service_core(uint8_t opcode, void *buf, uint16_t len)
@@ -178,7 +180,8 @@ static void handle_service_core(uint8_t opcode, void *buf, uint16_t len)
break;
default:
ipc_send_rsp(g_io_channel_unix_get_fd(hal_cmd_io),
- HAL_SERVICE_ID_CORE, HAL_STATUS_FAILED);
+ HAL_SERVICE_ID_CORE, opcode,
+ HAL_STATUS_FAILED);
break;
}
}
@@ -274,7 +277,8 @@ static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond,
bt_pan_handle_cmd(fd, msg->opcode, msg->payload, msg->len);
break;
default:
- ipc_send_rsp(fd, msg->service_id, HAL_STATUS_FAILED);
+ ipc_send_rsp(fd, msg->service_id, msg->opcode,
+ HAL_STATUS_FAILED);
break;
}
diff --git a/android/pan.c b/android/pan.c
index 46b3700..2a11f46 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -87,7 +87,7 @@ void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_PAN, status);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_PAN, opcode, status);
}
bool bt_pan_register(int sk, const bdaddr_t *addr)
diff --git a/android/socket.c b/android/socket.c
index e580036..04bb7d1 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -75,7 +75,7 @@ void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
break;
}
- ipc_send_rsp(sk, HAL_SERVICE_ID_SOCK, HAL_STATUS_FAILED);
+ ipc_send_rsp(sk, HAL_SERVICE_ID_SOCK, opcode, HAL_STATUS_FAILED);
}
bool bt_socket_register(int sk, const bdaddr_t *addr)
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 2/2] android/hal: Verify command status response before processing
From: Szymon Janc @ 2013-11-18 12:58 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1384779520-2104-1-git-send-email-szymon.janc@tieto.com>
This makes HAL IPC code verify error reply before processing it. It
also verify if success status was reported according to IPC spec.
---
android/hal-ipc.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/android/hal-ipc.c b/android/hal-ipc.c
index 026e245..5155e04 100644
--- a/android/hal-ipc.c
+++ b/android/hal-ipc.c
@@ -367,6 +367,17 @@ int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param,
if (cmd.opcode == HAL_OP_STATUS) {
struct hal_status *s = rsp;
+
+ if (sizeof(*s) != cmd.len) {
+ error("Invalid status length, aborting");
+ exit(EXIT_FAILURE);
+ }
+
+ if (s->code == HAL_STATUS_SUCCESS) {
+ error("Invalid success status response, aborting");
+ exit(EXIT_FAILURE);
+ }
+
return s->code;
}
--
1.8.4.2
^ permalink raw reply related
* Re: [PATCH v2 1/2] android: Improve IPC helper to not send invalid status response
From: Johan Hedberg @ 2013-11-18 13:18 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1384779520-2104-1-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
On Mon, Nov 18, 2013, Szymon Janc wrote:
> This fix issue with sending invalid success response from several
> places where ipc_send_rsp was used for reporting success. Instead of
> using using ipc_send for success response, make helper handle that.
> ---
> V2: fixed hardcoded service id in ipc_send_rsp
>
> android/a2dp.c | 2 +-
> android/bluetooth.c | 2 +-
> android/hidhost.c | 2 +-
> android/ipc.c | 7 ++++++-
> android/ipc.h | 2 +-
> android/main.c | 12 ++++++++----
> android/pan.c | 2 +-
> android/socket.c | 2 +-
> 8 files changed, 20 insertions(+), 11 deletions(-)
Both patches have been applied. Thanks.
Johan
^ permalink raw reply
* [PATCHv4 00/17] Socket HAL
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This is initial code implementing socket HAL. OPP currently works with send/receive files. Probaly
other profiles works as well, not tested yet.
Changes:
* v4: Changed name rfslot -> rfsock following Johan's comment and other cosmetic changes, fixed one bug in SDP
record, use NULL instead of 0 for sdp functions.
* v3: Fixed coding style with write/send between file descriptors.
* v2: Following Marcel comments changed way copying between file descriptors works, added SDP record
for OPP and now it is possible to send files through GUI. Merged one patch with structures with actual user.
* v1: Rebased and use static src address, hal_fd removed from structure and closed after sent to framework,
added connect calls and SDP parsing, added cleanup_rfcomm function, minor fixes.
* RFC Initial
TODO:
* Add SDP record for PBAP and other profiles
* Use splice() (requires bionic change first)
For tracking rfcomm sockets I use structure rfslot which has following
fields:
- real_sock - real RFCOMM socket
- fd - fd to communicate with Android framework
create_rfslot sets hal_fd which is fd passed to Android framework with CMSG
Andrei Emeltchenko (17):
android/socket: Add connect signal to socket
android: trivial: Add comment making code consistent
android/socket: Add get RFCOMM default channel
android/socket: Define structs and implement listen
android/socket: Implement socket accepted event
android/socket: Implement Android RFCOMM stack events
android/socket: Implement RFCOMM events
android/socket: Implement accept signal over Android fd
android/socket: Write channel to Android fd
android/socket: Implement socket connect HAL method
android/socket: Parse SDP response and connect
android/socket: Implement HAL connect call
android/socket: Send RFCOMM channel to framework
android/socket: Send connect signal on connect
android/socket: Close file descriptor after sending
android/socket: Add SDP record for OPP profile
android/socket: Add MAS uuid to channel mapping
android/hal-msg.h | 2 +
android/socket.c | 612 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
android/socket.h | 7 +
3 files changed, 617 insertions(+), 4 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCHv4 01/17] android/socket: Add connect signal to socket
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-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/socket.h | 7 +++++++
1 file changed, 7 insertions(+)
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
* [PATCHv4 02/17] android: trivial: Add comment making code consistent
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/hal-msg.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 44fd5c8..9e3a81f 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];
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 03/17] android/socket: Add get RFCOMM default channel
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
RFCOMM default channel is the same like in other BlueZ code, it is
defined in src/profile.c
---
android/socket.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index e580036..9c94c03 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -35,13 +35,54 @@
#include "ipc.h"
#include "socket.h"
+#define OPP_DEFAULT_CHANNEL 9
+#define PBAP_DEFAULT_CHANNEL 15
+
static bdaddr_t adapter_addr;
+static struct {
+ uint8_t uuid[16];
+ uint8_t channel;
+} uuid_to_chan[] = {
+ {
+ .uuid = {
+ 0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+ },
+ .channel = PBAP_DEFAULT_CHANNEL,
+ }, {
+ .uuid = {
+ 0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
+ 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
+ },
+ .channel = OPP_DEFAULT_CHANNEL
+ }
+};
+
+static int get_rfcomm_default_chan(const uint8_t *uuid)
+{
+ unsigned int i;
+
+ for (i = 0; i < G_N_ELEMENTS(uuid_to_chan); i++) {
+ if (!memcmp(uuid_to_chan[i].uuid, uuid, 16))
+ return uuid_to_chan[i].channel;
+ }
+
+ return -ENOENT;
+}
+
static int handle_listen(void *buf)
{
- DBG("Not implemented");
+ int hal_fd;
+ int chan;
- return -1;
+ DBG("");
+
+ chan = get_rfcomm_default_chan(cmd->uuid);
+ if (chan < 0)
+ return chan;
+
+ return hal_fd;
}
static int handle_connect(void *buf)
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 04/17] android/socket: Define structs and implement listen
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This defines structures for socket HAL. We need to emulate Android
sockets by sending connect/accept signals over file descriptor.
Handle HAL socket listen call. Create RFCOMM socket and wait for events.
---
android/socket.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 9c94c03..0731bd9 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -27,8 +27,12 @@
#include <glib.h>
#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
#include "lib/bluetooth.h"
+#include "btio/btio.h"
+#include "lib/sdp.h"
#include "log.h"
#include "hal-msg.h"
#include "hal-ipc.h"
@@ -40,6 +44,50 @@
static bdaddr_t adapter_addr;
+/* Simple list of RFCOMM server sockets */
+GList *servers = NULL;
+
+/* Simple list of RFCOMM connected sockets */
+GList *connections = NULL;
+
+struct rfcomm_sock {
+ int fd; /* descriptor for communication with Java framework */
+ int real_sock; /* real RFCOMM socket */
+ int channel; /* RFCOMM channel */
+};
+
+static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
+{
+ 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;
+ return NULL;
+ }
+
+ rfsock = g_new0(struct rfcomm_sock, 1);
+ rfsock->fd = fds[0];
+ *hal_fd = fds[1];
+ rfsock->real_sock = sock;
+
+ return rfsock;
+}
+
+static void cleanup_rfsock(struct rfcomm_sock *rfsock)
+{
+ DBG("rfsock: %p fd %d real_sock %d chan %u",
+ rfsock, rfsock->fd, rfsock->real_sock, rfsock->channel);
+
+ if (rfsock->fd > 0)
+ close(rfsock->fd);
+ if (rfsock->real_sock > 0)
+ close(rfsock->real_sock);
+
+ g_free(rfsock);
+}
+
static struct {
uint8_t uuid[16];
uint8_t channel;
@@ -71,8 +119,16 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
return -ENOENT;
}
+static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
+{
+}
+
static int handle_listen(void *buf)
{
+ struct hal_cmd_sock_listen *cmd = buf;
+ struct rfcomm_sock *rfsock;
+ GIOChannel *io;
+ GError *err = NULL;
int hal_fd;
int chan;
@@ -82,6 +138,29 @@ static int handle_listen(void *buf)
if (chan < 0)
return chan;
+ DBG("rfcomm channel %d", chan);
+
+ rfsock = create_rfsock(-1, &hal_fd);
+ if (!rfsock)
+ return -1;
+
+ io = bt_io_listen(accept_cb, NULL, rfsock, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+ BT_IO_OPT_CHANNEL, chan,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("Failed listen: %s", err->message);
+ g_error_free(err);
+ cleanup_rfsock(rfsock);
+ return -1;
+ }
+
+ rfsock->real_sock = g_io_channel_unix_get_fd(io);
+ servers = g_list_append(servers, rfsock);
+
+ DBG("real_sock %d fd %d hal_fd %d",
+ rfsock->real_sock, rfsock->fd, hal_fd);
+
return hal_fd;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 05/17] android/socket: Implement socket accepted event
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-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 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 0731bd9..12c3687 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -119,8 +119,59 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
return -ENOENT;
}
+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 accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
+ struct rfcomm_sock *rfsock = user_data;
+ struct rfcomm_sock *rfsock_acc;
+ GIOChannel *io_stack;
+ bdaddr_t dst;
+ char address[18];
+ int sock_acc;
+ int hal_fd = -1;
+
+ 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 rfsock %p", address, rfsock);
+
+ DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+ rfsock->fd, rfsock->real_sock, rfsock->channel,
+ g_io_channel_unix_get_fd(io));
+
+ sock_acc = g_io_channel_unix_get_fd(io);
+ rfsock_acc = create_rfsock(sock_acc, &hal_fd);
+ connections = g_list_append(connections, rfsock_acc);
+
+ /* Handle events from Android */
+ io_stack = g_io_channel_unix_new(rfsock_acc->fd);
+ g_io_add_watch(io_stack, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ sock_stack_event_cb, rfsock_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, rfsock_acc);
+
+ DBG("rfsock %p rfsock_acc %p", rfsock, rfsock_acc);
}
static int handle_listen(void *buf)
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 06/17] android/socket: Implement Android RFCOMM stack events
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-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. Consider splice() in the future.
---
android/socket.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 12c3687..3be8ff6 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -119,9 +119,69 @@ static int get_rfcomm_default_chan(const uint8_t *uuid)
return -ENOENT;
}
+static int try_write_all(int fd, unsigned char *buf, int len)
+{
+ int sent = 0;
+
+ while (len > 0) {
+ int written;
+
+ written = write(fd, buf, len);
+ if (written < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ return -1;
+ }
+
+ if (!written)
+ return 0;
+
+ len -= written; buf += written; sent += written;
+ }
+
+ return sent;
+}
+
static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
+ struct rfcomm_sock *rfsock = data;
+ unsigned char buf[1024];
+ int len, sent;
+
+ DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+ rfsock->fd, rfsock->real_sock, rfsock->channel,
+ g_io_channel_unix_get_fd(io));
+
+ if (!g_list_find(connections, rfsock)) {
+ error("rfsock %p not found in the list", rfsock);
+ return FALSE;
+ }
+
+ 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);
+ connections = g_list_remove(connections, rfsock);
+ cleanup_rfsock(rfsock);
+ return FALSE;
+ }
+
+ len = read(rfsock->fd, buf, sizeof(buf));
+ if (len <= 0) {
+ error("read(): %s", strerror(errno));
+ return FALSE;
+ }
+
+ DBG("read %d bytes write to %d", len, rfsock->real_sock);
+
+ sent = try_write_all(rfsock->real_sock, buf, len);
+ if (sent < 0) {
+ error("write(): %s", strerror(errno));
+ return FALSE;
+ }
+
+ DBG("Written %d bytes", sent);
+
return TRUE;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 07/17] android/socket: Implement RFCOMM events
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Copy data from RFCOMM socket to Android framework. Consider splice
in the future.
---
android/socket.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 3be8ff6..154c330 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -188,6 +188,43 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
gpointer data)
{
+ struct rfcomm_sock *rfsock = data;
+ unsigned char buf[1024];
+ int len, sent;
+
+ DBG("rfsock: fd %d real_sock %d chan %u sock %d",
+ rfsock->fd, rfsock->real_sock, rfsock->channel,
+ g_io_channel_unix_get_fd(io));
+
+ if (!g_list_find(connections, rfsock)) {
+ error("rfsock %p not found in the list", rfsock);
+ return FALSE;
+ }
+
+ 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);
+ connections = g_list_remove(connections, rfsock);
+ cleanup_rfsock(rfsock);
+ return FALSE;
+ }
+
+ len = read(rfsock->real_sock, buf, sizeof(buf));
+ if (len <= 0) {
+ error("read(): %s", strerror(errno));
+ return FALSE;
+ }
+
+ DBG("read %d bytes, write to fd %d", len, rfsock->fd);
+
+ sent = try_write_all(rfsock->fd, buf, len);
+ if (sent < 0) {
+ error("write(): %s", strerror(errno));
+ return FALSE;
+ }
+
+ DBG("Written %d bytes", sent);
+
return TRUE;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 08/17] android/socket: Implement accept signal over Android fd
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-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 154c330..a02bb1e 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -37,6 +37,7 @@
#include "hal-msg.h"
#include "hal-ipc.h"
#include "ipc.h"
+#include "utils.h"
#include "socket.h"
#define OPP_DEFAULT_CHANNEL 9
@@ -107,6 +108,45 @@ static struct {
}
};
+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 int get_rfcomm_default_chan(const uint8_t *uuid)
{
unsigned int i;
@@ -228,6 +268,21 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
return TRUE;
}
+static void sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr,
+ int fd_accepted)
+{
+ struct hal_sock_connect_signal cmd;
+
+ DBG("");
+
+ cmd.size = sizeof(cmd);
+ bdaddr2android(bdaddr, cmd.bdaddr);
+ cmd.channel = rfsock->channel;
+ cmd.status = 0;
+
+ bt_sock_send_fd(rfsock->fd, &cmd, sizeof(cmd), fd_accepted);
+}
+
static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
{
struct rfcomm_sock *rfsock = user_data;
@@ -258,6 +313,8 @@ static void accept_cb(GIOChannel *io, GError *err, gpointer user_data)
rfsock_acc = create_rfsock(sock_acc, &hal_fd);
connections = g_list_append(connections, rfsock_acc);
+ sock_send_accept(rfsock, &dst, hal_fd);
+
/* Handle events from Android */
io_stack = g_io_channel_unix_new(rfsock_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
* [PATCHv4 09/17] android/socket: Write channel to Android fd
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Android framework expects to receive channel number as int.
---
android/socket.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index a02bb1e..bfe7ca6 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -363,6 +363,13 @@ static int handle_listen(void *buf)
rfsock->real_sock = g_io_channel_unix_get_fd(io);
servers = g_list_append(servers, rfsock);
+ /* TODO: Check this */
+ if (write(rfsock->fd, &chan, sizeof(chan)) != sizeof(chan)) {
+ error("Error sending RFCOMM channel");
+ cleanup_rfsock(rfsock);
+ return -1;
+ }
+
DBG("real_sock %d fd %d hal_fd %d",
rfsock->real_sock, rfsock->fd, hal_fd);
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 10/17] android/socket: Implement socket connect HAL method
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
First step is to query remote device for RFCOMM channel.
---
android/socket.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/android/socket.c b/android/socket.c
index bfe7ca6..7939eee 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -33,6 +33,9 @@
#include "lib/bluetooth.h"
#include "btio/btio.h"
#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "src/sdp-client.h"
+
#include "log.h"
#include "hal-msg.h"
#include "hal-ipc.h"
@@ -55,6 +58,7 @@ struct rfcomm_sock {
int fd; /* descriptor for communication with Java framework */
int real_sock; /* real RFCOMM socket */
int channel; /* RFCOMM channel */
+ bdaddr_t dst;
};
static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
@@ -376,11 +380,37 @@ static int handle_listen(void *buf)
return hal_fd;
}
+static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
+{
+ DBG("");
+}
+
static int handle_connect(void *buf)
{
- DBG("Not implemented");
+ struct hal_cmd_sock_connect *cmd = buf;
+ struct rfcomm_sock *rfsock;
+ bdaddr_t dst;
+ uuid_t uuid;
+ int hal_fd = -1;
- return -1;
+ DBG("");
+
+ android2bdaddr(cmd->bdaddr, &dst);
+ rfsock = create_rfsock(-1, &hal_fd);
+ bacpy(&rfsock->dst, &dst);
+
+ memset(&uuid, 0, sizeof(uuid));
+ uuid.type = SDP_UUID128;
+ memcpy(&uuid.value.uuid128, cmd->uuid, sizeof(uint128_t));
+
+ if (bt_search_service(&adapter_addr, &dst, &uuid, sdp_search_cb, rfsock,
+ NULL) < 0) {
+ error("Failed to search SDP records");
+ cleanup_rfsock(rfsock);
+ return -1;
+ }
+
+ return hal_fd;
}
void bt_sock_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
--
1.7.10.4
^ permalink raw reply related
* [PATCHv4 11/17] android/socket: Parse SDP response and connect
From: Andrei Emeltchenko @ 2013-11-18 13:20 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1384780854-20970-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Parse SDP response, find RFCOMM channel and connect.
---
android/socket.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/android/socket.c b/android/socket.c
index 7939eee..63c553a 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -380,9 +380,72 @@ static int handle_listen(void *buf)
return hal_fd;
}
+static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
+{
+}
+
static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
{
+ struct rfcomm_sock *rfsock = data;
+ GError *gerr = NULL;
+ sdp_list_t *list;
+ GIOChannel *io;
+ int chan;
+
DBG("");
+
+ if (err < 0) {
+ error("Unable to get SDP record: %s", strerror(-err));
+ goto fail;
+ }
+
+ if (!recs || !recs->data) {
+ error("No SDP records found");
+ goto fail;
+ }
+
+ for (list = recs; list != NULL; list = list->next) {
+ sdp_record_t *rec = list->data;
+ sdp_list_t *protos;
+
+ if (sdp_get_access_protos(rec, &protos) < 0) {
+ error("Unable to get proto list");
+ goto fail;
+ }
+
+ chan = sdp_get_proto_port(protos, RFCOMM_UUID);
+
+ sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free,
+ NULL);
+ sdp_list_free(protos, NULL);
+ }
+
+ if (chan <= 0) {
+ error("Could not get RFCOMM channel %d", chan);
+ goto fail;
+ }
+
+ DBG("Got RFCOMM channel %d", 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, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("Failed connect: %s", gerr->message);
+ g_error_free(gerr);
+ goto fail;
+ }
+
+ rfsock->real_sock = g_io_channel_unix_get_fd(io);
+ rfsock->channel = chan;
+ connections = g_list_append(connections, rfsock);
+ return;
+
+fail:
+ cleanup_rfsock(rfsock);
}
static int handle_connect(void *buf)
--
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