* HFP: typo in error path?
From: Daniel Wagner @ 2010-12-16 6:42 UTC (permalink / raw)
To: linux-bluetooth
Hi,
I'm reading a bit through the code and try to understand how the HF
role in HFP is implemented. I found following in audio/gateway.c:
static gboolean sco_io_cb(GIOChannel *chan, GIOCondition cond,
struct audio_device *dev)
{
struct gateway *gw = dev->gateway;
if (cond & G_IO_NVAL)
return FALSE;
if (cond & (G_IO_ERR | G_IO_HUP)) {
DBG("sco connection is released");
g_io_channel_shutdown(gw->sco, TRUE, NULL);
g_io_channel_unref(gw->sco);
gw->sco = NULL;
change_state(dev, GATEWAY_STATE_CONNECTED);
return FALSE;
}
return TRUE;
}
I don't really understand what's going on here, but just from the
naming I think the change_state call should be
GATEWAY_STATE_DISCONNECTED. If my assumation is correct I can spin a
patch.
cheers,
daniel
^ permalink raw reply
* Re: [PATCH v7] Bluetooth: btwilink driver
From: Pavan Savoy @ 2010-12-16 6:09 UTC (permalink / raw)
To: Gustavo F. Padovan, marcel; +Cc: linux-bluetooth, linux-kernel
In-Reply-To: <AANLkTimewUbJMax-pv+-JSdnbNZvOU8yTVGV-T+BJBo1@mail.gmail.com>
On Thu, Dec 9, 2010 at 1:17 PM, Pavan Savoy <pavan_savoy@sify.com> wrote:
> Gustavo,
>
> On Tue, Dec 7, 2010 at 3:05 AM, Vitaly Wool <vitalywool@gmail.com> wrote:
>> Hi Gustavo,
>>
>> On Mon, Dec 6, 2010 at 10:23 PM, Gustavo F. Padovan
>> <padovan@profusion.mobi> wrote:
>>
>>> Can't you differentiate Bluetooth data in a generic way, withou looking=
if it
>>> is ACL, SCO or HCI EVENT? That done, you can just accumulate in a buffe=
r all
>>> the Bluetooth data you received in that stream then send it to Bluetoot=
h
>>> driver after finish that stream processing.
>>
>> I'm afraid he can't do this because he needs to route events to the
>> appropriate entity (BT/FM/GPS). I'm not sure how it can be done
>> without analyzing the incoming packet.
>
> Think of TI-ST driver as a extension to the HCI-H4 driver or HCI-LL
> with FM and GPS being the additional protocols, and more protocols
> coming in future...
> So some driver has to have a knowledge of the protocols which are on chip=
.
> the basic arch can be found @ http://omappedia.org/wiki/Wilink_ST
Gustavo, Marcel,
Any suggestion to this?
Is including net/bluetooth headers a problem?
and is this a big blocking factor to try and push it to mainline?
I know it would be a dumb question, but do you want me to redeclare
the ACL, SCO and Event headers structures?
All I need is the off-set of the structure where the payload length resides=
....
Please suggest ...
regards,
Pavan
> As Vitaly rightly pointed out, the TI-ST driver needs to peek into all
> the protocol's data be it BT, FM or GPS to assemble fragmented data
> (say ACL data coming out of TTY in 2 fragments) or fragment multiple
> protocol data (say HCI-Event + FM Channel 8 event data)....
> Note: we include even the FM and GPS headers to understand protocol
> frames, but they lack a standard unlike Bluetooth...
>
> Since there lacks a generic way to differentiate BT, FM or GPS data at
> TI-ST driver layer, =C2=A0please suggest what can be done ...
>
>
>> Thanks,
>> =C2=A0 Vitaly
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetoot=
h" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at =C2=A0http://vger.kernel.org/majordomo-info.html
>>
>
^ permalink raw reply
* Re: [PATCH] Added enc_read_blob_req() API to ATT transport, to enable the reading of attributes that exceed the length of the MTU.
From: Anderson Lizardo @ 2010-12-16 3:03 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <AANLkTikB4K__a3aS1L19nz4USmtEcU+GEufcFkqZLrUb@mail.gmail.com>
On Tue, Dec 14, 2010 at 4:29 PM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Another issue: looks your e-mail client replaced tabs with spaces (but
> it might just be Google messing up on my side).
BTW just checked and indeed it was just bad formatting by gmail
webmail (from my side). The tabs on your patch are correct. The other
comments I still think are valid.
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH 4/4] covert more dbus errors to btd_error_*
From: Gustavo F. Padovan @ 2010-12-15 22:07 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292450823-17640-3-git-send-email-padovan@profusion.mobi>
---
audio/headset.c | 4 +---
serial/port.c | 8 +-------
serial/proxy.c | 12 ++----------
src/adapter.c | 10 ++--------
4 files changed, 6 insertions(+), 28 deletions(-)
diff --git a/audio/headset.c b/audio/headset.c
index be14d3b..b7489a9 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1873,9 +1873,7 @@ static DBusMessage *hs_set_gain(DBusConnection *conn,
err = headset_set_gain(device, gain, type);
if (err < 0)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".InvalidArgument",
- "Must be less than or equal to 15");
+ return btd_error_invalid_args(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
diff --git a/serial/port.c b/serial/port.c
index 33450b3..233e317 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -234,12 +234,6 @@ void port_release_all(void)
g_slist_free(devices);
}
-static inline DBusMessage *failed(DBusMessage *msg, const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "%s", description);
-}
-
static void open_notify(int fd, int err, struct serial_port *port)
{
struct serial_device *device = port->device;
@@ -495,7 +489,7 @@ static DBusMessage *port_connect(DBusConnection *conn,
}
if (port->listener_id)
- return failed(msg, "Port already in use");
+ return btd_error_failed(msg, "Port already in use");
port->listener_id = g_dbus_add_disconnect_watch(conn,
dbus_message_get_sender(msg),
diff --git a/serial/proxy.c b/serial/proxy.c
index 20aea7d..b1ee65e 100644
--- a/serial/proxy.c
+++ b/serial/proxy.c
@@ -131,12 +131,6 @@ static void proxy_free(struct serial_proxy *prx)
g_free(prx);
}
-static inline DBusMessage *failed(DBusMessage *msg, const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "%s", description);
-}
-
static void add_lang_attr(sdp_record_t *r)
{
sdp_lang_attr_t base_lang;
@@ -551,9 +545,7 @@ static DBusMessage *proxy_enable(DBusConnection *conn,
int err;
err = enable_proxy(prx);
- if (err == -EALREADY)
- return failed(msg, "Already enabled");
- else if (err < 0)
+ if (err < 0)
return btd_error_failed(msg, strerror(-err));
return dbus_message_new_method_return(msg);
@@ -565,7 +557,7 @@ static DBusMessage *proxy_disable(DBusConnection *conn,
struct serial_proxy *prx = data;
if (!prx->io)
- return failed(msg, "Not enabled");
+ return btd_error_failed(msg, "Not enabled");
/* Remove the watches and unregister the record */
disable_proxy(prx);
diff --git a/src/adapter.c b/src/adapter.c
index f0e1d36..27a8d39 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -140,12 +140,6 @@ struct btd_adapter {
static void adapter_set_pairable_timeout(struct btd_adapter *adapter,
guint interval);
-static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotInProgress",
- "%s", str);
-}
-
static int found_device_cmp(const struct remote_dev_info *d1,
const struct remote_dev_info *d2)
{
@@ -1226,7 +1220,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
ba2str(&adapter->bdaddr, srcaddr);
if (check_address(srcaddr) < 0)
- return adapter_not_ready(msg);
+ return btd_error_invalid_args(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1505,7 +1499,7 @@ static DBusMessage *cancel_device_creation(DBusConnection *conn,
device = adapter_find_device(adapter, address);
if (!device || !device_is_creating(device, NULL))
- return not_in_progress(msg, "Device creation not in progress");
+ return btd_error_does_not_exist(msg);
if (!device_is_creating(device, sender))
return btd_error_not_authorized(msg);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 3/4] add btd_error_not_ready()
From: Gustavo F. Padovan @ 2010-12-15 22:07 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292450823-17640-2-git-send-email-padovan@profusion.mobi>
---
audio/headset.c | 3 +--
src/adapter.c | 16 +++++-----------
src/error.c | 6 ++++++
src/error.h | 1 +
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/audio/headset.c b/audio/headset.c
index 55bdc61..be14d3b 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1696,8 +1696,7 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
return btd_error_already_connected(msg);
if (hs->hfp_handle && !ag.telephony_ready)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
- "Telephony subsystem not ready");
+ return btd_error_not_ready(msg);
device->auto_connect = FALSE;
diff --git a/src/adapter.c b/src/adapter.c
index 73c8a9b..f0e1d36 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -140,12 +140,6 @@ struct btd_adapter {
static void adapter_set_pairable_timeout(struct btd_adapter *adapter,
guint interval);
-static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
- "Adapter is not ready");
-}
-
static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".NotInProgress",
@@ -554,7 +548,7 @@ static DBusMessage *set_pairable(DBusConnection *conn, DBusMessage *msg,
int err;
if (adapter->scan_mode == SCAN_DISABLED)
- return adapter_not_ready(msg);
+ return btd_error_not_ready(msg);
if (pairable == adapter->pairable)
goto done;
@@ -1166,7 +1160,7 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
int err;
if (!adapter->up)
- return adapter_not_ready(msg);
+ return btd_error_not_ready(msg);
req = find_session(adapter->disc_sessions, sender);
if (req) {
@@ -1198,7 +1192,7 @@ static DBusMessage *adapter_stop_discovery(DBusConnection *conn,
const char *sender = dbus_message_get_sender(msg);
if (!adapter->up)
- return adapter_not_ready(msg);
+ return btd_error_not_ready(msg);
req = find_session(adapter->disc_sessions, sender);
if (!req)
@@ -1575,7 +1569,7 @@ static DBusMessage *create_device(DBusConnection *conn,
return btd_error_invalid_args(msg);
if (!adapter->up)
- return adapter_not_ready(msg);
+ return btd_error_not_ready(msg);
if (adapter_find_device(adapter, address))
return btd_error_already_exists(msg);
@@ -1652,7 +1646,7 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
return btd_error_invalid_args(msg);
if (!adapter->up)
- return adapter_not_ready(msg);
+ return btd_error_not_ready(msg);
sender = dbus_message_get_sender(msg);
if (adapter->agent &&
diff --git a/src/error.c b/src/error.c
index 7d3afd4..8ee79b8 100644
--- a/src/error.c
+++ b/src/error.c
@@ -103,6 +103,12 @@ DBusMessage *btd_error_agent_not_assigned(DBusMessage *msg)
"Agent Not Assigned");
}
+DBusMessage *btd_error_not_ready(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
+ "Resource Not Ready");
+}
+
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str)
{
return g_dbus_create_error(msg, ERROR_INTERFACE
diff --git a/src/error.h b/src/error.h
index b8c06ce..6cd3cbf 100644
--- a/src/error.h
+++ b/src/error.h
@@ -39,4 +39,5 @@ DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
DBusMessage *btd_error_not_authorized(DBusMessage *msg);
DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
DBusMessage *btd_error_agent_not_assigned(DBusMessage *msg);
+DBusMessage *btd_error_not_ready(DBusMessage *msg);
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 2/4] remove error_common_reply()
From: Gustavo F. Padovan @ 2010-12-15 22:07 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292450823-17640-1-git-send-email-padovan@profusion.mobi>
Remove old dbus error report function. This patch doesn't make things
really really better, but is a start.
---
audio/gateway.c | 18 ++++++++++--------
audio/headset.c | 37 +++++++++++++++----------------------
audio/sink.c | 7 ++++---
audio/source.c | 7 ++++---
src/error.c | 18 ------------------
src/error.h | 3 ---
6 files changed, 33 insertions(+), 57 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index 6a095ca..da899a0 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -254,10 +254,11 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err,
return;
fail:
- if (gw->msg)
- error_common_reply(dev->conn, gw->msg,
- ERROR_INTERFACE ".Failed",
- "Connection attempt failed");
+ if (gw->msg) {
+ DBusMessage *reply;
+ reply = btd_error_failed(gw->msg, "Connect failed");
+ g_dbus_send_message(dev->conn, reply);
+ }
change_state(dev, GATEWAY_STATE_DISCONNECTED);
}
@@ -333,10 +334,11 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
return;
fail:
- if (gw->msg)
- error_common_reply(dev->conn, gw->msg,
- ERROR_INTERFACE ".NotSupported",
- "Not supported");
+ if (gw->msg) {
+ DBusMessage *reply = btd_error_failed(gw->msg,
+ gerr ? gerr->message : strerror(-err));
+ g_dbus_send_message(dev->conn, reply);
+ }
change_state(dev, GATEWAY_STATE_DISCONNECTED);
diff --git a/audio/headset.c b/audio/headset.c
index 34b2b89..55bdc61 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -176,19 +176,12 @@ struct event {
static GSList *headset_callbacks = NULL;
-static DBusHandlerResult error_not_supported(DBusConnection *conn,
- DBusMessage *msg)
+static void error_connect_failed(DBusConnection *conn, DBusMessage *msg,
+ int err)
{
- return error_common_reply(conn, msg, ERROR_INTERFACE ".NotSupported",
- "Not supported");
-}
-
-static DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn,
- DBusMessage *msg, int err)
-{
- return error_common_reply(conn, msg,
- ERROR_INTERFACE ".ConnectionAttemptFailed",
- err < 0 ? strerror(-err) : "Connection attempt failed");
+ DBusMessage *reply = btd_error_failed(msg,
+ err < 0 ? strerror(-err) : "Connect failed");
+ g_dbus_send_message(conn, reply);
}
static int rfcomm_connect(struct audio_device *device, headset_stream_cb_t cb,
@@ -567,9 +560,7 @@ static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
if (p != NULL) {
p->err = -errno;
if (p->msg)
- error_connection_attempt_failed(dev->conn,
- p->msg,
- p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
pending_connect_finalize(dev);
}
@@ -679,7 +670,7 @@ static void hfp_slc_complete(struct audio_device *dev)
p->err = sco_connect(dev, NULL, NULL, NULL);
if (p->err < 0) {
if (p->msg)
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
pending_connect_finalize(dev);
}
}
@@ -1397,7 +1388,7 @@ void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
failed:
if (p && p->msg)
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
pending_connect_finalize(dev);
if (hs->rfcomm)
headset_set_state(dev, HEADSET_STATE_CONNECTED);
@@ -1454,7 +1445,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
error("Unable to get service record: %s (%d)",
strerror(-err), -err);
p->err = -err;
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
goto failed;
}
@@ -1503,7 +1494,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
if (err < 0) {
error("Unable to connect: %s (%d)", strerror(-err), -err);
p->err = -err;
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
goto failed;
}
@@ -1513,8 +1504,10 @@ failed_not_supported:
if (p->svclass == HANDSFREE_SVCLASS_ID &&
get_records(dev, NULL, NULL, NULL) == 0)
return;
- if (p->msg)
- error_not_supported(dev->conn, p->msg);
+ if (p->msg) {
+ DBusMessage *reply = btd_error_not_supported(p->msg);
+ g_dbus_send_message(dev->conn, reply);
+ }
failed:
p->svclass = 0;
pending_connect_finalize(dev);
@@ -2667,7 +2660,7 @@ void headset_shutdown(struct audio_device *dev)
struct pending_connect *p = dev->headset->pending;
if (p && p->msg)
- error_connection_attempt_failed(dev->conn, p->msg, ECANCELED);
+ error_connect_failed(dev->conn, p->msg, ECANCELED);
pending_connect_finalize(dev);
headset_set_state(dev, HEADSET_STATE_DISCONNECTED);
diff --git a/audio/sink.c b/audio/sink.c
index 5746c55..2d5db18 100644
--- a/audio/sink.c
+++ b/audio/sink.c
@@ -253,10 +253,11 @@ static void stream_state_changed(struct avdtp_stream *stream,
sink->stream_state = new_state;
}
-static DBusHandlerResult error_failed(DBusConnection *conn,
- DBusMessage *msg, const char * desc)
+static void error_failed(DBusConnection *conn, DBusMessage *msg,
+ const char *desc)
{
- return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
+ DBusMessage *reply = btd_error_failed(msg, desc);
+ g_dbus_send_message(conn, reply);
}
static gboolean stream_setup_retry(gpointer user_data)
diff --git a/audio/source.c b/audio/source.c
index 29ceb0f..6d266f2 100644
--- a/audio/source.c
+++ b/audio/source.c
@@ -206,10 +206,11 @@ static void stream_state_changed(struct avdtp_stream *stream,
source->stream_state = new_state;
}
-static DBusHandlerResult error_failed(DBusConnection *conn,
- DBusMessage *msg, const char * desc)
+static void error_failed(DBusConnection *conn, DBusMessage *msg,
+ const char *desc)
{
- return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
+ DBusMessage *reply = btd_error_failed(msg, desc);
+ g_dbus_send_message(conn, reply);
}
static gboolean stream_setup_retry(gpointer user_data)
diff --git a/src/error.c b/src/error.c
index 25f89f6..7d3afd4 100644
--- a/src/error.c
+++ b/src/error.c
@@ -31,24 +31,6 @@
#include "error.h"
-/* Helper function - internal use only */
-DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
- const char *name, const char *descr)
-{
- DBusMessage *derr;
-
- if (!conn || !msg)
- return DBUS_HANDLER_RESULT_HANDLED;
-
- derr = dbus_message_new_error(msg, name, descr);
- if (!derr)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
- g_dbus_send_message(conn, derr);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
DBusMessage *btd_error_invalid_args(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
diff --git a/src/error.h b/src/error.h
index 0f2eb22..b8c06ce 100644
--- a/src/error.h
+++ b/src/error.h
@@ -27,9 +27,6 @@
#define ERROR_INTERFACE "org.bluez.Error"
-DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
- const char *name, const char *descr);
-
DBusMessage *btd_error_invalid_args(DBusMessage *msg);
DBusMessage *btd_error_busy(DBusMessage *msg);
DBusMessage *btd_error_already_exists(DBusMessage *msg);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 1/4] add btd_error_agent_not_assigned()
From: Gustavo F. Padovan @ 2010-12-15 22:07 UTC (permalink / raw)
To: linux-bluetooth
---
audio/gateway.c | 3 +--
src/adapter.c | 3 +--
src/error.c | 6 ++++++
src/error.h | 1 +
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index 4d38be7..6a095ca 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -367,8 +367,7 @@ static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg,
int err;
if (!gw->agent)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".Failed", "Agent not assigned");
+ return btd_error_agent_not_assigned(msg);
err = get_records(au_dev);
if (err < 0)
diff --git a/src/adapter.c b/src/adapter.c
index 2ff59a0..73c8a9b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1412,8 +1412,7 @@ static DBusMessage *request_session(DBusConnection *conn,
int err;
if (!adapter->agent)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "No agent registered");
+ return btd_error_agent_not_assigned(msg);
if (!adapter->mode_sessions)
adapter->global_mode = adapter->mode;
diff --git a/src/error.c b/src/error.c
index 3a78628..25f89f6 100644
--- a/src/error.c
+++ b/src/error.c
@@ -115,6 +115,12 @@ DBusMessage *btd_error_no_such_adapter(DBusMessage *msg)
"No such adapter");
}
+DBusMessage *btd_error_agent_not_assigned(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".AgentNotAssigned",
+ "Agent Not Assigned");
+}
+
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str)
{
return g_dbus_create_error(msg, ERROR_INTERFACE
diff --git a/src/error.h b/src/error.h
index faaef0a..0f2eb22 100644
--- a/src/error.h
+++ b/src/error.h
@@ -41,4 +41,5 @@ DBusMessage *btd_error_in_progress(DBusMessage *msg);
DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
DBusMessage *btd_error_not_authorized(DBusMessage *msg);
DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
+DBusMessage *btd_error_agent_not_assigned(DBusMessage *msg);
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 3/3] convert more dbus errors to btd_error_*
From: Gustavo F. Padovan @ 2010-12-15 21:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292448568-16854-2-git-send-email-padovan@profusion.mobi>
---
audio/headset.c | 7 ++-----
serial/port.c | 8 +-------
serial/proxy.c | 12 ++----------
src/adapter.c | 10 ++--------
4 files changed, 7 insertions(+), 30 deletions(-)
diff --git a/audio/headset.c b/audio/headset.c
index 55bdc61..6fbb4dd 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1696,8 +1696,7 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
return btd_error_already_connected(msg);
if (hs->hfp_handle && !ag.telephony_ready)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
- "Telephony subsystem not ready");
+ return btd_error_failed(msg, "Telephony subsystem not ready");
device->auto_connect = FALSE;
@@ -1874,9 +1873,7 @@ static DBusMessage *hs_set_gain(DBusConnection *conn,
err = headset_set_gain(device, gain, type);
if (err < 0)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".InvalidArgument",
- "Must be less than or equal to 15");
+ return btd_error_invalid_args(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
diff --git a/serial/port.c b/serial/port.c
index 33450b3..233e317 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -234,12 +234,6 @@ void port_release_all(void)
g_slist_free(devices);
}
-static inline DBusMessage *failed(DBusMessage *msg, const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "%s", description);
-}
-
static void open_notify(int fd, int err, struct serial_port *port)
{
struct serial_device *device = port->device;
@@ -495,7 +489,7 @@ static DBusMessage *port_connect(DBusConnection *conn,
}
if (port->listener_id)
- return failed(msg, "Port already in use");
+ return btd_error_failed(msg, "Port already in use");
port->listener_id = g_dbus_add_disconnect_watch(conn,
dbus_message_get_sender(msg),
diff --git a/serial/proxy.c b/serial/proxy.c
index 20aea7d..b1ee65e 100644
--- a/serial/proxy.c
+++ b/serial/proxy.c
@@ -131,12 +131,6 @@ static void proxy_free(struct serial_proxy *prx)
g_free(prx);
}
-static inline DBusMessage *failed(DBusMessage *msg, const char *description)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "%s", description);
-}
-
static void add_lang_attr(sdp_record_t *r)
{
sdp_lang_attr_t base_lang;
@@ -551,9 +545,7 @@ static DBusMessage *proxy_enable(DBusConnection *conn,
int err;
err = enable_proxy(prx);
- if (err == -EALREADY)
- return failed(msg, "Already enabled");
- else if (err < 0)
+ if (err < 0)
return btd_error_failed(msg, strerror(-err));
return dbus_message_new_method_return(msg);
@@ -565,7 +557,7 @@ static DBusMessage *proxy_disable(DBusConnection *conn,
struct serial_proxy *prx = data;
if (!prx->io)
- return failed(msg, "Not enabled");
+ return btd_error_failed(msg, "Not enabled");
/* Remove the watches and unregister the record */
disable_proxy(prx);
diff --git a/src/adapter.c b/src/adapter.c
index 73c8a9b..2b66490 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -146,12 +146,6 @@ static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
"Adapter is not ready");
}
-static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
-{
- return g_dbus_create_error(msg, ERROR_INTERFACE ".NotInProgress",
- "%s", str);
-}
-
static int found_device_cmp(const struct remote_dev_info *d1,
const struct remote_dev_info *d2)
{
@@ -1232,7 +1226,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
ba2str(&adapter->bdaddr, srcaddr);
if (check_address(srcaddr) < 0)
- return adapter_not_ready(msg);
+ return btd_error_invalid_args(msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -1511,7 +1505,7 @@ static DBusMessage *cancel_device_creation(DBusConnection *conn,
device = adapter_find_device(adapter, address);
if (!device || !device_is_creating(device, NULL))
- return not_in_progress(msg, "Device creation not in progress");
+ return btd_error_does_not_exist(msg);
if (!device_is_creating(device, sender))
return btd_error_not_authorized(msg);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 2/3] remove error_common_reply()
From: Gustavo F. Padovan @ 2010-12-15 21:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1292448568-16854-1-git-send-email-padovan@profusion.mobi>
Remove old dbus error report function. This patch doesn't make things
really really better, but is a start.
---
audio/gateway.c | 18 ++++++++++--------
audio/headset.c | 37 +++++++++++++++----------------------
audio/sink.c | 7 ++++---
audio/source.c | 7 ++++---
src/error.c | 18 ------------------
src/error.h | 3 ---
6 files changed, 33 insertions(+), 57 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index 6a095ca..da899a0 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -254,10 +254,11 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err,
return;
fail:
- if (gw->msg)
- error_common_reply(dev->conn, gw->msg,
- ERROR_INTERFACE ".Failed",
- "Connection attempt failed");
+ if (gw->msg) {
+ DBusMessage *reply;
+ reply = btd_error_failed(gw->msg, "Connect failed");
+ g_dbus_send_message(dev->conn, reply);
+ }
change_state(dev, GATEWAY_STATE_DISCONNECTED);
}
@@ -333,10 +334,11 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
return;
fail:
- if (gw->msg)
- error_common_reply(dev->conn, gw->msg,
- ERROR_INTERFACE ".NotSupported",
- "Not supported");
+ if (gw->msg) {
+ DBusMessage *reply = btd_error_failed(gw->msg,
+ gerr ? gerr->message : strerror(-err));
+ g_dbus_send_message(dev->conn, reply);
+ }
change_state(dev, GATEWAY_STATE_DISCONNECTED);
diff --git a/audio/headset.c b/audio/headset.c
index 34b2b89..55bdc61 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -176,19 +176,12 @@ struct event {
static GSList *headset_callbacks = NULL;
-static DBusHandlerResult error_not_supported(DBusConnection *conn,
- DBusMessage *msg)
+static void error_connect_failed(DBusConnection *conn, DBusMessage *msg,
+ int err)
{
- return error_common_reply(conn, msg, ERROR_INTERFACE ".NotSupported",
- "Not supported");
-}
-
-static DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn,
- DBusMessage *msg, int err)
-{
- return error_common_reply(conn, msg,
- ERROR_INTERFACE ".ConnectionAttemptFailed",
- err < 0 ? strerror(-err) : "Connection attempt failed");
+ DBusMessage *reply = btd_error_failed(msg,
+ err < 0 ? strerror(-err) : "Connect failed");
+ g_dbus_send_message(conn, reply);
}
static int rfcomm_connect(struct audio_device *device, headset_stream_cb_t cb,
@@ -567,9 +560,7 @@ static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
if (p != NULL) {
p->err = -errno;
if (p->msg)
- error_connection_attempt_failed(dev->conn,
- p->msg,
- p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
pending_connect_finalize(dev);
}
@@ -679,7 +670,7 @@ static void hfp_slc_complete(struct audio_device *dev)
p->err = sco_connect(dev, NULL, NULL, NULL);
if (p->err < 0) {
if (p->msg)
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
pending_connect_finalize(dev);
}
}
@@ -1397,7 +1388,7 @@ void headset_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
failed:
if (p && p->msg)
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
pending_connect_finalize(dev);
if (hs->rfcomm)
headset_set_state(dev, HEADSET_STATE_CONNECTED);
@@ -1454,7 +1445,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
error("Unable to get service record: %s (%d)",
strerror(-err), -err);
p->err = -err;
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
goto failed;
}
@@ -1503,7 +1494,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
if (err < 0) {
error("Unable to connect: %s (%d)", strerror(-err), -err);
p->err = -err;
- error_connection_attempt_failed(dev->conn, p->msg, p->err);
+ error_connect_failed(dev->conn, p->msg, p->err);
goto failed;
}
@@ -1513,8 +1504,10 @@ failed_not_supported:
if (p->svclass == HANDSFREE_SVCLASS_ID &&
get_records(dev, NULL, NULL, NULL) == 0)
return;
- if (p->msg)
- error_not_supported(dev->conn, p->msg);
+ if (p->msg) {
+ DBusMessage *reply = btd_error_not_supported(p->msg);
+ g_dbus_send_message(dev->conn, reply);
+ }
failed:
p->svclass = 0;
pending_connect_finalize(dev);
@@ -2667,7 +2660,7 @@ void headset_shutdown(struct audio_device *dev)
struct pending_connect *p = dev->headset->pending;
if (p && p->msg)
- error_connection_attempt_failed(dev->conn, p->msg, ECANCELED);
+ error_connect_failed(dev->conn, p->msg, ECANCELED);
pending_connect_finalize(dev);
headset_set_state(dev, HEADSET_STATE_DISCONNECTED);
diff --git a/audio/sink.c b/audio/sink.c
index 5746c55..2d5db18 100644
--- a/audio/sink.c
+++ b/audio/sink.c
@@ -253,10 +253,11 @@ static void stream_state_changed(struct avdtp_stream *stream,
sink->stream_state = new_state;
}
-static DBusHandlerResult error_failed(DBusConnection *conn,
- DBusMessage *msg, const char * desc)
+static void error_failed(DBusConnection *conn, DBusMessage *msg,
+ const char *desc)
{
- return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
+ DBusMessage *reply = btd_error_failed(msg, desc);
+ g_dbus_send_message(conn, reply);
}
static gboolean stream_setup_retry(gpointer user_data)
diff --git a/audio/source.c b/audio/source.c
index 29ceb0f..6d266f2 100644
--- a/audio/source.c
+++ b/audio/source.c
@@ -206,10 +206,11 @@ static void stream_state_changed(struct avdtp_stream *stream,
source->stream_state = new_state;
}
-static DBusHandlerResult error_failed(DBusConnection *conn,
- DBusMessage *msg, const char * desc)
+static void error_failed(DBusConnection *conn, DBusMessage *msg,
+ const char *desc)
{
- return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
+ DBusMessage *reply = btd_error_failed(msg, desc);
+ g_dbus_send_message(conn, reply);
}
static gboolean stream_setup_retry(gpointer user_data)
diff --git a/src/error.c b/src/error.c
index 25f89f6..7d3afd4 100644
--- a/src/error.c
+++ b/src/error.c
@@ -31,24 +31,6 @@
#include "error.h"
-/* Helper function - internal use only */
-DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
- const char *name, const char *descr)
-{
- DBusMessage *derr;
-
- if (!conn || !msg)
- return DBUS_HANDLER_RESULT_HANDLED;
-
- derr = dbus_message_new_error(msg, name, descr);
- if (!derr)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
- g_dbus_send_message(conn, derr);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
DBusMessage *btd_error_invalid_args(DBusMessage *msg)
{
return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
diff --git a/src/error.h b/src/error.h
index 0f2eb22..b8c06ce 100644
--- a/src/error.h
+++ b/src/error.h
@@ -27,9 +27,6 @@
#define ERROR_INTERFACE "org.bluez.Error"
-DBusHandlerResult error_common_reply(DBusConnection *conn, DBusMessage *msg,
- const char *name, const char *descr);
-
DBusMessage *btd_error_invalid_args(DBusMessage *msg);
DBusMessage *btd_error_busy(DBusMessage *msg);
DBusMessage *btd_error_already_exists(DBusMessage *msg);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 1/3] add btd_error_agent_not_assigned()
From: Gustavo F. Padovan @ 2010-12-15 21:29 UTC (permalink / raw)
To: linux-bluetooth
---
audio/gateway.c | 3 +--
src/adapter.c | 3 +--
src/error.c | 6 ++++++
src/error.h | 1 +
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/audio/gateway.c b/audio/gateway.c
index 4d38be7..6a095ca 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -367,8 +367,7 @@ static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg,
int err;
if (!gw->agent)
- return g_dbus_create_error(msg, ERROR_INTERFACE
- ".Failed", "Agent not assigned");
+ return btd_error_agent_not_assigned(msg);
err = get_records(au_dev);
if (err < 0)
diff --git a/src/adapter.c b/src/adapter.c
index 2ff59a0..73c8a9b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1412,8 +1412,7 @@ static DBusMessage *request_session(DBusConnection *conn,
int err;
if (!adapter->agent)
- return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
- "No agent registered");
+ return btd_error_agent_not_assigned(msg);
if (!adapter->mode_sessions)
adapter->global_mode = adapter->mode;
diff --git a/src/error.c b/src/error.c
index 3a78628..25f89f6 100644
--- a/src/error.c
+++ b/src/error.c
@@ -115,6 +115,12 @@ DBusMessage *btd_error_no_such_adapter(DBusMessage *msg)
"No such adapter");
}
+DBusMessage *btd_error_agent_not_assigned(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".AgentNotAssigned",
+ "Agent Not Assigned");
+}
+
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str)
{
return g_dbus_create_error(msg, ERROR_INTERFACE
diff --git a/src/error.h b/src/error.h
index faaef0a..0f2eb22 100644
--- a/src/error.h
+++ b/src/error.h
@@ -41,4 +41,5 @@ DBusMessage *btd_error_in_progress(DBusMessage *msg);
DBusMessage *btd_error_does_not_exist(DBusMessage *msg);
DBusMessage *btd_error_not_authorized(DBusMessage *msg);
DBusMessage *btd_error_no_such_adapter(DBusMessage *msg);
+DBusMessage *btd_error_agent_not_assigned(DBusMessage *msg);
DBusMessage *btd_error_failed(DBusMessage *msg, const char *str);
--
1.7.3.2
^ permalink raw reply related
* [PATCH] Fix memory leak of gattrib commands queue
From: Claudio Takahasi @ 2010-12-15 20:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
---
attrib/gattrib.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 4ed29d9..eace01b 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -177,6 +177,7 @@ void g_attrib_unref(GAttrib *attrib)
while ((c = g_queue_pop_head(attrib->queue)))
command_destroy(c);
+ g_queue_free(attrib->queue);
attrib->queue = NULL;
for (l = attrib->events; l; l = l->next)
--
1.7.3.3
^ permalink raw reply related
* [PATCH 5/5] Remove unneeded variable
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
---
src/glib-helper.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/glib-helper.c b/src/glib-helper.c
index edc46d8..8cf29ae 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -525,7 +525,6 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
{
struct gattrib_context *ctxt;
GIOChannel *io;
- GError *gerr = NULL;
ctxt = g_try_new0(struct gattrib_context, 1);
if (ctxt == NULL)
@@ -538,14 +537,14 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
ctxt->destroy = destroy;
if (psm < 0)
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
+ io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, NULL,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_CID, GATT_CID,
BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
else
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
+ io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, NULL,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_PSM, psm,
--
1.7.3.3
^ permalink raw reply related
* [PATCH 4/5] Fix missing reply when create device is cancelled
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
When CancelDeviceCreation is called or when the device is removed for
any reason, the reply for the pending CreateDevice is not sent.
---
src/device.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/device.c b/src/device.c
index cf3b146..a881c4c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -730,8 +730,10 @@ void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
if (device->bonding)
bonding_request_cancel(device->bonding);
- if (device->browse)
+ if (device->browse) {
+ discover_services_reply(device->browse, -ECANCELED, NULL);
browse_request_cancel(device->browse);
+ }
if (msg)
device->disconnects = g_slist_append(device->disconnects,
@@ -1043,8 +1045,10 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
if (device->bonding)
device_cancel_bonding(device, HCI_OE_USER_ENDED_CONNECTION);
- if (device->browse)
+ if (device->browse) {
+ discover_services_reply(device->browse, -ECANCELED, NULL);
browse_request_cancel(device->browse);
+ }
if (device->handle)
do_disconnect(device);
--
1.7.3.3
^ permalink raw reply related
* [PATCH 3/5] Return an error if adapter_create_device fails
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
This function can fail if the device object is already registered or if
the system doesn't have enough memory. Issue detected due wrong device
object reference counting that doesn't unregister the D-Bus object path
when the device is removed.
---
src/adapter.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index c1fddce..f71d063 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1595,7 +1595,8 @@ static DBusMessage *create_device(DBusConnection *conn,
device = adapter_create_device(conn, adapter, address, type);
if (!device)
- return NULL;
+ return btd_error_failed(msg,
+ "Unable to create a new device object");
if (type == DEVICE_TYPE_LE && !event_is_connectable(dev->evt_type)) {
/* Device is not connectable */
@@ -1693,7 +1694,8 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
device = adapter_create_device(conn, adapter, address, type);
if (!device)
- return NULL;
+ return btd_error_failed(msg,
+ "Unable to create a new device object");
} else
type = device_get_type(device);
--
1.7.3.3
^ permalink raw reply related
* [PATCH 2/5] Change CreatePairedDevice to support LE devices
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
From: Sheldon Demario <sheldon.demario@openbossa.org>
CreatePairedDevice implements now the same behaviour of CreateDevice,
triggering Discover All Primary Services when needed. SMP negotiation
starts when the link is established. LE capable kernel is required to
test this method properly.
Limitation: For dual mode devices, Discover All Primary Services is not
being executed after SDP search if GATT record is found.
---
src/adapter.c | 46 ++++++++++++++++++++++++---
src/device.c | 89 +++++++++++++++++++++++++++-------------------------
src/device.h | 7 +++-
src/glib-helper.c | 5 ++-
src/glib-helper.h | 3 ++
5 files changed, 98 insertions(+), 52 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 2ff59a0..c1fddce 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1611,7 +1611,11 @@ static DBusMessage *create_device(DBusConnection *conn,
return reply;
}
- err = device_browse(device, conn, msg, NULL, FALSE);
+ if (type != DEVICE_TYPE_LE)
+ err = device_browse_sdp(device, conn, msg, NULL, FALSE);
+ else
+ err = device_browse_primary(device, conn, msg, BT_IO_SEC_LOW);
+
if (err < 0) {
adapter_remove_device(conn, adapter, device, TRUE);
return btd_error_failed(msg, strerror(-err));
@@ -1642,6 +1646,8 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
struct btd_device *device;
const gchar *address, *agent_path, *capability, *sender;
uint8_t cap;
+ device_type_t type;
+ int err;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_OBJECT_PATH, &agent_path,
@@ -1666,12 +1672,40 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
if (cap == IO_CAPABILITY_INVALID)
return btd_error_invalid_args(msg);
- device = adapter_get_device(conn, adapter, address);
- if (!device)
- return btd_error_failed(msg,
- "Unable to create a new device object");
+ device = adapter_find_device(adapter, address);
+ if (!device) {
+ struct remote_dev_info *dev, match;
+
+ memset(&match, 0, sizeof(struct remote_dev_info));
+ str2ba(address, &match.bdaddr);
+ match.name_status = NAME_ANY;
+
+ dev = adapter_search_found_devices(adapter, &match);
+ if (dev && dev->flags)
+ type = flags2type(dev->flags);
+ else
+ type = DEVICE_TYPE_BREDR;
+
+ if (type == DEVICE_TYPE_LE &&
+ !event_is_connectable(dev->evt_type))
+ return btd_error_failed(msg,
+ "Device is not connectable");
+
+ device = adapter_create_device(conn, adapter, address, type);
+ if (!device)
+ return NULL;
+ } else
+ type = device_get_type(device);
+
+ if (type != DEVICE_TYPE_LE)
+ return device_create_bonding(device, conn, msg,
+ agent_path, cap);
- return device_create_bonding(device, conn, msg, agent_path, cap);
+ err = device_browse_primary(device, conn, msg, BT_IO_SEC_HIGH);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+
+ return NULL;
}
static gint device_path_cmp(struct btd_device *device, const gchar *path)
diff --git a/src/device.c b/src/device.c
index d20a6d4..cf3b146 100644
--- a/src/device.c
+++ b/src/device.c
@@ -586,7 +586,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
return btd_error_invalid_args(msg);
if (strlen(pattern) == 0) {
- err = device_browse(device, conn, msg, NULL, FALSE);
+ err = device_browse_sdp(device, conn, msg, NULL, FALSE);
if (err < 0)
goto fail;
} else {
@@ -597,7 +597,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
sdp_uuid128_to_uuid(&uuid);
- err = device_browse(device, conn, msg, &uuid, FALSE);
+ err = device_browse_sdp(device, conn, msg, &uuid, FALSE);
if (err < 0)
goto fail;
}
@@ -988,6 +988,11 @@ void device_get_name(struct btd_device *device, char *name, size_t len)
strncpy(name, device->name, len);
}
+device_type_t device_get_type(struct btd_device *device)
+{
+ return device->type;
+}
+
void device_remove_bonding(struct btd_device *device)
{
char filename[PATH_MAX + 1];
@@ -1540,41 +1545,62 @@ done:
browse_request_free(req);
}
-static struct browse_req *browse_primary(struct btd_device *device, int *err)
+int device_browse_primary(struct btd_device *device, DBusConnection *conn,
+ DBusMessage *msg, BtIOSecLevel sec_level)
{
struct btd_adapter *adapter = device->adapter;
struct browse_req *req;
bdaddr_t src;
- int ret;
+ int err;
+
+ if (device->browse)
+ return -EBUSY;
req = g_new0(struct browse_req, 1);
req->device = btd_device_ref(device);
adapter_get_address(adapter, &src);
- ret = bt_discover_primary(&src, &device->bdaddr, -1, primary_cb, req,
- NULL);
-
- if (ret < 0) {
+ err = bt_discover_primary(&src, &device->bdaddr, -1, primary_cb, req,
+ sec_level, NULL);
+ if (err < 0) {
browse_request_free(req);
- if (err)
- *err = ret;
+ return err;
+ }
- return NULL;
+ if (conn == NULL)
+ conn = get_dbus_connection();
+
+ req->conn = dbus_connection_ref(conn);
+ device->browse = req;
+
+ if (msg) {
+ const char *sender = dbus_message_get_sender(msg);
+
+ req->msg = dbus_message_ref(msg);
+ /* Track the request owner to cancel it
+ * automatically if the owner exits */
+ req->listener_id = g_dbus_add_disconnect_watch(conn,
+ sender,
+ discover_services_req_exit,
+ req, NULL);
}
- return req;
+ return err;
}
-static struct browse_req *browse_sdp(struct btd_device *device, uuid_t *search,
- gboolean reverse, int *err)
+int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
+ DBusMessage *msg, uuid_t *search, gboolean reverse)
{
struct btd_adapter *adapter = device->adapter;
struct browse_req *req;
bt_callback_t cb;
bdaddr_t src;
uuid_t uuid;
- int ret;
+ int err;
+
+ if (device->browse)
+ return -EBUSY;
adapter_get_address(adapter, &src);
@@ -1589,34 +1615,11 @@ static struct browse_req *browse_sdp(struct btd_device *device, uuid_t *search,
cb = browse_cb;
}
- ret = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
- if (ret < 0) {
+ err = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
+ if (err < 0) {
browse_request_free(req);
- if (err)
- *err = ret;
-
- return NULL;
- }
-
- return req;
-}
-
-int device_browse(struct btd_device *device, DBusConnection *conn,
- DBusMessage *msg, uuid_t *search, gboolean reverse)
-{
- struct browse_req *req;
- int err = 0;
-
- if (device->browse)
- return -EBUSY;
-
- if (device->type == DEVICE_TYPE_LE)
- req = browse_primary(device, &err);
- else
- req = browse_sdp(device, search, reverse, &err);
-
- if (req == NULL)
return err;
+ }
if (conn == NULL)
conn = get_dbus_connection();
@@ -1719,7 +1722,7 @@ static gboolean start_discovery(gpointer user_data)
{
struct btd_device *device = user_data;
- device_browse(device, NULL, NULL, NULL, TRUE);
+ device_browse_sdp(device, NULL, NULL, NULL, TRUE);
device->discov_timer = 0;
@@ -2051,7 +2054,7 @@ void device_bonding_complete(struct btd_device *device, uint8_t status)
device->discov_timer = 0;
}
- device_browse(device, bonding->conn, bonding->msg,
+ device_browse_sdp(device, bonding->conn, bonding->msg,
NULL, FALSE);
bonding_request_free(bonding);
diff --git a/src/device.h b/src/device.h
index 784e931..cafa529 100644
--- a/src/device.h
+++ b/src/device.h
@@ -24,6 +24,8 @@
#define DEVICE_INTERFACE "org.bluez.Device"
+#include "btio.h"
+
struct btd_device;
typedef enum {
@@ -46,9 +48,12 @@ struct btd_device *device_create(DBusConnection *conn,
const gchar *address, device_type_t type);
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
+device_type_t device_get_type(struct btd_device *device);
void device_remove(struct btd_device *device, gboolean remove_stored);
gint device_address_cmp(struct btd_device *device, const gchar *address);
-int device_browse(struct btd_device *device, DBusConnection *conn,
+int device_browse_primary(struct btd_device *device, DBusConnection *conn,
+ DBusMessage *msg, BtIOSecLevel sec_level);
+int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
DBusMessage *msg, uuid_t *search, gboolean reverse);
void device_probe_drivers(struct btd_device *device, GSList *profiles);
const sdp_record_t *btd_device_get_record(struct btd_device *device,
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 6505249..edc46d8 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -520,6 +520,7 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
bt_primary_t cb, void *user_data,
+ BtIOSecLevel sec_level,
bt_destroy_t destroy)
{
struct gattrib_context *ctxt;
@@ -541,14 +542,14 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_CID, GATT_CID,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
else
io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_PSM, psm,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
if (io == NULL) {
diff --git a/src/glib-helper.h b/src/glib-helper.h
index 5bb20a6..a16de6c 100644
--- a/src/glib-helper.h
+++ b/src/glib-helper.h
@@ -21,6 +21,8 @@
*
*/
+#include "btio.h"
+
typedef void (*bt_callback_t) (sdp_list_t *recs, int err, gpointer user_data);
typedef void (*bt_primary_t) (GSList *l, int err, gpointer user_data);
typedef void (*bt_destroy_t) (gpointer user_data);
@@ -35,6 +37,7 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst);
int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
bt_primary_t cb, void *user_data,
+ BtIOSecLevel sec_level,
bt_destroy_t destroy);
gchar *bt_uuid2string(uuid_t *uuid);
--
1.7.3.3
^ permalink raw reply related
* [PATCH 1/5] Implement cancel primary discovery session
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
Extend bt_cancel_discovery function to cancel an ongoing Discover
All Primary Services procedure.
---
src/device.c | 11 +++----
src/glib-helper.c | 73 ++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 63 insertions(+), 21 deletions(-)
diff --git a/src/device.c b/src/device.c
index cec2153..d20a6d4 100644
--- a/src/device.c
+++ b/src/device.c
@@ -186,8 +186,7 @@ static void browse_request_cancel(struct browse_req *req)
adapter_get_address(adapter, &src);
- if (device->type != DEVICE_TYPE_LE)
- bt_cancel_discovery(&src, &device->bdaddr);
+ bt_cancel_discovery(&src, &device->bdaddr);
device->browse = NULL;
browse_request_free(req);
@@ -1530,11 +1529,11 @@ static void primary_cb(GSList *services, int err, gpointer user_data)
goto done;
}
- services_changed(req->device);
- device_set_temporary(req->device, FALSE);
- device_probe_drivers(req->device, services);
+ services_changed(device);
+ device_set_temporary(device, FALSE);
+ device_probe_drivers(device, services);
- create_device_reply(req->device, req);
+ create_device_reply(device, req);
done:
device->browse = NULL;
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 8181f4d..6505249 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -51,12 +51,15 @@ struct gattrib_context {
bdaddr_t src;
bdaddr_t dst;
GAttrib *attrib;
+ GIOChannel *io;
bt_primary_t cb;
bt_destroy_t destroy;
gpointer user_data;
GSList *uuids;
};
+static GSList *gattrib_list = NULL;
+
struct cached_sdp_session {
bdaddr_t src;
bdaddr_t dst;
@@ -68,12 +71,18 @@ static GSList *cached_sdp_sessions = NULL;
static void gattrib_context_free(struct gattrib_context *ctxt)
{
+ gattrib_list = g_slist_remove(gattrib_list, ctxt);
if (ctxt->destroy)
ctxt->destroy(ctxt->user_data);
g_slist_foreach(ctxt->uuids, (GFunc) g_free, NULL);
g_slist_free(ctxt->uuids);
g_attrib_unref(ctxt->attrib);
+ if (ctxt->io) {
+ g_io_channel_unref(ctxt->io);
+ g_io_channel_shutdown(ctxt->io, FALSE, NULL);
+ }
+
g_free(ctxt);
}
@@ -138,7 +147,6 @@ struct search_context {
bdaddr_t dst;
sdp_session_t *session;
bt_callback_t cb;
- bt_primary_t prim_cb;
bt_destroy_t destroy;
gpointer user_data;
uuid_t uuid;
@@ -373,21 +381,16 @@ static gint find_by_bdaddr(gconstpointer data, gconstpointer user_data)
bacmp(&ctxt->src, &search->src));
}
-int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
+static gint gattrib_find_by_bdaddr(gconstpointer data, gconstpointer user_data)
{
- struct search_context search, *ctxt;
- GSList *match;
+ const struct gattrib_context *ctxt = data, *search = user_data;
- memset(&search, 0, sizeof(search));
- bacpy(&search.src, src);
- bacpy(&search.dst, dst);
-
- /* Ongoing SDP Discovery */
- match = g_slist_find_custom(context_list, &search, find_by_bdaddr);
- if (!match)
- return -ENODATA;
+ return (bacmp(&ctxt->dst, &search->dst) &&
+ bacmp(&ctxt->src, &search->src));
+}
- ctxt = match->data;
+static int cancel_sdp(struct search_context *ctxt)
+{
if (!ctxt->session)
return -ENOTCONN;
@@ -398,9 +401,48 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
sdp_close(ctxt->session);
search_context_cleanup(ctxt);
+
+ return 0;
+}
+
+static int cancel_gattrib(struct gattrib_context *ctxt)
+{
+ if (ctxt->attrib)
+ g_attrib_cancel_all(ctxt->attrib);
+
+ gattrib_context_free(ctxt);
+
return 0;
}
+int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
+{
+ struct search_context sdp_ctxt;
+ struct gattrib_context gatt_ctxt;
+ GSList *match;
+
+ memset(&sdp_ctxt, 0, sizeof(sdp_ctxt));
+ bacpy(&sdp_ctxt.src, src);
+ bacpy(&sdp_ctxt.dst, dst);
+
+ /* Ongoing SDP Discovery */
+ match = g_slist_find_custom(context_list, &sdp_ctxt, find_by_bdaddr);
+ if (match)
+ return cancel_sdp(match->data);
+
+ memset(&gatt_ctxt, 0, sizeof(gatt_ctxt));
+ bacpy(&gatt_ctxt.src, src);
+ bacpy(&gatt_ctxt.dst, dst);
+
+ /* Ongoing Discover All Primary Services */
+ match = g_slist_find_custom(gattrib_list, &gatt_ctxt,
+ gattrib_find_by_bdaddr);
+ if (match == NULL)
+ return -ENOTCONN;
+
+ return cancel_gattrib(match->data);
+}
+
static void primary_cb(guint8 status, const guint8 *pdu, guint16 plen,
gpointer user_data)
{
@@ -471,6 +513,7 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
return;
}
+ ctxt->attrib = g_attrib_new(io);
gatt_discover_primary(ctxt->attrib, 0x0001, 0xffff, NULL, primary_cb,
ctxt);
}
@@ -513,9 +556,9 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
return -EIO;
}
- ctxt->attrib = g_attrib_new(io);
+ ctxt->io = io;
- g_io_channel_unref(io);
+ gattrib_list = g_slist_append(gattrib_list, ctxt);
return 0;
}
--
1.7.3.3
^ permalink raw reply related
* Re: [PATCH] Fix crash while reading from mapped file
From: Anderson Lizardo @ 2010-12-15 18:19 UTC (permalink / raw)
To: Lukasz Pawlik; +Cc: Bastien Nocera, Johan Hedberg, linux-bluetooth
In-Reply-To: <AANLkTimMOeuyUj5CRMsm7QpoumgHRMmOsby2E6GoSHrd@mail.gmail.com>
On Tue, Dec 14, 2010 at 2:20 PM, Lukasz Pawlik <lucas.pawlik@gmail.com> wrote:
> Hi,
>
>> If somebody can explain what that code is supposed to do, then writing a
>> glib-ish version should be trivial, without having to duplicate the
>> contents again. Then again, using something like:
>> g_mapped_file_new ();
>> g_strsplit ();
>> g_mapped_file_unref ();
>
> That won't fix anything since g_mapped_file_new uses mmap function so
> contents may not be zero-terminated and we want use string function
> next.
What about using g_strstr_len() instead of strpbrk() on the original
code? See http://library.gnome.org/devel/glib/unstable/glib-String-Utility-Functions.html#g-strstr-len
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH v2] Bluetooth: Fix __hci_request synchronization for hci_open_dev
From: johan.hedberg @ 2010-12-15 17:33 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
The initialization function used by hci_open_dev (hci_init_req) sends
many different HCI commands. The __hci_request function should only
return when all of these commands have completed (or a timeout occurs).
Several of these commands cause hci_req_complete to be called which
causes __hci_request to return prematurely.
This patch fixes the issue by adding a new hdev->last_init_cmd variable
and making use of the HCI_INIT flag which is set during the
initialization procedure. The hci_req_complete function will no longer
do anything when this flag is set and the completed command wasn't the
last_init_cmd one.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
v2: (based on feedback from Gustavo Padovan) hci_event.c and hci_core.c
are now less dependent on each other regarding this issue. Now the
hci_init_complete call doesn't need to be moved to a new location in
hci_event.c if the sequence of initialization HCI commands changes in
hci_core.c.
include/net/bluetooth/hci_core.h | 4 +++-
net/bluetooth/hci_core.c | 8 ++++++--
net/bluetooth/hci_event.c | 33 +++++++++++++++++++++++----------
3 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3786ee8..23ca4b1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -134,6 +134,8 @@ struct hci_dev {
struct hci_conn_hash conn_hash;
struct list_head blacklist;
+ int last_init_cmd;
+
struct hci_dev_stats stat;
struct sk_buff_head driver_init;
@@ -693,6 +695,6 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock)
-void hci_req_complete(struct hci_dev *hdev, int result);
+void hci_req_complete(struct hci_dev *hdev, int cmd, int result);
#endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6374054..e37b839 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -91,9 +91,12 @@ static void hci_notify(struct hci_dev *hdev, int event)
/* ---- HCI requests ---- */
-void hci_req_complete(struct hci_dev *hdev, int result)
+void hci_req_complete(struct hci_dev *hdev, int cmd, int result)
{
- BT_DBG("%s result 0x%2.2x", hdev->name, result);
+ BT_DBG("%s command %d result 0x%2.2x", hdev->name, cmd, result);
+
+ if (test_bit(HCI_INIT, &hdev->flags) && cmd != hdev->last_init_cmd)
+ return;
if (hdev->req_status == HCI_REQ_PEND) {
hdev->req_result = result;
@@ -252,6 +255,7 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Connection accept timeout ~20 secs */
param = cpu_to_le16(0x7d00);
hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m);
+ hdev->last_init_cmd = HCI_OP_WRITE_CA_TIMEOUT;
}
static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8923b36..3810017 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -58,7 +58,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
hci_conn_check_pending(hdev);
}
@@ -174,7 +174,7 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *s
if (!status)
hdev->link_policy = get_unaligned_le16(sent);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
}
static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
@@ -183,7 +183,7 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_RESET, status);
}
static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -235,7 +235,7 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_AUTH, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
}
static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
@@ -258,7 +258,7 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_ENCRYPT, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
}
static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
@@ -285,7 +285,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
set_bit(HCI_PSCAN, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
}
static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
@@ -383,7 +383,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
}
static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
@@ -536,7 +536,16 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
if (!rp->status)
bacpy(&hdev->bdaddr, &rp->bdaddr);
- hci_req_complete(hdev, rp->status);
+ hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
+}
+
+static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
}
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
@@ -544,7 +553,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
BT_DBG("%s status 0x%x", hdev->name, status);
if (status) {
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
} else
@@ -871,7 +880,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
}
@@ -1379,6 +1388,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_cc_read_bd_addr(hdev, skb);
break;
+ case HCI_OP_WRITE_CA_TIMEOUT:
+ hci_cc_write_ca_timeout(hdev, skb);
+ break;
+
default:
BT_DBG("%s opcode 0x%x", hdev->name, opcode);
break;
--
1.7.2.3
^ permalink raw reply related
* Re: [RFC] Bluetooth: Use non-flushable pb flag by default for ACL data on capable chipsets.
From: Mat Martineau @ 2010-12-15 16:35 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: Emeltchenko Andrei, linux-bluetooth
In-Reply-To: <20101214192223.GD18509@vigoh>
On Tue, 14 Dec 2010, Gustavo F. Padovan wrote:
> Hi Andrei,
>
> * Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2010-12-13 16:38:25 +0200]:
>
>> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
>>
>> Modification of Nick Pelly <npelly@google.com> patch.
>>
>> With Bluetooth 2.1 ACL packets can be flushable or non-flushable. This commit
>> makes ACL data packets non-flushable by default on compatible chipsets, and
>> adds the BT_FLUSHABLE socket option to explicitly request flushable ACL
>> data packets for a given L2CAP socket. This is useful for A2DP data which can
>> be safely discarded if it can not be delivered within a short time (while
>> other ACL data should not be discarded).
>>
>> Note that making ACL data flushable has no effect unless the automatic flush
>> timeout for that ACL link is changed from its default of 0 (infinite).
This is a great feature to add, not only for A2DP. Both ERTM and
streaming mode only really make sense on unreliable links.
>> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
>> ---
>> include/net/bluetooth/bluetooth.h | 5 +++++
>> include/net/bluetooth/hci.h | 2 ++
>> include/net/bluetooth/hci_core.h | 1 +
>> include/net/bluetooth/l2cap.h | 2 ++
>> net/bluetooth/hci_core.c | 6 ++++--
>> net/bluetooth/l2cap.c | 33 +++++++++++++++++++++++++++++++--
>> 6 files changed, 45 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
>> index 0c5e725..ed7d775 100644
>> --- a/include/net/bluetooth/bluetooth.h
>> +++ b/include/net/bluetooth/bluetooth.h
>> @@ -64,6 +64,11 @@ struct bt_security {
>>
>> #define BT_DEFER_SETUP 7
>>
>> +#define BT_FLUSHABLE 8
>> +
>> +#define BT_FLUSHABLE_OFF 0
>> +#define BT_FLUSHABLE_ON 1
>> +
>> #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
>> #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
>> #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
>> index 29a7a8c..333d5cb 100644
>> --- a/include/net/bluetooth/hci.h
>> +++ b/include/net/bluetooth/hci.h
>> @@ -150,6 +150,7 @@ enum {
>> #define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
>>
>> /* ACL flags */
>> +#define ACL_START_NO_FLUSH 0x00
>> #define ACL_CONT 0x01
>> #define ACL_START 0x02
>> #define ACL_ACTIVE_BCAST 0x04
>> @@ -193,6 +194,7 @@ enum {
>> #define LMP_EDR_ESCO_3M 0x40
>> #define LMP_EDR_3S_ESCO 0x80
>>
>> +#define LMP_NO_FLUSH 0x01
>> #define LMP_SIMPLE_PAIR 0x08
>>
>> /* Connection modes */
>> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
>> index 1992fac..9778bc8 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -456,6 +456,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
>> #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
>> #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO)
>> #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
>> +#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
>
> IMHO lmp_flush_capable() makes more sense. We can avoid things like
> (!lmp_no_flush_capable(dev)) and add two negatives in the same comparison.
>
>>
>> /* ----- HCI protocols ----- */
>> struct hci_proto {
>> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
>> index 7ad25ca..af35711 100644
>> --- a/include/net/bluetooth/l2cap.h
>> +++ b/include/net/bluetooth/l2cap.h
>> @@ -75,6 +75,7 @@ struct l2cap_conninfo {
>> #define L2CAP_LM_TRUSTED 0x0008
>> #define L2CAP_LM_RELIABLE 0x0010
>> #define L2CAP_LM_SECURE 0x0020
>> +#define L2CAP_LM_FLUSHABLE 0x0040
>
> Not using this anywhere.
>
>>
>> /* L2CAP command codes */
>> #define L2CAP_COMMAND_REJ 0x01
>> @@ -327,6 +328,7 @@ struct l2cap_pinfo {
>> __u8 sec_level;
>> __u8 role_switch;
>> __u8 force_reliable;
>> + __u8 flushable;
>>
>> __u8 conf_req[64];
>> __u8 conf_len;
>> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
>> index 51c61f7..c0d776b 100644
>> --- a/net/bluetooth/hci_core.c
>> +++ b/net/bluetooth/hci_core.c
>> @@ -1380,7 +1380,7 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
>>
>> skb->dev = (void *) hdev;
>> bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
>> - hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
>> + hci_add_acl_hdr(skb, conn->handle, flags);
>>
>> list = skb_shinfo(skb)->frag_list;
>> if (!list) {
>> @@ -1398,12 +1398,14 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
>> spin_lock_bh(&conn->data_q.lock);
>>
>> __skb_queue_tail(&conn->data_q, skb);
>> + flags &= ~ACL_START;
>> + flags |= ACL_CONT;
>> do {
>> skb = list; list = list->next;
>>
>> skb->dev = (void *) hdev;
>> bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
>> - hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
>> + hci_add_acl_hdr(skb, conn->handle, flags);
>>
>> BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
>>
>> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
>> index c791fcd..c7f25c2 100644
>> --- a/net/bluetooth/l2cap.c
>> +++ b/net/bluetooth/l2cap.c
>> @@ -362,13 +362,19 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
>> static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
>> {
>> struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
>> + u8 flags;
>>
>> BT_DBG("code 0x%2.2x", code);
>>
>> if (!skb)
>> return;
>>
>> - hci_send_acl(conn->hcon, skb, 0);
>> + if (lmp_no_flush_capable(conn->hcon->hdev))
>> + flags = ACL_START_NO_FLUSH;
>> + else
>> + flags = ACL_START;
>> +
>> + hci_send_acl(conn->hcon, skb, flags);
>
> I also agree that l2cap commands should be non-flushable. Just pass
> ACL_START_NO_FLUSH to hci_send_acl() here.
> You should add this check to l2cap_do_send() instead.
>
>> }
>>
>> static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
>> @@ -900,6 +906,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
>> pi->sec_level = l2cap_pi(parent)->sec_level;
>> pi->role_switch = l2cap_pi(parent)->role_switch;
>> pi->force_reliable = l2cap_pi(parent)->force_reliable;
>> + pi->flushable = l2cap_pi(parent)->flushable;
>> } else {
>> pi->imtu = L2CAP_DEFAULT_MTU;
>> pi->omtu = 0;
>> @@ -915,6 +922,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
>> pi->sec_level = BT_SECURITY_LOW;
>> pi->role_switch = 0;
>> pi->force_reliable = 0;
>> + pi->flushable = BT_FLUSHABLE_OFF;
>> }
>>
>> /* Default config options */
>> @@ -2098,6 +2106,20 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
>> bt_sk(sk)->defer_setup = opt;
>> break;
>>
>> + case BT_FLUSHABLE:
>> + if (get_user(opt, (u32 __user *) optval)) {
>> + err = -EFAULT;
>> + break;
>> + }
>> +
>> + if (opt > BT_FLUSHABLE_ON) {
>> + err = -EINVAL;
>> + break;
>> + }
>> +
>> + l2cap_pi(sk)->flushable = opt;
Does it make sense to check the HCI device for flush capability here?
If the HCI device is not capable, this option should remain false.
This would also let the application use getsockopt() to find out if
the link is really flushable or not.
>
> You are not using this flushable value anywhere. Something is wrong here.
I agree - like Gustavo mentioned above, l2cap_do_send() needs to be
checking l2cap_pi(sk)->flushable and setting the flags in
hci_send_acl() appropriately.
There is one more thing missing: Even though there is an L2CAP socket
option to set flush_to, and the flush_to is passed around during L2CAP
configuration, there is no use of the "Write Automatic Flush Timeout"
HCI command to tell the baseband what the flush timeout is! Since the
flush timeout is shared across all connections on the ACL, how should
BlueZ handle the case where different flush timeouts are set on
connections that share the same ACL? (My guess is that either the
longest or shortest timeout should be used, but there are good
arguments either way)
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* [PATCH] Add AVDTP SRC stream send buffer size verification
From: Dmitriy Paliy @ 2010-12-15 9:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Dmitriy Paliy
In-Reply-To: <1292406533-18574-1-git-send-email-dmitriy.paliy@nokia.com>
Functions get_send_buffer_size and set_send_buffer_size are added to
avdpt.c.
get_send_buffer_size returns size of send buffer for a given socket
on success or error code on failure. set_send_buffer_size sets size
of send buffer for a given socket, and returns 0 on success or error
code on failure.
Size of send buffer for L2CAP socket for SRC AVDTP stream is verified
during establishment of a new transport channel. If the size is less
than twice of outgoing L2CAP MTU, then it is considered as being
insufficient to handle streaming data reliably.
In this case buffer size is increased to be twice of MTU size. Such
fixes some IOP problems with car-kits that use large MTU for music
playback.
---
audio/avdtp.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/audio/avdtp.c b/audio/avdtp.c
index 1683e7c..34b95fd 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -838,6 +838,40 @@ static gboolean transport_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
}
+static int get_send_buffer_size(int sk)
+{
+ int size;
+ socklen_t optlen = sizeof(size);
+
+ if (getsockopt(sk, SOL_SOCKET, SO_SNDBUF, &size, &optlen) < 0) {
+ int err = -errno;
+ error("getsockopt(SO_SNDBUF) failed: %s (%d)", strerror(-err),
+ -err);
+ return err;
+ }
+
+ /*
+ * Doubled value is returned by getsockopt since kernel uses that
+ * space for its own purposes (see man 7 socket, bookkeeping overhead
+ * for SO_SNDBUF).
+ */
+ return size / 2;
+}
+
+static int set_send_buffer_size(int sk, int size)
+{
+ socklen_t optlen = sizeof(size);
+
+ if (setsockopt(sk, SOL_SOCKET, SO_SNDBUF, &size, optlen) < 0) {
+ int err = -errno;
+ error("setsockopt(SO_SNDBUF) failed: %s (%d)", strerror(-err),
+ -err);
+ return err;
+ }
+
+ return 0;
+}
+
static void handle_transport_connect(struct avdtp *session, GIOChannel *io,
uint16_t imtu, uint16_t omtu)
{
@@ -865,6 +899,25 @@ static void handle_transport_connect(struct avdtp *session, GIOChannel *io,
stream->omtu = omtu;
stream->imtu = imtu;
+ /* only if local SEP is of type SRC */
+ if (sep->info.type == AVDTP_SEP_TYPE_SOURCE) {
+ int sk, buf_size, min_buf_size;
+
+ sk = g_io_channel_unix_get_fd(stream->io);
+ buf_size = get_send_buffer_size(sk);
+ if (buf_size < 0)
+ goto proceed;
+
+ DBG("sk %d, omtu %d, send buffer size %d", sk, omtu, buf_size);
+ min_buf_size = omtu * 2;
+ if (buf_size < min_buf_size) {
+ DBG("send buffer size to be increassed to %d",
+ min_buf_size);
+ set_send_buffer_size(sk, min_buf_size);
+ }
+ }
+
+proceed:
if (!stream->open_acp && sep->cfm && sep->cfm->open)
sep->cfm->open(session, sep, stream, NULL, sep->user_data);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 0/1] AVDTP SRC stream send buffer size verification
From: Dmitriy Paliy @ 2010-12-15 9:48 UTC (permalink / raw)
To: linux-bluetooth
Hi,
In this patch, send buffer size for L2CAP socket is verified against
outgoing L2CAP MTU size and increased to be twice of it if it is less
than that. Such verification is done for AVDTP source transport channel
only.
Reason to do this check is that system default socket buffer size was
reduced in Meego and it affected IOP with some car-kits that use large
MTUs.
Worth to mention that send buffer size is never decreased, and can be
increased only.
BR,
Dmitriy
^ permalink raw reply
* Re: [PATCH] Added enc_read_blob_req() API to ATT transport, to enable the reading of attributes that exceed the length of the MTU.
From: Anderson Lizardo @ 2010-12-14 20:29 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <1292356246-24012-2-git-send-email-bgix@codeaurora.org>
On Tue, Dec 14, 2010 at 3:50 PM, Brian Gix <bgix@codeaurora.org> wrote:
> --
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>
> ---
> attrib/att.c | 19 +++++++++++++++++++
> attrib/att.h | 2 ++
> 2 files changed, 21 insertions(+), 0 deletions(-)
Usually, patches sent do Bluez, starte with short commit messages like:
Add ...
Fix ...
Implement ...
Note that we don't use "Added", "Fixed" etc. See the git log for
reference. In this case, you should consider at least adding a short
summary and your original summary as the "commit description", in the
form:
<short summary, e.g. "Implement Read Blob Request">
<empty line>
<long description>
Also as Vinicius mentioned, I think your e-mail signature will show up
on the commit description if someone applies it with "git am". I
suggest you send your patches with "git send-email".
Another issue: looks your e-mail client replaced tabs with spaces (but
it might just be Google messing up on my side).
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* Re: [PATCH 0/1] Add enc_read_blob_req() API to ATT
From: Brian Gix @ 2010-12-14 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer
In-Reply-To: <1292356246-24012-1-git-send-email-bgix@codeaurora.org>
Hi Gustavo, Vinicius,
On 12/14/2010 11:50 AM, Brian Gix wrote:
> Atomic change to add ATT_OP_READ_BLOB_REQ encoing to ATT. No dependancies.
>
>
This patch contains only the stand-alone ATT changes, and corrects the
ws issue identified by Vinicius.
--
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* [PATCH] Added enc_read_blob_req() API to ATT transport, to enable the reading of attributes that exceed the length of the MTU.
From: Brian Gix @ 2010-12-14 19:50 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer, Brian Gix
In-Reply-To: <1292356246-24012-1-git-send-email-bgix@codeaurora.org>
--
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
---
attrib/att.c | 19 +++++++++++++++++++
attrib/att.h | 2 ++
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/attrib/att.c b/attrib/att.c
index 445b192..f8dbc02 100644
--- a/attrib/att.c
+++ b/attrib/att.c
@@ -542,6 +542,25 @@ uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len)
return min_len;
}
+uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
+ int len)
+{
+ const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle) +
+ sizeof(offset);
+
+ if (pdu == NULL)
+ return 0;
+
+ if (len < min_len)
+ return 0;
+
+ pdu[0] = ATT_OP_READ_BLOB_REQ;
+ att_put_u16(handle, &pdu[1]);
+ att_put_u16(offset, &pdu[3]);
+
+ return min_len;
+}
+
uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle)
{
const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle);
diff --git a/attrib/att.h b/attrib/att.h
index 2c8c724..0b8612e 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -202,6 +202,8 @@ uint16_t enc_write_req(uint16_t handle, const uint8_t *value, int vlen,
uint16_t dec_write_req(const uint8_t *pdu, int len, uint16_t *handle,
uint8_t *value, int *vlen);
uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len);
+uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
+ int len);
uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle);
uint16_t enc_read_resp(uint8_t *value, int vlen, uint8_t *pdu, int len);
uint16_t dec_read_resp(const uint8_t *pdu, int len, uint8_t *value, int *vlen);
--
1.7.1
^ permalink raw reply related
* [PATCH 0/1] Add enc_read_blob_req() API to ATT
From: Brian Gix @ 2010-12-14 19:50 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer
Atomic change to add ATT_OP_READ_BLOB_REQ encoing to ATT. No dependancies.
--
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
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