* [RFC -v2 15/16] Bluetooth: Create l2cap->ops->set_shutdown()
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Isolates the code that sets the socket shutdown mask. This is the last
commit to remove the socket usage from l2cap_core.c
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 5 +++++
net/bluetooth/a2mp.c | 1 +
net/bluetooth/l2cap_core.c | 7 +------
net/bluetooth/l2cap_sock.c | 10 ++++++++++
4 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index cab7773..d3c8f57 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -556,6 +556,7 @@ struct l2cap_ops {
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
unsigned long len, int nb);
void (*resume) (struct l2cap_chan *chan);
+ void (*set_shutdown) (struct l2cap_chan *chan);
};
struct l2cap_conn {
@@ -794,6 +795,10 @@ static inline void l2cap_chan_no_resume(struct l2cap_chan *chan)
{
}
+static inline void l2cap_chan_no_set_shutdown(struct l2cap_chan *chan)
+{
+}
+
extern bool disable_ertm;
int l2cap_init_sockets(void);
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 4a542b3..0a2ec84 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -709,6 +709,7 @@ static struct l2cap_ops a2mp_chan_ops = {
.ready = l2cap_chan_no_ready,
.defer = l2cap_chan_no_defer,
.resume = l2cap_chan_no_resume,
+ .set_shutdown = l2cap_chan_no_set_shutdown,
};
static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 72dd394..5104a88 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3973,7 +3973,6 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
struct l2cap_disconn_rsp rsp;
u16 dcid, scid;
struct l2cap_chan *chan;
- struct sock *sk;
scid = __le16_to_cpu(req->scid);
dcid = __le16_to_cpu(req->dcid);
@@ -3990,15 +3989,11 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
l2cap_chan_lock(chan);
- sk = chan->sk;
-
rsp.dcid = cpu_to_le16(chan->scid);
rsp.scid = cpu_to_le16(chan->dcid);
l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
- lock_sock(sk);
- sk->sk_shutdown = SHUTDOWN_MASK;
- release_sock(sk);
+ chan->ops->set_shutdown(chan);
l2cap_chan_hold(chan);
l2cap_chan_del(chan, ECONNRESET);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index e7b3291..07ef90c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1159,6 +1159,15 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
release_sock(sk);
}
+static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan)
+{
+ struct sock *sk = chan->data;
+
+ lock_sock(sk);
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ release_sock(sk);
+}
+
static struct l2cap_ops l2cap_chan_ops = {
.name = "L2CAP Socket Interface",
.new_connection = l2cap_sock_new_connection_cb,
@@ -1170,6 +1179,7 @@ static struct l2cap_ops l2cap_chan_ops = {
.defer = l2cap_sock_defer_cb,
.alloc_skb = l2cap_sock_alloc_skb_cb,
.resume = l2cap_sock_resume_cb,
+ .set_shutdown = l2cap_sock_set_shutdown_cb,
};
static void l2cap_sock_destruct(struct sock *sk)
--
1.8.0.2
^ permalink raw reply related
* [RFC -v2 16/16] Bluetooth: Remove sk member from struct l2cap_chan
From: Gustavo Padovan @ 2012-12-21 18:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1356113459-7932-1-git-send-email-gustavo@padovan.org>
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Now that the removal of socket usage from l2cap_core.c is done we can
remove sk from struct l2cap_chan since we do not use it anywhere anymore.
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
include/net/bluetooth/l2cap.h | 2 --
net/bluetooth/l2cap_sock.c | 5 ++---
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index d3c8f57..e444d55 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -433,8 +433,6 @@ struct l2cap_seq_list {
#define L2CAP_SEQ_LIST_TAIL 0x8000
struct l2cap_chan {
- struct sock *sk;
-
bdaddr_t src;
bdaddr_t dst;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 07ef90c..910c9d7 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1101,11 +1101,12 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
unsigned long len, int nb)
{
+ struct sock *sk = chan->data;
struct sk_buff *skb;
int err;
l2cap_chan_unlock(chan);
- skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
+ skb = bt_skb_send_alloc(sk, len, nb, &err);
l2cap_chan_lock(chan);
if (!skb)
@@ -1293,8 +1294,6 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
l2cap_chan_hold(chan);
- chan->sk = sk;
-
l2cap_pi(sk)->chan = chan;
return sk;
--
1.8.0.2
^ permalink raw reply related
* Re: [PATCH 2/2] Bluetooth: mgmt: Avoid using magic number in status code
From: Gustavo Padovan @ 2012-12-21 19:10 UTC (permalink / raw)
To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1355407881-22110-2-git-send-email-szymon.janc@tieto.com>
Hi Szymon,
* Szymon Janc <szymon.janc@tieto.com> [2012-12-13 15:11:21 +0100]:
> Use MGMT_STATUS_SUCCESS for success return code.
>
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
> net/bluetooth/mgmt.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
Both patches have been applied to bluetooth-next. Thanks.
Gustavo
^ permalink raw reply
* Re: [PATCH 1/2] Bluetooth: Fix to update EIR for uuid16 properly
From: Johan Hedberg @ 2012-12-21 19:31 UTC (permalink / raw)
To: Syam Sidhardhan; +Cc: linux-bluetooth
In-Reply-To: <1356097469-24073-1-git-send-email-s.syam@samsung.com>
Hi Syam,
On Fri, Dec 21, 2012, Syam Sidhardhan wrote:
> If we register a uuid other than uuid16, especially custom 128 bit uuid
> then nothing is updated in the EIR and it was broken.
>
> After registering a 16 bit uuid. ex: "sdptool add SP", we can see the
> uuid in the EIR as below.
> < 0000: 01 52 0c f1 00 08 09 52 65 64 77 6f 6f 64 15 03 .R.....Redwood..
> 0010: 01 11 32 11 2f 11 06 11 05 11 0a 11 0e 11 0c 11 ..2./...........
> 0020: 1f 11 12 11 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00f0: 00 00 00 00 00 .....
> > 0000: 04 0e 04 01 52 0c 00 ....R..
>
> But after register a user defined 128 bit uuid, nothing is
> updated in the EIR.
>
> < 0000: 01 52 0c f1 00 08 09 52 65 64 77 6f 6f 64 00 00 .R.....Redwood..
> 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00f0: 00 00 00 00 00 .....
> > 0000: 04 0e 04 01 52 0c 00 ....R..
>
> With this fix, we can see the EIR is updated properly.
>
> Signed-off-by: Syam Sidhardhan <s.syam@samsung.com>
> ---
> net/bluetooth/mgmt.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index f559b96..512a3f5 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -514,8 +514,6 @@ static void create_eir(struct hci_dev *hdev, u8 *data)
> u16 uuid16;
>
> uuid16 = get_uuid16(uuid->uuid);
> - if (uuid16 == 0)
> - return;
>
> if (uuid16 < 0x1100)
> continue;
Nak. The bug is real and should be fixed but your fix is wrong. The
right fix it to convert this return statement into a continue statement
since we do still want to check for a 0 return value from get_uuid16.
Along with this patch please prepare another one to increment the mgmt
revision. These two should go together to upstream trees so that we can
introduce a check in user space to know whether it's safe to pass
non-16bit UUIDs to the kernel or not.
Johan
^ permalink raw reply
* [PATCH BlueZ 00/25] Broadcaster/Observer implementation
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
Main changes from RFC series:
- Add version to Observer interface (org.bluez.Observer1)
- Merge some patches to decrease series size.
This series contains the implementation for Broadcaster/Observer roles. It has
changes for adapter API, userspace implementation for MGMT API and new commands
in btmgmt tool.
The kernel patches for new MGMT commands were sent one week ago by Jefferson
Delfes: http://article.gmane.org/gmane.linux.bluez.kernel/32703
For now, only Service Data and Manufacturer Specific Data can be
broadcasted/observed. All other data types defined by BT SIG are not
appropriate for general application use, and should be managed by BlueZ itself.
For Observer role, we have:
* Two methods to register watchers: RegisterServiceObserver() and
RegisterManufacturerObserver().
* Respective methods to unregister watchers: UnregisterServiceObserver() and
UnregisterManufacturerObserver()
* The data received are sent to application through ServiceReceived() and/or
ManufacturerReceived().
An application can register only a observer watcher for each type: one for
Service Data and one for Manufacturer Specific Data. Both types can be enabled
for the same watcher.
For Broadcaster role, we have:
* Two methods to set data in controller: SetServiceData() and
SetManufacturerData().
* One method for releasing any previously set Advertising data:
ClearBroadcastData().
The same application can set a new Service Data and a new Manufacturer Specific
Data. To update any data set previously, the application should use
SetServiceData() or SetManufacturerData() using same Service UUID or Company
Identifier Code, respectively. Using ClearBroadcastData() will clean all data
set by application.
For MGMT API, new functions were implemented for Set Observer, Set Broadcaster,
Set Controller Data and Unset Controller Data (see doc/mgmt-api.txt for
details).
Anderson Lizardo (1):
mgmt-api: Broadcaster/Observer management API
Bruna Moreira (13):
lib: Add set broadcaster/observer operations
btmgmt: Add set controller data support
btmgmt: Add unset controller data support
doc: Add Broadcaster/Observer D-Bus API documentation
observer: Add Register/UnregisterManufacturerObserver() D-Bus method
observer: Add watchers and filters for observers
observer: Add Service/ManufacturerReceived() D-Bus method
observer: Add python test script
lib: Maximum value to advertising and scan response
broadcaster: Build and send ADV/EIR data blob to kernel
broadcaster: Add ClearBroadcastData() D-Bus method
broadcaster: Update some data of already broadcast value
broadcaster: Add python test script
Jefferson Delfes (11):
lib: Add set/uset controller data operations
btmgmt: Add set broadcaster and set observer support
mgmt: Add set observer and set broadcaster command
mgmt: Add set controller data command
mgmt: Add unset controller data command
adapter: Add D-Bus API for Observer GAP Role
observer: Add Register/UnregisterServiceObserver() D-Bus method
eir: Add manufacturer and service data fields
adapter: Add D-Bus API for Broadcaster GAP Role
broadcaster: Add SetService/ManufacturerData() D-Bus method
broadcaster: Add list of broadcaster sessions
doc/adapter-api.txt | 117 +++++++
doc/mgmt-api.txt | 64 ++++
lib/hci.h | 6 +-
lib/mgmt.h | 26 ++
src/adapter.c | 811 ++++++++++++++++++++++++++++++++++++++++++++++++-
src/adapter.h | 3 +
src/bluetooth.conf | 1 +
src/eir.c | 42 +++
src/eir.h | 19 ++
src/mgmt.c | 119 ++++++++
src/mgmt.h | 6 +
test/test-broadcaster | 61 ++++
test/test-observer | 75 +++++
tools/btmgmt.c | 139 +++++++++
14 files changed, 1486 insertions(+), 3 deletions(-)
create mode 100755 test/test-broadcaster
create mode 100755 test/test-observer
--
1.7.9.5
^ permalink raw reply
* [PATCH BlueZ 01/25] mgmt-api: Broadcaster/Observer management API
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Anderson Lizardo <anderson.lizardo@openbossa.org>
Add new management commands for enabling or disabling broadcasting and
observation modes, as defined by the Observer and Broadcaster GAP roles
on the Core specification 4.0.
The commands can also be used for adding information to EIR on BR/EDR
controllers. For a list of all available AD/EIR types, see the Core
Specification Supplement (CSS) document.
Note that some AD/EIR types are managed internally by the kernel and are
not available through these new commands.
---
doc/mgmt-api.txt | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index 60f4da4..fe052af 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -141,6 +141,8 @@ Read Controller Information Command
8 Basic Rate/Enhanced Data Rate
9 High Speed
10 Low Energy
+ 11 Broadcaster
+ 12 Observer
This command generates a Command Complete event on success or
a Command Status event on failure.
@@ -845,6 +847,68 @@ Set Device ID Command
a Command Status event on failure.
+Set Controller Data Command
+===========================
+
+ Command Code: 0x0029
+ Controller Index: <controller id>
+ Command Parameters: Flags (1 Octet)
+ Type (1 Octet)
+ Length (1 Octet)
+ Data (0-255 Octets)
+ Return Parameters:
+
+ This command can be used to set AD for LE capable controllers or EIR
+ for BR/EDR controllers. Multiple AD/EIR types can be configured by
+ calling this command multiple times. If the controller is BR/EDR/LE
+ capable (also known as "dual mode"), only the LE advertising is set.
+
+ The Flags parameter is currently unused, but it will contain bitwise
+ flags to fine tune how and when the data will set on the controller.
+
+ This command generates a Command Complete event on success or
+ a Command Status event on failure.
+
+
+Unset Controller Data Command
+=============================
+
+ Command Code: 0x002A
+ Controller Index: <controller id>
+ Command Parameters: Type (1 Octet)
+ Return Parameters:
+
+ Remove the AD/EIR information identified by Type, so it will not be
+ broadcasted anymore.
+
+ This command generates a Command Complete event on success or
+ on failure.
+
+
+Set Broadcaster Command
+=======================
+
+ Command Code: 0x002B
+ Controller Index: <controller id>
+ Command Parameters: Broadcaster (1 Octet)
+ Return Parameters: Current_Settings (4 Octets)
+
+ This command generates a Command Complete event on success or
+ a Command Status event on failure.
+
+
+Set Observer Command
+====================
+
+ Command Code: 0x002C
+ Controller Index: <controller id>
+ Command Parameters: Observer (1 Octet)
+ Return Parameters: Current_Settings (4 Octets)
+
+ This command generates a Command Complete event on success or
+ a Command Status event on failure.
+
+
Command Complete Event
======================
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 02/25] lib: Add set/uset controller data operations
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
Add structure for new commands: Set Controller Data and Unset Controller
Data. Add new defines for flags that will be used in Set/Unset
Controller Data operation.
---
lib/mgmt.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/lib/mgmt.h b/lib/mgmt.h
index 6c7e44a..fffb0aa 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -318,6 +318,22 @@ struct mgmt_cp_set_device_id {
uint16_t version;
} __packed;
+#define MGMT_DATA_NORMAL_PRIORITY 0x00
+#define MGMT_DATA_HIGH_PRIORITY 0x01
+
+#define MGMT_OP_SET_CONTROLLER_DATA 0x0029
+struct mgmt_cp_set_controller_data {
+ uint8_t flags;
+ uint8_t type;
+ uint8_t length;
+ uint8_t data[0];
+} __packed;
+
+#define MGMT_OP_UNSET_CONTROLLER_DATA 0x002A
+struct mgmt_cp_unset_controller_data {
+ uint8_t type;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
@@ -496,6 +512,8 @@ static const char *mgmt_op[] = {
"Block Device",
"Unblock Device",
"Set Device ID",
+ "Set Controller Data",
+ "Unset Controller Data",
};
static const char *mgmt_ev[] = {
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 03/25] lib: Add set broadcaster/observer operations
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
Add opcodes for new Set Broadcaster and Set Observer commands.
---
lib/mgmt.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/mgmt.h b/lib/mgmt.h
index fffb0aa..44c4405 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -92,6 +92,8 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_BREDR 0x00000080
#define MGMT_SETTING_HS 0x00000100
#define MGMT_SETTING_LE 0x00000200
+#define MGMT_SETTING_BROADCASTER 0x00000400
+#define MGMT_SETTING_OBSERVER 0x00000800
#define MGMT_OP_READ_INFO 0x0004
struct mgmt_rp_read_info {
@@ -334,6 +336,10 @@ struct mgmt_cp_unset_controller_data {
uint8_t type;
} __packed;
+#define MGMT_OP_SET_BROADCASTER 0x002B
+
+#define MGMT_OP_SET_OBSERVER 0x002C
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
@@ -514,6 +520,8 @@ static const char *mgmt_op[] = {
"Set Device ID",
"Set Controller Data",
"Unset Controller Data",
+ "Set Broadcaster",
+ "Set Observer",
};
static const char *mgmt_ev[] = {
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 04/25] btmgmt: Add set broadcaster and set observer support
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
Add new broadcaster command for running the Set Broadcaster operation
from MGMT API. Also, add new observer command for running the Set
Observer operation from MGMT API.
---
tools/btmgmt.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index b89bcac..4d9eab6 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -235,6 +235,8 @@ static const char *settings_str[] = {
"br/edr",
"hs",
"le" ,
+ "broadcaster",
+ "observer",
};
static void print_settings(uint32_t settings)
@@ -1111,6 +1113,16 @@ static void cmd_le(int mgmt_sk, uint16_t index, int argc, char **argv)
cmd_setting(mgmt_sk, index, MGMT_OP_SET_LE, argc, argv);
}
+static void cmd_broadcaster(int mgmt_sk, uint16_t index, int argc, char **argv)
+{
+ cmd_setting(mgmt_sk, index, MGMT_OP_SET_BROADCASTER, argc, argv);
+}
+
+static void cmd_observer(int mgmt_sk, uint16_t index, int argc, char **argv)
+{
+ cmd_setting(mgmt_sk, index, MGMT_OP_SET_OBSERVER, argc, argv);
+}
+
static void class_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
void *rsp, uint16_t len, void *user_data)
{
@@ -1848,6 +1860,8 @@ static struct {
{ "rm-uuid", cmd_remove_uuid, "Remove UUID" },
{ "clr-uuids", cmd_clr_uuids, "Clear UUIDs", },
{ "did", cmd_did, "Set Device ID", },
+ { "broadcaster",cmd_broadcaster,"Toggle Broadcaster Mode", },
+ { "observer", cmd_observer, "Toggle Observer Mode", },
{ NULL, NULL, 0 }
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 05/25] btmgmt: Add set controller data support
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
Add new command set-data for running the Set Controller Data operation
from MGMT API.
---
tools/btmgmt.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 4d9eab6..3ae0ecb 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -1829,6 +1829,90 @@ done:
}
}
+static void set_data_rsp(int mgmt_sk, uint16_t op, uint16_t id, uint8_t status,
+ void *rsp, uint16_t len, void *user_data)
+{
+ if (status != 0) {
+ fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
+ mgmt_opstr(op), status, mgmt_errstr(status));
+ exit(EXIT_FAILURE);
+ }
+
+ exit(EXIT_SUCCESS);
+}
+
+static void set_data_usage(void)
+{
+ printf("Usage: btmgmt set_data [-p] <data type> <byte array>\n");
+ printf("\nexample: btmgmt set_data -p 0xff 11 11 aa bb cc\n");
+ printf("\nparameters:\n");
+ printf("\tp: controller data priority.\n");
+ printf("\t<data type>: 0x16 (service data) or 0xff (manufacturer\n"
+ "\t specific data). Values different from that will return\n"
+ "\t error from kernel.\n");
+ printf("\t<byte array>: two bytes (service uuid or company identifier\n"
+ "\t code) following by hex encoded bytes (data).\n");
+}
+
+static struct option set_data_options[] = {
+ { "help", 0, 0, 'h' },
+ { "priority", 1, 0, 'p' },
+ { 0, 0, 0, 0 }
+};
+
+static void cmd_set_data(int mgmt_sk, uint16_t index, int argc, char **argv)
+{
+ struct mgmt_cp_set_controller_data *cp;
+ uint8_t data_len, flags = 0;
+ unsigned int i;
+ int opt;
+
+ while ((opt = getopt_long(argc, argv, "+ph", set_data_options,
+ NULL)) != -1) {
+ switch (opt) {
+ case 'p':
+ flags = MGMT_DATA_HIGH_PRIORITY;
+ break;
+ case 'h':
+ default:
+ set_data_usage();
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ optind = 0;
+
+ if (argc < 1) {
+ set_data_usage();
+ exit(EXIT_FAILURE);
+ }
+
+ data_len = argc - 1;
+ cp = malloc(sizeof(*cp) + data_len);
+ cp->flags = flags;
+ sscanf(argv[0], "%hhx", &cp->type);
+
+ for (i = 0; i < data_len; i++)
+ sscanf(argv[i + 1], "%hhx", &cp->data[i]);
+
+ cp->length = data_len;
+
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ if (mgmt_send_cmd(mgmt_sk, MGMT_OP_SET_CONTROLLER_DATA, index,
+ cp, sizeof(*cp) + data_len,
+ set_data_rsp, NULL) < 0) {
+ free(cp);
+ fprintf(stderr, "Unable to send set controller data cmd\n");
+ exit(EXIT_FAILURE);
+ }
+
+ free(cp);
+}
+
static struct {
char *cmd;
void (*func)(int mgmt_sk, uint16_t index, int argc, char **argv);
@@ -1862,6 +1946,7 @@ static struct {
{ "did", cmd_did, "Set Device ID", },
{ "broadcaster",cmd_broadcaster,"Toggle Broadcaster Mode", },
{ "observer", cmd_observer, "Toggle Observer Mode", },
+ { "set-data", cmd_set_data, "Set Controller Data", },
{ NULL, NULL, 0 }
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 06/25] btmgmt: Add unset controller data support
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
Add new command unset-data for running the Unset Controller Data
operation from MGMT API.
---
tools/btmgmt.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 3ae0ecb..99f5562 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -1913,6 +1913,45 @@ static void cmd_set_data(int mgmt_sk, uint16_t index, int argc, char **argv)
free(cp);
}
+static void unset_data_rsp(int mgmt_sk, uint16_t op, uint16_t id,
+ uint8_t status, void *rsp, uint16_t len, void *user_data)
+{
+ if (status != 0) {
+ fprintf(stderr, "%s failed, status 0x%02x (%s)\n",
+ mgmt_opstr(op), status, mgmt_errstr(status));
+ exit(EXIT_FAILURE);
+ }
+
+ exit(EXIT_SUCCESS);
+}
+
+static void cmd_unset_data(int mgmt_sk, uint16_t index, int argc, char **argv)
+{
+ struct mgmt_cp_unset_controller_data cp;
+
+ if (argc < 2) {
+ printf("Usage: btmgmt %s <data type>\n", argv[0]);
+ printf("\nexample: btmgmt %s 0xff\n", argv[0]);
+ printf("\nparameters:\n");
+ printf("\t<data type>: 0x16 (service data) or 0xff\n"
+ "\t(manufacturer specific data).\n");
+
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&cp, 0, sizeof(cp));
+ sscanf(argv[1], "%hhx", &cp.type);
+
+ if (index == MGMT_INDEX_NONE)
+ index = 0;
+
+ if (mgmt_send_cmd(mgmt_sk, MGMT_OP_UNSET_CONTROLLER_DATA, index,
+ &cp, sizeof(cp), unset_data_rsp, NULL) < 0) {
+ fprintf(stderr, "Unable to send unset controller data cmd\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
static struct {
char *cmd;
void (*func)(int mgmt_sk, uint16_t index, int argc, char **argv);
@@ -1947,6 +1986,7 @@ static struct {
{ "broadcaster",cmd_broadcaster,"Toggle Broadcaster Mode", },
{ "observer", cmd_observer, "Toggle Observer Mode", },
{ "set-data", cmd_set_data, "Set Controller Data", },
+ { "unset-data", cmd_unset_data, "Unset Controller Data", },
{ NULL, NULL, 0 }
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 07/25] mgmt: Add set observer and set broadcaster command
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
Implement Set Observer and Set Broadcaster support in MGMT API.
For observer, setting TRUE will make the adapter start LE discovery,
otherwise, setting FALSE will make the adapter stop LE discovery.
For broadcaster, setting TRUE will make the new data sent by Set
Controller Data command to be set in adapter and the advertising will
start. Setting FALSE will stop advertising.
---
src/mgmt.c | 16 ++++++++++++++++
src/mgmt.h | 2 ++
2 files changed, 18 insertions(+)
diff --git a/src/mgmt.c b/src/mgmt.c
index 03ec049..0f212b2 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1651,6 +1651,12 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
case MGMT_OP_SET_DEVICE_ID:
DBG("set_did complete");
break;
+ case MGMT_OP_SET_BROADCASTER:
+ DBG("set_broadcaster complete");
+ break;
+ case MGMT_OP_SET_OBSERVER:
+ DBG("set_observer complete");
+ break;
default:
error("Unknown command complete for opcode %u", opcode);
break;
@@ -2358,6 +2364,16 @@ int mgmt_set_fast_connectable(int index, gboolean enable)
return 0;
}
+int mgmt_set_broadcaster(int index, gboolean enable)
+{
+ return mgmt_set_mode(index, MGMT_OP_SET_BROADCASTER, enable);
+}
+
+int mgmt_set_observer(int index, gboolean enable)
+{
+ return mgmt_set_mode(index, MGMT_OP_SET_OBSERVER, enable);
+}
+
int mgmt_read_clock(int index, const bdaddr_t *bdaddr, int which, int timeout,
uint32_t *clock, uint16_t *accuracy)
{
diff --git a/src/mgmt.h b/src/mgmt.h
index 1ea8488..1607a95 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -32,6 +32,8 @@ int mgmt_set_pairable(int index, gboolean pairable);
int mgmt_set_name(int index, const char *name);
int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor);
int mgmt_set_fast_connectable(int index, gboolean enable);
+int mgmt_set_broadcaster(int index, gboolean enable);
+int mgmt_set_observer(int index, gboolean enable);
int mgmt_start_discovery(int index);
int mgmt_start_le_scanning(int index);
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 08/25] mgmt: Add set controller data command
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
Implement new Set Controller Data command in MGMT API. The maximum size
for new data is 27 bytes. The data sent using this command will be
stored in internal list and it will be set in adapter after receiving a
Set Broadcaster with TRUE.
---
src/adapter.c | 8 ++++++
src/adapter.h | 3 +++
src/mgmt.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/mgmt.h | 3 +++
4 files changed, 92 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 6ff20e1..d741ae1 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -563,6 +563,10 @@ void adapter_name_changed(struct btd_adapter *adapter, const char *name)
(const uint8_t *) name, strlen(name));
}
+void adapter_set_controller_data_complete(struct btd_adapter *adapter)
+{
+}
+
int adapter_set_name(struct btd_adapter *adapter, const char *name)
{
char maxname[MAX_NAME_LENGTH + 1];
@@ -1150,6 +1154,10 @@ static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
+void adapter_set_controller_data_failed(struct btd_adapter *adapter)
+{
+}
+
static const GDBusMethodTable adapter_methods[] = {
{ GDBUS_METHOD("StartDiscovery", NULL, NULL,
adapter_start_discovery) },
diff --git a/src/adapter.h b/src/adapter.h
index d35b8db..ad79ae1 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -236,3 +236,6 @@ void adapter_store_cached_name(const bdaddr_t *local, const bdaddr_t *peer,
void btd_adapter_for_each_device(struct btd_adapter *adapter,
void (*cb)(struct btd_device *device, void *data),
void *data);
+
+void adapter_set_controller_data_complete(struct btd_adapter *adapter);
+void adapter_set_controller_data_failed(struct btd_adapter *adapter);
diff --git a/src/mgmt.c b/src/mgmt.c
index 0f212b2..d1b5043 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1426,6 +1426,28 @@ static void start_discovery_complete(int sk, uint16_t index, uint8_t status,
adapter_set_discovering(adapter, FALSE);
}
+static void set_controller_data_complete(int sk, uint16_t index, void *buf,
+ size_t len)
+{
+ struct btd_adapter *adapter;
+
+ DBG("hci%d", index);
+
+ if (index > max_index) {
+ error("Unexpected index %u in set_controller data complete",
+ index);
+ return;
+ }
+
+ adapter = manager_find_adapter_by_id(index);
+ if (adapter == NULL) {
+ DBG("Adapter not found");
+ return;
+ }
+
+ adapter_set_controller_data_complete(adapter);
+}
+
static void read_local_oob_data_failed(int sk, uint16_t index)
{
struct btd_adapter *adapter;
@@ -1443,6 +1465,23 @@ static void read_local_oob_data_failed(int sk, uint16_t index)
adapter_read_local_oob_data_complete(adapter, NULL, NULL);
}
+static void set_controller_data_failed(int sk, uint16_t index)
+{
+ struct btd_adapter *adapter;
+
+ if (index > max_index) {
+ error("Unexpected index %u in set_controller_data_failed",
+ index);
+ return;
+ }
+
+ DBG("hci%u", index);
+
+ adapter = manager_find_adapter_by_id(index);
+ if (adapter)
+ adapter_set_controller_data_failed(adapter);
+}
+
static void handle_pending_uuids(uint16_t index)
{
struct controller_info *info;
@@ -1651,6 +1690,10 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
case MGMT_OP_SET_DEVICE_ID:
DBG("set_did complete");
break;
+ case MGMT_OP_SET_CONTROLLER_DATA:
+ DBG("set_controller_data complete");
+ set_controller_data_complete(sk, index, ev->data, len);
+ break;
case MGMT_OP_SET_BROADCASTER:
DBG("set_broadcaster complete");
break;
@@ -1701,6 +1744,9 @@ static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
return;
}
break;
+ case MGMT_OP_SET_CONTROLLER_DATA:
+ set_controller_data_failed(sk, index);
+ break;
}
error("hci%u: %s (0x%04x) failed: %s (0x%02x)", index,
@@ -2821,3 +2867,35 @@ int mgmt_ssp_enabled(int index)
return mgmt_ssp(info->current_settings);
}
+
+int mgmt_set_controller_data(int index, uint8_t flags, uint8_t data_type,
+ uint8_t *data, uint8_t data_length)
+{
+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_controller_data) +
+ HCI_MAX_EIR_LENGTH];
+ struct mgmt_hdr *hdr = (void *) buf;
+ struct mgmt_cp_set_controller_data *cp = (void *) &buf[sizeof(*hdr)];
+ uint16_t cp_size;
+ int err = 0;
+
+ DBG("hci%d flags %d data_type 0x%hhx data_length %d", index, flags,
+ data_type, data_length);
+
+ memset(buf, 0, sizeof(buf));
+
+ cp_size = sizeof(*cp) + data_length;
+
+ hdr->opcode = htobs(MGMT_OP_SET_CONTROLLER_DATA);
+ hdr->index = htobs(index);
+ hdr->len = htobs(cp_size);
+
+ cp->flags = flags;
+ cp->type = data_type;
+ cp->length = data_length;
+ memcpy(cp->data, data, data_length);
+
+ if (write(mgmt_sock, buf, sizeof(*hdr) + cp_size) < 0)
+ err = -errno;
+
+ return err;
+}
diff --git a/src/mgmt.h b/src/mgmt.h
index 1607a95..92b4757 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -84,3 +84,6 @@ int mgmt_confirm_name(int index, const bdaddr_t *bdaddr, uint8_t bdaddr_type,
gboolean name_known);
int mgmt_ssp_enabled(int index);
+
+int mgmt_set_controller_data(int index, uint8_t flags, uint8_t data_type,
+ uint8_t *data, uint8_t data_length);
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 09/25] mgmt: Add unset controller data command
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
Implement Unset Controller Data command in MGMT API. This operation
will remove all data from specific type that was set previously with Set
Controller Data operation.
---
src/mgmt.c | 25 +++++++++++++++++++++++++
src/mgmt.h | 1 +
2 files changed, 26 insertions(+)
diff --git a/src/mgmt.c b/src/mgmt.c
index d1b5043..9a6affc 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1694,6 +1694,9 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
DBG("set_controller_data complete");
set_controller_data_complete(sk, index, ev->data, len);
break;
+ case MGMT_OP_UNSET_CONTROLLER_DATA:
+ DBG("unset_controller_data complete");
+ break;
case MGMT_OP_SET_BROADCASTER:
DBG("set_broadcaster complete");
break;
@@ -2899,3 +2902,25 @@ int mgmt_set_controller_data(int index, uint8_t flags, uint8_t data_type,
return err;
}
+
+int mgmt_unset_controller_data(int index, uint8_t data_type)
+{
+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_unset_controller_data)];
+ struct mgmt_hdr *hdr = (void *) buf;
+ struct mgmt_cp_unset_controller_data *cp = (void *) &buf[sizeof(*hdr)];
+
+ DBG("hci%d data_type 0x%hhx", index, data_type);
+
+ memset(buf, 0, sizeof(buf));
+
+ hdr->opcode = htobs(MGMT_OP_UNSET_CONTROLLER_DATA);
+ hdr->index = htobs(index);
+ hdr->len = htobs(sizeof(*cp));
+
+ cp->type = data_type;
+
+ if (write(mgmt_sock, buf, sizeof(buf)) < 0)
+ return -errno;
+
+ return 0;
+}
diff --git a/src/mgmt.h b/src/mgmt.h
index 92b4757..187c971 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -87,3 +87,4 @@ int mgmt_ssp_enabled(int index);
int mgmt_set_controller_data(int index, uint8_t flags, uint8_t data_type,
uint8_t *data, uint8_t data_length);
+int mgmt_unset_controller_data(int index, uint8_t data_type);
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 10/25] doc: Add Broadcaster/Observer D-Bus API documentation
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
---
doc/adapter-api.txt | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/doc/adapter-api.txt b/doc/adapter-api.txt
index 62c7a27..e8ca305 100644
--- a/doc/adapter-api.txt
+++ b/doc/adapter-api.txt
@@ -43,6 +43,102 @@ Methods void StartDiscovery()
Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.Failed
+ void RegisterServiceObserver(object observer,
+ uint16 match_value)
+
+ Registers an observer agent to monitor Service Data
+ broadcasts. This agent will be notified whenever a
+ broadcast is received that matches that filter. It is
+ possible use same object path for two observers:
+ Service Data and Manufacturer Specific Data.
+
+ The match_value parameter must be the 16-bit UUID for
+ the service whose data is to be monitored.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.AlreadyExists
+
+ void RegisterManufacturerObserver(object observer,
+ uint16 match_value)
+
+ Registers an observer agent to monitor Manufacturer
+ Specific Data broadcasts. This agent will be notified
+ whenever a broadcast is received that matches that
+ filter. It is possible use same object path for two
+ observers: Service Data and Manufacturer Specific Data.
+
+ The match_value parameter must be the 16-bit Company
+ Identifier Code for the manufacturer whose data is to
+ be monitored.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.AlreadyExists
+
+ void UnregisterServiceObserver(object observer)
+
+ Unregisters a Service Data observer. Broadcasts will
+ not be notified to this agent anymore. The observer
+ will be destroyed only if no Manufacturer Specific Data
+ was registered with the same object path.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.DoesNotExist
+
+ void UnregisterManufacturerObserver(object observer)
+
+ Unregisters a Manufacturer Specific Data observer.
+ Broadcasts will not be notified to this agent anymore.
+ The observer will be destroyed only if no Service Data
+ was registered with the same object path.
+
+ Possible errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.DoesNotExist
+
+ void SetServiceData(uint16 uuid, array{byte} data)
+
+ Set Service Data for broadcast. Different applications
+ can register different Adv. data types, and they are
+ all concatenated to form the Adv. data. Broadcasting is
+ enabled as soon as the first SetServiceData() call is
+ made.
+
+ This method can be used to update service data already
+ being broadcasted.
+
+ Use ClearBroadcastData() to release any Adv. data for
+ the application. Advertising data is also released when
+ application exits, and once the last Broadcaster exits,
+ advertising is disabled.
+
+ Possible Errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.Failed
+
+ void SetManufacturerData(uint16 cid, array{byte} data)
+
+ Set Manufacturer Specific Data for broadcast. Different
+ applications can register different Adv. data types,
+ and they are all concatenated to form the Adv. data.
+ Broadcasting is enabled as soon as the first
+ SetManufacturerData() call is made.
+
+ This method can be used to update manufacturer data
+ already being broadcasted.
+
+ Use ClearBroadcastData() to release any Adv. data for
+ the application. Advertising data is also released when
+ application exits, and once the last Broadcaster exits,
+ advertising is disabled.
+
+ Possible Errors: org.bluez.Error.InvalidArguments
+ org.bluez.Error.Failed
+
+ void ClearBroadcastData()
+
+ This method will release any previously set Advertising
+ data.
+
+ Possible errors: org.bluez.Error.Failed
+
Properties string Address [readonly]
The Bluetooth device address.
@@ -118,3 +214,24 @@ Properties string Address [readonly]
List of 128-bit UUIDs that represents the available
local services.
+
+Observer hierarchy
+==================
+
+Service unique name
+Interface org.bluez.Observer1
+Object path freely definable
+
+Methods void ServiceReceived(string address, uint16 uuid,
+ array{byte} data)
+
+ This callback gets called when a broadcast data has
+ arrived that matches filter used in
+ RegisterServiceObserver.
+
+ void ManufacturerReceived(string address, uint16 cid,
+ array{byte} data)
+
+ This callback gets called when a broadcast data has
+ arrived that matches filter used in
+ RegisterManufacturerObserver.
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 11/25] adapter: Add D-Bus API for Observer GAP Role
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
Implement dummy calls for register or unregister Observer Agents.
---
src/adapter.c | 38 ++++++++++++++++++++++++++++++++++++++
src/bluetooth.conf | 1 +
2 files changed, 39 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index d741ae1..34dad6e 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1154,6 +1154,30 @@ static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
+static DBusMessage *register_service_observer(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_service_observer(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *register_manuf_observer(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_manuf_observer(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
void adapter_set_controller_data_failed(struct btd_adapter *adapter)
{
}
@@ -1166,6 +1190,20 @@ static const GDBusMethodTable adapter_methods[] = {
{ GDBUS_ASYNC_METHOD("RemoveDevice",
GDBUS_ARGS({ "device", "o" }), NULL,
remove_device) },
+ { GDBUS_METHOD("RegisterServiceObserver",
+ GDBUS_ARGS({ "observer", "o" }, { "match_value", "q" }),
+ NULL,
+ register_service_observer) },
+ { GDBUS_METHOD("UnregisterServiceObserver",
+ GDBUS_ARGS({ "observer", "o" }), NULL,
+ unregister_service_observer) },
+ { GDBUS_METHOD("RegisterManufacturerObserver",
+ GDBUS_ARGS({ "observer", "o" }, { "match_value", "q" }),
+ NULL,
+ register_manuf_observer) },
+ { GDBUS_METHOD("UnregisterManufacturerObserver",
+ GDBUS_ARGS({ "observer", "o" }), NULL,
+ unregister_manuf_observer) },
{ }
};
diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 0495200..e8176ed 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -15,6 +15,7 @@
<allow send_interface="org.bluez.MediaPlayer1"/>
<allow send_interface="org.bluez.ThermometerWatcher1"/>
<allow send_interface="org.bluez.AlertAgent1"/>
+ <allow send_interface="org.bluez.Observer1"/>
<allow send_interface="org.bluez.Profile1"/>
<allow send_interface="org.bluez.HeartRateWatcher1"/>
<allow send_interface="org.bluez.CyclingSpeedWatcher1"/>
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 12/25] observer: Add Register/UnregisterServiceObserver() D-Bus method
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
An observer for Service Data must be registered using
RegisterServiceObserver() D-Bus method so it can receive any advertising
which matches with the filter used. Use UnregisterServiceObserver()
D-Bus method for unregistering an observer and stop sending broadcasts
to the agent.
---
src/adapter.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 34dad6e..a5c23da 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1157,12 +1157,47 @@ static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg,
static DBusMessage *register_service_observer(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ struct btd_adapter *adapter = data;
+ const char *path, *sender = dbus_message_get_sender(msg);
+ unsigned int uuid;
+ int err;
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_UINT16, &uuid,
+ DBUS_TYPE_INVALID) == FALSE)
+ return btd_error_invalid_args(msg);
+
+ err = mgmt_set_observer(adapter->dev_id, TRUE);
+ if (err < 0) {
+ error("Failed to set Observer: %s (%d)", strerror(-err), -err);
+
+ return btd_error_failed(msg, strerror(-err));
+ }
+
+ DBG("Service Data Observer registered for hci%d at %s:%s",
+ adapter->dev_id, sender, path);
+
return dbus_message_new_method_return(msg);
}
static DBusMessage *unregister_service_observer(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ const char *path, *sender = dbus_message_get_sender(msg);
+ struct btd_adapter *adapter = data;
+ int err;
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID) == FALSE)
+ return btd_error_invalid_args(msg);
+
+ err = mgmt_set_observer(adapter->dev_id, FALSE);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+
+ DBG("Service Data Observer unregistered for hci%d at %s:%s",
+ adapter->dev_id, sender, path);
+
return dbus_message_new_method_return(msg);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 13/25] observer: Add Register/UnregisterManufacturerObserver() D-Bus method
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
An observer for Manufacturer Specific Data must be registered using
RegisterManufacturerObserver() D-Bus method so it can receive any
advertising which matches with the filter used. Use
UnregisterManufacturerObserver() D-Bus method for unregistering an
observer avoid stop sending broadcasts to the agent.
---
src/adapter.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index a5c23da..60dd54c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1204,12 +1204,47 @@ static DBusMessage *unregister_service_observer(DBusConnection *conn,
static DBusMessage *register_manuf_observer(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ struct btd_adapter *adapter = data;
+ const char *path, *sender = dbus_message_get_sender(msg);
+ unsigned int company_id;
+ int err;
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_UINT16, &company_id,
+ DBUS_TYPE_INVALID) == FALSE)
+ return btd_error_invalid_args(msg);
+
+ err = mgmt_set_observer(adapter->dev_id, TRUE);
+ if (err < 0) {
+ error("Failed to set Observer: %s (%d)", strerror(-err), -err);
+
+ return btd_error_failed(msg, strerror(-err));
+ }
+
+ DBG("Manufacturer Specific Data Observer registered for hci%d at %s:%s",
+ adapter->dev_id, sender, path);
+
return dbus_message_new_method_return(msg);
}
static DBusMessage *unregister_manuf_observer(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ const char *path, *sender = dbus_message_get_sender(msg);
+ struct btd_adapter *adapter = data;
+ int err;
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID) == FALSE)
+ return btd_error_invalid_args(msg);
+
+ err = mgmt_set_observer(adapter->dev_id, FALSE);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+
+ DBG("Manuf. Specific Data Observer unregistered for hci%d at %s:%s",
+ adapter->dev_id, sender, path);
+
return dbus_message_new_method_return(msg);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 14/25] observer: Add watchers and filters for observers
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
The adapter will keep a list of observers listening for advertising.
The new observer is added on the list when it is registered.
When an observer is registered, the filter must be stored to be used
after receiving a new advertising. The observer will only receive the
data from advertising if the filter matches.
---
src/adapter.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 179 insertions(+), 8 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 60dd54c..316acb9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -85,6 +85,11 @@
#define REMOVE_TEMP_TIMEOUT (3 * 60)
static const char *base_path = "/org/bluez";
+
+/* Filter Types (for Observer) */
+#define FILTER_SERVICE_UUID 0x01
+#define FILTER_COMPANY_IC 0x02
+
static GSList *adapter_drivers = NULL;
enum session_req_type {
@@ -116,6 +121,16 @@ struct discovery {
GSList *found;
};
+struct observer_watcher {
+ struct btd_adapter *adapter;
+ guint id; /* Listener id */
+ uint8_t filter_type; /* Filer type: Service or Manufacturer
+ * data */
+ void *filter_data; /* Value of filter */
+ char *sender; /* DBus sender */
+ char *path; /* DBus path */
+};
+
struct btd_adapter {
uint16_t dev_id;
gboolean powered;
@@ -136,6 +151,7 @@ struct btd_adapter {
GSList *disc_sessions; /* Discovery sessions */
struct session_req *scanning_session;
GSList *connect_list; /* Devices to connect when found */
+ GSList *observers; /* Observer watchers */
guint discov_id; /* Discovery timer */
struct discovery *discovery; /* Discovery active */
gboolean connecting; /* Connect active */
@@ -1154,10 +1170,85 @@ static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg,
return NULL;
}
+static void destroy_observer(gpointer user_data)
+{
+ struct observer_watcher *obs = user_data;
+
+ btd_adapter_unref(obs->adapter);
+
+ g_dbus_remove_watch(btd_get_dbus_connection(), obs->id);
+
+ g_free(obs->path);
+ g_free(obs->sender);
+ g_free(obs);
+}
+
+static gint cmp_observer(gconstpointer a, gconstpointer b)
+{
+ const struct observer_watcher *obs = a;
+ const struct observer_watcher *match = b;
+ int ret;
+
+ ret = g_strcmp0(obs->sender, match->sender);
+ if (ret != 0)
+ return ret;
+
+ ret = g_strcmp0(obs->path, match->path);
+ if (ret != 0)
+ return ret;
+
+ return obs->filter_type - match->filter_type;
+}
+
+static struct observer_watcher *find_observer(GSList *list, const char *sender,
+ const char *path, uint8_t filter)
+{
+ struct observer_watcher *match;
+ GSList *l;
+
+ match = g_new0(struct observer_watcher, 1);
+ match->sender = g_strdup(sender);
+ match->path = g_strdup(path);
+ match->filter_type = filter;
+
+ l = g_slist_find_custom(list, match, cmp_observer);
+ g_free(match->sender);
+ g_free(match->path);
+ g_free(match);
+
+ return l ? l->data : NULL;
+}
+
+static void observer_exit(DBusConnection *conn, void *user_data)
+{
+ struct observer_watcher *obs = user_data;
+ struct btd_adapter *adapter = obs->adapter;
+
+ if (obs->filter_type == FILTER_SERVICE_UUID)
+ DBG("Service Data Observer watcher %s disconnected", obs->path);
+ else
+ DBG("Manufacturer Data Observer watcher %s disconnected",
+ obs->path);
+
+ adapter->observers = g_slist_remove(adapter->observers, obs);
+
+ if (adapter->observers == NULL) {
+ int err;
+
+ err = mgmt_set_observer(adapter->dev_id, FALSE);
+ if (err < 0)
+ error("Failed to set Observer: %s (%d)",
+ strerror(-err), -err);
+ }
+
+ destroy_observer(obs);
+}
+
static DBusMessage *register_service_observer(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct btd_adapter *adapter = data;
+ struct observer_watcher *obs;
const char *path, *sender = dbus_message_get_sender(msg);
unsigned int uuid;
int err;
@@ -1167,8 +1258,26 @@ static DBusMessage *register_service_observer(DBusConnection *conn,
DBUS_TYPE_INVALID) == FALSE)
return btd_error_invalid_args(msg);
+ obs = find_observer(adapter->observers, sender, path,
+ FILTER_SERVICE_UUID);
+ if (obs)
+ return btd_error_already_exists(msg);
+
+ obs = g_new0(struct observer_watcher, 1);
+ obs->filter_type = FILTER_SERVICE_UUID;
+ obs->filter_data = GUINT_TO_POINTER(uuid);
+ obs->sender = g_strdup(sender);
+ obs->path = g_strdup(path);
+ obs->adapter = btd_adapter_ref(adapter);
+ obs->id = g_dbus_add_disconnect_watch(conn, sender, observer_exit,
+ obs, NULL);
+
+ adapter->observers = g_slist_prepend(adapter->observers, obs);
+
err = mgmt_set_observer(adapter->dev_id, TRUE);
if (err < 0) {
+ adapter->observers = g_slist_remove(adapter->observers, obs);
+ destroy_observer(obs);
error("Failed to set Observer: %s (%d)", strerror(-err), -err);
return btd_error_failed(msg, strerror(-err));
@@ -1185,15 +1294,28 @@ static DBusMessage *unregister_service_observer(DBusConnection *conn,
{
const char *path, *sender = dbus_message_get_sender(msg);
struct btd_adapter *adapter = data;
- int err;
+ struct observer_watcher *obs;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID) == FALSE)
return btd_error_invalid_args(msg);
- err = mgmt_set_observer(adapter->dev_id, FALSE);
- if (err < 0)
- return btd_error_failed(msg, strerror(-err));
+ obs = find_observer(adapter->observers, sender, path,
+ FILTER_SERVICE_UUID);
+ if (obs == NULL)
+ return btd_error_does_not_exist(msg);
+
+ adapter->observers = g_slist_remove(adapter->observers, obs);
+ g_dbus_remove_watch(btd_get_dbus_connection(), obs->id);
+ destroy_observer(obs);
+
+ if (adapter->observers == NULL) {
+ int err;
+
+ err = mgmt_set_observer(adapter->dev_id, FALSE);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+ }
DBG("Service Data Observer unregistered for hci%d at %s:%s",
adapter->dev_id, sender, path);
@@ -1205,6 +1327,7 @@ static DBusMessage *register_manuf_observer(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct btd_adapter *adapter = data;
+ struct observer_watcher *obs;
const char *path, *sender = dbus_message_get_sender(msg);
unsigned int company_id;
int err;
@@ -1214,8 +1337,26 @@ static DBusMessage *register_manuf_observer(DBusConnection *conn,
DBUS_TYPE_INVALID) == FALSE)
return btd_error_invalid_args(msg);
+ obs = find_observer(adapter->observers, sender, path,
+ FILTER_COMPANY_IC);
+ if (obs)
+ return btd_error_already_exists(msg);
+
+ obs = g_new0(struct observer_watcher, 1);
+ obs->filter_type = FILTER_COMPANY_IC;
+ obs->filter_data = GUINT_TO_POINTER(company_id);
+ obs->sender = g_strdup(sender);
+ obs->path = g_strdup(path);
+ obs->adapter = btd_adapter_ref(adapter);
+ obs->id = g_dbus_add_disconnect_watch(conn, sender, observer_exit,
+ obs, NULL);
+
+ adapter->observers = g_slist_prepend(adapter->observers, obs);
+
err = mgmt_set_observer(adapter->dev_id, TRUE);
if (err < 0) {
+ adapter->observers = g_slist_remove(adapter->observers, obs);
+ destroy_observer(obs);
error("Failed to set Observer: %s (%d)", strerror(-err), -err);
return btd_error_failed(msg, strerror(-err));
@@ -1232,15 +1373,28 @@ static DBusMessage *unregister_manuf_observer(DBusConnection *conn,
{
const char *path, *sender = dbus_message_get_sender(msg);
struct btd_adapter *adapter = data;
- int err;
+ struct observer_watcher *obs;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID) == FALSE)
return btd_error_invalid_args(msg);
- err = mgmt_set_observer(adapter->dev_id, FALSE);
- if (err < 0)
- return btd_error_failed(msg, strerror(-err));
+ obs = find_observer(adapter->observers, sender, path,
+ FILTER_COMPANY_IC);
+ if (obs == NULL)
+ return btd_error_does_not_exist(msg);
+
+ adapter->observers = g_slist_remove(adapter->observers, obs);
+ g_dbus_remove_watch(btd_get_dbus_connection(), obs->id);
+ destroy_observer(obs);
+
+ if (adapter->observers == NULL) {
+ int err;
+
+ err = mgmt_set_observer(adapter->dev_id, FALSE);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+ }
DBG("Manuf. Specific Data Observer unregistered for hci%d at %s:%s",
adapter->dev_id, sender, path);
@@ -2830,6 +2984,21 @@ struct btd_adapter *adapter_create(int id)
return btd_adapter_ref(adapter);
}
+static void release_all_obs(struct btd_adapter *adapter)
+{
+ int err;
+
+ if (!adapter->observers)
+ return;
+
+ err = mgmt_set_observer(adapter->dev_id, FALSE);
+ if (err < 0)
+ error("Failed to set Observer: %s (%d)",
+ strerror(-err), -err);
+
+ g_slist_free_full(adapter->observers, destroy_observer);
+}
+
void adapter_remove(struct btd_adapter *adapter)
{
GSList *l;
@@ -2852,6 +3021,8 @@ void adapter_remove(struct btd_adapter *adapter)
g_slist_free(adapter->pin_callbacks);
+ release_all_obs(adapter);
+
if (adapter->powered)
mgmt_set_powered(adapter->dev_id, FALSE);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 15/25] eir: Add manufacturer and service data fields
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
For advertising, there are another possible fields, Service Data and
Manufacturer Specific Data.
---
src/eir.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/eir.h | 16 ++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/src/eir.c b/src/eir.c
index 1b6db8c..96adc5c 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -41,6 +41,22 @@
#define EIR_OOB_MIN (2 + 6)
+static void svc_data_free(void *p)
+{
+ struct svc_data *sdata = p;
+
+ g_free(sdata->data);
+ g_free(sdata);
+}
+
+static void manuf_data_free(void *p)
+{
+ struct manuf_data *mdata = p;
+
+ g_free(mdata->data);
+ g_free(mdata);
+}
+
void eir_data_free(struct eir_data *eir)
{
g_slist_free_full(eir->services, g_free);
@@ -51,6 +67,10 @@ void eir_data_free(struct eir_data *eir)
eir->hash = NULL;
g_free(eir->randomizer);
eir->randomizer = NULL;
+ g_slist_free_full(eir->svcs_data, svc_data_free);
+ eir->svcs_data = NULL;
+ g_slist_free_full(eir->manufs_data, manuf_data_free);
+ eir->manufs_data = NULL;
}
static void eir_parse_uuid16(struct eir_data *eir, void *data, uint8_t len)
@@ -139,6 +159,8 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len)
while (len < eir_len - 1) {
uint8_t field_len = eir_data[0];
uint8_t data_len, *data = &eir_data[2];
+ struct svc_data *sdata;
+ struct manuf_data *mdata;
/* Check for the end of EIR */
if (field_len == 0)
@@ -193,6 +215,16 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len)
(data[2] << 16);
break;
+ case EIR_SVC_DATA:
+ if (data_len < 2)
+ break;
+ sdata = g_new(struct svc_data, 1);
+ sdata->uuid = bt_get_le16(data);
+ sdata->data_len = data_len - 2;
+ sdata->data = g_memdup(data + 2, data_len - 2);
+ eir->svcs_data = g_slist_append(eir->svcs_data, sdata);
+ break;
+
case EIR_GAP_APPEARANCE:
if (data_len < 2)
break;
@@ -209,6 +241,16 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data, uint8_t eir_len)
if (data_len < 16)
break;
eir->randomizer = g_memdup(data, 16);
+
+ case EIR_MANUF_DATA:
+ if (data_len < 2)
+ break;
+ mdata = g_new(struct manuf_data, 1);
+ mdata->company_id = bt_get_le16(data);
+ mdata->data_len = data_len - 2;
+ mdata->data = g_memdup(data + 2, data_len - 2);
+ eir->manufs_data = g_slist_append(eir->manufs_data,
+ mdata);
break;
}
diff --git a/src/eir.h b/src/eir.h
index 91e045e..e410753 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -36,7 +36,21 @@
#define EIR_SSP_HASH 0x0E /* SSP Hash */
#define EIR_SSP_RANDOMIZER 0x0F /* SSP Randomizer */
#define EIR_DEVICE_ID 0x10 /* device ID */
+#define EIR_SVC_DATA 0x16 /* service data */
#define EIR_GAP_APPEARANCE 0x19 /* GAP appearance */
+#define EIR_MANUF_DATA 0xFF /* manufacturer specific data */
+
+struct svc_data {
+ uint16_t uuid;
+ uint8_t data_len;
+ uint8_t *data;
+};
+
+struct manuf_data {
+ uint16_t company_id;
+ uint8_t data_len;
+ uint8_t *data;
+};
struct eir_data {
GSList *services;
@@ -48,6 +62,8 @@ struct eir_data {
uint8_t *hash;
uint8_t *randomizer;
bdaddr_t addr;
+ GSList *svcs_data;
+ GSList *manufs_data;
};
void eir_data_free(struct eir_data *eir);
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 16/25] observer: Add Service/ManufacturerReceived() D-Bus method
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
When an advertising matches with the filter registered in
RegisterServiceObserver() or RegisterManufacturerObserver(), the data is
sent to all observers registered using ServiceReceived() or
ManufacturerReceived(), respectively.
---
src/adapter.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 116 insertions(+), 1 deletion(-)
diff --git a/src/adapter.c b/src/adapter.c
index 316acb9..4fc4fa9 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -86,6 +86,8 @@
static const char *base_path = "/org/bluez";
+#define OBSERVER_INTERFACE "org.bluez.Observer1"
+
/* Filter Types (for Observer) */
#define FILTER_SERVICE_UUID 0x01
#define FILTER_COMPANY_IC 0x02
@@ -180,6 +182,11 @@ struct btd_adapter {
static gboolean process_auth_queue(gpointer user_data);
+struct broadcast_data {
+ struct eir_data *eir_data;
+ char peer_addr[18];
+};
+
int btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
uint8_t minor)
{
@@ -3179,6 +3186,106 @@ static gboolean connect_pending_cb(gpointer user_data)
return FALSE;
}
+static void service_received(struct observer_watcher *obs, char *peer_addr,
+ struct svc_data *sdata)
+{
+ const char *paddr = peer_addr;
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_call(obs->sender, obs->path,
+ OBSERVER_INTERFACE,
+ "ServiceReceived");
+ if (msg == NULL) {
+ error("Unable to allocate new ServiceReceived method");
+ return;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &paddr,
+ DBUS_TYPE_UINT16, &sdata->uuid,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &sdata->data, sdata->data_len,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+ g_dbus_send_message(btd_get_dbus_connection(), msg);
+}
+
+static void manufacturer_received(struct observer_watcher *obs,
+ char *peer_addr, struct manuf_data *mdata)
+{
+ const char *paddr = peer_addr;
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_call(obs->sender, obs->path,
+ OBSERVER_INTERFACE,
+ "ManufacturerReceived");
+ if (msg == NULL) {
+ error("Unable to allocate new ManufacturerReceived method");
+ return;
+ }
+
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &paddr,
+ DBUS_TYPE_UINT16, &mdata->company_id,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &mdata->data, mdata->data_len,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_set_no_reply(msg, TRUE);
+ g_dbus_send_message(btd_get_dbus_connection(), msg);
+}
+
+static void update_observer(gpointer data, gpointer user_data)
+{
+ struct observer_watcher *obs = data;
+ struct broadcast_data *bdata = user_data;
+ struct eir_data *eir = bdata->eir_data;
+ GSList *l;
+
+ if (obs->filter_type == FILTER_SERVICE_UUID) {
+ for (l = eir->svcs_data; l != NULL; l = g_slist_next(l)) {
+ struct svc_data *sdata = l->data;
+ uint16_t uuid = GPOINTER_TO_UINT(obs->filter_data);
+
+ if (uuid == sdata->uuid)
+ service_received(obs, bdata->peer_addr, sdata);
+ }
+ } else if (obs->filter_type == FILTER_COMPANY_IC) {
+ for (l = eir->manufs_data; l != NULL; l = g_slist_next(l)) {
+ struct manuf_data *mdata = l->data;
+ uint16_t company_id =
+ GPOINTER_TO_UINT(obs->filter_data);
+
+ if (company_id == mdata->company_id)
+ manufacturer_received(obs, bdata->peer_addr,
+ mdata);
+ }
+ }
+}
+
+static void adapter_broadcast_received(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, struct eir_data *eir_data)
+{
+ struct broadcast_data *bdata;
+
+ /* No observers listening for advertising */
+ if (adapter->observers == NULL)
+ return;
+
+ /* No service/manufacturer data was sent */
+ if (eir_data->svcs_data == NULL && eir_data->manufs_data == NULL)
+ return;
+
+ bdata = g_new(struct broadcast_data, 1);
+ bdata->eir_data = eir_data;
+ ba2str(bdaddr, bdata->peer_addr);
+
+ DBG("Broadcast received from %s", bdata->peer_addr);
+
+ g_slist_foreach(adapter->observers, update_observer, bdata);
+
+ g_free(bdata);
+}
+
void adapter_update_found_devices(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type, int8_t rssi,
@@ -3192,7 +3299,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
int err;
GSList *l;
- if (!discovery) {
+ if (!discovery && !adapter->observers) {
error("Device found event while no discovery in progress");
return;
}
@@ -3204,6 +3311,14 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
return;
}
+ /* Send advertising to observers */
+ adapter_broadcast_received(adapter, bdaddr, &eir_data);
+
+ if (!discovery) {
+ eir_data_free(&eir_data);
+ return;
+ }
+
if (eir_data.name != NULL && eir_data.name_complete)
adapter_store_cached_name(&adapter->bdaddr, bdaddr,
eir_data.name);
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 17/25] observer: Add python test script
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
---
test/test-observer | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100755 test/test-observer
diff --git a/test/test-observer b/test/test-observer
new file mode 100755
index 0000000..04d3f05
--- /dev/null
+++ b/test/test-observer
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+
+'''Observer test script
+'''
+
+from __future__ import absolute_import, print_function, unicode_literals
+
+from gi.repository import GObject
+
+import sys
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+from optparse import OptionParser, make_option
+import bluezutils
+
+def dbus_data(data):
+ return "".join(["%02x" % c for c in data])
+
+class Observer(dbus.service.Object):
+ @dbus.service.method("org.bluez.Observer1",
+ in_signature="sqay", out_signature="")
+ def ServiceReceived(self, address, uuid, value):
+ print("[ " + address + " ]")
+ print(" Service UUID = 0x%04x" % int(uuid))
+ print(" Data = %s" % dbus_data(value))
+ print()
+
+ @dbus.service.method("org.bluez.Observer1",
+ in_signature="sqay", out_signature="")
+ def ManufacturerReceived(self, address, cid, value):
+ print("[ " + address + " ]")
+ print(" Company ID = 0x%04x" % int(cid))
+ print(" Data = %s" % dbus_data(value))
+ print()
+
+if __name__ == "__main__":
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+ bus = dbus.SystemBus()
+
+ manager = dbus.Interface(bus.get_object("org.bluez", "/"),
+ "org.bluez.Manager")
+
+ option_list = [
+ make_option("-i", "--adapter", action="store",
+ type="string", dest="adapter"),
+ make_option("-s", "--service", action="store",
+ type="int", dest="service_uuid",
+ help="Service UUID (e.g. \"0x0001\")"),
+ make_option("-c", "--company", action="store",
+ type="int", dest="company_id",
+ help="Company Identifier Code (e.g. \"0x0002\")"),
+ ]
+
+ parser = OptionParser(option_list=option_list)
+
+ (options, args) = parser.parse_args()
+
+ if not options.service_uuid and not options.company_id:
+ parser.error("At least one option is required: -c or -s")
+
+ adapter = bluezutils.find_adapter(options.adapter)
+
+ path = "/test/observer"
+ observer = Observer(bus, path)
+
+ if options.service_uuid:
+ adapter.RegisterServiceObserver(path, dbus.UInt16(options.service_uuid))
+
+ if options.company_id:
+ adapter.RegisterManufacturerObserver(path, dbus.UInt16(options.company_id))
+
+ mainloop = GObject.MainLoop()
+ mainloop.run()
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 18/25] adapter: Add D-Bus API for Broadcaster GAP Role
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
Implement dummy calls for register or unregister Broadcaster.
---
src/adapter.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 4fc4fa9..90aab94 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1413,6 +1413,24 @@ void adapter_set_controller_data_failed(struct btd_adapter *adapter)
{
}
+static DBusMessage *set_service_data(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *set_manufacturer_data(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *clear_broadcast_data(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ return dbus_message_new_method_return(msg);
+}
+
static const GDBusMethodTable adapter_methods[] = {
{ GDBUS_METHOD("StartDiscovery", NULL, NULL,
adapter_start_discovery) },
@@ -1435,6 +1453,15 @@ static const GDBusMethodTable adapter_methods[] = {
{ GDBUS_METHOD("UnregisterManufacturerObserver",
GDBUS_ARGS({ "observer", "o" }), NULL,
unregister_manuf_observer) },
+ { GDBUS_ASYNC_METHOD("SetServiceData", GDBUS_ARGS({ "uuid", "q" },
+ { "data", "ay" }), NULL,
+ set_service_data) },
+ { GDBUS_ASYNC_METHOD("SetManufacturerData",
+ GDBUS_ARGS({ "company_id", "q" },
+ { "data", "ay" }), NULL,
+ set_manufacturer_data) },
+ { GDBUS_METHOD("ClearBroadcastData", NULL, NULL,
+ clear_broadcast_data) },
{ }
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 19/25] lib: Maximum value to advertising and scan response
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Bruna Moreira
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
Create a constant to define the maximum lenght for advertising and scan
response data format.
---
lib/hci.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/hci.h b/lib/hci.h
index 56c9316..bce6b41 100644
--- a/lib/hci.h
+++ b/lib/hci.h
@@ -1505,17 +1505,19 @@ typedef struct {
} __attribute__ ((packed)) le_read_advertising_channel_tx_power_rp;
#define LE_READ_ADVERTISING_CHANNEL_TX_POWER_RP_SIZE 2
+#define HCI_LE_MAX_ADV_DATA_LENGTH 31
+
#define OCF_LE_SET_ADVERTISING_DATA 0x0008
typedef struct {
uint8_t length;
- uint8_t data[31];
+ uint8_t data[HCI_LE_MAX_ADV_DATA_LENGTH];
} __attribute__ ((packed)) le_set_advertising_data_cp;
#define LE_SET_ADVERTISING_DATA_CP_SIZE 32
#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009
typedef struct {
uint8_t length;
- uint8_t data[31];
+ uint8_t data[HCI_LE_MAX_ADV_DATA_LENGTH];
} __attribute__ ((packed)) le_set_scan_response_data_cp;
#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32
--
1.7.9.5
^ permalink raw reply related
* [PATCH BlueZ 20/25] broadcaster: Add SetService/ManufacturerData() D-Bus method
From: Bruna Moreira @ 2012-12-21 20:26 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1356121612-15172-1-git-send-email-bruna.moreira@openbossa.org>
From: Jefferson Delfes <jefferson.delfes@openbossa.org>
For SetServiceData(), receive the service UUID with advertising data
that will be set in device.
For SetManufacturerData(), receive the Company Identifier Code with
advertising data that will be set in device.
---
src/adapter.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 90aab94..60c0697 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1416,12 +1416,46 @@ void adapter_set_controller_data_failed(struct btd_adapter *adapter)
static DBusMessage *set_service_data(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ struct btd_adapter *adapter = data;
+ const char *sender;
+ uint16_t uuid;
+ uint8_t *sdata;
+ int ssize;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT16, &uuid,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &sdata, &ssize,
+ DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ sender = dbus_message_get_sender(msg);
+
+ DBG("Service Data Broadcaster registered for hci%d at %s",
+ adapter->dev_id, sender);
+
return dbus_message_new_method_return(msg);
}
static DBusMessage *set_manufacturer_data(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ struct btd_adapter *adapter = data;
+ const char *sender;
+ uint16_t company_id;
+ uint8_t *mdata;
+ int msize;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT16, &company_id,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &mdata, &msize,
+ DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ sender = dbus_message_get_sender(msg);
+
+ DBG("Manufacturer Specific Data Broadcaster registered for hci%d at %s",
+ adapter->dev_id, sender);
+
return dbus_message_new_method_return(msg);
}
--
1.7.9.5
^ 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