* Re: [PATCH] Bluetooth: Make hci_blacklist_clear function static
From: Johan Hedberg @ 2014-02-28 7:32 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1393558554-42295-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Thu, Feb 27, 2014, Marcel Holtmann wrote:
> The hci_blacklist_clear function is not used outside of hci_core.c and
> can be made static.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci_core.h | 1 -
> net/bluetooth/hci_core.c | 2 +-
> 2 files changed, 1 insertion(+), 2 deletions(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 1/4] Bluetooth: Add definitions for LE white list HCI commands
From: Johan Hedberg @ 2014-02-28 7:32 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1393562251-7555-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Thu, Feb 27, 2014, Marcel Holtmann wrote:
> Add the definitions for clearing the LE white list, adding entries to
> the LE white list and removing entries from the LE white list.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci.h | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
All four patches have been applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* [PATCH] Bluetooth: Add timer to force power off
From: johan.hedberg @ 2014-02-28 7:33 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
If some of the cleanup commands caused by mgmt_set_powered(off) never
complete we should still force the adapter to be powered down. This is
rather easy to do since hdev->power_off is already a delayed work
struct. This patch schedules this delayed work if at least one HCI
command was sent by the cleanup procedure.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
include/net/bluetooth/hci.h | 1 +
net/bluetooth/mgmt.c | 16 +++++++++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index c3834d3aecbb..8d1bf8c4689c 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -182,6 +182,7 @@ enum {
#define HCI_CMD_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */
#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
+#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */
/* HCI data types */
#define HCI_COMMAND_PKT 0x01
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 73b6ff817796..e7c87231b9ea 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1031,8 +1031,10 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
{
BT_DBG("%s status 0x%02x", hdev->name, status);
- if (hci_conn_count(hdev) == 0)
+ if (hci_conn_count(hdev) == 0) {
+ cancel_delayed_work(&hdev->power_off);
queue_work(hdev->req_workqueue, &hdev->power_off.work);
+ }
}
static int clean_up_hci_state(struct hci_dev *hdev)
@@ -1139,9 +1141,13 @@ static int set_powered(struct sock *sk, struct hci_dev *hdev, void *data,
} else {
/* Disconnect connections, stop scans, etc */
err = clean_up_hci_state(hdev);
+ if (!err)
+ queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
+ HCI_POWER_OFF_TIMEOUT);
/* ENODATA means there were no HCI commands queued */
if (err == -ENODATA) {
+ cancel_delayed_work(&hdev->power_off);
queue_work(hdev->req_workqueue, &hdev->power_off.work);
err = 0;
}
@@ -5147,8 +5153,10 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
/* The connection is still in hci_conn_hash so test for 1
* instead of 0 to know if this is the last one.
*/
- if (!cp->val && hci_conn_count(hdev) == 1)
+ if (!cp->val && hci_conn_count(hdev) == 1) {
+ cancel_delayed_work(&hdev->power_off);
queue_work(hdev->req_workqueue, &hdev->power_off.work);
+ }
}
if (!mgmt_connected)
@@ -5217,8 +5225,10 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
/* The connection is still in hci_conn_hash so test for 1
* instead of 0 to know if this is the last one.
*/
- if (!cp->val && hci_conn_count(hdev) == 1)
+ if (!cp->val && hci_conn_count(hdev) == 1) {
+ cancel_delayed_work(&hdev->power_off);
queue_work(hdev->req_workqueue, &hdev->power_off.work);
+ }
}
bacpy(&ev.addr.bdaddr, bdaddr);
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH v2 2/2] Bluetooth: Fix disconnecting connections in non-connected states
From: Marcel Holtmann @ 2014-02-28 7:35 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1393504512-21877-2-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> When powering off and disconnecting devices we should also consider
> connections which have not yet reached the BT_CONNECTED state. They may
> not have a valid handle yet and simply sending a HCI_Disconnect will not
> work.
>
> This patch updates the code to either disconnect, cancel connection
> creation or reject incoming connection creation based on the current
> conn->state value as well as the link type in question.
>
> When the power off procedure results in canceling connection attempts
> instead of disconnecting connections we get a connection failed event
> instead of a disconnection event. Therefore, we also need to have extra
> code in the mgmt_connect_failed function to check if we should proceed
> with the power off or not.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/mgmt.c | 44 ++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 40 insertions(+), 4 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [PATCHv2 3/8] shared/hfp: Add initial implementiation of processing commands
From: Marcin Kraglak @ 2014-02-28 7:37 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <BA9EB144-665E-4A51-81EF-EEEFAB18C822@holtmann.org>
Hi Marcel,
On 28 February 2014 08:05, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Marcin,
>
>> ---
>> src/shared/hfp.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++----
>> 1 file changed, 51 insertions(+), 4 deletions(-)
>>
>> diff --git a/src/shared/hfp.c b/src/shared/hfp.c
>> index e164dd6..cf54a8f 100644
>> --- a/src/shared/hfp.c
>> +++ b/src/shared/hfp.c
>> @@ -69,6 +69,11 @@ struct prefix_handler_data {
>> hfp_result_func_t callback;
>> };
>>
>> +struct hfp_gw_result {
>> + const char *data;
>> + int offset;
>> +};
>> +
>> static void destroy_prefix_handler_data(void *data)
>> {
>> struct prefix_handler_data *handler = data;
>> @@ -130,6 +135,46 @@ static void wakeup_writer(struct hfp_gw *hfp)
>> hfp->writer_active = true;
>> }
>>
>> +static bool process_basic(struct hfp_gw *hfp, struct hfp_gw_result *result)
>> +{
>> + return false;
>> +}
>> +
>> +static bool process_extended(struct hfp_gw *hfp, struct hfp_gw_result *result)
>> +{
>> + return false;
>> +}
>> +
>> +static void skip_whitespace(struct hfp_gw_result *result)
>> +{
>> + while (result->data[result->offset] == ' ')
>> + result->offset++;
>> +}
>> +
>> +static bool call_prefix_handler(struct hfp_gw *hfp, const char *data)
>> +{
>> + struct hfp_gw_result result;
>> +
>> + result.offset = 0;
>> + result.data = data;
>> +
>> + skip_whitespace(&result);
>
> I would just do the skip leading whitespace here without bothering putting it into a separate function. There is really no point.
I use this function later, in getters, therefore I introduced it here
>
>> +
>> + if (strlen(data + result.offset) < 3)
>> + return false;
>> +
>> + if (strncmp(data + result.offset, "AT", 2))
>> + if (strncmp(data + result.offset, "at", 2))
>> + return false;
>> +
>> + result.offset += 2;
>> +
>> + if (data[result.offset] == '+')
>> + return process_extended(hfp, &result);
>> + else
>> + return process_basic(hfp, &result);
>
> Please do not do this. I mentioned this before, this basic vs extended is pointless.
>
> Command matching should be either based on commands like "D" or "+BRSF" and not bother trying to treat the + any special. See how src/emulator.c in oFono registers all the handlers.
Ok, I'll fix it
>
> Regards
>
> Marcel
>
BR
Marcin
^ permalink raw reply
* Re: [PATCH BlueZ] core: retry connect_dbus() several times
From: Marcel Holtmann @ 2014-02-28 7:40 UTC (permalink / raw)
To: Adam Lee; +Cc: linux-bluetooth
In-Reply-To: <20140228073113.GA3771@adam-laptop>
Hi Adam,
>>> Sometimes the hardware, especially which needs firmware patching, is not
>>> yet ready when connect_dbus().
>>
>> this makes no sense. Connecting to D-Bus has nothing to do with
>> firmware patching. What are you exactly fixing here?
>
> connect_dbus() fails sometimes with Intel 7260 bluetooth, sleeping 0.5s
> before executing bluetoothd workarounds it. I assume the firmware
> patching slows down hardware initialization then fails to connect.
>
> Any other possibility? I'm not a D-Bus guru :)
it has nothing to do with D-Bus. You need to find the root cause.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH] Bluetooth: Add timer to force power off
From: Marcel Holtmann @ 2014-02-28 7:41 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1393572824-663-1-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> If some of the cleanup commands caused by mgmt_set_powered(off) never
> complete we should still force the adapter to be powered down. This is
> rather easy to do since hdev->power_off is already a delayed work
> struct. This patch schedules this delayed work if at least one HCI
> command was sent by the cleanup procedure.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> include/net/bluetooth/hci.h | 1 +
> net/bluetooth/mgmt.c | 16 +++++++++++++---
> 2 files changed, 14 insertions(+), 3 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [RFC] Bluetooth: Use __le64 type for LE random numbers
From: Johan Hedberg @ 2014-02-28 7:45 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1393545628-29566-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Thu, Feb 27, 2014, Marcel Holtmann wrote:
> The random numbers in Bluetooth Low Energy are 64-bit numbers and should
> also be little endian since the HCI specification is little endian.
>
> Change the whole Low Energy pairing to use __le64 instead of a byte
> array.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci.h | 4 ++--
> include/net/bluetooth/hci_core.h | 8 ++++----
> include/net/bluetooth/mgmt.h | 2 +-
> net/bluetooth/hci_conn.c | 6 +++---
> net/bluetooth/hci_core.c | 13 ++++++-------
> net/bluetooth/hci_event.c | 2 +-
> net/bluetooth/mgmt.c | 2 +-
> net/bluetooth/smp.c | 22 ++++++++++------------
> net/bluetooth/smp.h | 2 +-
> 9 files changed, 29 insertions(+), 32 deletions(-)
Applied to bluetooth-next. Thanks.
Johan
^ permalink raw reply
* Re: [PATCHv2 4/8] shared/hfp: Add implementation of precessing commands
From: Marcin Kraglak @ 2014-02-28 7:46 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <6C75B4EB-5878-4EFB-AEBD-E1FE7BC7B7BF@holtmann.org>
Hi Marcel,
On 28 February 2014 08:13, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Marcin,
>
>> It will process both extended and basic commands.
>> ---
>> src/shared/hfp.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>> 1 file changed, 94 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/shared/hfp.c b/src/shared/hfp.c
>> index cf54a8f..6a39a36 100644
>> --- a/src/shared/hfp.c
>> +++ b/src/shared/hfp.c
>> @@ -29,6 +29,7 @@
>> #include <unistd.h>
>> #include <string.h>
>> #include <stdarg.h>
>> +#include <ctype.h>
>>
>> #include "src/shared/util.h"
>> #include "src/shared/ringbuf.h"
>> @@ -135,14 +136,105 @@ static void wakeup_writer(struct hfp_gw *hfp)
>> hfp->writer_active = true;
>> }
>>
>> +static enum hfp_cmd_type get_cmd_type(struct hfp_gw_result *result)
>> +{
>> + if (result->data[result->offset] == '=') {
>> + result->offset++;
>> + if (result->data[result->offset] == '?') {
>> + result->offset++;
>> + return HFP_AT_TEST;
>> + } else {
>> + return HFP_AT_SET;
>> + }
>
> can we please keep the kernel coding style out of user space. And I hate it when both if parts use return.
>
> if (blah) {
> xxxx
> return x;
> }
>
> return y.
>
>> + } else if (result->data[result->offset] == '?') {
>
> And this else if is pointless as well. You are leaving the function in the first if part no matter what.
>
>> + result->offset++;
>> + return HFP_AT_READ;
>> + } else {
>> + return HFP_AT_COMMAND;
>> + }
>
> Same here.
>
>> +}
>> +
>> static bool process_basic(struct hfp_gw *hfp, struct hfp_gw_result *result)
>> {
>> - return false;
>> + const char *prefix = result->data + result->offset;
>> + struct prefix_handler_data *handler;
>> + enum hfp_cmd_type type;
>> + char lookup_prefix[4];
>> + uint8_t pref_len = 0;
>> + int i;
>> +
>> + /* Check if first sign is character */
>> + if (isalpha(prefix[pref_len])) {
>> + /* Handle S-parameter prefix */
>> + if (toupper(prefix[pref_len]) == 'S') {
>> + do {
>> + pref_len++;
>> + } while (isdigit(prefix[pref_len]));
>> + /*S-parameter must be followed with number*/
>> + if (pref_len == 1)
>> + pref_len--;
>
> Where is the S parameter stuff coming from? I did ask this before and never got an answer to it.
V.250 5.3.2 S-parameters. If it is not used in HFP I can remove it. It
was added just to be compatibile with V.250 spec.
>
> Regards
>
> Marcel
>
BR
Marcin
^ permalink raw reply
* Re: [PATCHv2 2/8] shared/hfp: Add prefix handlers functionality
From: Marcin Kraglak @ 2014-02-28 7:48 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth@vger.kernel.org development
In-Reply-To: <97847860-E690-4FC9-A631-16A0E4CE8486@holtmann.org>
Hi Marcel,
On 28 February 2014 08:06, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Marcin,
>
>> Add two functions: hfp_gw_set_prefix_handler() and
>> hfp_gw_remove_prefix_handler(). It will allow user to register for
>> specific command. Current implementation just adds or removes data
>> from hfp_gw structure.
>> ---
>> Makefile.tools | 1 +
>> src/shared/hfp.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> src/shared/hfp.h | 17 ++++++++++++
>> 3 files changed, 102 insertions(+)
>>
>> diff --git a/Makefile.tools b/Makefile.tools
>> index 9f7ba9f..31e1093 100644
>> --- a/Makefile.tools
>> +++ b/Makefile.tools
>> @@ -63,6 +63,7 @@ emulator_hfp_SOURCES = emulator/hfp.c \
>> monitor/mainloop.h monitor/mainloop.c \
>> src/shared/io.h src/shared/io-mainloop.c \
>> src/shared/util.h src/shared/util.c \
>> + src/shared/queue.h src/shared/queue.c \
>> src/shared/ringbuf.h src/shared/ringbuf.c \
>> src/shared/hfp.h src/shared/hfp.c
>>
>> diff --git a/src/shared/hfp.c b/src/shared/hfp.c
>> index 0681b19..e164dd6 100644
>> --- a/src/shared/hfp.c
>> +++ b/src/shared/hfp.c
>> @@ -32,6 +32,7 @@
>>
>> #include "src/shared/util.h"
>> #include "src/shared/ringbuf.h"
>> +#include "src/shared/queue.h"
>> #include "src/shared/io.h"
>> #include "src/shared/hfp.h"
>>
>> @@ -42,6 +43,7 @@ struct hfp_gw {
>> struct io *io;
>> struct ringbuf *read_buf;
>> struct ringbuf *write_buf;
>> + struct queue *prefix_handlers;
>> bool writer_active;
>> bool permissive_syntax;
>> bool result_pending;
>> @@ -60,6 +62,37 @@ struct hfp_gw {
>> bool destroyed;
>> };
>>
>> +struct prefix_handler_data {
>> + char *prefix;
>> + void *user_data;
>> + hfp_destroy_func_t destroy;
>> + hfp_result_func_t callback;
>> +};
>> +
>> +static void destroy_prefix_handler_data(void *data)
>> +{
>> + struct prefix_handler_data *handler = data;
>> +
>> + if (handler->destroy)
>> + handler->destroy(handler->user_data);
>> +
>> + free(handler);
>> +}
>> +
>> +static bool match_handler_prefix(const void *a, const void *b)
>> +{
>> + const struct prefix_handler_data *handler = a;
>> + const char *prefix = b;
>> +
>> + if (strlen(handler->prefix) != strlen(prefix))
>> + return false;
>> +
>> + if (memcmp(handler->prefix, prefix, strlen(prefix)))
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> static void write_watch_destroy(void *user_data)
>> {
>> struct hfp_gw *hfp = user_data;
>> @@ -194,8 +227,19 @@ struct hfp_gw *hfp_gw_new(int fd)
>> return NULL;
>> }
>>
>> + hfp->prefix_handlers = queue_new();
>> + if (!hfp->prefix_handlers) {
>> + io_destroy(hfp->io);
>> + ringbuf_free(hfp->write_buf);
>> + ringbuf_free(hfp->read_buf);
>> + free(hfp);
>> + return NULL;
>> + }
>> +
>> if (!io_set_read_handler(hfp->io, can_read_data,
>> hfp, read_watch_destroy)) {
>> + queue_destroy(hfp->prefix_handlers,
>> + destroy_prefix_handler_data);
>> io_destroy(hfp->io);
>> ringbuf_free(hfp->write_buf);
>> ringbuf_free(hfp->read_buf);
>> @@ -248,6 +292,9 @@ void hfp_gw_unref(struct hfp_gw *hfp)
>> ringbuf_free(hfp->write_buf);
>> hfp->write_buf = NULL;
>>
>> + queue_destroy(hfp->prefix_handlers, destroy_prefix_handler_data);
>> + hfp->prefix_handlers = NULL;
>> +
>> if (!hfp->in_disconnect) {
>> free(hfp);
>> return;
>> @@ -407,6 +454,43 @@ bool hfp_gw_set_command_handler(struct hfp_gw *hfp,
>> return true;
>> }
>>
>> +bool hfp_gw_set_prefix_handler(struct hfp_gw *hfp, hfp_result_func_t callback,
>> + char *prefix, void *user_data,
>> + hfp_destroy_func_t destroy)
>> +{
>
> it is either add and remove or register and unregister, but never set and remove. If you set something, the next call to set would overwrite it.
>
> Regards
>
> Marcel
>
I'll change names
BR
Marcin
^ permalink raw reply
* [PATCH] Bluetooth: Fix clearing SMP keys if pairing fails
From: johan.hedberg @ 2014-02-28 8:10 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@intel.com>
If SMP fails we should not leave any keys (LTKs or IRKs) hanging around
the internal lists. This patch adds the necessary code to
smp_chan_destroy to remove any keys we may have in case of pairing
failure.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/smp.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 6ace0b48dc6a..710f4e171bf1 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -589,6 +589,24 @@ void smp_chan_destroy(struct l2cap_conn *conn)
complete = test_bit(SMP_FLAG_COMPLETE, &smp->smp_flags);
mgmt_smp_complete(conn->hcon, complete);
+ /* If pairing failed clean up any keys we might have */
+ if (!complete) {
+ if (smp->ltk) {
+ list_del(&smp->ltk->list);
+ kfree(smp->ltk);
+ }
+
+ if (smp->slave_ltk) {
+ list_del(&smp->slave_ltk->list);
+ kfree(smp->slave_ltk);
+ }
+
+ if (smp->remote_irk) {
+ list_del(&smp->remote_irk->list);
+ kfree(smp->remote_irk);
+ }
+ }
+
kfree(smp);
conn->smp_chan = NULL;
conn->hcon->smp_conn = NULL;
--
1.8.5.3
^ permalink raw reply related
* [PATCHv2 0/9] Combined set of AVRCP test patches
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Combined set of AVRCP function implementation and unit tests.
Andrei Emeltchenko (9):
android/avrcp: Refactor get_caps() to allow parameter
unit/avrcp: Fix lengths byte order
unit/avrcp: Add /TP/CFG/BI-01-C test
android/avrcp: Add list player attributes command
unit/avrcp: Add /TP/PAS/BV-01-C test
unit/avrcp: Add /TP/PAS/BV-02-C test
android/avrcp: Implement get player attributes text
unit/avrcp: Add /TP/PAS/BV-03-C test
unit/avrcp: Add /TP/PAS/BV-04-C test
android/avrcp-lib.c | 23 ++++++++++++---
android/avrcp-lib.h | 7 ++++-
unit/test-avrcp.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 105 insertions(+), 7 deletions(-)
--
1.8.3.2
^ permalink raw reply
* [PATCHv2 1/9] android/avrcp: Refactor get_caps() to allow parameter
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Allow passing parameter specifying capability ID.
---
android/avrcp-lib.c | 6 ++----
android/avrcp-lib.h | 4 ++--
unit/test-avrcp.c | 3 ++-
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 1b5a294..6ae8df8 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -297,11 +297,9 @@ static int avrcp_send_req(struct avrcp *session, uint8_t code, uint8_t subunit,
session->tx_buf, len, func, user_data);
}
-int avrcp_get_capabilities(struct avrcp *session, avctp_rsp_cb func,
- void *user_data)
+int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
+ avctp_rsp_cb func, void *user_data)
{
- uint8_t param = CAP_EVENTS_SUPPORTED;
-
return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
AVRCP_GET_CAPABILITIES, ¶m, sizeof(param),
func, user_data);
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 75802b9..e6e12c1 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -106,5 +106,5 @@ void avrcp_set_passthrough_handlers(struct avrcp *session,
int avrcp_init_uinput(struct avrcp *session, const char *name,
const char *address);
-int avrcp_get_capabilities(struct avrcp *session, avctp_rsp_cb func,
- void *user_data);
+int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
+ avctp_rsp_cb func, void *user_data);
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index bcd8f88..f222df8 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -353,7 +353,8 @@ static void test_client(gconstpointer data)
struct context *context = create_context(0x0100, data);
if (g_str_equal(context->data->test_name, "/TP/CFG/BV-01-C"))
- avrcp_get_capabilities(context->session, NULL, NULL);
+ avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
+ NULL, NULL);
execute_context(context);
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 2/9] unit/avrcp: Fix lengths byte order
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
params_len is passed as function argument and needs to be in host byte
order.
---
unit/test-avrcp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index f222df8..a43985a 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -323,7 +323,7 @@ static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
}
fail:
- *params_len = htons(1);
+ *params_len = 1;
params[0] = AVRCP_STATUS_INVALID_PARAM;
return AVC_CTYPE_REJECTED;
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 3/9] unit/avrcp: Add /TP/CFG/BI-01-C test
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies the get capabilities response issued from the Target when
an invalid capability is requested (0x7f).
---
unit/test-avrcp.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index a43985a..0924a7e 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -311,6 +311,8 @@ static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
{
uint32_t id = 0x001958;
+ DBG("params[0] %d params_len %d", params[0], *params_len);
+
if (*params_len != 1)
goto fail;
@@ -441,5 +443,14 @@ int main(int argc, char *argv[])
0x00, 0x19, 0x58, 0x10, 0x00, 0x00,
0x05, 0x02, 0x01, 0x00, 0x19, 0x58));
+ define_test("/TP/CFG/BI-01-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58, 0x10, 0x00, 0x00,
+ 0x01, 0x7f),
+ raw_pdu(0x02, 0x11, 0x0e, AVC_CTYPE_REJECTED,
+ 0x48, 0x00, 0x00, 0x19, 0x58, 0x10,
+ 0x00, 0x00, 0x01,
+ AVRCP_STATUS_INVALID_PARAM));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 4/9] android/avrcp: Add list player attributes command
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/avrcp-lib.c | 8 ++++++++
android/avrcp-lib.h | 2 ++
2 files changed, 10 insertions(+)
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 6ae8df8..3db5bda 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -304,3 +304,11 @@ int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
AVRCP_GET_CAPABILITIES, ¶m, sizeof(param),
func, user_data);
}
+
+int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
+ void *user_data)
+{
+ return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
+ AVRCP_LIST_PLAYER_ATTRIBUTES, NULL, 0,
+ func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index e6e12c1..7283203 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -108,3 +108,5 @@ int avrcp_init_uinput(struct avrcp *session, const char *name,
int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
avctp_rsp_cb func, void *user_data);
+int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
+ void *user_data);
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 5/9] unit/avrcp: Add /TP/PAS/BV-01-C test
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies that the List Player Application Setting Attributes command
issued from the Controller.
---
unit/test-avrcp.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index 0924a7e..c65f743 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -358,6 +358,9 @@ static void test_client(gconstpointer data)
avrcp_get_capabilities(context->session, CAP_EVENTS_SUPPORTED,
NULL, NULL);
+ if (g_str_equal(context->data->test_name, "/TP/PAS/BV-01-C"))
+ avrcp_list_player_attributes(context->session, NULL, NULL);
+
execute_context(context);
}
@@ -452,5 +455,12 @@ int main(int argc, char *argv[])
0x00, 0x00, 0x01,
AVRCP_STATUS_INVALID_PARAM));
+ /* Player Application Settings tests */
+
+ define_test("/TP/PAS/BV-01-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58, 0x11, 0x00, 0x00,
+ 0x00));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 6/9] unit/avrcp: Add /TP/PAS/BV-02-C test
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies that the List Player Application Setting Attributes
response issued from the Target.
---
unit/test-avrcp.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index c65f743..c4faca3 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -331,9 +331,23 @@ fail:
return AVC_CTYPE_REJECTED;
}
+static uint8_t avrcp_handle_list_attributes(struct avrcp *session,
+ uint8_t transaction, uint16_t *params_len,
+ uint8_t *params, void *user_data)
+{
+ DBG("");
+
+ *params_len = 1;
+ params[0] = 0;
+
+ return AVC_CTYPE_STABLE;
+}
+
static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
avrcp_handle_get_capabilities },
+ { AVRCP_LIST_PLAYER_ATTRIBUTES, AVC_CTYPE_STATUS,
+ avrcp_handle_list_attributes },
{ },
};
@@ -462,5 +476,13 @@ int main(int argc, char *argv[])
0x00, 0x19, 0x58, 0x11, 0x00, 0x00,
0x00));
+ define_test("/TP/PAS/BV-02-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58, 0x11, 0x00, 0x00,
+ 0x00),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+ 0x00, 0x19, 0x58, 0x11, 0x00, 0x00,
+ 0x01, 0x00));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 7/9] android/avrcp: Implement get player attributes text
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
android/avrcp-lib.c | 9 +++++++++
android/avrcp-lib.h | 3 +++
2 files changed, 12 insertions(+)
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
index 3db5bda..52074a7 100644
--- a/android/avrcp-lib.c
+++ b/android/avrcp-lib.c
@@ -312,3 +312,12 @@ int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
AVRCP_LIST_PLAYER_ATTRIBUTES, NULL, 0,
func, user_data);
}
+
+int avrcp_get_player_attribute_text(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_len, avctp_rsp_cb func,
+ void *user_data)
+{
+ return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL,
+ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, attributes,
+ attr_len, func, user_data);
+}
diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h
index 7283203..da8c990 100644
--- a/android/avrcp-lib.h
+++ b/android/avrcp-lib.h
@@ -110,3 +110,6 @@ int avrcp_get_capabilities(struct avrcp *session, uint8_t param,
avctp_rsp_cb func, void *user_data);
int avrcp_list_player_attributes(struct avrcp *session, avctp_rsp_cb func,
void *user_data);
+int avrcp_get_player_attribute_text(struct avrcp *session, uint8_t *attributes,
+ uint8_t attr_len, avctp_rsp_cb func,
+ void *user_data);
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 8/9] unit/avrcp: Add /TP/PAS/BV-03-C test
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies that the get player application settings attribute text
command issued from the Controller.
---
unit/test-avrcp.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index c4faca3..a75165b 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -375,6 +375,10 @@ static void test_client(gconstpointer data)
if (g_str_equal(context->data->test_name, "/TP/PAS/BV-01-C"))
avrcp_list_player_attributes(context->session, NULL, NULL);
+ if (g_str_equal(context->data->test_name, "/TP/PAS/BV-03-C"))
+ avrcp_get_player_attribute_text(context->session, NULL, 0,
+ NULL, NULL);
+
execute_context(context);
}
@@ -484,5 +488,11 @@ int main(int argc, char *argv[])
0x00, 0x19, 0x58, 0x11, 0x00, 0x00,
0x01, 0x00));
+ define_test("/TP/PAS/BV-03-C", test_client,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
+ 0x00, 0x00, 0x00));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 9/9] unit/avrcp: Add /TP/PAS/BV-04-C test
From: Andrei Emeltchenko @ 2014-02-28 8:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Test verifies that the Get Player Application Setting Attribute Text
response issued from the Target.
---
unit/test-avrcp.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c
index a75165b..db9cb92 100644
--- a/unit/test-avrcp.c
+++ b/unit/test-avrcp.c
@@ -343,11 +343,25 @@ static uint8_t avrcp_handle_list_attributes(struct avrcp *session,
return AVC_CTYPE_STABLE;
}
+static uint8_t avrcp_handle_get_player_attr_text(struct avrcp *session,
+ uint8_t transaction, uint16_t *params_len,
+ uint8_t *params, void *user_data)
+{
+ DBG("");
+
+ *params_len = 1;
+ params[0] = 0;
+
+ return AVC_CTYPE_STABLE;
+}
+
static const struct avrcp_control_handler control_handlers[] = {
{ AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
avrcp_handle_get_capabilities },
{ AVRCP_LIST_PLAYER_ATTRIBUTES, AVC_CTYPE_STATUS,
avrcp_handle_list_attributes },
+ { AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, AVC_CTYPE_STATUS,
+ avrcp_handle_get_player_attr_text },
{ },
};
@@ -494,5 +508,15 @@ int main(int argc, char *argv[])
AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
0x00, 0x00, 0x00));
+ define_test("/TP/PAS/BV-04-C", test_server,
+ raw_pdu(0x00, 0x11, 0x0e, 0x01, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
+ 0x00, 0x00, 0x00),
+ raw_pdu(0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00,
+ 0x00, 0x19, 0x58,
+ AVRCP_GET_PLAYER_ATTRIBUTE_TEXT,
+ 0x00, 0x00, 0x01, 0x00));
+
return g_test_run();
}
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCHv2 0/9] Combined set of AVRCP test patches
From: Luiz Augusto von Dentz @ 2014-02-28 9:04 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1393575778-28681-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Fri, Feb 28, 2014 at 9:22 AM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Combined set of AVRCP function implementation and unit tests.
>
> Andrei Emeltchenko (9):
> android/avrcp: Refactor get_caps() to allow parameter
> unit/avrcp: Fix lengths byte order
> unit/avrcp: Add /TP/CFG/BI-01-C test
> android/avrcp: Add list player attributes command
> unit/avrcp: Add /TP/PAS/BV-01-C test
> unit/avrcp: Add /TP/PAS/BV-02-C test
> android/avrcp: Implement get player attributes text
> unit/avrcp: Add /TP/PAS/BV-03-C test
> unit/avrcp: Add /TP/PAS/BV-04-C test
>
> android/avrcp-lib.c | 23 ++++++++++++---
> android/avrcp-lib.h | 7 ++++-
> unit/test-avrcp.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++--
> 3 files changed, 105 insertions(+), 7 deletions(-)
>
> --
> 1.8.3.2
Applied, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] Bluetooth: Fix clearing SMP keys if pairing fails
From: Marcel Holtmann @ 2014-02-28 9:07 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1393575016-12166-1-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> If SMP fails we should not leave any keys (LTKs or IRKs) hanging around
> the internal lists. This patch adds the necessary code to
> smp_chan_destroy to remove any keys we may have in case of pairing
> failure.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/smp.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* [PATCHv3 1/6] shared/hfp: Add prefix handlers functionality
From: Marcin Kraglak @ 2014-02-28 9:22 UTC (permalink / raw)
To: linux-bluetooth
Add two functions: hfp_gw_register_prefix_handler() and
hfp_gw_unregister_prefix_handler(). It will allow user to register for
specific command. Current implementation just adds or removes data
from hfp_gw structure.
---
Makefile.tools | 1 +
src/shared/hfp.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/shared/hfp.h | 18 ++++++++++++
3 files changed, 104 insertions(+)
diff --git a/Makefile.tools b/Makefile.tools
index 9f7ba9f..31e1093 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -63,6 +63,7 @@ emulator_hfp_SOURCES = emulator/hfp.c \
monitor/mainloop.h monitor/mainloop.c \
src/shared/io.h src/shared/io-mainloop.c \
src/shared/util.h src/shared/util.c \
+ src/shared/queue.h src/shared/queue.c \
src/shared/ringbuf.h src/shared/ringbuf.c \
src/shared/hfp.h src/shared/hfp.c
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 854cf46..12d0754 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -32,6 +32,7 @@
#include "src/shared/util.h"
#include "src/shared/ringbuf.h"
+#include "src/shared/queue.h"
#include "src/shared/io.h"
#include "src/shared/hfp.h"
@@ -42,6 +43,7 @@ struct hfp_gw {
struct io *io;
struct ringbuf *read_buf;
struct ringbuf *write_buf;
+ struct queue *prefix_handlers;
bool writer_active;
bool permissive_syntax;
bool result_pending;
@@ -60,6 +62,37 @@ struct hfp_gw {
bool destroyed;
};
+struct prefix_handler_data {
+ char *prefix;
+ void *user_data;
+ hfp_destroy_func_t destroy;
+ hfp_result_func_t callback;
+};
+
+static void destroy_prefix_handler_data(void *data)
+{
+ struct prefix_handler_data *handler = data;
+
+ if (handler->destroy)
+ handler->destroy(handler->user_data);
+
+ free(handler);
+}
+
+static bool match_handler_prefix(const void *a, const void *b)
+{
+ const struct prefix_handler_data *handler = a;
+ const char *prefix = b;
+
+ if (strlen(handler->prefix) != strlen(prefix))
+ return false;
+
+ if (memcmp(handler->prefix, prefix, strlen(prefix)))
+ return false;
+
+ return true;
+}
+
static void write_watch_destroy(void *user_data)
{
struct hfp_gw *hfp = user_data;
@@ -196,8 +229,19 @@ struct hfp_gw *hfp_gw_new(int fd)
return NULL;
}
+ hfp->prefix_handlers = queue_new();
+ if (!hfp->prefix_handlers) {
+ io_destroy(hfp->io);
+ ringbuf_free(hfp->write_buf);
+ ringbuf_free(hfp->read_buf);
+ free(hfp);
+ return NULL;
+ }
+
if (!io_set_read_handler(hfp->io, can_read_data,
hfp, read_watch_destroy)) {
+ queue_destroy(hfp->prefix_handlers,
+ destroy_prefix_handler_data);
io_destroy(hfp->io);
ringbuf_free(hfp->write_buf);
ringbuf_free(hfp->read_buf);
@@ -250,6 +294,9 @@ void hfp_gw_unref(struct hfp_gw *hfp)
ringbuf_free(hfp->write_buf);
hfp->write_buf = NULL;
+ queue_destroy(hfp->prefix_handlers, destroy_prefix_handler_data);
+ hfp->prefix_handlers = NULL;
+
if (!hfp->in_disconnect) {
free(hfp);
return;
@@ -405,6 +452,44 @@ bool hfp_gw_set_command_handler(struct hfp_gw *hfp,
return true;
}
+bool hfp_gw_register_prefix_handler(struct hfp_gw *hfp,
+ hfp_result_func_t callback,
+ char *prefix, void *user_data,
+ hfp_destroy_func_t destroy)
+{
+ struct prefix_handler_data *handler;
+
+ handler = queue_find(hfp->prefix_handlers, match_handler_prefix,
+ prefix);
+ if (handler)
+ return false;
+
+ handler = new0(struct prefix_handler_data, 1);
+ if (!handler)
+ return false;
+
+ handler->callback = callback;
+ handler->prefix = prefix;
+ handler->destroy = destroy;
+ handler->user_data = user_data;
+
+ return queue_push_tail(hfp->prefix_handlers, handler);
+}
+
+bool hfp_gw_unregister_prefix_handler(struct hfp_gw *hfp, char *prefix)
+{
+ struct prefix_handler_data *handler;
+
+ handler = queue_remove_if(hfp->prefix_handlers, match_handler_prefix,
+ prefix);
+ if (!handler)
+ return false;
+
+ destroy_prefix_handler_data(handler);
+
+ return true;
+}
+
static void disconnect_watch_destroy(void *user_data)
{
struct hfp_gw *hfp = user_data;
diff --git a/src/shared/hfp.h b/src/shared/hfp.h
index b0bd934..4dc293f 100644
--- a/src/shared/hfp.h
+++ b/src/shared/hfp.h
@@ -60,6 +60,18 @@ enum hfp_error {
HFP_ERROR_NETWORK_NOT_ALLOWED = 32,
};
+enum hfp_cmd_type {
+ HFP_AT_READ,
+ HFP_AT_SET,
+ HFP_AT_TEST,
+ HFP_AT_COMMAND
+};
+
+struct hfp_gw_result;
+
+typedef void (*hfp_result_func_t)(struct hfp_gw_result *result,
+ enum hfp_cmd_type type, void *user_data);
+
typedef void (*hfp_destroy_func_t)(void *user_data);
typedef void (*hfp_debug_func_t)(const char *str, void *user_data);
@@ -94,3 +106,9 @@ bool hfp_gw_set_disconnect_handler(struct hfp_gw *hfp,
hfp_destroy_func_t destroy);
bool hfp_gw_disconnect(struct hfp_gw *hfp);
+
+bool hfp_gw_register_prefix_handler(struct hfp_gw *hfp,
+ hfp_result_func_t callback,
+ char *prefix, void *user_data,
+ hfp_destroy_func_t destroy);
+bool hfp_gw_unregister_prefix_handler(struct hfp_gw *hfp, char *prefix);
--
1.8.5.3
^ permalink raw reply related
* [PATCHv3 2/6] shared/hfp: Add implementiation of processing commands
From: Marcin Kraglak @ 2014-02-28 9:22 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1393579358-11514-1-git-send-email-marcin.kraglak@tieto.com>
It will look for prefix handler for given cammand.
---
src/shared/hfp.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 94 insertions(+), 4 deletions(-)
diff --git a/src/shared/hfp.c b/src/shared/hfp.c
index 12d0754..e4cb011 100644
--- a/src/shared/hfp.c
+++ b/src/shared/hfp.c
@@ -29,6 +29,7 @@
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
+#include <ctype.h>
#include "src/shared/util.h"
#include "src/shared/ringbuf.h"
@@ -69,6 +70,11 @@ struct prefix_handler_data {
hfp_result_func_t callback;
};
+struct hfp_gw_result {
+ const char *data;
+ int offset;
+};
+
static void destroy_prefix_handler_data(void *data)
{
struct prefix_handler_data *handler = data;
@@ -130,6 +136,88 @@ static void wakeup_writer(struct hfp_gw *hfp)
hfp->writer_active = true;
}
+static void skip_whitespace(struct hfp_gw_result *result)
+{
+ while (result->data[result->offset] == ' ')
+ result->offset++;
+}
+
+static bool call_prefix_handler(struct hfp_gw *hfp, const char *data)
+{
+ struct prefix_handler_data *handler;
+ const char *separators = ";?=\0";
+ struct hfp_gw_result result;
+ enum hfp_cmd_type type;
+ char lookup_prefix[18];
+ uint8_t pref_len = 0;
+ const char *prefix;
+ int i;
+
+ result.offset = 0;
+ result.data = data;
+
+ skip_whitespace(&result);
+
+ if (strlen(data + result.offset) < 3)
+ return false;
+
+ if (strncmp(data + result.offset, "AT", 2))
+ if (strncmp(data + result.offset, "at", 2))
+ return false;
+
+ result.offset += 2;
+ prefix = data + result.offset;
+
+ if (isalpha(prefix[0])) {
+ lookup_prefix[pref_len++] = toupper(prefix[0]);
+ } else {
+ pref_len = strcspn(prefix, separators);
+ if (pref_len > 17 || pref_len < 2)
+ return false;
+
+ for (i = 0; i < pref_len; i++)
+ lookup_prefix[i] = toupper(prefix[i]);
+ }
+
+ lookup_prefix[pref_len] = '\0';
+ result.offset += pref_len;
+
+ if (lookup_prefix[0] == 'D') {
+ type = HFP_AT_SET;
+ goto done;
+ }
+
+ if (data[result.offset] == '=') {
+ result.offset++;
+ if (data[result.offset] == '?') {
+ result.offset++;
+ type = HFP_AT_TEST;
+ } else {
+ type = HFP_AT_SET;
+ }
+ goto done;
+ }
+
+ if (data[result.offset] == '?') {
+ result.offset++;
+ type = HFP_AT_READ;
+ goto done;
+ }
+
+ type = HFP_AT_COMMAND;
+
+done:
+
+ handler = queue_find(hfp->prefix_handlers, match_handler_prefix,
+ lookup_prefix);
+ if (!handler)
+ return false;
+
+ handler->callback(&result, type, handler->user_data);
+
+ return true;
+}
+
static void process_input(struct hfp_gw *hfp)
{
char *str, *ptr;
@@ -162,10 +250,12 @@ static void process_input(struct hfp_gw *hfp)
hfp->result_pending = true;
- if (hfp->command_callback)
- hfp->command_callback(str, hfp->command_data);
- else
- hfp_gw_send_result(hfp, HFP_RESULT_ERROR);
+ if (!call_prefix_handler(hfp, str)) {
+ if (hfp->command_callback)
+ hfp->command_callback(str, hfp->command_data);
+ else
+ hfp_gw_send_result(hfp, HFP_RESULT_ERROR);
+ }
len = ringbuf_drain(hfp->read_buf, count + 1);
--
1.8.5.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox