* [PATCH] Bluetooth: ath3k: add support for 0930:021c
From: Robin Kreis @ 2013-10-18 15:35 UTC (permalink / raw)
To: linux-bluetooth
This is needed for my Toshiba C850-1K0 (AR9462 chip) to discover any
Bluetooth devices.
---
drivers/bluetooth/ath3k.c | 2 ++
drivers/bluetooth/btusb.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 0a327f4..23b813a 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -87,6 +87,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0CF3, 0xE004) },
{ USB_DEVICE(0x0CF3, 0xE005) },
{ USB_DEVICE(0x0930, 0x0219) },
+ { USB_DEVICE(0x0930, 0x021c) },
{ USB_DEVICE(0x0489, 0xe057) },
{ USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x0489, 0xe04e) },
@@ -129,6 +130,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f3dfc0a..92fe3c00 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -154,6 +154,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
--
1.8.4.1
^ permalink raw reply related
* Re: [PATCH] wiimote: add new documented device IDs
From: Johan Hedberg @ 2013-10-18 14:26 UTC (permalink / raw)
To: David Herrmann; +Cc: linux-bluetooth
In-Reply-To: <1382105627-22344-1-git-send-email-dh.herrmann@gmail.com>
Hi David,
On Fri, Oct 18, 2013, David Herrmann wrote:
> Add some new device IDs for the LEGO wiimote and Wii U Pro Controllers.
> Also add comments for each ID so we can track them better.
> ---
> plugins/wiimote.c | 12 +++++++-----
> 1 file changed, 7 insertions(+), 5 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [RFC 06/15] Bluetooth: Background scanning
From: Andre Guedes @ 2013-10-18 14:26 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <CA624B73-F848-407A-B7DB-10D564049EAF@holtmann.org>
Hi Marcel,
On Oct 17, 2013, at 6:31 AM, Marcel Holtmann wrote:
> Hi Andre,
>=20
>> This patch adds helpers to trigger and untrigger the background
>> scanning. As long as the number of triggers are greater than zero,
>> we keep the background scanning running. Once the number of triggers
>> reaches zero, it is stopped.
>>=20
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> include/net/bluetooth/hci_core.h | 7 ++++
>> net/bluetooth/hci_core.c | 83 =
++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 90 insertions(+)
>>=20
>> diff --git a/include/net/bluetooth/hci_core.h =
b/include/net/bluetooth/hci_core.h
>> index 1e67da5..cb6458a 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -288,6 +288,10 @@ struct hci_dev {
>> __u8 scan_rsp_data[HCI_MAX_AD_LENGTH];
>> __u8 scan_rsp_data_len;
>>=20
>> + /* This counter tracks the number of background scanning =
triggers
>> + */
>> + atomic_t background_scan_cnt;
>> +
>> int (*open)(struct hci_dev *hdev);
>> int (*close)(struct hci_dev *hdev);
>> int (*flush)(struct hci_dev *hdev);
>> @@ -1191,4 +1195,7 @@ void hci_le_start_enc(struct hci_conn *conn, =
__le16 ediv, __u8 rand[8],
>> #define SCO_AIRMODE_CVSD 0x0000
>> #define SCO_AIRMODE_TRANSP 0x0003
>>=20
>> +int hci_trigger_background_scan(struct hci_dev *hdev);
>> +int hci_untrigger_background_scan(struct hci_dev *hdev);
>> +
>=20
> instead of plastering the code with all these places it might be =
better to create a connection parameter hash that actually knows if it =
has any connection parameters stored that need require a passive scan =
now.
>=20
> So instead of trigger and intriguer, the code that adds or removes the =
actual data from our hash can be the trigger itself. Since it knows =
better. And checking after disconnection or other cases becomes a lot =
simpler since you just check the hash if you should be connecting.
I'll follow this approach in v2.
Regards,
Andre=
^ permalink raw reply
* Re: [RFC 07/15] Bluetooth: Refactor hci_disconn_complete_evt
From: Andre Guedes @ 2013-10-18 14:17 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <FDFC9B6A-260D-4A54-83B7-ACCA36DF7B42@holtmann.org>
Hi Marcel,
On Oct 17, 2013, at 6:33 AM, Marcel Holtmann wrote:
> Hi Andrei,
>=20
>> hci_disconn_complete_evt() logic is more complicated than what it
>> should be, making it hard to follow and add new features. This patch
>> does some code refactoring by letting the main flow of the function
>> in first level of function scope.
>>=20
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> net/bluetooth/hci_event.c | 62 =
+++++++++++++++++++++++++----------------------
>> 1 file changed, 33 insertions(+), 29 deletions(-)
>=20
> why this is patch 7/15 is beyond me. These things should go first and =
with a clear commit message why they are are needed. Since if that is =
clear and easily to review, then you do not have to re-base them all the =
time.
I'll move this patch to the beginning of v2 patch set.
>=20
>>=20
>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>> index 6c3b193..edb2342 100644
>> --- a/net/bluetooth/hci_event.c
>> +++ b/net/bluetooth/hci_event.c
>> @@ -1781,6 +1781,8 @@ static void hci_disconn_complete_evt(struct =
hci_dev *hdev, struct sk_buff *skb)
>> {
>> struct hci_ev_disconn_complete *ev =3D (void *) skb->data;
>> struct hci_conn *conn;
>> + u8 type;
>> + bool send_mgmt_event =3D false;
>>=20
>> BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
>>=20
>> @@ -1790,44 +1792,46 @@ static void hci_disconn_complete_evt(struct =
hci_dev *hdev, struct sk_buff *skb)
>> if (!conn)
>> goto unlock;
>>=20
>> - if (ev->status =3D=3D 0)
>> - conn->state =3D BT_CLOSED;
>> -
>> if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
>> - (conn->type =3D=3D ACL_LINK || conn->type =3D=3D LE_LINK)) {
>> - if (ev->status) {
>> + (conn->type =3D=3D ACL_LINK || conn->type =3D=3D LE_LINK))
>> + send_mgmt_event =3D true;
>> +
>> + if (ev->status) {
>> + if (send_mgmt_event)
>> mgmt_disconnect_failed(hdev, &conn->dst, =
conn->type,
>> conn->dst_type, =
ev->status);
>> - } else {
>> - u8 reason =3D hci_to_mgmt_reason(ev->reason);
>> -
>> - mgmt_device_disconnected(hdev, &conn->dst, =
conn->type,
>> - conn->dst_type, =
reason);
>> - }
>> + return;
>> }
>=20
> Unfortunately this diff is hard to read. So you need to explain to me =
in plain English why we are doing this and how it is the same.
Yeah, diff is not good. I'll be more verbose on next version.
Regards,
Andre=
^ permalink raw reply
* [PATCH] wiimote: add new documented device IDs
From: David Herrmann @ 2013-10-18 14:13 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Johan Hedberg, David Herrmann
Add some new device IDs for the LEGO wiimote and Wii U Pro Controllers.
Also add comments for each ID so we can track them better.
---
plugins/wiimote.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/plugins/wiimote.c b/plugins/wiimote.c
index beda307..6cc21ee 100644
--- a/plugins/wiimote.c
+++ b/plugins/wiimote.c
@@ -59,14 +59,16 @@
*/
static uint16_t wii_ids[][2] = {
- { 0x057e, 0x0306 },
- { 0x057e, 0x0330 },
+ { 0x057e, 0x0306 }, /* 1st gen */
+ { 0x054c, 0x0306 }, /* LEGO wiimote */
+ { 0x057e, 0x0330 }, /* 2nd gen */
};
static const char *wii_names[] = {
- "Nintendo RVL-CNT-01",
- "Nintendo RVL-CNT-01-TR",
- "Nintendo RVL-WBC-01",
+ "Nintendo RVL-CNT-01", /* 1st gen */
+ "Nintendo RVL-CNT-01-TR", /* 2nd gen */
+ "Nintendo RVL-CNT-01-UC", /* Wii U Pro Controller */
+ "Nintendo RVL-WBC-01", /* Balance Board */
};
static ssize_t wii_pincb(struct btd_adapter *adapter, struct btd_device *device,
--
1.8.4
^ permalink raw reply related
* Re: [RFC 11/15] Bluetooth: Temporarily stop background scanning on connection
From: Andre Guedes @ 2013-10-18 14:08 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <A1459AED-62FA-4042-B021-7A3157823952@holtmann.org>
Hi Marcel,
On Oct 17, 2013, at 6:43 AM, Marcel Holtmann wrote:
> Hi Andre,
>=20
>> Some LE controllers don't support scanning and initiating a =
connection
>> at the same time. So, for those controllers, we should temporarily
>> stop the background scanning and start it again once the connection
>> attempt is finished (successfully or not).
>>=20
>> So this patch introduces the hci_check_background_scan() which checks
>> if the background scanning should be started.
>>=20
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> include/net/bluetooth/hci_core.h | 1 +
>> net/bluetooth/hci_conn.c | 25 +++++++++++++++++++++++++
>> net/bluetooth/hci_core.c | 18 ++++++++++++++++++
>> net/bluetooth/hci_event.c | 6 ++++++
>> 4 files changed, 50 insertions(+)
>>=20
>> diff --git a/include/net/bluetooth/hci_core.h =
b/include/net/bluetooth/hci_core.h
>> index db39eca..017decc 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -1201,5 +1201,6 @@ void hci_le_start_enc(struct hci_conn *conn, =
__le16 ediv, __u8 rand[8],
>>=20
>> int hci_trigger_background_scan(struct hci_dev *hdev);
>> int hci_untrigger_background_scan(struct hci_dev *hdev);
>> +void hci_check_background_scan(struct hci_dev *hdev);
>>=20
>> #endif /* __HCI_CORE_H */
>> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
>> index d64000e..6ae42c2 100644
>> --- a/net/bluetooth/hci_conn.c
>> +++ b/net/bluetooth/hci_conn.c
>> @@ -541,6 +541,18 @@ static void create_le_conn_complete(struct =
hci_dev *hdev, u8 status)
>>=20
>> done:
>> hci_dev_unlock(hdev);
>> +
>> + /* Check the background scanning since it may have been =
temporarily
>> + * stopped if the controller doesn't support scanning and =
initiate
>> + * state combination.
>> + */
>> + hci_check_background_scan(hdev);
>> +}
>=20
> so what I would do first is assume the controller can not scan while =
being in initiating state or being connected. Make the dead simple only =
a single connection at a time work perfectly. Get the basic =
infrastructure in place.
Ok, I'll do like that.
>=20
>> +
>> +/* Check if controller supports scanning and initiating states =
combination */
>> +static bool is_state_combination_supported(struct hci_dev *hdev)
>> +{
>> + return (hdev->le_states[2] & BIT(6)) ? true : false;
>> }
>>=20
>=20
> Worst function name ever. Also this should use !!(hdev->le_states & x) =
style.
I'll come up with a better name for this helper and use the !! approach.
>=20
> Also we need this more generic anyway. So get the simple part working =
for dumb controllers and we deal with the rest when that part works.
Ok.
Regards,
Andre=
^ permalink raw reply
* Re: [RFC 07/15] Bluetooth: Refactor hci_disconn_complete_evt
From: Andre Guedes @ 2013-10-18 14:08 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <FDFC9B6A-260D-4A54-83B7-ACCA36DF7B42@holtmann.org>
Hi Marcel,
On Oct 17, 2013, at 6:33 AM, Marcel Holtmann wrote:
> Hi Andrei,
>
>> hci_disconn_complete_evt() logic is more complicated than what it
>> should be, making it hard to follow and add new features. This patch
>> does some code refactoring by letting the main flow of the function
>> in first level of function scope.
>>
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> net/bluetooth/hci_event.c | 62 +++++++++++++++++++++++++----------------------
>> 1 file changed, 33 insertions(+), 29 deletions(-)
>
> why this is patch 7/15 is beyond me. These things should go first and with a clear commit message why they are are needed. Since if that is clear and easily to review, then you do not have to re-base them all the time.
I'll move this patch to the beginning of the patch set.
>
>>
>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>> index 6c3b193..edb2342 100644
>> --- a/net/bluetooth/hci_event.c
>> +++ b/net/bluetooth/hci_event.c
>> @@ -1781,6 +1781,8 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
>> {
>> struct hci_ev_disconn_complete *ev = (void *) skb->data;
>> struct hci_conn *conn;
>> + u8 type;
>> + bool send_mgmt_event = false;
>>
>> BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
>>
>> @@ -1790,44 +1792,46 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
>> if (!conn)
>> goto unlock;
>>
>> - if (ev->status == 0)
>> - conn->state = BT_CLOSED;
>> -
>> if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
>> - (conn->type == ACL_LINK || conn->type == LE_LINK)) {
>> - if (ev->status) {
>> + (conn->type == ACL_LINK || conn->type == LE_LINK))
>> + send_mgmt_event = true;
>> +
>> + if (ev->status) {
>> + if (send_mgmt_event)
>> mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
>> conn->dst_type, ev->status);
>> - } else {
>> - u8 reason = hci_to_mgmt_reason(ev->reason);
>> -
>> - mgmt_device_disconnected(hdev, &conn->dst, conn->type,
>> - conn->dst_type, reason);
>> - }
>> + return;
>> }
>
> Unfortunately this diff is hard to read. So you need to explain to me in plain English why we are doing this and how it is the same.
Yes, this diff is not good. I'll be more verbose in the commit message.
Regards,
Andre
^ permalink raw reply
* Re: [RFC 15/15] Bluetooth: Auto connection and power off/on
From: Andre Guedes @ 2013-10-18 14:08 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <2BA6ACEE-8390-48E0-883A-73738551FDDD@holtmann.org>
Hi Marcel,
On Oct 17, 2013, at 7:55 AM, Marcel Holtmann wrote:
> Hi Andre,
>=20
>> If hdev is closed (e.g. Mgmt power off command, RFKILL or controller =
is
>> reset), the established connections are dropped and no Disconnection
>> Complete Event is sent to host. This way, the background scan is not
>> triggered when devices configured with BT_AUTO_CONN_ALWAYS option
>> disconnect. To fix this issue, before dropping the LE connections, we
>> trigger the background scan for each connected device that requires
>> BT_AUTO_CONN_ALWAYS auto connection.
>>=20
>> Moreover, once the adapter is powered on, we should start the =
background
>> scan if we have triggers registered. This way, we keep the background
>> scan running after a power off and power on sequence.
>=20
> these are actually two independent patches.
I'll split this in two patches.
>=20
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> net/bluetooth/hci_conn.c | 35 +++++++++++++++++++++++++++++++++++
>> net/bluetooth/hci_core.c | 2 ++
>> 2 files changed, 37 insertions(+)
>>=20
>> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
>> index 5caf13b..66823eb 100644
>> --- a/net/bluetooth/hci_conn.c
>> +++ b/net/bluetooth/hci_conn.c
>> @@ -954,6 +954,31 @@ timer:
>> =
msecs_to_jiffies(hdev->idle_timeout));
>> }
>>=20
>> +static void le_conn_drop_fixup(struct hci_conn *conn)
>> +{
>> + struct hci_dev *hdev =3D conn->hdev;
>> + struct hci_conn_param *param;
>> + int err;
>> +
>> + param =3D hci_find_conn_param(hdev, &conn->dst, conn->dst_type);
>> + if (!param)
>> + return;
>> +
>> + if (param->auto_connect !=3D BT_AUTO_CONN_ALWAYS)
>> + goto done;
>> +
>> + err =3D hci_trigger_background_scan(hdev);
>> + if (err) {
>> + BT_ERR("Failed to trigger background scanning: %d", =
err);
>> + goto done;
>> + }
>> +
>> + param->bg_scan_triggered =3D true;
>> +
>> +done:
>> + hci_conn_param_put(param);
>> +}
>> +
>> /* Drop all connection on the device */
>> void hci_conn_hash_flush(struct hci_dev *hdev)
>> {
>> @@ -963,6 +988,16 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
>> BT_DBG("hdev %s", hdev->name);
>>=20
>> list_for_each_entry_safe(c, n, &h->list, list) {
>> + /* If this is a LE connection in connected state we =
should do
>> + * some fixup before dropping this connection. Since no
>> + * Disconnection Complete Event will be sent to the =
host, we
>> + * have to trigger the background scan in case this is a
>> + * BT_AUTO_CONN_ALWAYS device. This is handled by the =
le_conn_
>> + * drop_fixup() helper.
>> + */
>> + if (c->type =3D=3D LE_LINK && c->state =3D=3D =
BT_CONNECTED)
>> + le_conn_drop_fixup(c);
>> +
>> c->state =3D BT_CLOSED;
>=20
> I do not like this part. We already have the case where we need to =
re-enable advertising after a connection drops. So this should be in a =
common place. I do not want to hack this in into all kinds of places.
Ok, I'll follow the same approach we have for re-enable advertising.
Regards,
Andre=
^ permalink raw reply
* Re: [RFC 05/15] Bluetooth: Use connection parameters if any
From: Andre Guedes @ 2013-10-18 14:07 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <06808003-600D-45E8-88FD-E8F766DCFBA4@holtmann.org>
Hi Marcel,
On Oct 17, 2013, at 6:27 AM, Marcel Holtmann wrote:
> Hi Andre,
>=20
>> This patch changes hci_create_le_conn() so it uses the connection
>> parameters specified by the user. If no parameters were configured,
>> we use the default values.
>>=20
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> net/bluetooth/hci_conn.c | 12 ++++++++++--
>> 1 file changed, 10 insertions(+), 2 deletions(-)
>>=20
>> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
>> index 4e72650..d64000e 100644
>> --- a/net/bluetooth/hci_conn.c
>> +++ b/net/bluetooth/hci_conn.c
>> @@ -548,6 +548,7 @@ static int hci_create_le_conn(struct hci_conn =
*conn)
>> struct hci_dev *hdev =3D conn->hdev;
>> struct hci_cp_le_create_conn cp;
>> struct hci_request req;
>> + struct hci_conn_param *param;
>> int err;
>>=20
>> hci_req_init(&req, hdev);
>> @@ -558,11 +559,18 @@ static int hci_create_le_conn(struct hci_conn =
*conn)
>> bacpy(&cp.peer_addr, &conn->dst);
>> cp.peer_addr_type =3D conn->dst_type;
>> cp.own_address_type =3D conn->src_type;
>> - cp.conn_interval_min =3D __constant_cpu_to_le16(0x0028);
>> - cp.conn_interval_max =3D __constant_cpu_to_le16(0x0038);
>> cp.supervision_timeout =3D __constant_cpu_to_le16(0x002a);
>> cp.min_ce_len =3D __constant_cpu_to_le16(0x0000);
>> cp.max_ce_len =3D __constant_cpu_to_le16(0x0000);
>> + param =3D hci_find_conn_param(hdev, &conn->dst, conn->dst_type);
>> + if (param) {
>> + cp.conn_interval_min =3D =
cpu_to_le16(param->min_conn_interval);
>> + cp.conn_interval_max =3D =
cpu_to_le16(param->max_conn_interval);
>> + hci_conn_param_put(param);
>> + } else {
>> + cp.conn_interval_min =3D __constant_cpu_to_le16(0x0028);
>> + cp.conn_interval_max =3D __constant_cpu_to_le16(0x0038);
>> + }
>> hci_req_add(&req, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp);
>=20
> so this is part that I do not like at all. We already have the =
hci_conn connection object at this point. So why are these values not =
stored in there. In the end we are paying the price for code like this =
where we have to check if parameters exists, if they do apply them, if =
not use the defaults.
>=20
> I did change the code back from the check for public address and what =
own address type to use. Since it turned out that later on you actually =
need to what you where doing.
>=20
> And this is the same thing in the future. We actually want to know =
what connection parameters we current used. In case we have to update =
them or they change while the connection is on-going.
Sure, I'll save these parameters in hci_conn object.
Regards,
Andre=
^ permalink raw reply
* Re: [RFC 02/15] Bluetooth: Mgmt command for adding connection parameters
From: Andre Guedes @ 2013-10-18 14:07 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <BA029FAA-265C-47A8-953F-95E6B504941B@holtmann.org>
Hi Marcel,
On Oct 17, 2013, at 6:22 AM, Marcel Holtmann wrote:
> Hi Andre,
>=20
>> This patch introduces a new Mgmt command (MGMT_OP_ADD_CONN_PARAM) =
which
>> adds the connection parameters to controller's connection parameters
>> list. These parameters will be used by the kernel when it establishes =
a
>> connection with the given device.
>>=20
>> This patch also moves the 'auto_connect' enum from hci_core.h to
>> bluetooth.h since the will accessed used by userspace in order to
>> send the MGMT_OP_ADD_CONN_PARAM command.
>=20
> the comment about userspace makes no sense. And is not an argument to =
move the enum anywhere. Also if these are mgmt "modes" or "types" then =
they should be somewhere else and not in bluetooth.h.
Ok, so for now I'll leave these macros in hci_core.h.
>=20
>>=20
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> include/net/bluetooth/bluetooth.h | 6 ++++++
>> include/net/bluetooth/hci_core.h | 6 +-----
>> include/net/bluetooth/mgmt.h | 9 +++++++++
>> net/bluetooth/mgmt.c | 35 =
+++++++++++++++++++++++++++++++++++
>> 4 files changed, 51 insertions(+), 5 deletions(-)
>>=20
>> diff --git a/include/net/bluetooth/bluetooth.h =
b/include/net/bluetooth/bluetooth.h
>> index bf2ddff..8509520 100644
>> --- a/include/net/bluetooth/bluetooth.h
>> +++ b/include/net/bluetooth/bluetooth.h
>> @@ -354,4 +354,10 @@ void sco_exit(void);
>>=20
>> void bt_sock_reclassify_lock(struct sock *sk, int proto);
>>=20
>> +enum {
>> + BT_AUTO_CONN_DISABLED,
>> + BT_AUTO_CONN_ALWAYS,
>> + BT_AUTO_CONN_LINK_LOSS,
>> +};
>> +
>> #endif /* __BLUETOOTH_H */
>> diff --git a/include/net/bluetooth/hci_core.h =
b/include/net/bluetooth/hci_core.h
>> index 5052bf0..98be273 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -376,11 +376,7 @@ struct hci_conn_param {
>> bdaddr_t addr;
>> u8 addr_type;
>>=20
>> - enum {
>> - HCI_AUTO_CONN_DISABLED,
>> - HCI_AUTO_CONN_ALWAYS,
>> - HCI_AUTO_CONN_LINK_LOSS,
>> - } auto_connect;
>> + u8 auto_connect;
>>=20
>> u16 min_conn_interval;
>> u16 max_conn_interval;
>> diff --git a/include/net/bluetooth/mgmt.h =
b/include/net/bluetooth/mgmt.h
>> index 518c5c8..ed689b5 100644
>> --- a/include/net/bluetooth/mgmt.h
>> +++ b/include/net/bluetooth/mgmt.h
>> @@ -369,6 +369,15 @@ struct mgmt_cp_set_scan_params {
>> } __packed;
>> #define MGMT_SET_SCAN_PARAMS_SIZE 4
>>=20
>> +#define MGMT_OP_ADD_CONN_PARAM 0x002D
>> +struct mgmt_cp_add_conn_param {
>> + struct mgmt_addr_info addr;
>> + __u8 auto_connect;
>> + __le16 min_conn_interval;
>> + __le16 max_conn_interval;
>> +} __packed;
>> +#define MGMT_ADD_CONN_PARAM_SIZE (MGMT_ADDR_INFO_SIZE + 5)
>> +
>> #define MGMT_EV_CMD_COMPLETE 0x0001
>> struct mgmt_ev_cmd_complete {
>> __le16 opcode;
>> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
>> index a727b47..5d1a2e8 100644
>> --- a/net/bluetooth/mgmt.c
>> +++ b/net/bluetooth/mgmt.c
>> @@ -79,6 +79,7 @@ static const u16 mgmt_commands[] =3D {
>> MGMT_OP_SET_BREDR,
>> MGMT_OP_SET_STATIC_ADDRESS,
>> MGMT_OP_SET_SCAN_PARAMS,
>> + MGMT_OP_ADD_CONN_PARAM,
>> };
>=20
> So my 2nd patch wouldn't have been the mgmt command. I would have put =
all the cleanup and infrastructure changes in first. And I would have =
turned the connect() into the first user with a mode of "connect once" =
and default connection parameters.
>=20
> This clearly shows later on where all this magic handling comes into =
place. But in the end, the connect() call is just a connect once type of =
passive scanning. And maybe with learned connection slave interval =
values from advertising data during the scanning.
In v2, I'll put this patch after the infrastructure changes.
I didn't know we want to change connect() behavior. What is the issue we =
are trying address with this changing?
>=20
> The other problem that I have is that we can never update the =
parameters for a device. We need to remove them and re-add them. That is =
just not a good idea since we will almost certainly learn about updated =
values here. And maybe even change the mode of a device.
These connection parameters and auto connection policy is pretty much =
static values. We know ahead configuring the kernel what profiles the =
device supports. And the profiles the device supports don't dynamically =
change.
>=20
> In general just having one Update Connection Parameters call might be =
better. The kernel can happily just expire values from connection once =
or disabled by itself. So this needs a bit more discussion. Doing the =
mgmt interface last would allow to get all the other patches merged. =
Otherwise you are stuck on the mgmt part until we figure that out.
Sure we need more discussion on this. As I said, I'll move this mgmt =
command patches to the end of this patch set.
>=20
>> static const u16 mgmt_events[] =3D {
>> @@ -4025,6 +4026,39 @@ static int load_long_term_keys(struct sock =
*sk, struct hci_dev *hdev,
>> return err;
>> }
>>=20
>> +static int add_conn_param(struct sock *sk, struct hci_dev *hdev, =
void *cp_data,
>> + u16 len)
>> +{
>> + struct mgmt_cp_add_conn_param *cp =3D cp_data;
>> + u8 status;
>> + u8 addr_type;
>> +
>> + if (cp->addr.type =3D=3D BDADDR_BREDR)
>> + return cmd_complete(sk, hdev->id, =
MGMT_OP_ADD_CONN_PARAM,
>> + MGMT_STATUS_NOT_SUPPORTED, NULL, 0);
>=20
> Instead of checking for BDADDR_BREDR it would be better to check for =
!bdaddr_type_is_le().
>=20
> I really want everybody to get into the habit to do proper input =
validation. Not the half backed thing. That is why mgmt-tester can catch =
these kind of things easily and repeatedly.
I'll replace this with !bdaddr_type_is_le().
>=20
>> +
>> + status =3D mgmt_le_support(hdev);
>> + if (status)
>> + return cmd_complete(sk, hdev->id, =
MGMT_OP_ADD_CONN_PARAM,
>> + status, NULL, 0);
>> +
>> + if (cp->addr.type =3D=3D BDADDR_LE_PUBLIC)
>> + addr_type =3D ADDR_LE_DEV_PUBLIC;
>> + else
>> + addr_type =3D ADDR_LE_DEV_RANDOM;
>> +
>> + if (hci_add_conn_param(hdev, &cp->addr.bdaddr, addr_type,
>> + cp->auto_connect,
>> + __le16_to_cpu(cp->min_conn_interval),
>> + __le16_to_cpu(cp->max_conn_interval)))
>> + status =3D MGMT_STATUS_FAILED;
>> + else
>> + status =3D MGMT_STATUS_SUCCESS;
>> +
>> + return cmd_complete(sk, hdev->id, MGMT_OP_ADD_CONN_PARAM, =
status,
>> + NULL, 0);
>> +}
>> +
>> static const struct mgmt_handler {
>> int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
>> u16 data_len);
>> @@ -4076,6 +4110,7 @@ static const struct mgmt_handler {
>> { set_bredr, false, MGMT_SETTING_SIZE },
>> { set_static_address, false, MGMT_SET_STATIC_ADDRESS_SIZE },
>> { set_scan_params, false, MGMT_SET_SCAN_PARAMS_SIZE },
>> + { add_conn_param, false, MGMT_ADD_CONN_PARAM_SIZE },
>> };
>>=20
>=20
> And btw. it is always plural "params". It is not single parameter.
I'll fix it.
Regards,
Andre
^ permalink raw reply
* Re: [PATCH 0/3] Tab completion for haltest tool
From: Johan Hedberg @ 2013-10-18 13:51 UTC (permalink / raw)
To: Jerzy Kasenberg; +Cc: linux-bluetooth
In-Reply-To: <1382102160-21532-1-git-send-email-jerzy.kasenberg@tieto.com>
Hi Jerzy,
On Fri, Oct 18, 2013, Jerzy Kasenberg wrote:
> This patchset add tab completion to haltest so using this tool
> will be much easier.
>
> It allows to build for andriod 4.3 and for host with autotools.
>
> Jerzy Kasenberg (3):
> android: Add tab completion to haltest
> android: Fix error in draw line in haltest tool
> android: Add completion for adapter to haltest
>
> Makefile.android | 2 +
> android/Android.mk | 1 +
> android/client/haltest.c | 11 +-
> android/client/if-bt.c | 331 ++++++++++++++++++++++++++++++++++------
> android/client/if-main.h | 44 +++++-
> android/client/tabcompletion.c | 313 +++++++++++++++++++++++++++++++++++++
> android/client/terminal.c | 4 +-
> android/client/textconv.c | 21 +++
> android/client/textconv.h | 4 +
> 9 files changed, 673 insertions(+), 58 deletions(-)
> create mode 100644 android/client/tabcompletion.c
All three patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] android: Add missing signal handler functionality
From: Johan Hedberg @ 2013-10-18 13:19 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth
In-Reply-To: <1382101802-23965-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Fri, Oct 18, 2013, Ravi kumar Veeramally wrote:
> Added singal handling based on singalfd and removed sigaction
> based code.
> ---
> android/main.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 65 insertions(+), 15 deletions(-)
Applied (after a minor fix to exit the daemon if the setup function
fails). Thanks.
Johan
^ permalink raw reply
* [PATCH 3/3] android: Add completion for adapter to haltest
From: Jerzy Kasenberg @ 2013-10-18 13:16 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382102160-21532-1-git-send-email-jerzy.kasenberg@tieto.com>
This patch adds all completion functions for adapter methods.
It also adds short help lines for all methods that require arguments.
---
android/client/haltest.c | 11 +-
android/client/if-bt.c | 331 ++++++++++++++++++++++++++++++++++++++-------
android/client/if-main.h | 16 +++
android/client/textconv.c | 21 +++
android/client/textconv.h | 4 +
5 files changed, 330 insertions(+), 53 deletions(-)
diff --git a/android/client/haltest.c b/android/client/haltest.c
index 6dcabbc..6b37f33 100644
--- a/android/client/haltest.c
+++ b/android/client/haltest.c
@@ -103,11 +103,12 @@ static void process_line(char *line_buffer)
continue;
}
if (argc < 2 || strcmp(argv[1], "?") == 0) {
- j = 0;
- while (strcmp(interfaces[i]->methods[j].name, "")) {
- haltest_info("%s %s\n", argv[0],
- interfaces[i]->methods[j].name);
- ++j;
+ struct method *m = &interfaces[i]->methods[0];
+ while (strcmp(m->name, "")) {
+ haltest_info("%s %s %s\n", argv[0],
+ m->name,
+ (m->help ? m->help : ""));
+ m++;
}
return;
}
diff --git a/android/client/if-bt.c b/android/client/if-bt.c
index 90ef732..30b41cd 100644
--- a/android/client/if-bt.c
+++ b/android/client/if-bt.c
@@ -19,6 +19,16 @@
const bt_interface_t *if_bluetooth;
+#define VERIFY_PROP_TYPE_ARG(n, typ) \
+ do { \
+ if (n < argc) \
+ typ = str2btpropertytype(argv[n]); \
+ else { \
+ haltest_error("No property type specified\n"); \
+ return;\
+ } \
+ } while (0)
+
static char *bdaddr2str(const bt_bdaddr_t *bd_addr)
{
static char buf[18];
@@ -177,6 +187,84 @@ static void dump_properties(int num_properties, bt_property_t *properties)
}
}
+/*
+ * Cache for remote devices, stored in sorted array
+ */
+static bt_bdaddr_t *remote_devices = NULL;
+static int remote_devices_cnt = 0;
+static int remote_devices_capacity = 0;
+
+/* Adds address to remote device set so it can be used in tab completion */
+void add_remote_device(const bt_bdaddr_t *addr)
+{
+ int i;
+
+ if (remote_devices == NULL) {
+ remote_devices = malloc(4 * sizeof(bt_bdaddr_t));
+ remote_devices_cnt = 0;
+ if (remote_devices == NULL) {
+ remote_devices_capacity = 0;
+ return;
+ }
+ remote_devices_capacity = 4;
+ }
+
+ /* Array is sorted, search for right place */
+ for (i = 0; i < remote_devices_cnt; ++i) {
+ int res = memcmp(&remote_devices[i], addr, sizeof(*addr));
+ if (res == 0)
+ return; /* Already added */
+ else if (res > 0)
+ break;
+ }
+
+ /* Realloc space if needed */
+ if (remote_devices_cnt >= remote_devices_capacity) {
+ remote_devices_capacity *= 2;
+ remote_devices = realloc(remote_devices, sizeof(bt_bdaddr_t) *
+ remote_devices_capacity);
+ if (remote_devices == NULL) {
+ remote_devices_capacity = 0;
+ remote_devices_cnt = 0;
+ return;
+ }
+ }
+
+ if (i < remote_devices_cnt)
+ memmove(remote_devices + i + 1, remote_devices + i,
+ (remote_devices_cnt - i) * sizeof(bt_bdaddr_t));
+ remote_devices[i] = *addr;
+ remote_devices_cnt++;
+}
+
+const char *enum_devices(void *v, int i)
+{
+ static char buf[19];
+
+ if (i >= remote_devices_cnt)
+ return NULL;
+
+ bt_bdaddr_t2str(&remote_devices[i], buf);
+ return buf;
+}
+
+static void add_remote_device_from_props(int num_properties,
+ const bt_property_t *properties)
+{
+ int i;
+
+ for (i = 0; i < num_properties; i++) {
+ /*
+ * properities sometimes come unaligned hence memcp to
+ * aligned buffer
+ */
+ bt_property_t property;
+ memcpy(&property, properties + i, sizeof(property));
+ if (property.type == BT_PROPERTY_BDADDR)
+ add_remote_device((bt_bdaddr_t *) property.val);
+ }
+}
+
static void adapter_state_changed_cb(bt_state_t state)
{
haltest_info("%s: state=%s\n", __func__, bt_state_t2str(state));
@@ -198,6 +286,8 @@ static void remote_device_properties_cb(bt_status_t status,
__func__, bt_status_t2str(status), bdaddr2str(bd_addr),
num_properties);
+ add_remote_device(bd_addr);
+
dump_properties(num_properties, properties);
}
@@ -205,6 +295,8 @@ static void device_found_cb(int num_properties, bt_property_t *properties)
{
haltest_info("%s: num_properties=%d\n", __func__, num_properties);
+ add_remote_device_from_props(num_properties, properties);
+
dump_properties(num_properties, properties);
}
@@ -214,19 +306,33 @@ static void discovery_state_changed_cb(bt_discovery_state_t state)
bt_discovery_state_t2str(state));
}
+/*
+ * Buffer for remote addres that came from one of bind request.
+ * It's stored for command completion.
+ */
+static char last_remote_addr[18];
+static bt_ssp_variant_t last_ssp_variant = (bt_ssp_variant_t)-1;
+
static void pin_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
uint32_t cod)
{
+ /* Store for command completion */
+ bt_bdaddr_t2str(remote_bd_addr, last_remote_addr);
+
haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x\n", __func__,
- bdaddr2str(remote_bd_addr), bd_name->name, cod);
+ last_remote_addr, bd_name->name, cod);
}
static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
uint32_t cod, bt_ssp_variant_t pairing_variant,
uint32_t pass_key)
{
+ /* Store for command completion */
+ bt_bdaddr_t2str(remote_bd_addr, last_remote_addr);
+ last_ssp_variant = pairing_variant;
+
haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x pairing_variant=%s pass_key=%d\n",
- __func__, bdaddr2str(remote_bd_addr), bd_name->name, cod,
+ __func__, last_remote_addr, bd_name->name, cod,
bt_ssp_variant_t2str(pairing_variant), pass_key);
}
@@ -338,15 +444,45 @@ static void get_adapter_properties_p(int argc, const char **argv)
EXEC(if_bluetooth->get_adapter_properties);
}
+static void get_adapter_property_c(int argc, const char **argv,
+ enum_func *penum_func, void **puser)
+{
+ if (argc == 3) {
+ *puser = TYPE_ENUM(bt_property_type_t);
+ *penum_func = enum_defines;
+ }
+}
+
static void get_adapter_property_p(int argc, const char **argv)
{
- int type = str2btpropertytype(argv[2]);
+ int type;
RETURN_IF_NULL(if_bluetooth);
+ VERIFY_PROP_TYPE_ARG(2, type);
EXEC(if_bluetooth->get_adapter_property, type);
}
+static const char * const names[] = {
+ "BT_PROPERTY_BDNAME",
+ "BT_PROPERTY_ADAPTER_SCAN_MODE",
+ "BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT", NULL
+};
+
+static void set_adapter_property_c(int argc, const char **argv,
+ enum_func *penum_func, void **puser)
+{
+ if (argc == 3) {
+ *puser = (void *) names;
+ *penum_func = enum_strings;
+ } else if (argc == 4) {
+ if (0 == strcmp(argv[2], "BT_PROPERTY_ADAPTER_SCAN_MODE")) {
+ *puser = TYPE_ENUM(bt_scan_mode_t);
+ *penum_func = enum_defines;
+ }
+ }
+}
+
static void set_adapter_property_p(int argc, const char **argv)
{
bt_property_t property;
@@ -354,9 +490,12 @@ static void set_adapter_property_p(int argc, const char **argv)
int timeout;
RETURN_IF_NULL(if_bluetooth);
+ VERIFY_PROP_TYPE_ARG(2, property.type);
- property.type = str2btpropertytype(argv[2]);
-
+ if (argc <= 3) {
+ haltest_error("No property value specified\n");
+ return;
+ }
switch (property.type) {
case BT_PROPERTY_BDNAME:
property.len = strlen(argv[3]) + 1;
@@ -383,39 +522,70 @@ static void set_adapter_property_p(int argc, const char **argv)
EXEC(if_bluetooth->set_adapter_property, &property);
}
+/*
+ * This function is to be used for completion methods that need only address
+ */
+static void complete_addr_c(int argc, const char **argv,
+ enum_func *penum_func, void **puser)
+{
+ if (argc == 3) {
+ *puser = NULL;
+ *penum_func = enum_devices;
+ }
+}
+
+/* Just addres to complete, use complete_addr_c */
+#define get_remote_device_properties_c complete_addr_c
+
static void get_remote_device_properties_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
RETURN_IF_NULL(if_bluetooth);
-
- str2bt_bdaddr_t(argv[2], &addr);
+ VERIFY_ADDR_ARG(2, &addr);
EXEC(if_bluetooth->get_remote_device_properties, &addr);
}
+static void get_remote_device_property_c(int argc, const char **argv,
+ enum_func *penum_func,
+ void **puser)
+{
+ if (argc == 3) {
+ *puser = NULL;
+ *penum_func = enum_devices;
+ } else if (argc == 4) {
+ *puser = TYPE_ENUM(bt_property_type_t);
+ *penum_func = enum_defines;
+ }
+}
+
static void get_remote_device_property_p(int argc, const char **argv)
{
bt_property_type_t type;
bt_bdaddr_t addr;
RETURN_IF_NULL(if_bluetooth);
-
- str2bt_bdaddr_t(argv[2], &addr);
- type = str2btpropertytype(argv[3]);
+ VERIFY_ADDR_ARG(2, &addr);
+ VERIFY_PROP_TYPE_ARG(3, type);
EXEC(if_bluetooth->get_remote_device_property, &addr, type);
}
+/*
+ * Same completion as for get_remote_device_property_c can be used for
+ * set_remote_device_property_c. No need to create separate function.
+ */
+#define set_remote_device_property_c get_remote_device_property_c
+
static void set_remote_device_property_p(int argc, const char **argv)
{
bt_property_t property;
bt_bdaddr_t addr;
RETURN_IF_NULL(if_bluetooth);
-
- str2bt_bdaddr_t(argv[2], &addr);
- property.type = str2btpropertytype(argv[3]);
+ VERIFY_ADDR_ARG(2, &addr);
+ VERIFY_PROP_TYPE_ARG(3, property.type);
switch (property.type) {
case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
@@ -430,26 +600,37 @@ static void set_remote_device_property_p(int argc, const char **argv)
EXEC(if_bluetooth->set_remote_device_property, &addr, &property);
}
+/*
+ * For now uuid is not autocompleted. Use routine for complete_addr_c
+ */
+#define get_remote_service_record_c complete_addr_c
+
static void get_remote_service_record_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
bt_uuid_t uuid;
RETURN_IF_NULL(if_bluetooth);
+ VERIFY_ADDR_ARG(2, &addr);
- str2bt_bdaddr_t(argv[2], &addr);
+ if (argc <= 3) {
+ haltest_error("No uuid specified\n");
+ return;
+ }
str2bt_uuid_t(argv[3], &uuid);
EXEC(if_bluetooth->get_remote_service_record, &addr, &uuid);
}
+/* Just addres to complete, use complete_addr_c */
+#define get_remote_services_c complete_addr_c
+
static void get_remote_services_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
RETURN_IF_NULL(if_bluetooth);
-
- str2bt_bdaddr_t(argv[2], &addr);
+ VERIFY_ADDR_ARG(2, &addr);
EXEC(if_bluetooth->get_remote_services, &addr);
}
@@ -468,39 +649,55 @@ static void cancel_discovery_p(int argc, const char **argv)
EXEC(if_bluetooth->cancel_discovery);
}
+/* Just addres to complete, use complete_addr_c */
+#define create_bond_c complete_addr_c
+
static void create_bond_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
RETURN_IF_NULL(if_bluetooth);
-
- str2bt_bdaddr_t(argv[2], &addr);
+ VERIFY_ADDR_ARG(2, &addr);
EXEC(if_bluetooth->create_bond, &addr);
}
+/* Just addres to complete, use complete_addr_c */
+#define remove_bond_c complete_addr_c
+
static void remove_bond_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
RETURN_IF_NULL(if_bluetooth);
-
- str2bt_bdaddr_t(argv[2], &addr);
+ VERIFY_ADDR_ARG(2, &addr);
EXEC(if_bluetooth->remove_bond, &addr);
}
+/* Just addres to complete, use complete_addr_c */
+#define cancel_bond_c complete_addr_c
+
static void cancel_bond_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
RETURN_IF_NULL(if_bluetooth);
-
- str2bt_bdaddr_t(argv[2], &addr);
+ VERIFY_ADDR_ARG(2, &addr);
EXEC(if_bluetooth->cancel_bond, &addr);
}
+static void pin_reply_c(int argc, const char **argv,
+ enum_func *penum_func, void **puser)
+{
+ static const char *const completions[] = { last_remote_addr, NULL };
+ if (argc == 3) {
+ *puser = (void *) completions;
+ *penum_func = enum_strings;
+ }
+}
+
static void pin_reply_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
@@ -509,14 +706,9 @@ static void pin_reply_p(int argc, const char **argv)
int accept;
RETURN_IF_NULL(if_bluetooth);
+ VERIFY_ADDR_ARG(2, &addr);
- if (argc < 3) {
- haltest_error("No address specified\n");
- return;
- }
- str2bt_bdaddr_t(argv[2], &addr);
-
- if (argc >= 4) {
+ if (argc > 3) {
accept = 1;
pin_len = strlen(argv[3]);
memcpy(pin.pin, argv[3], pin_len);
@@ -525,6 +717,26 @@ static void pin_reply_p(int argc, const char **argv)
EXEC(if_bluetooth->pin_reply, &addr, accept, pin_len, &pin);
}
+static void ssp_reply_c(int argc, const char **argv,
+ enum_func *penum_func, void **puser)
+{
+ if (argc == 3) {
+ *puser = last_remote_addr;
+ *penum_func = enum_one_string;
+ } else if (argc == 5) {
+ *puser = "1";
+ *penum_func = enum_one_string;
+ } else if (argc == 4) {
+ if (-1 != (int) last_ssp_variant) {
+ *puser = (void *) bt_ssp_variant_t2str(last_ssp_variant);
+ *penum_func = enum_one_string;
+ } else {
+ *puser = TYPE_ENUM(bt_ssp_variant_t);
+ *penum_func = enum_defines;
+ }
+ }
+}
+
static void ssp_reply_p(int argc, const char **argv)
{
bt_bdaddr_t addr;
@@ -533,12 +745,8 @@ static void ssp_reply_p(int argc, const char **argv)
int passkey;
RETURN_IF_NULL(if_bluetooth);
+ VERIFY_ADDR_ARG(2, &addr);
- if (argc < 3) {
- haltest_error("No address specified\n");
- return;
- }
- str2bt_bdaddr_t(argv[2], &addr);
if (argc < 4) {
haltest_error("No ssp variant specified\n");
return;
@@ -557,6 +765,29 @@ static void ssp_reply_p(int argc, const char **argv)
EXEC(if_bluetooth->ssp_reply, &addr, var, accept, passkey);
}
+static void get_profile_interface_c(int argc, const char **argv,
+ enum_func *penum_func, void **puser)
+{
+ static const char *const profile_ids[] = {
+ BT_PROFILE_HANDSFREE_ID,
+ BT_PROFILE_ADVANCED_AUDIO_ID,
+ BT_PROFILE_HEALTH_ID,
+ BT_PROFILE_SOCKETS_ID,
+ BT_PROFILE_HIDHOST_ID,
+ BT_PROFILE_PAN_ID,
+#if PLATFORM_SDK_VERSION >= 18
+ BT_PROFILE_GATT_ID,
+#endif
+ BT_PROFILE_AV_RC_ID,
+ NULL
+ };
+
+ if (argc == 3) {
+ *puser = (void *) profile_ids;
+ *penum_func = enum_strings;
+ }
+}
+
static void get_profile_interface_p(int argc, const char **argv)
{
const char *id = argv[2];
@@ -595,6 +826,10 @@ static void dut_mode_configure_p(int argc, const char **argv)
RETURN_IF_NULL(if_bluetooth);
+ if (argc <= 2) {
+ haltest_error("No dut mode specified\n");
+ return;
+ }
mode = strtol(argv[2], NULL, 0);
EXEC(if_bluetooth->dut_mode_configure, mode);
@@ -606,22 +841,22 @@ static struct method methods[] = {
STD_METHOD(enable),
STD_METHOD(disable),
STD_METHOD(get_adapter_properties),
- STD_METHOD(get_adapter_property),
- STD_METHOD(set_adapter_property),
- STD_METHOD(get_remote_device_properties),
- STD_METHOD(get_remote_device_property),
- STD_METHOD(set_remote_device_property),
- STD_METHOD(get_remote_service_record),
- STD_METHOD(get_remote_services),
+ STD_METHODCH(get_adapter_property, "<prop_type>"),
+ STD_METHODCH(set_adapter_property, "<prop_type> <prop_value>"),
+ STD_METHODCH(get_remote_device_properties, "<addr>"),
+ STD_METHODCH(get_remote_device_property, "<addr> <property_type>"),
+ STD_METHODCH(set_remote_device_property, "<addr> <property_type> <value>"),
+ STD_METHODCH(get_remote_service_record, "<addr> <uuid>"),
+ STD_METHODCH(get_remote_services, "<addr>"),
STD_METHOD(start_discovery),
STD_METHOD(cancel_discovery),
- STD_METHOD(create_bond),
- STD_METHOD(remove_bond),
- STD_METHOD(cancel_bond),
- STD_METHOD(pin_reply),
- STD_METHOD(ssp_reply),
- STD_METHOD(get_profile_interface),
- STD_METHOD(dut_mode_configure),
+ STD_METHODCH(create_bond, "<addr>"),
+ STD_METHODCH(remove_bond, "<addr>"),
+ STD_METHODCH(cancel_bond, "<addr>"),
+ STD_METHODCH(pin_reply, "<address> [<pin>]"),
+ STD_METHODCH(ssp_reply, "<address> <ssp_veriant> 1|0 [<passkey>]"),
+ STD_METHODCH(get_profile_interface, "<profile id>"),
+ STD_METHODH(dut_mode_configure, "<dut mode>"),
END_METHOD
};
diff --git a/android/client/if-main.h b/android/client/if-main.h
index 3fb3007..b6bbf05 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -103,6 +103,12 @@ int haltest_error(const char *format, ...);
int haltest_info(const char *format, ...);
int haltest_warn(const char *format, ...);
+/*
+ * Enumerator for discovered devices, to be used as tab completion enum_func
+ */
+const char *enum_devices(void *v, int i);
+void add_remote_device(const bt_bdaddr_t *addr);
+
/* Helper macro for executing function on interface and printing BT_STATUS */
#define EXEC(f, ...) \
{ \
@@ -119,3 +125,13 @@ int haltest_warn(const char *format, ...);
#define RETURN_IF_NULL(x) \
do { if (!x) { haltest_error("%s is NULL\n", #x); return; } } while (0)
+
+#define VERIFY_ADDR_ARG(n, adr) \
+ do { \
+ if (n < argc) \
+ str2bt_bdaddr_t(argv[n], adr); \
+ else { \
+ haltest_error("No address specified\n");\
+ return;\
+ } \
+ } while (0)
diff --git a/android/client/textconv.c b/android/client/textconv.c
index eebad70..3493b1c 100644
--- a/android/client/textconv.c
+++ b/android/client/textconv.c
@@ -203,3 +203,24 @@ void str2bt_uuid_t(const char *str, bt_uuid_t *uuid)
str += 2;
}
}
+
+const char *enum_defines(void *v, int i)
+{
+ const struct int2str *m = v;
+
+ return m[i].str != NULL ? m[i].str : NULL;
+}
+
+const char *enum_strings(void *v, int i)
+{
+ const char **m = v;
+
+ return m[i] != NULL ? m[i] : NULL;
+}
+
+const char *enum_one_string(void *v, int i)
+{
+ const char *m = v;
+
+ return (i == 0) && (m[0] != 0) ? m : NULL;
+}
diff --git a/android/client/textconv.h b/android/client/textconv.h
index 8fe976c..88da641 100644
--- a/android/client/textconv.h
+++ b/android/client/textconv.h
@@ -54,7 +54,11 @@ struct int2str {
int int2str_findint(int v, const struct int2str m[]);
int int2str_findstr(const char *str, const struct int2str m[]);
+const char *enum_defines(void *v, int i);
+const char *enum_strings(void *v, int i);
+const char *enum_one_string(void *v, int i);
+#define TYPE_ENUM(type) ((void *)&__##type##2str[0])
#define DECINTMAP(type) \
extern struct int2str __##type##2str[]; \
const char *type##2##str(type v); \
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/3] android: Fix error in draw line in haltest tool
From: Jerzy Kasenberg @ 2013-10-18 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382102160-21532-1-git-send-email-jerzy.kasenberg@tieto.com>
This fixes small error that showed up when tab completion inserted
characters before end of line.
Cursor in line was not moved correctly.
---
android/client/terminal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/client/terminal.c b/android/client/terminal.c
index 0421633..8dd3a25 100644
--- a/android/client/terminal.c
+++ b/android/client/terminal.c
@@ -140,7 +140,7 @@ void terminal_draw_command_line(void)
putchar('>');
/* move cursor to it's place */
- terminal_move_cursor(line_len - line_buf_ix);
+ terminal_move_cursor(line_buf_ix - line_len);
}
/* inserts string into command line at cursor position */
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/3] android: Add tab completion to haltest
From: Jerzy Kasenberg @ 2013-10-18 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
In-Reply-To: <1382102160-21532-1-git-send-email-jerzy.kasenberg@tieto.com>
This patch adds tab completion to interfaces, methods and parameters
in haltest.
---
Makefile.android | 2 +
android/Android.mk | 1 +
android/client/if-main.h | 28 +++-
android/client/tabcompletion.c | 313 ++++++++++++++++++++++++++++++++++++++++
android/client/terminal.c | 2 +-
5 files changed, 342 insertions(+), 4 deletions(-)
create mode 100644 android/client/tabcompletion.c
diff --git a/Makefile.android b/Makefile.android
index 56caf78..dcaca3c 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -42,6 +42,7 @@ android_haltest_SOURCES = android/client/haltest.c \
android/client/terminal.c \
android/client/history.c \
android/client/textconv.c \
+ android/client/tabcompletion.c \
android/client/if-bt.c \
android/client/hwmodule.c
@@ -67,6 +68,7 @@ EXTRA_DIST += android/client/terminal.c \
android/client/history.c \
android/client/if-bt.c \
android/client/textconv.c \
+ android/client/tabcompletion.c \
android/client/textconv.h \
android/client/if-main.h \
android/client/pollhandler.h \
diff --git a/android/Android.mk b/android/Android.mk
index 5858c3d..30b2169 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -78,6 +78,7 @@ LOCAL_SRC_FILES := \
client/terminal.c \
client/history.c \
client/textconv.c \
+ client/tabcompletion.c \
client/if-bt.c \
LOCAL_SHARED_LIBRARIES := libhardware
diff --git a/android/client/if-main.h b/android/client/if-main.h
index 9cac7ef..3fb3007 100644
--- a/android/client/if-main.h
+++ b/android/client/if-main.h
@@ -56,9 +56,12 @@ extern const struct interface bluetooth_if;
/* Interfaces that will show up in tool (first part of command line) */
extern const struct interface *interfaces[];
-#define METHOD(name, func) {name, func}
-#define STD_METHOD(m) {#m, m##_p}
-#define END_METHOD {"", NULL}
+#define METHOD(name, func, comp, help) {name, func, comp, help}
+#define STD_METHOD(m) {#m, m##_p, NULL, NULL}
+#define STD_METHODC(m) {#m, m##_p, m##_c, NULL}
+#define STD_METHODH(m, h) {#m, m##_p, NULL, h}
+#define STD_METHODCH(m, h) {#m, m##_p, m##_c, h}
+#define END_METHOD {"", NULL, NULL, NULL}
/*
* Function to parse argument for function, argv[0] and argv[1] are already
@@ -69,12 +72,31 @@ extern const struct interface *interfaces[];
typedef void (*parse_and_call)(int argc, const char **argv);
/*
+ * This is prototype of function that will return string for given number.
+ * Purpose is to enumerate string for auto completion.
+ * Function of this type will always be called in loop.
+ * First time function is called i = 0, then if function returns non-NULL
+ * it will be called again till for some value of i it will return NULL
+ */
+typedef const char *(*enum_func)(void *user, int i);
+
+/*
+ * This is prototype of function that when given argc, argv will
+ * fill penum_func with pointer to function that will enumerate
+ * parameters for argc argument, puser will be passed to penum_func.
+ */
+typedef void (*tab_complete)(int argc, const char **argv,
+ enum_func *penum_func, void **puser);
+
+/*
* For each method there is name and two functions to parse command line
* and call proper hal function on.
*/
struct method {
const char *name;
parse_and_call func;
+ tab_complete complete;
+ const char *help;
};
int haltest_error(const char *format, ...);
diff --git a/android/client/tabcompletion.c b/android/client/tabcompletion.c
new file mode 100644
index 0000000..e9c9921
--- /dev/null
+++ b/android/client/tabcompletion.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "if-main.h"
+#include "terminal.h"
+
+/* how many times tab was hit */
+static int tab_hit_count;
+
+typedef struct split_arg {
+ struct split_arg *next; /* next argument in buffer */
+ const char *origin; /* pointer to original argument */
+ char ntcopy[1]; /* null terminated copy of argument */
+} split_arg_t;
+
+/* function returns interface of given name or NULL if not found */
+static const struct interface *get_interface(const char *name)
+{
+ int i;
+
+ for (i = 0; interfaces[i] != NULL; ++i) {
+ if (strcmp(interfaces[i]->name, name) == 0)
+ break;
+ }
+
+ return interfaces[i];
+}
+
+/* function returns method of given name or NULL if not found */
+static const struct method *get_method(const char *iname, const char *mname)
+{
+ int i;
+ const struct interface *iface = get_interface(iname);
+
+ if (iface == NULL)
+ return NULL;
+
+ for (i = 0; iface->methods[i].name[0]; ++i) {
+ if (0 == strcmp(iface->methods[i].name, mname))
+ return &iface->methods[i];
+ }
+ return NULL;
+}
+
+/* prints matching elements */
+static void print_matches(enum_func f, void *user, const char *prefix, int len)
+{
+ int i;
+ const char *enum_name;
+
+ putchar('\n');
+ for (i = 0; NULL != (enum_name = f(user, i)); ++i) {
+ if (strncmp(enum_name, prefix, len) == 0)
+ printf("%s\t", enum_name);
+ }
+ putchar('\n');
+ terminal_draw_command_line();
+}
+
+/*
+ * This function splits command line into linked list of arguments.
+ * line_buffer - pointer to input comman line
+ * size - size of command line to parse
+ * buf - output buffer to keep splited arguments list
+ * buf_size_in_bytes - size of buf
+ */
+static int split_command(const char *line_buffer, int size,
+ split_arg_t *buf, int buf_size_in_bytes)
+{
+ split_arg_t *prev = NULL;
+ split_arg_t *arg = buf;
+ int argc = 0;
+ const char *p = line_buffer;
+ const char *e = p + (size > 0 ? size : (int) strlen(p));
+ int len;
+
+ do {
+ while (p < e && isspace(*p))
+ p++;
+ arg->origin = p;
+ arg->next = NULL;
+ while (p < e && !isspace(*p))
+ p++;
+ len = p - arg->origin;
+ if (&arg->ntcopy[0] + len + 1 >
+ (const char *) buf + buf_size_in_bytes)
+ break;
+ strncpy(arg->ntcopy, arg->origin, len);
+ arg->ntcopy[len] = 0;
+ if (prev != NULL)
+ prev->next = arg;
+ prev = arg;
+ arg += (2 * sizeof(*arg) + len) / sizeof(*arg);
+ argc++;
+ } while (p < e);
+
+ return argc;
+}
+
+/* Function to enumerate interface names */
+static const char *interface_name(void *v, int i)
+{
+ return interfaces[i] ? interfaces[i]->name : NULL;
+}
+
+/* Function to enumerate method names */
+static const char *methods_name(void *v, int i)
+{
+ const struct interface *iface = v;
+
+ return iface->methods[i].name[0] ? iface->methods[i].name : NULL;
+}
+
+struct command_completion_args;
+typedef void (*short_help)(struct command_completion_args *args);
+
+struct command_completion_args {
+ const split_arg_t *arg; /* list of arguments */
+ const char *typed; /* last typed element */
+ enum_func func; /* enumerating function */
+ void *user; /* argument to enumerating function */
+ short_help help; /* help function */
+ void *user_help; /* additional data (used by short_help) */
+};
+
+/*
+ * complete command line
+ */
+static void command_completion(struct command_completion_args *args)
+{
+ const char *name = args->typed;
+ const int len = strlen(name);
+ int i;
+ int j;
+ char prefix[128] = {0};
+ int prefix_len = 0;
+ int count = 0;
+ const char *enum_name;
+
+ for (i = 0; NULL != (enum_name = args->func(args->user, i)); ++i) {
+ /* prefix does not match */
+ if (strncmp(enum_name, name, len) != 0)
+ continue;
+ /* prefix matches first time */
+ if (count++ == 0) {
+ strcpy(prefix, enum_name);
+ prefix_len = strlen(prefix);
+ continue;
+ }
+ /*
+ * Prefix matches next time
+ * reduce prefix to common part
+ */
+ for (j = 0; prefix[j] != 0
+ && prefix[j] == enum_name[j];)
+ ++j;
+ prefix_len = j;
+ prefix[j] = 0;
+ }
+
+ if (count == 0) {
+ /* no matches */
+ if (args->help != NULL)
+ args->help(args);
+ tab_hit_count = 0;
+ return;
+ }
+ /* len == prefix_len => nothing new was added */
+ if (len == prefix_len) {
+ if (count != 1) {
+ if (tab_hit_count == 1)
+ putchar('\a');
+ else if (tab_hit_count == 2 ||
+ args->help == NULL) {
+ print_matches(args->func,
+ args->user, name, len);
+ } else {
+ args->help(args);
+ tab_hit_count = 1;
+ }
+ } else if (count == 1) {
+ /* nothing to add, exact match add space */
+ terminal_insert_into_command_line(" ");
+ }
+ } else {
+ /* new chars can be added from some interface name(s) */
+ if (count == 1) {
+ /* exact match, add space */
+ prefix[prefix_len++] = ' ';
+ prefix[prefix_len] = '\0';
+ }
+ terminal_insert_into_command_line(prefix + len);
+ tab_hit_count = 0;
+ }
+}
+
+/* interface completion */
+static void interface_completion(split_arg_t *arg)
+{
+ struct command_completion_args args = {
+ .arg = arg,
+ .typed = arg->ntcopy,
+ .func = interface_name
+ };
+
+ command_completion(&args);
+}
+
+/* method completion */
+static void method_completion(const struct interface *iface, split_arg_t *arg)
+{
+ struct command_completion_args args = {
+ .arg = arg,
+ .typed = arg->next->ntcopy,
+ .func = methods_name,
+ .user = (void *) iface
+ };
+
+ if (iface == NULL)
+ return;
+
+ command_completion(&args);
+}
+
+/* prints short help on method for interface */
+static void method_help(struct command_completion_args *args)
+{
+ if (args->user_help == NULL)
+ return;
+
+ haltest_info("%s %s %s\n", args->arg->ntcopy,
+ args->arg->next->ntcopy, args->user_help);
+}
+
+/* So we have empty enumeration */
+static const char *return_null(void *user, int i)
+{
+ return NULL;
+}
+
+/* parameter completion function */
+static void param_completion(int argc, const split_arg_t *arg)
+{
+ const struct method *method;
+ int i;
+ const char *argv[argc];
+ const split_arg_t *tmp = arg;
+ struct command_completion_args args = {
+ .arg = arg,
+ .func = return_null
+ };
+
+ /* prepare standard argv from arg */
+ for (i = 0; i < argc; ++i) {
+ argv[i] = tmp->ntcopy;
+ tmp = tmp->next;
+ }
+
+ /* Find method for <interface, name> pair */
+ method = get_method(argv[0], argv[1]);
+
+ if (method != NULL && method->complete != NULL) {
+ /* ask method for completion function */
+ method->complete(argc, argv, &args.func, &args.user);
+ }
+
+ /* If method provided enumeration function call try to complete */
+ if (args.func != NULL) {
+ args.typed = argv[argc - 1];
+ args.help = method_help;
+ args.user_help = (void *) method->help;
+
+ command_completion(&args);
+ }
+}
+
+/*
+ * This methd gets called when user tapped tab key.
+ * line - points to comman line
+ * len - size of line that should be used for comletions. This should be
+ * cursor position during tab hit.
+ */
+void process_tab(const char *line, int len)
+{
+ int argc;
+ static split_arg_t buf[(LINE_BUF_MAX * 2) / sizeof(split_arg_t)];
+
+ argc = split_command(line, len, buf, sizeof(buf));
+ tab_hit_count++;
+
+ if (argc == 1)
+ interface_completion(buf);
+ else if (argc == 2)
+ method_completion(get_interface(buf[0].ntcopy), buf);
+ else if (argc > 2)
+ param_completion(argc, buf);
+}
diff --git a/android/client/terminal.c b/android/client/terminal.c
index b484ef6..0421633 100644
--- a/android/client/terminal.c
+++ b/android/client/terminal.c
@@ -453,7 +453,7 @@ void terminal_process_char(int c, void (*process_line)(char *line))
break;
case '\t':
/* tab processing */
- /* TODO Add completion here */
+ process_tab(line_buf, line_buf_ix);
break;
case KEY_BACKSPACE:
if (line_buf_ix <= 0)
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/3] Tab completion for haltest tool
From: Jerzy Kasenberg @ 2013-10-18 13:15 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jerzy Kasenberg
This patchset add tab completion to haltest so using this tool
will be much easier.
It allows to build for andriod 4.3 and for host with autotools.
Jerzy Kasenberg (3):
android: Add tab completion to haltest
android: Fix error in draw line in haltest tool
android: Add completion for adapter to haltest
Makefile.android | 2 +
android/Android.mk | 1 +
android/client/haltest.c | 11 +-
android/client/if-bt.c | 331 ++++++++++++++++++++++++++++++++++------
android/client/if-main.h | 44 +++++-
android/client/tabcompletion.c | 313 +++++++++++++++++++++++++++++++++++++
android/client/terminal.c | 4 +-
android/client/textconv.c | 21 +++
android/client/textconv.h | 4 +
9 files changed, 673 insertions(+), 58 deletions(-)
create mode 100644 android/client/tabcompletion.c
--
1.7.9.5
^ permalink raw reply
* [PATCH] android: Add missing signal handler functionality
From: Ravi kumar Veeramally @ 2013-10-18 13:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Added singal handling based on singalfd and removed sigaction
based code.
---
android/main.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 65 insertions(+), 15 deletions(-)
diff --git a/android/main.c b/android/main.c
index 256b83b..4ae654c 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
+#include <sys/signalfd.h>
#include <glib.h>
@@ -54,23 +55,74 @@ static uint8_t mgmt_revision = 0;
static uint16_t adapter_index = MGMT_INDEX_NONE;
-static gboolean quit_eventloop(gpointer user_data)
+static volatile sig_atomic_t __terminated = 0;
+
+static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
+ gpointer user_data)
{
- g_main_loop_quit(event_loop);
+ struct signalfd_siginfo si;
+ ssize_t result;
+ int fd;
+
+ if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+ return FALSE;
+
+ fd = g_io_channel_unix_get_fd(channel);
+
+ result = read(fd, &si, sizeof(si));
+ if (result != sizeof(si))
+ return FALSE;
+
+ switch (si.ssi_signo) {
+ case SIGINT:
+ case SIGTERM:
+ if (__terminated == 0) {
+ info("Terminating");
+ g_main_loop_quit(event_loop);
+ }
+
+ __terminated = 1;
+ break;
+ }
- return FALSE;
+ return TRUE;
}
-static void sig_term(int sig)
+static guint setup_signalfd(void)
{
- static bool __terminated = false;
+ GIOChannel *channel;
+ guint source;
+ sigset_t mask;
+ int fd;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+
+ if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
+ perror("Failed to set signal mask");
+ return 0;
+ }
- if (!__terminated) {
- g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS,
- quit_eventloop, NULL);
+ fd = signalfd(-1, &mask, 0);
+ if (fd < 0) {
+ perror("Failed to create signal descriptor");
+ return 0;
}
- __terminated = true;
+ channel = g_io_channel_unix_new(fd);
+
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+
+ source = g_io_add_watch(channel,
+ G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ signal_handler, NULL);
+
+ g_io_channel_unref(channel);
+
+ return source;
}
static gboolean option_version = FALSE;
@@ -244,7 +296,7 @@ int main(int argc, char *argv[])
{
GOptionContext *context;
GError *err = NULL;
- struct sigaction sa;
+ guint signal;
context = g_option_context_new(NULL);
g_option_context_add_main_entries(context, options, NULL);
@@ -267,14 +319,10 @@ int main(int argc, char *argv[])
}
event_loop = g_main_loop_new(NULL, FALSE);
+ signal = setup_signalfd();
__btd_log_init("*", 0);
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = sig_term;
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGTERM, &sa, NULL);
-
if (!init_mgmt_interface())
return EXIT_FAILURE;
@@ -285,6 +333,8 @@ int main(int argc, char *argv[])
g_main_loop_run(event_loop);
+ g_source_remove(signal);
+
stop_sdp_server();
cleanup_mgmt_interface();
g_main_loop_unref(event_loop);
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH BlueZ] core: Fix typo in adapter.c comments
From: Johan Hedberg @ 2013-10-18 12:47 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1382099552-5562-3-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Fri, Oct 18, 2013, Claudio Takahasi wrote:
> ---
> src/adapter.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ] core: Remove unneeded includes in device.c
From: Johan Hedberg @ 2013-10-18 12:47 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1382099552-5562-2-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Fri, Oct 18, 2013, Claudio Takahasi wrote:
> ---
> src/device.c | 3 ---
> 1 file changed, 3 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ] core: Remove leftover adapter_get_default()
From: Johan Hedberg @ 2013-10-18 12:47 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1382099552-5562-1-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Fri, Oct 18, 2013, Claudio Takahasi wrote:
> ---
> src/adapter.h | 1 -
> 1 file changed, 1 deletion(-)
Applied. Thanks.
Johan
^ permalink raw reply
* [PATCH BlueZ] core: Fix typo in adapter.c comments
From: Claudio Takahasi @ 2013-10-18 12:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1382099552-5562-1-git-send-email-claudio.takahasi@openbossa.org>
---
src/adapter.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 40a9c4e..30bcc4d 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -285,7 +285,7 @@ static void set_dev_class_complete(uint8_t status, uint16_t length,
}
/*
- * The parameters are idential and also the task that is
+ * The parameters are identical and also the task that is
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
@@ -487,7 +487,7 @@ static void set_mode_complete(uint8_t status, uint16_t length,
}
/*
- * The parameters are idential and also the task that is
+ * The parameters are identical and also the task that is
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
@@ -631,7 +631,7 @@ static void set_local_name_complete(uint8_t status, uint16_t length,
}
/*
- * The parameters are idential and also the task that is
+ * The parameters are identical and also the task that is
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
@@ -753,7 +753,7 @@ static void add_uuid_complete(uint8_t status, uint16_t length,
}
/*
- * The parameters are idential and also the task that is
+ * The parameters are identical and also the task that is
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
@@ -805,7 +805,7 @@ static void remove_uuid_complete(uint8_t status, uint16_t length,
}
/*
- * The parameters are idential and also the task that is
+ * The parameters are identical and also the task that is
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
@@ -856,7 +856,7 @@ static void clear_uuids_complete(uint8_t status, uint16_t length,
}
/*
- * The parameters are idential and also the task that is
+ * The parameters are identical and also the task that is
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
@@ -1868,7 +1868,7 @@ static void property_set_mode_complete(uint8_t status, uint16_t length,
g_dbus_pending_property_success(data->id);
/*
- * The parameters are idential and also the task that is
+ * The parameters are identical and also the task that is
* required in both cases. So it is safe to just call the
* event handling functions here.
*/
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ] core: Remove unneeded includes in device.c
From: Claudio Takahasi @ 2013-10-18 12:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1382099552-5562-1-git-send-email-claudio.takahasi@openbossa.org>
---
src/device.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/device.c b/src/device.c
index 3dd3584..77f2322 100644
--- a/src/device.c
+++ b/src/device.c
@@ -31,8 +31,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <stdbool.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
#include <errno.h>
#include <dirent.h>
#include <time.h>
@@ -64,7 +62,6 @@
#include "sdp-client.h"
#include "attrib/gatt.h"
#include "agent.h"
-#include "sdp-xml.h"
#include "storage.h"
#include "attrib-server.h"
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ] core: Remove leftover adapter_get_default()
From: Claudio Takahasi @ 2013-10-18 12:32 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
---
src/adapter.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/adapter.h b/src/adapter.h
index 5d124e7..80c5f77 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -82,7 +82,6 @@ void adapter_shutdown(void);
struct btd_adapter *adapter_find(const bdaddr_t *sba);
struct btd_adapter *adapter_find_by_id(int id);
-struct btd_adapter *adapter_get_default(void);
void adapter_foreach(adapter_cb func, gpointer user_data);
bool btd_adapter_get_pairable(struct btd_adapter *adapter);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 1/2] Bluetooth: Use hcon directly instead of conn->hcon where possible
From: Johan Hedberg @ 2013-10-18 11:44 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1382092981-48006-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Fri, Oct 18, 2013, Marcel Holtmann wrote:
> When the HCI connection hcon is already dereferenced, then use hcon
> directly instead of conn->hcon.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/l2cap_core.c | 7 +++----
> net/bluetooth/smp.c | 2 +-
> 2 files changed, 4 insertions(+), 5 deletions(-)
Both patches have been applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCHv5 0/7] Android BlueZ patches, second chunk
From: Johan Hedberg @ 2013-10-18 11:36 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1381998406-16662-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Thu, Oct 17, 2013, Andrei Emeltchenko wrote:
> This is second chunk from my initial big patch set. Fixed style issues
> commented by Marcel.
>
> Changes:
> * v5: Rebased against upstream, hid and pan now uses explicit struct initialization,
> adapter-related functionality moved to adapter.c, fixed issues reported by Johan.
> * v4: Fixes several typos and missing style issues commented by Marcel earlier.
> * v3: Following upstream comments file names are changed from "_" to "-", added kernel style
> struct initialization, fixed bug checking status for mgmt commands, added 2 HALs skeletons.
> * v2: Corrected android_daemon -> enable_android autoconf stuff, better name for acquiring caps,
> renamed hal_msg.h to hal-msg.h due to Johan's comment. Added small test-sdp fix.
>
> Note that due to Marcel comment this cannot be built unless you include my patch
> for Android bionic library:
> http://code.google.com/p/android-bluez/source/detail?r=77a07e7703b63e280d9880baad30b3375e7df079&repo=bionic#
>
> Andrei Emeltchenko (7):
> android: Add capabilities and set userid
> android: Implement read_info_complete callback
> android: Use kernel style to initialize struct fields
> android: Rename hal_bluetooth.c to hal-bluetooth.c
> android: Rename hal_bt_sock.c to hal-bt-sock.c
> android: Add HID Host skeleton
> android: Add PAN skeleton
>
> Makefile.android | 3 +-
> android/Android.mk | 7 +-
> android/adapter.c | 108 +++++++++++--
> android/hal-bluetooth.c | 392 +++++++++++++++++++++++++++++++++++++++++++++++
> android/hal-bt-sock.c | 85 ++++++++++
> android/hal-hidhost.c | 204 ++++++++++++++++++++++++
> android/hal-pan.c | 120 +++++++++++++++
> android/hal.h | 2 +
> android/hal_bluetooth.c | 384 ----------------------------------------------
> android/hal_bt_sock.c | 85 ----------
> android/main.c | 77 ++++++++--
> configure.ac | 4 +
> 12 files changed, 980 insertions(+), 491 deletions(-)
> create mode 100644 android/hal-bluetooth.c
> create mode 100644 android/hal-bt-sock.c
> create mode 100644 android/hal-hidhost.c
> create mode 100644 android/hal-pan.c
> delete mode 100644 android/hal_bluetooth.c
> delete mode 100644 android/hal_bt_sock.c
After quite heavy fixing and additional patches of my own, these are now
upstream.
Johan
^ 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